<commit_before>import EventEmitter from 'events';
import {Middleware, PIPE_ENCODE} from './middleware';
import {PRESET_FAILED} from '../presets/defs';
import {logger} from '../utils';

// .on('broadcast')
// .on(`pre_${direction}`)
// .on(`post_${direction}`)
export class Pipe extends EventEmitter {

  _upstream_middlewares = [];

  _downstream_middlewares = [];

  _cacheBuffer = null;

  _destroyed = false;

  get destroyed() {
    return this._destroyed;
  }

  constructor(presets) {
    super();
    this.broadcast = this.broadcast.bind(this);
    this.createMiddlewares(presets);
  }

  broadcast(name, action) {
    const middlewares = this.getMiddlewares();
    const results = [];
    for (const middleware of middlewares) {
      if (middleware.name !== name) {
        results.push(middleware.notify(action));
      }
    }
    // if no middleware handled this action, bubble up to where pipe created.
    if (name !== 'pipe' && results.every((result) => !!result === false)) {
      this.emit('broadcast', action);
    }
  }

  createMiddlewares(presets) {
    const middlewares = [];
    for (const preset of presets) {
      const middleware = new Middleware(preset);
      middleware.setMaxListeners(4);
      middleware.on('broadcast', this.broadcast);
      middleware.on('fail', (name, message) => void this.broadcast(name, {
        type: PRESET_FAILED,
        payload: {
          name,
          message,
          orgData: this._cacheBuffer
        }
      }));
      middlewares.push(middleware);
    }
    this._upstream_middlewares = middlewares;
    this._downstream_middlewares = [].concat(middlewares).reverse();
  }

  getMiddlewares(direction = PIPE_ENCODE) {
    if (direction === PIPE_ENCODE) {
      return this._upstream_middlewares;
    } else {
      return this._downstream_middlewares;
    }
  }

  feed(direction, buffer) {
    try {
      // cache the current buffer for PRESET_FAILED action
      this._cacheBuffer = buffer;
      // pre-feed hook
      const preEventName = `pre_${direction}`;
      if (this.listenerCount(preEventName) > 0) {
        this.emit(preEventName, buffer, (buf) => this._feed(direction, buf));
      } else {
        this._feed(direction, buffer);
      }
    } catch (err) {
      logger.error(`[pipe] error occurred while piping`, err);
    }
  }

  destroy() {
    const middlewares = this.getMiddlewares();
    for (const middleware of middlewares) {
      middleware.onDestroy();
    }
    this._upstream_middlewares = null;
    this._downstream_middlewares = null;
    this._cacheBuffer = null;
    this._destroyed = true;
    this.removeAllListeners();
  }

  _feed(direction, buffer) {
    const middlewares = this.getMiddlewares(direction);
    // methods to be injected
    const direct = (buf, isReverse = false) => this.emit(isReverse ? `post_${-direction}` : `post_${direction}`, buf);
    // create event chain among middlewares
    const event = `next_${direction}`;
    const first = middlewares[0];
    if (!first.hasListener(event)) {
      const last = middlewares.reduce((prev, next) => {
        prev.on(event, (buf) => next.write(direction, {buffer: buf, direct}));
        return next;
      });
      // the last middleware send data out via direct(buf, false)
      last.on(event, direct);
    }
    // begin pipe
    first.write(direction, {buffer, direct});
  }

}
<commit_msg>core: fix lint error<commit_after>import EventEmitter from 'events';
import {Middleware, PIPE_ENCODE} from './middleware';
import {PRESET_FAILED} from '../presets/defs';
import {logger} from '../utils';

// .on('broadcast')
// .on(`pre_${direction}`)
// .on(`post_${direction}`)
export class Pipe extends EventEmitter {

  _upstream_middlewares = [];

  _downstream_middlewares = [];

  _cacheBuffer = null;

  _destroyed = false;

  get destroyed() {
    return this._destroyed;
  }

  constructor(presets) {
    super();
    this.broadcast = this.broadcast.bind(this);
    this.createMiddlewares(presets);
  }

  broadcast(name, action) {
    const middlewares = this.getMiddlewares();
    const results = [];
    for (const middleware of middlewares) {
      if (middleware.name !== name) {
        results.push(middleware.notify(action));
      }
    }
    // if no middleware handled this action, bubble up to where pipe created.
    if (name !== 'pipe' && results.every((result) => !!result === false)) {
      this.emit('broadcast', action);
    }
  }

  createMiddlewares(presets) {
    const middlewares = [];
    for (const preset of presets) {
      const middleware = new Middleware(preset);
      middleware.setMaxListeners(4);
      middleware.on('broadcast', this.broadcast);
      middleware.on('fail', (name, message) => void this.broadcast(name, {
        type: PRESET_FAILED,
        payload: {
          name,
          message,
          orgData: this._cacheBuffer
        }
      }));
      middlewares.push(middleware);
    }
    this._upstream_middlewares = middlewares;
    this._downstream_middlewares = [].concat(middlewares).reverse();
  }

  getMiddlewares(direction = PIPE_ENCODE) {
    if (direction === PIPE_ENCODE) {
      return this._upstream_middlewares;
    } else {
      return this._downstream_middlewares;
    }
  }

  feed(direction, buffer) {
    try {
      // cache the current buffer for PRESET_FAILED action
      this._cacheBuffer = buffer;
      // pre-feed hook
      const preEventName = `pre_${direction}`;
      if (this.listenerCount(preEventName) > 0) {
        this.emit(preEventName, buffer, (buf) => this._feed(direction, buf));
      } else {
        this._feed(direction, buffer);
      }
    } catch (err) {
      logger.error('[pipe] error occurred while piping', err);
    }
  }

  destroy() {
    const middlewares = this.getMiddlewares();
    for (const middleware of middlewares) {
      middleware.onDestroy();
    }
    this._upstream_middlewares = null;
    this._downstream_middlewares = null;
    this._cacheBuffer = null;
    this._destroyed = true;
    this.removeAllListeners();
  }

  _feed(direction, buffer) {
    const middlewares = this.getMiddlewares(direction);
    // methods to be injected
    const direct = (buf, isReverse = false) => this.emit(isReverse ? `post_${-direction}` : `post_${direction}`, buf);
    // create event chain among middlewares
    const event = `next_${direction}`;
    const first = middlewares[0];
    if (!first.hasListener(event)) {
      const last = middlewares.reduce((prev, next) => {
        prev.on(event, (buf) => next.write(direction, {buffer: buf, direct}));
        return next;
      });
      // the last middleware send data out via direct(buf, false)
      last.on(event, direct);
    }
    // begin pipe
    first.write(direction, {buffer, direct});
  }

}
<|endoftext|>


<commit_before>'use strict';

module.exports = {
	parserOptions: {
		ecmaVersion: 2018,
		sourceType: 'module',
		ecmaFeatures: {
			jsx: true
		}
	},
	env: {
		node: true,
		es6: true
	},
	rules: {
		'comma-dangle': ['error', 'never'],
		'for-direction': 'error',
		'getter-return': 'error',
		'no-async-promise-executor': 'error',
		'no-await-in-loop': 'error',
		'no-compare-neg-zero': 'error',
		'no-cond-assign': 'error',
		'no-constant-condition': 'error',
		'no-control-regex': 'error',
		'no-debugger': 'error',
		'no-dupe-args': 'error',
		'no-dupe-keys': 'error',
		'no-duplicate-case': 'error',
		'no-empty-character-class': 'error',
		'no-empty': ['error', {
			allowEmptyCatch: true
		}],
		'no-ex-assign': 'error',
		'no-extra-boolean-cast': 'error',
		// Disabled because of https://github.com/eslint/eslint/issues/6028
		// 'no-extra-parens': [2, 'all', {
		// 	nestedBinaryExpressions: false,
		// 	ignoreJSX: 'multi-line'
		// }],
		'no-extra-semi': 'error',
		'no-func-assign': 'error',
		'no-inner-declarations': 'error',
		'no-invalid-regexp': 'error',
		'no-irregular-whitespace': 'error',
		'no-misleading-character-class': 'error',
		'no-obj-calls': 'error',
		'no-prototype-builtins': 'error',
		'no-regex-spaces': 'error',
		'no-sparse-arrays': 'error',
		'no-template-curly-in-string': 'error',
		'no-unreachable': 'error',
		'no-unsafe-finally': 'error',
		'no-unsafe-negation': 'error',
		'require-atomic-updates': 'error',
		'use-isnan': 'error',
		'valid-typeof': ['error', {requireStringLiterals: false}],
		'no-unexpected-multiline': 'error',
		'accessor-pairs': 'error',
		'array-callback-return': 'error',
		'block-scoped-var': 'error',
		complexity: 'warn',
		curly: 'error',
		'default-case': 'error',
		'dot-notation': 'error',
		'dot-location': ['error', 'property'],
		eqeqeq: 'error',
		'guard-for-in': 'error',
		'no-alert': 'error',
		'no-caller': 'error',
		'no-case-declarations': 'error',
		'no-div-regex': 'error',
		'no-else-return': ['error', {
			allowElseIf: false
		}],
		'no-empty-pattern': 'error',
		'no-eq-null': 'error',
		'no-eval': 'error',
		'no-extend-native': 'error',
		'no-extra-bind': 'error',
		'no-extra-label': 'error',
		'no-fallthrough': 'error',
		'no-floating-decimal': 'error',
		'no-global-assign': 'error',
		'no-implicit-coercion': 'error',
		'no-implicit-globals': 'error',
		'no-implied-eval': 'error',
		'no-iterator': 'error',
		'no-labels': 'error',
		'no-lone-blocks': 'error',
		'no-multi-spaces': 'error',
		'no-multi-str': 'error',
		'no-new-func': 'error',
		'no-new-wrappers': 'error',
		'no-new': 'error',
		'no-octal-escape': 'error',
		'no-octal': 'error',
		'no-proto': 'error',
		'no-redeclare': 'error',
		'no-return-assign': ['error', 'always'],
		'no-return-await': 'error',
		'no-script-url': 'error',
		'no-self-assign': ['error', {props: true}],
		'no-self-compare': 'error',
		'no-sequences': 'error',
		'no-throw-literal': 'error',
		'no-unmodified-loop-condition': 'error',
		'no-unused-expressions': 'error',
		'no-unused-labels': 'error',
		'no-useless-call': 'error',
		'no-useless-concat': 'error',
		'no-useless-escape': 'error',
		'no-useless-return': 'error',
		'no-void': 'error',
		'no-warning-comments': 'warn',
		'no-with': 'error',
		'prefer-promise-reject-errors': ['error', {allowEmptyReject: true}],
		radix: 'error',
		'require-await': 'error',

		// Disabled for now as it causes too much churn
		// TODO: Enable it in the future when I have time to deal with
		// the churn and the rule is stable and has an autofixer
		// 'require-unicode-regexp': 'error',

		'wrap-iife': ['error', 'inside', {functionPrototypeMethods: true}],
		yoda: 'error',
		'no-delete-var': 'error',
		'no-label-var': 'error',
		'no-restricted-globals': ['error', 'event'],
		'no-shadow-restricted-names': 'error',
		'no-undef-init': 'error',
		'no-undef': ['error', {
			typeof: true
		}],
		'no-unused-vars': ['error', {
			ignoreRestSiblings: true,
			argsIgnorePattern: '^_$'
		}],
		// Disabled because of https://github.com/eslint/eslint/issues/3420
		// 'callback-return': ['warn', ['cb', 'callback', 'next', 'done']],
		'handle-callback-err': 'warn',
		'no-buffer-constructor': 'error',
		'no-mixed-requires': ['error', {
			grouping: true,
			allowCall: true
		}],
		'no-new-require': 'error',
		'no-path-concat': 'error',
		'no-restricted-imports': ['error', 'domain', 'freelist', 'smalloc', 'sys', 'colors'],
		'no-restricted-modules': ['error', 'domain', 'freelist', 'smalloc', 'sys', 'colors'],
		'array-bracket-newline': ['error', 'consistent'],
		'array-bracket-spacing': ['error', 'never'],
		'array-element-newline': ['error', 'consistent'],
		'brace-style': ['error', '1tbs', {
			allowSingleLine: false
		}],
		camelcase: ['error', {
			properties: 'always'
		}],
		'capitalized-comments': ['error', 'always', {
			// You can also ignore this rule by wrapping the first word in quotes
			ignorePattern: 'pragma|ignore|prettier-ignore',
			ignoreInlineComments: true,
			ignoreConsecutiveComments: true
		}],
		'comma-spacing': ['error', {
			before: false,
			after: true
		}],
		'comma-style': ['error', 'last'],
		'computed-property-spacing': ['error', 'never'],
		'eol-last': 'error',
		'func-call-spacing': ['error', 'never'],
		'func-name-matching': ['error', {considerPropertyDescriptor: true}],
		'func-names': ['error', 'never'],
		indent: ['error', 'tab', {
			SwitchCase: 1
		}],
		'jsx-quotes': 'error',
		'key-spacing': ['error', {
			beforeColon: false,
			afterColon: true
		}],
		'keyword-spacing': 'error',
		'linebreak-style': [(process.platform === 'win32' ? 'off' : 'error'), 'unix'],
		'lines-between-class-members': ['error', 'always'],
		'max-depth': 'warn',
		'max-nested-callbacks': ['warn', 4],
		'max-params': ['warn', {
			max: 4
		}],
		'max-statements-per-line': 'error',
		'new-cap': ['error', {
			newIsCap: true,
			capIsNew: true
		}],
		'new-parens': 'error',
		'no-array-constructor': 'error',
		'no-lonely-if': 'error',
		'no-mixed-operators': 'error',
		'no-mixed-spaces-and-tabs': 'error',
		'no-multi-assign': 'error',
		'no-multiple-empty-lines': ['error', {
			max: 1
		}],
		'no-negated-condition': 'error',
		'no-new-object': 'error',
		'no-restricted-syntax': ['error', 'WithStatement'],
		'no-whitespace-before-property': 'error',
		'no-trailing-spaces': 'error',
		'no-unneeded-ternary': 'error',
		'object-curly-spacing': ['error', 'never'],
		// Disabled because of https://github.com/xojs/eslint-config-xo/issues/27
		// 'object-property-newline': 'error',
		'one-var': ['error', 'never'],
		'one-var-declaration-per-line': 'error',
		'operator-assignment': ['error', 'always'],
		'operator-linebreak': ['error', 'after'],
		'padded-blocks': ['error', 'never'],
		'quote-props': ['error', 'as-needed'],
		quotes: ['error', 'single'],
		'semi-spacing': ['error', {
			before: false,
			after: true
		}],
		'semi-style': ['error', 'last'],
		semi: ['error', 'always'],
		'space-before-blocks': ['error', 'always'],
		'space-before-function-paren': ['error', {
			anonymous: 'always',
			named: 'never',
			asyncArrow: 'always'
		}],
		'space-in-parens': ['error', 'never'],
		'space-infix-ops': 'error',
		'space-unary-ops': 'error',
		'spaced-comment': ['error', 'always', {
			line: {
				exceptions: ['-', '+', '*'],
				markers: ['!', '/']
			},
			block: {
				exceptions: ['-', '+', '*'],
				markers: ['!', '*'],
				balanced: true
			}
		}],
		'switch-colon-spacing': ['error', {
			after: true,
			before: false
		}],
		'template-tag-spacing': ['error', 'never'],
		'unicode-bom': ['error', 'never'],
		'arrow-parens': ['error', 'as-needed'],
		'arrow-spacing': ['error', {
			before: true,
			after: true
		}],
		'constructor-super': 'error',
		'generator-star-spacing': ['error', 'both'],
		'no-class-assign': 'error',
		'no-const-assign': 'error',
		'no-dupe-class-members': 'error',
		'no-new-symbol': 'error',
		'no-this-before-super': 'error',
		'no-useless-computed-key': 'error',
		'no-useless-constructor': 'error',
		'no-useless-rename': 'error',
		'require-yield': 'error',
		'rest-spread-spacing': ['error', 'never'],
		'symbol-description': 'error',
		'template-curly-spacing': 'error',
		'yield-star-spacing': ['error', 'both'],
		'valid-jsdoc': ['warn', {
			'requireReturn': false,
			'requireParamDescription': true,
			'requireReturnDescription': true
		}]
	}
};
<commit_msg>Allow `//=> foo`-style comments<commit_after>'use strict';

module.exports = {
	parserOptions: {
		ecmaVersion: 2018,
		sourceType: 'module',
		ecmaFeatures: {
			jsx: true
		}
	},
	env: {
		node: true,
		es6: true
	},
	rules: {
		'comma-dangle': ['error', 'never'],
		'for-direction': 'error',
		'getter-return': 'error',
		'no-async-promise-executor': 'error',
		'no-await-in-loop': 'error',
		'no-compare-neg-zero': 'error',
		'no-cond-assign': 'error',
		'no-constant-condition': 'error',
		'no-control-regex': 'error',
		'no-debugger': 'error',
		'no-dupe-args': 'error',
		'no-dupe-keys': 'error',
		'no-duplicate-case': 'error',
		'no-empty-character-class': 'error',
		'no-empty': ['error', {
			allowEmptyCatch: true
		}],
		'no-ex-assign': 'error',
		'no-extra-boolean-cast': 'error',
		// Disabled because of https://github.com/eslint/eslint/issues/6028
		// 'no-extra-parens': [2, 'all', {
		// 	nestedBinaryExpressions: false,
		// 	ignoreJSX: 'multi-line'
		// }],
		'no-extra-semi': 'error',
		'no-func-assign': 'error',
		'no-inner-declarations': 'error',
		'no-invalid-regexp': 'error',
		'no-irregular-whitespace': 'error',
		'no-misleading-character-class': 'error',
		'no-obj-calls': 'error',
		'no-prototype-builtins': 'error',
		'no-regex-spaces': 'error',
		'no-sparse-arrays': 'error',
		'no-template-curly-in-string': 'error',
		'no-unreachable': 'error',
		'no-unsafe-finally': 'error',
		'no-unsafe-negation': 'error',
		'require-atomic-updates': 'error',
		'use-isnan': 'error',
		'valid-typeof': ['error', {requireStringLiterals: false}],
		'no-unexpected-multiline': 'error',
		'accessor-pairs': 'error',
		'array-callback-return': 'error',
		'block-scoped-var': 'error',
		complexity: 'warn',
		curly: 'error',
		'default-case': 'error',
		'dot-notation': 'error',
		'dot-location': ['error', 'property'],
		eqeqeq: 'error',
		'guard-for-in': 'error',
		'no-alert': 'error',
		'no-caller': 'error',
		'no-case-declarations': 'error',
		'no-div-regex': 'error',
		'no-else-return': ['error', {
			allowElseIf: false
		}],
		'no-empty-pattern': 'error',
		'no-eq-null': 'error',
		'no-eval': 'error',
		'no-extend-native': 'error',
		'no-extra-bind': 'error',
		'no-extra-label': 'error',
		'no-fallthrough': 'error',
		'no-floating-decimal': 'error',
		'no-global-assign': 'error',
		'no-implicit-coercion': 'error',
		'no-implicit-globals': 'error',
		'no-implied-eval': 'error',
		'no-iterator': 'error',
		'no-labels': 'error',
		'no-lone-blocks': 'error',
		'no-multi-spaces': 'error',
		'no-multi-str': 'error',
		'no-new-func': 'error',
		'no-new-wrappers': 'error',
		'no-new': 'error',
		'no-octal-escape': 'error',
		'no-octal': 'error',
		'no-proto': 'error',
		'no-redeclare': 'error',
		'no-return-assign': ['error', 'always'],
		'no-return-await': 'error',
		'no-script-url': 'error',
		'no-self-assign': ['error', {props: true}],
		'no-self-compare': 'error',
		'no-sequences': 'error',
		'no-throw-literal': 'error',
		'no-unmodified-loop-condition': 'error',
		'no-unused-expressions': 'error',
		'no-unused-labels': 'error',
		'no-useless-call': 'error',
		'no-useless-concat': 'error',
		'no-useless-escape': 'error',
		'no-useless-return': 'error',
		'no-void': 'error',
		'no-warning-comments': 'warn',
		'no-with': 'error',
		'prefer-promise-reject-errors': ['error', {allowEmptyReject: true}],
		radix: 'error',
		'require-await': 'error',

		// Disabled for now as it causes too much churn
		// TODO: Enable it in the future when I have time to deal with
		// the churn and the rule is stable and has an autofixer
		// 'require-unicode-regexp': 'error',

		'wrap-iife': ['error', 'inside', {functionPrototypeMethods: true}],
		yoda: 'error',
		'no-delete-var': 'error',
		'no-label-var': 'error',
		'no-restricted-globals': ['error', 'event'],
		'no-shadow-restricted-names': 'error',
		'no-undef-init': 'error',
		'no-undef': ['error', {
			typeof: true
		}],
		'no-unused-vars': ['error', {
			ignoreRestSiblings: true,
			argsIgnorePattern: '^_$'
		}],
		// Disabled because of https://github.com/eslint/eslint/issues/3420
		// 'callback-return': ['warn', ['cb', 'callback', 'next', 'done']],
		'handle-callback-err': 'warn',
		'no-buffer-constructor': 'error',
		'no-mixed-requires': ['error', {
			grouping: true,
			allowCall: true
		}],
		'no-new-require': 'error',
		'no-path-concat': 'error',
		'no-restricted-imports': ['error', 'domain', 'freelist', 'smalloc', 'sys', 'colors'],
		'no-restricted-modules': ['error', 'domain', 'freelist', 'smalloc', 'sys', 'colors'],
		'array-bracket-newline': ['error', 'consistent'],
		'array-bracket-spacing': ['error', 'never'],
		'array-element-newline': ['error', 'consistent'],
		'brace-style': ['error', '1tbs', {
			allowSingleLine: false
		}],
		camelcase: ['error', {
			properties: 'always'
		}],
		'capitalized-comments': ['error', 'always', {
			// You can also ignore this rule by wrapping the first word in quotes
			ignorePattern: 'pragma|ignore|prettier-ignore',
			ignoreInlineComments: true,
			ignoreConsecutiveComments: true
		}],
		'comma-spacing': ['error', {
			before: false,
			after: true
		}],
		'comma-style': ['error', 'last'],
		'computed-property-spacing': ['error', 'never'],
		'eol-last': 'error',
		'func-call-spacing': ['error', 'never'],
		'func-name-matching': ['error', {considerPropertyDescriptor: true}],
		'func-names': ['error', 'never'],
		indent: ['error', 'tab', {
			SwitchCase: 1
		}],
		'jsx-quotes': 'error',
		'key-spacing': ['error', {
			beforeColon: false,
			afterColon: true
		}],
		'keyword-spacing': 'error',
		'linebreak-style': [(process.platform === 'win32' ? 'off' : 'error'), 'unix'],
		'lines-between-class-members': ['error', 'always'],
		'max-depth': 'warn',
		'max-nested-callbacks': ['warn', 4],
		'max-params': ['warn', {
			max: 4
		}],
		'max-statements-per-line': 'error',
		'new-cap': ['error', {
			newIsCap: true,
			capIsNew: true
		}],
		'new-parens': 'error',
		'no-array-constructor': 'error',
		'no-lonely-if': 'error',
		'no-mixed-operators': 'error',
		'no-mixed-spaces-and-tabs': 'error',
		'no-multi-assign': 'error',
		'no-multiple-empty-lines': ['error', {
			max: 1
		}],
		'no-negated-condition': 'error',
		'no-new-object': 'error',
		'no-restricted-syntax': ['error', 'WithStatement'],
		'no-whitespace-before-property': 'error',
		'no-trailing-spaces': 'error',
		'no-unneeded-ternary': 'error',
		'object-curly-spacing': ['error', 'never'],
		// Disabled because of https://github.com/xojs/eslint-config-xo/issues/27
		// 'object-property-newline': 'error',
		'one-var': ['error', 'never'],
		'one-var-declaration-per-line': 'error',
		'operator-assignment': ['error', 'always'],
		'operator-linebreak': ['error', 'after'],
		'padded-blocks': ['error', 'never'],
		'quote-props': ['error', 'as-needed'],
		quotes: ['error', 'single'],
		'semi-spacing': ['error', {
			before: false,
			after: true
		}],
		'semi-style': ['error', 'last'],
		semi: ['error', 'always'],
		'space-before-blocks': ['error', 'always'],
		'space-before-function-paren': ['error', {
			anonymous: 'always',
			named: 'never',
			asyncArrow: 'always'
		}],
		'space-in-parens': ['error', 'never'],
		'space-infix-ops': 'error',
		'space-unary-ops': 'error',
		'spaced-comment': ['error', 'always', {
			line: {
				exceptions: ['-', '+', '*'],
				markers: ['!', '/', '=>']
			},
			block: {
				exceptions: ['-', '+', '*'],
				markers: ['!', '*'],
				balanced: true
			}
		}],
		'switch-colon-spacing': ['error', {
			after: true,
			before: false
		}],
		'template-tag-spacing': ['error', 'never'],
		'unicode-bom': ['error', 'never'],
		'arrow-parens': ['error', 'as-needed'],
		'arrow-spacing': ['error', {
			before: true,
			after: true
		}],
		'constructor-super': 'error',
		'generator-star-spacing': ['error', 'both'],
		'no-class-assign': 'error',
		'no-const-assign': 'error',
		'no-dupe-class-members': 'error',
		'no-new-symbol': 'error',
		'no-this-before-super': 'error',
		'no-useless-computed-key': 'error',
		'no-useless-constructor': 'error',
		'no-useless-rename': 'error',
		'require-yield': 'error',
		'rest-spread-spacing': ['error', 'never'],
		'symbol-description': 'error',
		'template-curly-spacing': 'error',
		'yield-star-spacing': ['error', 'both'],
		'valid-jsdoc': ['warn', {
			'requireReturn': false,
			'requireParamDescription': true,
			'requireReturnDescription': true
		}]
	}
};
<|endoftext|>


<commit_before>
require('dotenv').config();

const vorpal = require('vorpal')();
const importer = require('./src/modules/importer');

vorpal
    .command('import', 'Launch the import script')
    .action(function(args, next) {
        importer.run(
            process.env.WP_JSON_ENDPOINT,
            process.env.WP_USER,
            process.env.WP_PASSWORD
        );
        next();
    });

vorpal
    .delimiter('WPimport')
    .show();
<commit_msg>[master] Add start and nb argument to cli<commit_after>
require('dotenv').config();

const vorpal    = require('vorpal')();
const importer  = require('./src/modules/importer');

vorpal
    .command('import', 'Launch the import script')
    .action(function(args, next) {
        importer.auth(
            process.env.WP_JSON_ENDPOINT,
            process.env.WP_USER,
            process.env.WP_PASSWORD
        );
        importer.run( args.start || 0, args.nb || 1);
        next();
    });

vorpal
    .delimiter('WPimport')
    .show();
<|endoftext|>


<commit_before>var http = require('http');
var ws = require('ws');
var path = require('path');
var events = require('events');
var util = require('util');
var async = require('async');
var url = require('url');

var ChromeConnection = (function() {
  function ChromeConnection(port, host) {
    events.EventEmitter.call(this);

    this._port = port;
    this._host = host;

    this._callbacks = [];
    this._counter = 0;

    this._scripts = [];
    this._console = new events.EventEmitter();
  }

  util.inherits(ChromeConnection, events.EventEmitter);

  Object.defineProperty(ChromeConnection.prototype, 'console', {
    get: function() {
      return this._console;
    },
  });

  ChromeConnection.prototype._send = function(method, params, callback) {
    var id = this._counter++;

    var message = {
      id: id,
      method: method,
      params: params
    };

    this._callbacks[id] = callback;

    try {
      this._socket.send(JSON.stringify(message));
    } catch (error) {
      return callback(error);
    }
  };

  ChromeConnection.prototype._process = function(message) {
    if (message.id !== undefined) {
      var callback = this._callbacks[message.id];

      if (callback) {
        if (message.error) {
          callback(message.error);
        } else if (message.params) {
          callback(null, message.params);
        } else if (message.result) {
          callback(null, message.result);
        }

        delete this._callbacks[message.id];
      }
    } else {
      if (message.method == 'Debugger.scriptParsed') {
        this._scripts.push(message.params);
      } else if (message.method == 'Console.messageAdded') {
        this._console.emit('data', message.params.message);
      }
    }
  };

  ChromeConnection.prototype.targets = function(callback) {
    var options = {
      host: this._host,
      port: this._port,
      path: '/json'
    };

    var self = this;
    var request = http.get(options, function(response) {
      var data = '';

      response.on('data', function(chunk) {
        data += chunk;
      });

      response.on('end', function() {
        var targets = JSON.parse(data);
        callback(targets);
      });
    });

    request.on('error', function(error) {
      self.emit('error', error);
    });
  };

  ChromeConnection.prototype.attach = function attach(target) {
    var socket = ws.connect(target.webSocketDebuggerUrl);

    var self = this;
    var send = self._send.bind(self);

    socket.on('open', function() {
      async.series([
        async.apply(send, 'Debugger.enable', {}),
        async.apply(send, 'Runtime.enable', {}),
        async.apply(send, 'Console.enable', {}),
      ], function(error) {
        if (error) {
          return self.emit('error', error);
        }

        self.emit('attach', target);
      });
    });

    socket.on('close', function() {
      self.emit('detatch', target);
    });

    socket.on('error', function(error) {
      self.emit('error', error);
    });

    socket.on('message', function(data) {
      try {
        var message = JSON.parse(data);
        self._process(message);
      } catch (error) {
        self.emit('error', error);
      }
    });

    this._socket = socket;
  };

  ChromeConnection.prototype.evaluate = function evaluate(expression, callback) {
    var params = {
      expression: expression,
    };

    this._send('Runtime.evaluate', params, function evaluate(error, params) {
      if (error) {
        return callback(error);
      }

      callback(null, params.result);
    });
  };

  ChromeConnection.prototype.scripts = function scripts(callback) {
    callback(this._scripts);
  };

  ChromeConnection.prototype.source = function source(script, contents, callback) {
    var params = {
      scriptId: script.scriptId,
      scriptSource: contents
    };

    var self = this;
    this._send('Debugger.setScriptSource', params, function(error, params) {
      if (error) {
        if (callback) {
          return callback(error);
        } else {
          return self.emit('error', error);
        }
      }

      self.emit('source', script);

      if (callback) {
        callback(null, params);
      }
    });
  };

  return ChromeConnection;
}());

function connect(port, host, callback) {
  var client = new ChromeConnection(port, host);

  if (callback) {
    client.on('attach', callback);
  }

  return client;
}

module.exports.connect = connect;
<commit_msg>Reset scripts on connect/close<commit_after>var http = require('http');
var ws = require('ws');
var path = require('path');
var events = require('events');
var util = require('util');
var async = require('async');
var url = require('url');

var ChromeConnection = (function() {
  function ChromeConnection(port, host) {
    events.EventEmitter.call(this);

    this._port = port;
    this._host = host;

    this._callbacks = [];
    this._counter = 0;

    this._scripts = [];
    this._console = new events.EventEmitter();
  }

  util.inherits(ChromeConnection, events.EventEmitter);

  Object.defineProperty(ChromeConnection.prototype, 'console', {
    get: function() {
      return this._console;
    },
  });

  ChromeConnection.prototype._send = function(method, params, callback) {
    var id = this._counter++;

    var message = {
      id: id,
      method: method,
      params: params
    };

    this._callbacks[id] = callback;

    try {
      this._socket.send(JSON.stringify(message));
    } catch (error) {
      return callback(error);
    }
  };

  ChromeConnection.prototype._process = function(message) {
    if (message.id !== undefined) {
      var callback = this._callbacks[message.id];

      if (callback) {
        if (message.error) {
          callback(message.error);
        } else if (message.params) {
          callback(null, message.params);
        } else if (message.result) {
          callback(null, message.result);
        }

        delete this._callbacks[message.id];
      }
    } else {
      if (message.method == 'Debugger.scriptParsed') {
        this._scripts.push(message.params);
      } else if (message.method == 'Console.messageAdded') {
        this._console.emit('data', message.params.message);
      }
    }
  };

  ChromeConnection.prototype.targets = function(callback) {
    var options = {
      host: this._host,
      port: this._port,
      path: '/json'
    };

    var self = this;
    var request = http.get(options, function(response) {
      var data = '';

      response.on('data', function(chunk) {
        data += chunk;
      });

      response.on('end', function() {
        var targets = JSON.parse(data);
        callback(targets);
      });
    });

    request.on('error', function(error) {
      self.emit('error', error);
    });
  };

  ChromeConnection.prototype.attach = function attach(target) {
    var socket = ws.connect(target.webSocketDebuggerUrl);

    var self = this;
    var send = self._send.bind(self);

    socket.on('open', function() {
      self._scripts = [];

      async.series([
        async.apply(send, 'Debugger.enable', {}),
        async.apply(send, 'Runtime.enable', {}),
        async.apply(send, 'Console.enable', {}),
      ], function(error) {
        if (error) {
          return self.emit('error', error);
        }

        self.emit('attach', target);
      });
    });

    socket.on('close', function() {
      self._scripts = [];

      self.emit('detatch', target);
    });

    socket.on('error', function(error) {
      self.emit('error', error);
    });

    socket.on('message', function(data) {
      try {
        var message = JSON.parse(data);
        self._process(message);
      } catch (error) {
        self.emit('error', error);
      }
    });

    this._socket = socket;
  };

  ChromeConnection.prototype.evaluate = function evaluate(expression, callback) {
    var params = {
      expression: expression,
    };

    this._send('Runtime.evaluate', params, function evaluate(error, params) {
      if (error) {
        return callback(error);
      }

      callback(null, params.result);
    });
  };

  ChromeConnection.prototype.scripts = function scripts(callback) {
    callback(this._scripts);
  };

  ChromeConnection.prototype.source = function source(script, contents, callback) {
    var params = {
      scriptId: script.scriptId,
      scriptSource: contents
    };

    var self = this;
    this._send('Debugger.setScriptSource', params, function(error, params) {
      if (error) {
        if (callback) {
          return callback(error);
        } else {
          return self.emit('error', error);
        }
      }

      self.emit('source', script);

      if (callback) {
        callback(null, params);
      }
    });
  };

  return ChromeConnection;
}());

function connect(port, host, callback) {
  var client = new ChromeConnection(port, host);

  if (callback) {
    client.on('attach', callback);
  }

  return client;
}

module.exports.connect = connect;
<|endoftext|>


<commit_before>const css = require('css');
const R = require('ramda');
const fs = require('fs');

fs.readFile(__dirname + '/test.css', function (err, data) {
    if (err) {
        throw err;
    }
    parse(data);
});

let parse = function (data) {
    // parse data file
    let obj = css.parse(data.toString(), { silent: false });

    // validation
    let isStylesheet = R.equals(obj.type, 'stylesheet');
    if (!isStylesheet) {
        throw 'file is not a stylesheet';
    }
    let hasParsingErrors = R.length(obj.stylesheet.parsingErrors.length) > 0;
    if (hasParsingErrors) {
        throw 'file has parsing errors';
    }
    var predRulesKeyframes = (rule) => rule.type === 'keyframes';
    let hasKeyframes = R.any(predRulesKeyframes, obj.stylesheet.rules);
    if (!hasKeyframes) {
        throw 'file does not contain keyframes rules';
    }
    var krs = obj.stylesheet.rules.filter(function (rule) {
        return rule.type === 'keyframes'
    });
    debugger
    var result = {};
    krs.forEach(function (kr) {
        result[kr.name] = [];
        kr.keyframes.forEach(function (kf) {
            kf.values.forEach(function (v) {
                var r = {};
                kf.declarations.forEach(function (d) {
                    var vNew;
                    vNew = v;
                    if (v === 'from') {
                        vNew = 0;
                    } else if (v === 'to') {
                        vNew = 100;
                    } else {
                        vNew = parseFloat(v);
                    }
                    r.offset = vNew;
                    r[d.property] = d.value;
                    result[kr.name].push(r);
                });
            });
        });
    });

    debugger
    // get all rules with type keyframes
    // for each rule keyframe take values
    // for each values
    // loop in declarations
    // create an object for result for each property and value

    var result = [];
    debugger

    console.log(obj);

    //let result = css.stringify(obj);
    //console.log(JSON.stringify(result));
};

<commit_msg>Add logic object creation<commit_after>const css = require('css');
const R = require('ramda');
const fs = require('fs');

fs.readFile(__dirname + '/test.css', function (err, data) {
    if (err) {
        throw err;
    }
    parse(data);
});

let parse = function (data) {
    // parse data file
    let obj = css.parse(data.toString(), { silent: false });

    // validation
    let isStylesheet = R.equals(obj.type, 'stylesheet');
    if (!isStylesheet) {
        throw 'file is not a stylesheet';
    }
    let hasParsingErrors = R.length(obj.stylesheet.parsingErrors.length) > 0;
    if (hasParsingErrors) {
        throw 'file has parsing errors';
    }
    var predRulesKeyframes = (rule) => rule.type === 'keyframes';
    let hasKeyframes = R.any(predRulesKeyframes, obj.stylesheet.rules);
    if (!hasKeyframes) {
        throw 'file does not contain keyframes rules';
    }
    var kfs = obj.stylesheet.rules.filter(function (rule) {
        return rule.type === 'keyframes'
    });
    debugger
    var result = {};
    // keyframes
    kfs.forEach(function (kf) {
        result[kf.name] = [];
        kf.keyframes.forEach(function (kfi) {
            kfi.values.forEach(function (v) {
                var r = {};
                var vNew;
                vNew = v;
                if (v === 'from') {
                    vNew = 0;
                } else if (v === 'to') {
                    vNew = 100;
                } else {
                    vNew = parseFloat(v);
                }
                r.offset = vNew;
                kfi.declarations.forEach(function (d) {
                    r[d.property] = d.value;

                });
                result[kf.name].push(r);
            });
        });
    });

    debugger
    // get all rules with type keyframes
    // for each rule keyframe take values
    // for each values
    // loop in declarations
    // create an object for result for each property and value

    var result = [];
    debugger

    console.log(obj);

    //let result = css.stringify(obj);
    //console.log(JSON.stringify(result));
};

<|endoftext|>


<commit_before>/// <reference path="../../typings/chrome/chrome.d.ts" />
/// <reference path="../../typings/tinyacc/tinyacc.intern.d.ts" />

'use strict';

/** create a delayed function, with a `cancel()` method */
function delayFunc(fn, timeout) {
	var timeout = 0;
	var args = [];
	var self = null;

	function timeoutCallback() {
		timeout = 0;
		fn.apply(self, args);
	}

	function call() {
		self = this;
		args = arguments;
		if (!timeout) timeout = setTimeout(timeoutCallback, timeout);
	}

	call.cancel = function() {
		if (timeout) {
			timeout = 0;
			clearTimeout(timeout);
		}
	}

	return call;
}

/** create a throttled Function */
function throttle(fn, timespan) {
	var timeout = 0;
	var nextTrig = 0;
	var _this, _args;

	function timeoutCallback() {
		timeout = 0;
		call.apply(_this, _args);
	}

	function call() {
		var now = +new Date();
		if (now >= nextTrig) {
			nextTrig = now + timespan;
			fn.apply(this, arguments);
		} else {
			_this = this;
			_args = arguments;
			if (!timeout) timeout = setTimeout(timeoutCallback, nextTrig - now);
		}
	}

	return call;
}

/**
 * Extract content from the range
 *
 * @param {Range} range
 */
function extract(range) {
	var tempDiv = document.createElement('div')
	var content = range.cloneContents()

	tempDiv.innerHTML = ''
	tempDiv.appendChild(content)

	var html = tempDiv.innerHTML
	var text = tempDiv.innerText.trim()

	return {
		html: html,
		text: text
	}
}

/** The TinyAcc Box class */
class TinyAccBox {
	constructor(box_info) {
		this.visible = false;
		this.position = { x: 0, y: 0, rects: [] };

		var container = this.container = document.createElement('div');
		var root = this.root = container.createShadowRoot();

		root.innerHTML = '<style style="display:none">\n' + box_info.style + '\n</style>' + box_info.html;

		/** @type {HTMLElement} */
		var div = root.querySelector('#box');
		this.div = div;
		this.view = root.querySelector('#view');
		this.entry = root.querySelector('#entry');
		this.size = box_info.size;

		var hidingFunc = delayFunc(() => {
			div.classList.remove('active');
		}, 1000);

		var showingFunc = function() {
			div.classList.add('active');
			hidingFunc.cancel();
		}

		container.setAttribute("style", "z-index: 2147483647; position: absolute; width: " + this.size.width + "px");
		div.style.maxHeight = this.size.height + 'px';
		div.addEventListener("mouseleave", hidingFunc, false);
		div.addEventListener("mouseenter", showingFunc, false);
	}

	setRefPosition(x, y) {
		this.position.x = x;
		this.position.y = y;
	}

	setRefRects(rects) {
		this.position.rects = rects;
	}

	updatePosition() {
		var box = this;
		if (!box.visible) return false;

		var rects = box.position.rects;
		var rect = rects[rects.length - 1];

		var left = rect.left;
		var top = rect.top;

		if (box.position.x || box.position.y) {
			let refX = box.position.x,
				refY = box.position.y,
				nearestDistance = 0x1A0BB00;
			left = refX;
			for (let i = 0; i !== rects.length; i++) {
				let ri = rects[i];
				if (ri.left <= refX && refX <= ri.right) {
					let riDistance = Math.abs(ri.top + (ri.height / 2) - refY);
					if (riDistance < nearestDistance) {
						top = ri.top;
						rect = ri;
						nearestDistance = riDistance;
					}
				}
			}
		} else {
			left = rect.left;
			top = rect.top;
		}

		if ((top - box.size.height) < 0) {
			top += rect.height;
			box.div.classList.add('vertical-reverse');
		} else {
			box.div.classList.remove('vertical-reverse');
		}

		if ((left + box.size.width) > window.innerWidth) {
			box.div.classList.add('horizontal-reverse');
			left -= box.size.width;
		} else {
			box.div.classList.remove('horizontal-reverse');
		}

		this.container.style.left = (left + document.body.scrollLeft) + 'px'
		this.container.style.top = (top + document.body.scrollTop) + 'px'

		return true;
	}

	/**
	 * @param {boolean} visible
	 */
	setVisibility(visible) {
		if (visible === this.visible) return
		var container = this.container;

		if (this.visible = visible) {
			document.body.appendChild(container);
			container.style.display = 'block';
		} else {
			container.parentElement && container.parentElement.removeChild(container);
			container.style.display = 'none';
			this.position.x = this.position.y = 0;
		}
	}
}

/**
 * works with `div > div[order]`
 *
 * @param {HTMLElement} ele the new child
 * @param {HTMLElement} parent
 * @param {number} order
 */
function insertOrdered(ele, parent, order) {
	var insertBefore = null;
	[].some.call(parent.children, (cmp) => {
		var cmpOrder = ~~cmp.getAttribute("order");
		if (cmpOrder < order) return false;

		insertBefore = cmp;
		return true;
	})
	ele.setAttribute("order", order);
	parent.insertBefore(ele, insertBefore);
}

/** the View Manager */
class TinyAccViewManager {
	/** @param {TinyAccBox} box */
	constructor(box) {
		this.box = box;
		this.empty();
	}

	empty() {
		this.box.view.innerHTML = ""
		this.box.entry.innerHTML = ""
		this.monodramaLast = null;
	}

	/**
	 * move a view of an instance to the top
	 *
	 * @param {TinyAcc.InstanceEventThis} insSelf
	 */
	monodrama(insSelf) {
		var lastView = this.monodramaLast;

		if (lastView) {
			lastView.view.style.display = 'none'
			lastView.button.classList.remove('active')
		}

		if (lastView = insSelf) {
			this.box.view.appendChild(lastView.view)
			lastView.view.style.display = 'block'
			lastView.button.classList.add('active')
		}

		this.monodramaLast = lastView;
	}

	/**
	 * Create functions and bind event handlers
	 *
	 * @param {HTMLElement} ele
	 * @param {TinyAcc.EventInfo} eventInfo
	 * @param {TinyAcc.InstanceEventThis} self
	 */
	eventBind(ele, eventInfo, self) {
		if (!ele || !eventInfo) return;
		Object.keys(eventInfo).forEach((eventName) => {
			let eventBody = eventInfo[eventName]
			let eventHandler = new Function("event", eventBody)
			ele.addEventListener(eventName, eventHandler.bind(self))
		})
	}

	/**
	 * Handle new Instance Result
	 *
	 * @param {TinyAcc.Instance} ins
	 * @param {number} order
	 */
	add(ins, order) {
		let self = {
			button: null,
			view: null
		}

		if (ins.button && ins.button.text) {
			var entryButton = document.createElement('div')
			entryButton.className = "entry-btn"
			entryButton.setAttribute("tinyacc-instance", ins.id)
			entryButton.textContent = ins.button.text
			insertOrdered(entryButton, this.box.entry, order)

			self.button = entryButton
			this.eventBind(entryButton, ins.button.event, self)
		}

		if (ins.view) {
			var viewContent = document.createElement('div')
			viewContent.className = "view-content"
			viewContent.setAttribute("tinyacc-instance", ins.id)
			viewContent.innerHTML = ins.view.html || ins.view

			self.view = viewContent
			insertOrdered(viewContent, this.box.view, order)
			this.eventBind(viewContent, ins.view.event, self)

			if (entryButton) {
				//if have a button and has a low priority, then hide it!!
				if (this.box.view.firstElementChild !== viewContent) {
					this.monodrama(self)
				}

				entryButton.addEventListener("mouseenter", (ev) => {
					this.monodrama(self)
				})
			}
		}

		if (ins.onCreated) {
			(new Function(ins.onCreated)).call(self)
		}
	}
}

(document.doctype || !document.xmlVersion) &&
	(function() {
		/** @type {TinyAccBox} */
		var box;

		/** @type {TinyAccViewManager} */
		var viewMgr;

		chrome.runtime.sendMessage("box", (box_info) => {
			box = new TinyAccBox(box_info);
			box.setVisibility(false);

			viewMgr = new TinyAccViewManager(box);

			initHooks();
		})

		var selection = window.getSelection();

		/** Read the selection and update box */
		var updateBox = throttle(updateBoxReal, 500);
		function updateBoxReal() {
			var range = selection.rangeCount && selection.getRangeAt(0)

			if (selection.isCollapsed) {
				var focusOnBox =
					range && range.startContainer && (
						range.startContainer === box.div ||
						range.startContainer.compareDocumentPosition(box.div) === Node.DOCUMENT_POSITION_CONTAINED_BY ||
						range.startContainer.childNodes[range.startOffset] === box.container
					)

				if (!focusOnBox) box.setVisibility(false);

				return false;
			}

			/** extract content */
			var content = extract(range);
			var text = content.text;
			var html = content.html;
			if (!text.length) return false;

			viewMgr.empty();

			box.setRefRects(range.getClientRects());
			box.setVisibility(true);
			box.updatePosition();

			var request = {
				id: genID(),
				info: {
					text: text,
					html: html,
					url: window.location.href
				}
			}

			port.postMessage(request)
			return true
		}

		var port = chrome.runtime.connect({ name: "page" })
		port.onMessage.addListener((msg) => {
			if (msg.id != currentID) return

			var ins = msg.instance
			var order = msg.order

			viewMgr.add(ins, order);
		})

		var currentID = ""
		function genID() {
			currentID = "ta+" + (+new Date()).toString(36)
			return currentID
		}

		/** init event hooks so that TinyAcc can handle selectionchange */
		function initHooks() {
			var selectionSuppress = false;
			var selectionSuppressed = false;

			document.addEventListener('selectionchange', (ev) => {
				if (selectionSuppress) {
					selectionSuppressed = true;
				} else {
					updateBox();
					selectionSuppressed = false;
				}
			}, true);

			document.body.addEventListener('mousedown', (ev) => {
				if (ev.target === box.container) return;
				selectionSuppress = true;
				box.setVisibility(false);
			}, true);

			document.body.addEventListener('mouseup', (ev) => {
				//NOTICE: selectionchange fires before mouseup
				if (ev.target === box.container) return;

				selectionSuppress = false;
				if (selectionSuppressed) {
					box.setRefPosition(
						ev.pageX - document.body.scrollLeft,
						ev.pageY - document.body.scrollTop
					)
					updateBox();
				}
			}, true);
		}

	})();
<commit_msg>Disable APIs<commit_after>/// <reference path="../../typings/chrome/chrome.d.ts" />
/// <reference path="../../typings/tinyacc/tinyacc.intern.d.ts" />

'use strict';

/** create a delayed function, with a `cancel()` method */
function delayFunc(fn, timeout) {
	var timeout = 0;
	var args = [];
	var self = null;

	function timeoutCallback() {
		timeout = 0;
		fn.apply(self, args);
	}

	function call() {
		self = this;
		args = arguments;
		if (!timeout) timeout = setTimeout(timeoutCallback, timeout);
	}

	call.cancel = function() {
		if (timeout) {
			timeout = 0;
			clearTimeout(timeout);
		}
	}

	return call;
}

/** create a throttled Function */
function throttle(fn, timespan) {
	var timeout = 0;
	var nextTrig = 0;
	var _this, _args;

	function timeoutCallback() {
		timeout = 0;
		call.apply(_this, _args);
	}

	function call() {
		var now = +new Date();
		if (now >= nextTrig) {
			nextTrig = now + timespan;
			fn.apply(this, arguments);
		} else {
			_this = this;
			_args = arguments;
			if (!timeout) timeout = setTimeout(timeoutCallback, nextTrig - now);
		}
	}

	return call;
}

/**
 * Extract content from the range
 *
 * @param {Range} range
 */
function extract(range) {
	var tempDiv = document.createElement('div')
	var content = range.cloneContents()

	tempDiv.innerHTML = ''
	tempDiv.appendChild(content)

	var html = tempDiv.innerHTML
	var text = tempDiv.innerText.trim()

	return {
		html: html,
		text: text
	}
}

/** The TinyAcc Box class */
class TinyAccBox {
	constructor(box_info) {
		this.visible = false;
		this.position = { x: 0, y: 0, rects: [] };

		var container = this.container = document.createElement('div');
		var root = this.root = container.createShadowRoot();

		root.innerHTML = '<style style="display:none">\n' + box_info.style + '\n</style>' + box_info.html;

		/** @type {HTMLElement} */
		var div = root.querySelector('#box');
		this.div = div;
		this.view = root.querySelector('#view');
		this.entry = root.querySelector('#entry');
		this.size = box_info.size;

		var hidingFunc = delayFunc(() => {
			div.classList.remove('active');
		}, 1000);

		var showingFunc = function() {
			div.classList.add('active');
			hidingFunc.cancel();
		}

		container.setAttribute("style", "z-index: 2147483647; position: absolute; width: " + this.size.width + "px");
		div.style.maxHeight = this.size.height + 'px';
		div.addEventListener("mouseleave", hidingFunc, false);
		div.addEventListener("mouseenter", showingFunc, false);
	}

	setRefPosition(x, y) {
		this.position.x = x;
		this.position.y = y;
	}

	setRefRects(rects) {
		this.position.rects = rects;
	}

	updatePosition() {
		var box = this;
		if (!box.visible) return false;

		var rects = box.position.rects;
		var rect = rects[rects.length - 1];

		var left = rect.left;
		var top = rect.top;

		if (box.position.x || box.position.y) {
			let refX = box.position.x,
				refY = box.position.y,
				nearestDistance = 0x1A0BB00;
			left = refX;
			for (let i = 0; i !== rects.length; i++) {
				let ri = rects[i];
				if (ri.left <= refX && refX <= ri.right) {
					let riDistance = Math.abs(ri.top + (ri.height / 2) - refY);
					if (riDistance < nearestDistance) {
						top = ri.top;
						rect = ri;
						nearestDistance = riDistance;
					}
				}
			}
		} else {
			left = rect.left;
			top = rect.top;
		}

		if ((top - box.size.height) < 0) {
			top += rect.height;
			box.div.classList.add('vertical-reverse');
		} else {
			box.div.classList.remove('vertical-reverse');
		}

		if ((left + box.size.width) > window.innerWidth) {
			box.div.classList.add('horizontal-reverse');
			left -= box.size.width;
		} else {
			box.div.classList.remove('horizontal-reverse');
		}

		this.container.style.left = (left + document.body.scrollLeft) + 'px'
		this.container.style.top = (top + document.body.scrollTop) + 'px'

		return true;
	}

	/**
	 * @param {boolean} visible
	 */
	setVisibility(visible) {
		if (visible === this.visible) return
		var container = this.container;

		if (this.visible = visible) {
			document.body.appendChild(container);
			container.style.display = 'block';
		} else {
			container.parentElement && container.parentElement.removeChild(container);
			container.style.display = 'none';
			this.position.x = this.position.y = 0;
		}
	}
}

/**
 * works with `div > div[order]`
 *
 * @param {HTMLElement} ele the new child
 * @param {HTMLElement} parent
 * @param {number} order
 */
function insertOrdered(ele, parent, order) {
	var insertBefore = null;
	[].some.call(parent.children, (cmp) => {
		var cmpOrder = ~~cmp.getAttribute("order");
		if (cmpOrder < order) return false;

		insertBefore = cmp;
		return true;
	})
	ele.setAttribute("order", order);
	parent.insertBefore(ele, insertBefore);
}

/** the View Manager */
class TinyAccViewManager {
	/** @param {TinyAccBox} box */
	constructor(box) {
		this.box = box;
		this.empty();
	}

	empty() {
		this.box.view.innerHTML = ""
		this.box.entry.innerHTML = ""
		this.monodramaLast = null;
	}

	/**
	 * move a view of an instance to the top
	 *
	 * @param {TinyAcc.InstanceEventThis} insSelf
	 */
	monodrama(insSelf) {
		var lastView = this.monodramaLast;

		if (lastView) {
			lastView.view.style.display = 'none'
			lastView.button.classList.remove('active')
		}

		if (lastView = insSelf) {
			this.box.view.appendChild(lastView.view)
			lastView.view.style.display = 'block'
			lastView.button.classList.add('active')
		}

		this.monodramaLast = lastView;
	}

	/**
	 * Create functions and bind event handlers
	 *
	 * @param {HTMLElement} ele
	 * @param {TinyAcc.EventInfo} eventInfo
	 * @param {TinyAcc.InstanceEventThis} self
	 */
	eventBind(ele, eventInfo, self) {
		if (!ele || !eventInfo) return;
		Object.keys(eventInfo).forEach((eventName) => {
			let eventBody = eventInfo[eventName]
			let eventHandler = new Function("event", eventBody)
			ele.addEventListener(eventName, eventHandler.bind(self))
		})
	}

	/**
	 * Handle new Instance Result
	 *
	 * @param {TinyAcc.Instance} ins
	 * @param {number} order
	 */
	add(ins, order) {
		let self = {
			button: null,
			view: null
		}

		if (ins.button && ins.button.text) {
			var entryButton = document.createElement('div')
			entryButton.className = "entry-btn"
			entryButton.setAttribute("tinyacc-instance", ins.id)
			entryButton.textContent = ins.button.text
			insertOrdered(entryButton, this.box.entry, order)

			self.button = entryButton
			this.eventBind(entryButton, ins.button.event, self)
		}

		if (ins.view) {
			var viewContent = document.createElement('div')
			viewContent.className = "view-content"
			viewContent.setAttribute("tinyacc-instance", ins.id)
			viewContent.innerHTML = ins.view.html || ins.view

			self.view = viewContent
			insertOrdered(viewContent, this.box.view, order)
			this.eventBind(viewContent, ins.view.event, self)

			if (entryButton) {
				//if have a button and has a low priority, then hide it!!
				if (this.box.view.firstElementChild !== viewContent) {
					this.monodrama(self)
				}

				entryButton.addEventListener("mouseenter", (ev) => {
					this.monodrama(self)
				})
			}
		}

		if (ins.onCreated) {
			(new Function(ins.onCreated)).call(self)
		}
	}
}

(document.doctype || !document.xmlVersion) &&
	(function() {
		/** @type {TinyAccBox} */
		var box;

		/** @type {TinyAccViewManager} */
		var viewMgr;

		// Remove all unsafe API from Chrome
		var chrome = window.chrome;
		window.chrome = {
			runtime: chrome.runtime
		};

		chrome.runtime.sendMessage("box", (box_info) => {
			box = new TinyAccBox(box_info);
			box.setVisibility(false);

			viewMgr = new TinyAccViewManager(box);

			initHooks();
		})

		var selection = window.getSelection();

		/** Read the selection and update box */
		var updateBox = throttle(updateBoxReal, 500);
		function updateBoxReal() {
			var range = selection.rangeCount && selection.getRangeAt(0)

			if (selection.isCollapsed) {
				var focusOnBox =
					range && range.startContainer && (
						range.startContainer === box.div ||
						range.startContainer.compareDocumentPosition(box.div) === Node.DOCUMENT_POSITION_CONTAINED_BY ||
						range.startContainer.childNodes[range.startOffset] === box.container
					)

				if (!focusOnBox) box.setVisibility(false);

				return false;
			}

			/** extract content */
			var content = extract(range);
			var text = content.text;
			var html = content.html;
			if (!text.length) return false;

			viewMgr.empty();

			box.setRefRects(range.getClientRects());
			box.setVisibility(true);
			box.updatePosition();

			var request = {
				id: genID(),
				info: {
					text: text,
					html: html,
					url: window.location.href
				}
			}

			port.postMessage(request)
			return true
		}

		var port = chrome.runtime.connect({ name: "page" })
		port.onMessage.addListener((msg) => {
			if (msg.id != currentID) return

			var ins = msg.instance
			var order = msg.order

			viewMgr.add(ins, order);
		})

		var currentID = ""
		function genID() {
			currentID = "ta+" + (+new Date()).toString(36)
			return currentID
		}

		/** init event hooks so that TinyAcc can handle selectionchange */
		function initHooks() {
			var selectionSuppress = false;
			var selectionSuppressed = false;

			document.addEventListener('selectionchange', (ev) => {
				if (selectionSuppress) {
					selectionSuppressed = true;
				} else {
					updateBox();
					selectionSuppressed = false;
				}
			}, true);

			document.body.addEventListener('mousedown', (ev) => {
				if (ev.target === box.container) return;
				selectionSuppress = true;
				box.setVisibility(false);
			}, true);

			document.body.addEventListener('mouseup', (ev) => {
				//NOTICE: selectionchange fires before mouseup
				if (ev.target === box.container) return;

				selectionSuppress = false;
				if (selectionSuppressed) {
					box.setRefPosition(
						ev.pageX - document.body.scrollLeft,
						ev.pageY - document.body.scrollTop
					)
					updateBox();
				}
			}, true);
		}

	})();
<|endoftext|>


<commit_before>'use strict';
const fs = require('fs');
const got = require('got');
const wallpaper = require('wallpaper');
const xmldom = require('xmldom');
const xpath = require('xpath');
const uri = require('url');

const downloadUrl = 'http://workhardanywhere.com/download/';
const tmpFile = './tmp.jpg';

const domParser = new xmldom.DOMParser({
	errorHandler: {}
});

function getRandomElement(array) {
	return array[Math.floor(Math.random() * array.length)];
}

function handleError(error) {
	console.log(error.response.body);
}

exports.setRandomWallpaper = function () {
	got(downloadUrl)
		.then(response => {
			let page = domParser.parseFromString(response.body);
			const articles = xpath.select('.//article/div/a/@href', page);

			got(getRandomElement(articles).value)
				.then(response => {
					page = domParser.parseFromString(response.body);
					let imgLink = xpath.select('//a[text()="Laptop Wallpaper"]/@href', page);
					const imgLinkParsed = uri.parse(imgLink[0].value);
					imgLink = `${imgLinkParsed.host + imgLinkParsed.pathname}?raw=1`;
					got.stream(imgLink).pipe(fs.createWriteStream(tmpFile));
				})
				.catch(console.log);
		})
		.catch(console.log);

	wallpaper
		.set(tmpFile)
		.catch(console.log);
};
<commit_msg>:gem: Stylish<commit_after>'use strict';
const fs = require('fs');
const got = require('got');
const wallpaper = require('wallpaper');
const xmldom = require('xmldom');
const xpath = require('xpath');
const uri = require('url');

const downloadUrl = 'http://workhardanywhere.com/download/';
const tmpFile = './tmp.jpg';

const domParser = new xmldom.DOMParser({
	errorHandler: {}
});

function getRandomElement(array) {
	return array[Math.floor(Math.random() * array.length)];
}

exports.setRandomWallpaper = function () {
	got(downloadUrl)
		.then(response => {
			let page = domParser.parseFromString(response.body);
			const articles = xpath.select('.//article/div/a/@href', page);

			got(getRandomElement(articles).value)
				.then(response => {
					page = domParser.parseFromString(response.body);
					let imgLink = xpath.select('//a[text()="Laptop Wallpaper"]/@href', page);
					const imgLinkParsed = uri.parse(imgLink[0].value);
					imgLink = `${imgLinkParsed.host + imgLinkParsed.pathname}?raw=1`;
					got.stream(imgLink).pipe(fs.createWriteStream(tmpFile));
				})
				.catch(console.log);
		})
		.catch(console.log);

	wallpaper
		.set(tmpFile)
		.catch(console.log);
};
<|endoftext|>


<commit_before>"use strict";
var path = require('path')
var globby = require('globby')
var frontMatter = require('yaml-front-matter')
var Remarkable = require('remarkable')
var remarkable = new Remarkable({
  linkify: true,
  typographer: true
})

module.exports = function markdowntojson(patterns) {
  var paths = globby.sync(patterns)
  var articles = paths.map(function(filePath) {
    var meta = frontMatter.loadFront(filePath, 'markdown')
    meta._path = path.dirname(filePath)
    meta._markdown = meta.markdown.replace(/^\n*/, '')
    return {
      meta: meta
    }
  })
  .map(function(json) {
    json.html = remarkable.render(json.meta._markdown)
    return json
  })

  return JSON.stringify(articles, null, 2)
}
<commit_msg>fix double markdown field in json<commit_after>"use strict";
var path = require('path')
var globby = require('globby')
var frontMatter = require('yaml-front-matter')
var Remarkable = require('remarkable')
var remarkable = new Remarkable({
  linkify: true,
  typographer: true
})

module.exports = function markdowntojson(patterns) {
  var paths = globby.sync(patterns)
  var articles = paths.map(function(filePath) {
    var meta = frontMatter.loadFront(filePath, '_markdown')
    meta._path = path.dirname(filePath)
    meta._markdown = meta._markdown.replace(/^\n*/, '')
    return {
      meta: meta
    }
  })
  .map(function(json) {
    json.html = remarkable.render(json.meta._markdown)
    return json
  })

  return JSON.stringify(articles, null, 2)
}
<|endoftext|>


<commit_before>'use strict';

var collisions = require('collide-3d-tilemap')
,   extend = require('extend')
,   aabb = require('aabb-3d')
,   vec3 = require('gl-vec3')

var RigidBody = require('./rigidBody')

module.exports = function(game, opts) {
  return new Physics(game, opts)
}

var defaults = {
  gravity: [0, -10, 0],
  airFriction: 0.995,
  minBounceImpulse: .5, // lowest collision impulse that bounces

}

/*
 *    CONSTRUCTOR - represents a world of rigid bodies.
 *
 *  Takes in a getBlock(x,y,z) function to query block solidity.
*/
function Physics(opts, getBlock) {
  opts = extend( {}, defaults, opts )

  this.gravity = opts.gravity
  this.airFriction = opts.airFriction
  this.minBounceImpulse = opts.minBounceImpulse
  this.bodies = []

  // collision function - TODO: abstract this into a setter?
  this.collideWorld = collisions(
    getBlock,
    1,
    [Infinity, Infinity, Infinity],
    [-Infinity, -Infinity, -Infinity]
  )
}

/*
 *    ADDING AND REMOVING RIGID BODIES
*/

Physics.prototype.addBody = function(_aabb, mass,
                                      friction, restitution, gravMult,
                                      onCollide) {
  _aabb = _aabb || new aabb( [0,0,0], [1,1,1] )
  if (typeof mass == 'undefined') mass = 1
  if (typeof friction == 'undefined') friction = 1
  if (typeof restitution == 'undefined') restitution = 0
  if (typeof gravMult == 'undefined') gravMult = 1
  var b = new RigidBody(_aabb, mass, friction, restitution, gravMult, onCollide)
  this.bodies.push(b)
  return b
}

Physics.prototype.removeBody = function(b) {
  var i = this.bodies.indexOf(b)
  if (i < 0) return undefined
  this.bodies.splice(i, 1)
  b.aabb = b.onCollide = null // in case it helps the GC
}

/*
 *    PHYSICS AND COLLISIONS
*/

var b, i, j, len
var world_x0 = vec3.create(),
    world_x1 = vec3.create(),
    world_dx = vec3.create(),
    friction = vec3.create(),
    a = vec3.create(),
    g = vec3.create(),
    dv = vec3.create(),
    dx = vec3.create(),
    impacts = vec3.create(),
    tmpBox,
    tmpDx = vec3.create(),
    tmpResting = vec3.create(),
    flag = { // boolean holder to get around scope peculiarities below
      value: false
    }

Physics.prototype.tick = function(dt) {
  // convert dt to seconds
  dt = dt/1000
  for(i=0, len=this.bodies.length; i<len; ++i) {
    b = this.bodies[i]

    // semi-implicit Euler integration

    // a = f/m + gravity*gravityMultiplier
    vec3.scale( a, b._forces, 1/b.mass )
    vec3.scale( g, this.gravity, b.gravityMultiplier )
    vec3.add  ( a, a, g )

    // v1 = v0 + i/m + a*dt
    vec3.scale( dv, b._impulses, 1/b.mass )
    vec3.add  ( b.velocity, b.velocity, dv )
    vec3.scale( dv, a, dt )
    vec3.add  ( b.velocity, b.velocity, dv )

    // apply friction if body was on ground last frame
    if (b.resting[1]<0) {
      // friction force <= - u |vel|
      // max friction impulse = (F/m)*dt = (mg)/m*dt = u*g*dt = dt*b.friction
      var fMax = dt * b.friction
      // friction direction - inversed horizontal velocity
      vec3.scale( friction, b.velocity, -1 )
      friction[1] = 0
      var vAmt = vec3.length(friction)
      if (vAmt > fMax) { // slow down
        vec3.scale( friction, friction, fMax/vAmt )
        vec3.add( b.velocity, b.velocity, friction )
      } else { // stop
        b.velocity[0] = b.velocity[2] = 0
      }
    } else {
      // not on ground, apply air resistance
      vec3.scale( b.velocity, b.velocity, this.airFriction )
    }

    // x1-x0 = v1*dt
    vec3.scale( dx, b.velocity, dt )

    // clear forces and impulses for next timestep
    vec3.set( b._forces, 0, 0, 0 )
    vec3.set( b._impulses, 0, 0, 0 )

    // cache stepped base/dx values for autostep
    if (b.autoStep) {
      tmpBox = new aabb( b.aabb.base, b.aabb.vec )
      vec3.copy( tmpDx, dx )
    }

    // run collisions
    vec3.set( b.resting, 0, 0, 0 )
    // flag.value is a check whether the body was collided already before
    // taking the movement vector into account. It's wrapped in an object
    // so we can pass it to and reference it from processHit()
    flag.value = false
    this.collideWorld(b.aabb, dx,
                      processHit.bind(null, dx, b.resting, flag) )

    // if autostep, and on ground, run collisions again with stepped up aabb
    if (b.autoStep && b.resting[1]<0 && (b.resting[0] || b.resting[2])) {
      vec3.set( tmpResting, 0, 0, 0 )
      var y = tmpBox.base[1]
      if (b.resting[1]<0) tmpDx[1]=0
      tmpBox.translate( [0, Math.floor(y+1.01)-y, 0] )
      this.collideWorld(tmpBox, tmpDx,
                        processHit.bind(null, tmpDx, tmpResting, flag) )
      var stepx = b.resting[0] && !tmpResting[0]
      var stepz = b.resting[2] && !tmpResting[2]
      // if stepping avoids collisions, copy stepped results into real data
      if (!flag.value && (stepx || stepz)) {
        setBoxPos( b.aabb, tmpBox.base )
        if (b.resting[1]<0) tmpResting[1]=-1
        vec3.copy( b.resting, tmpResting )
        if (b.onStep) b.onStep();
      }
    }

    // Collision impacts. b.resting shows which axes had collisions:
    for (j=0; j<3; ++j) {
      impacts[j] = 0
      if (b.resting[j]) {
        impacts[j] = -b.velocity[j]
        b.velocity[j] = 0
      }
    }
    var mag = vec3.length(impacts)
    if (mag>.001) { // epsilon
      // bounce if over minBounceImpulse
      if (mag>this.minBounceImpulse && b.restitution) {
        vec3.scale(impacts, impacts, b.restitution)
        b.applyImpulse( impacts )
      }
      // collision event regardless
      if (b.onCollide) b.onCollide(impacts);
    }
  }
}

// the on-hit function called by the collide-tilemap library
function processHit(vec, resting, wasCollided, axis, tile, coords, dir, edge) {
  // assume all truthy tile values collide
  if (!tile) return
  if (Math.abs(vec[axis]) < Math.abs(edge)) {
    // true when the body started out already collided with terrain
    wasCollided.value = true
    return
  }
  // a collision happened, process it
  resting[axis] = dir
  vec[axis] = edge
  return true
}

// helper function, since aabb has no easy way of setting position
function setBoxPos(box, pos) {
  vec3.copy( box.base, pos )
  vec3.add( box.max, box.base, box.vec )
}
<commit_msg>Move some declarations to be local<commit_after>'use strict';

var collisions = require('collide-3d-tilemap')
,   extend = require('extend')
,   aabb = require('aabb-3d')
,   vec3 = require('gl-vec3')

var RigidBody = require('./rigidBody')

module.exports = function(game, opts) {
  return new Physics(game, opts)
}

var defaults = {
  gravity: [0, -10, 0],
  airFriction: 0.995,
  minBounceImpulse: .5, // lowest collision impulse that bounces

}

/*
 *    CONSTRUCTOR - represents a world of rigid bodies.
 *
 *  Takes in a getBlock(x,y,z) function to query block solidity.
*/
function Physics(opts, getBlock) {
  opts = extend( {}, defaults, opts )

  this.gravity = opts.gravity
  this.airFriction = opts.airFriction
  this.minBounceImpulse = opts.minBounceImpulse
  this.bodies = []

  // collision function - TODO: abstract this into a setter?
  this.collideWorld = collisions(
    getBlock,
    1,
    [Infinity, Infinity, Infinity],
    [-Infinity, -Infinity, -Infinity]
  )
}

/*
 *    ADDING AND REMOVING RIGID BODIES
*/

Physics.prototype.addBody = function(_aabb, mass,
                                      friction, restitution, gravMult,
                                      onCollide) {
  _aabb = _aabb || new aabb( [0,0,0], [1,1,1] )
  if (typeof mass == 'undefined') mass = 1
  if (typeof friction == 'undefined') friction = 1
  if (typeof restitution == 'undefined') restitution = 0
  if (typeof gravMult == 'undefined') gravMult = 1
  var b = new RigidBody(_aabb, mass, friction, restitution, gravMult, onCollide)
  this.bodies.push(b)
  return b
}

Physics.prototype.removeBody = function(b) {
  var i = this.bodies.indexOf(b)
  if (i < 0) return undefined
  this.bodies.splice(i, 1)
  b.aabb = b.onCollide = null // in case it helps the GC
}

/*
 *    PHYSICS AND COLLISIONS
*/

var world_x0 = vec3.create(),
    world_x1 = vec3.create(),
    world_dx = vec3.create(),
    friction = vec3.create(),
    a = vec3.create(),
    g = vec3.create(),
    dv = vec3.create(),
    dx = vec3.create(),
    impacts = vec3.create(),
    tmpDx = vec3.create(),
    tmpResting = vec3.create(),
    flag = { // boolean holder to get around scope peculiarities below
      value: false
    }

Physics.prototype.tick = function(dt) {

  var b, i, j, len, tmpBox
  // convert dt to seconds
  dt = dt/1000
  for(i=0, len=this.bodies.length; i<len; ++i) {
    b = this.bodies[i]

    // semi-implicit Euler integration

    // a = f/m + gravity*gravityMultiplier
    vec3.scale( a, b._forces, 1/b.mass )
    vec3.scale( g, this.gravity, b.gravityMultiplier )
    vec3.add  ( a, a, g )

    // v1 = v0 + i/m + a*dt
    vec3.scale( dv, b._impulses, 1/b.mass )
    vec3.add  ( b.velocity, b.velocity, dv )
    vec3.scale( dv, a, dt )
    vec3.add  ( b.velocity, b.velocity, dv )

    // apply friction if body was on ground last frame
    if (b.resting[1]<0) {
      // friction force <= - u |vel|
      // max friction impulse = (F/m)*dt = (mg)/m*dt = u*g*dt = dt*b.friction
      var fMax = dt * b.friction
      // friction direction - inversed horizontal velocity
      vec3.scale( friction, b.velocity, -1 )
      friction[1] = 0
      var vAmt = vec3.length(friction)
      if (vAmt > fMax) { // slow down
        vec3.scale( friction, friction, fMax/vAmt )
        vec3.add( b.velocity, b.velocity, friction )
      } else { // stop
        b.velocity[0] = b.velocity[2] = 0
      }
    } else {
      // not on ground, apply air resistance
      vec3.scale( b.velocity, b.velocity, this.airFriction )
    }

    // x1-x0 = v1*dt
    vec3.scale( dx, b.velocity, dt )

    // clear forces and impulses for next timestep
    vec3.set( b._forces, 0, 0, 0 )
    vec3.set( b._impulses, 0, 0, 0 )

    // cache stepped base/dx values for autostep
    if (b.autoStep) {
      tmpBox = new aabb( b.aabb.base, b.aabb.vec )
      vec3.copy( tmpDx, dx )
    }

    // run collisions
    vec3.set( b.resting, 0, 0, 0 )
    // flag.value is a check whether the body was collided already before
    // taking the movement vector into account. It's wrapped in an object
    // so we can pass it to and reference it from processHit()
    flag.value = false
    this.collideWorld(b.aabb, dx,
                      processHit.bind(null, dx, b.resting, flag) )

    // if autostep, and on ground, run collisions again with stepped up aabb
    if (b.autoStep && b.resting[1]<0 && (b.resting[0] || b.resting[2])) {
      vec3.set( tmpResting, 0, 0, 0 )
      var y = tmpBox.base[1]
      if (b.resting[1]<0) tmpDx[1]=0
      tmpBox.translate( [0, Math.floor(y+1.01)-y, 0] )
      this.collideWorld(tmpBox, tmpDx,
                        processHit.bind(null, tmpDx, tmpResting, flag) )
      var stepx = b.resting[0] && !tmpResting[0]
      var stepz = b.resting[2] && !tmpResting[2]
      // if stepping avoids collisions, copy stepped results into real data
      if (!flag.value && (stepx || stepz)) {
        setBoxPos( b.aabb, tmpBox.base )
        if (b.resting[1]<0) tmpResting[1]=-1
        vec3.copy( b.resting, tmpResting )
        if (b.onStep) b.onStep();
      }
    }

    // Collision impacts. b.resting shows which axes had collisions:
    for (j=0; j<3; ++j) {
      impacts[j] = 0
      if (b.resting[j]) {
        impacts[j] = -b.velocity[j]
        b.velocity[j] = 0
      }
    }
    var mag = vec3.length(impacts)
    if (mag>.001) { // epsilon
      // bounce if over minBounceImpulse
      if (mag>this.minBounceImpulse && b.restitution) {
        vec3.scale(impacts, impacts, b.restitution)
        b.applyImpulse( impacts )
      }
      // collision event regardless
      if (b.onCollide) b.onCollide(impacts);
    }
  }
}

// the on-hit function called by the collide-tilemap library
function processHit(vec, resting, wasCollided, axis, tile, coords, dir, edge) {
  // assume all truthy tile values collide
  if (!tile) return
  if (Math.abs(vec[axis]) < Math.abs(edge)) {
    // true when the body started out already collided with terrain
    wasCollided.value = true
    return
  }
  // a collision happened, process it
  resting[axis] = dir
  vec[axis] = edge
  return true
}

// helper function, since aabb has no easy way of setting position
function setBoxPos(box, pos) {
  vec3.copy( box.base, pos )
  vec3.add( box.max, box.base, box.vec )
}
<|endoftext|>