<commit_before>const { resolve, dirname } = require('path');

const { setTimeoutPromise, moveAcrossDevice } = require('../util');
const { access, rename, link, unlink } = require('../fs');

const remove = require('./remove');
const mkdirs = require('./mkdirs');

/**
 * @typedef {Object} MoveOptions
 * @memberof fsn/nextra
 * @property {boolean} [mkdirp = true] Should the move create directories recursivly for the destination path
 * @property {boolean} [overwrite = false] Should the move overwrite an identical file at the destination path
 * @property {boolean} [clobber = false] Alias to overwrite for parity to fs-extra
 */

/**
 * @function move
 * @memberof fsn/nextra
 * @param {string} source The source path of the file
 * @param {string} destination The destination path of the file
 * @param {MoveOptions} [options={}] The options for the move
 * @returns {Promise<void>}
 */
module.exports = async function move(source, destination, options = {}) {
	const shouldMkdirp = 'mkdirp' in options ? options.mkdirp : true;
	const overwrite = options.overwrite || options.clobber || false;

	if (shouldMkdirp) await mkdirs(dirname(destination));

	if (resolve(source) === resolve(destination)) {
		return access(source);
	} else if (overwrite) {
		return rename(source, destination)
			.catch(async (err) => {
				if (err.code === 'ENOTEMPTY' || err.code === 'EEXIST') {
					await remove(destination);
					options.overwrite = false;
					return move(source, destination, options);
				}

				// Windows
				/* istanbul ignore if */
				if (err.code === 'EPERM') {
					await setTimeoutPromise(200);
					await remove(destination);
					options.overwrite = false;
					return move(source, destination, options);
				}

				// For renaming files across devices, can't test via travis
				/* istanbul ignore if */
				if (err.code !== 'EXDEV') throw err;

				// For moving files across the network, can't test via travis
				/* istanbul ignore next */
				return moveAcrossDevice(source, destination, overwrite);
			});
	}
	return link(source, destination)
		.then(() => unlink(source))
		.catch(err => {
			if (err.code === 'EXDEV' || err.code === 'EISDIR' || err.code === 'EPERM' || err.code === 'ENOTSUP') return moveAcrossDevice(source, destination, overwrite);
			throw err;
		});
};
<commit_msg>more clear logic/ comments<commit_after>const { resolve, dirname } = require('path');

const { setTimeoutPromise, moveAcrossDevice } = require('../util');
const { access, rename, link, unlink } = require('../fs');

const remove = require('./remove');
const mkdirs = require('./mkdirs');

/**
 * @typedef {Object} MoveOptions
 * @memberof fsn/nextra
 * @property {boolean} [mkdirp = true] Should the move create directories recursivly for the destination path
 * @property {boolean} [overwrite = false] Should the move overwrite an identical file at the destination path
 * @property {boolean} [clobber = false] Alias to overwrite for parity to fs-extra
 */

/**
 * @function move
 * @memberof fsn/nextra
 * @param {string} source The source path of the file
 * @param {string} destination The destination path of the file
 * @param {MoveOptions} [options={}] The options for the move
 * @returns {Promise<void>}
 */
module.exports = async function move(source, destination, options = {}) {
	const shouldMkdirp = 'mkdirp' in options ? options.mkdirp : true;
	const overwrite = options.overwrite || options.clobber || false;

	if (shouldMkdirp) await mkdirs(dirname(destination));

	if (resolve(source) === resolve(destination)) {
		return access(source);
	} else if (overwrite) {
		return rename(source, destination)
			.catch(async (err) => {
				if (err.code === 'ENOTEMPTY' || err.code === 'EEXIST') {
					await remove(destination);
					options.overwrite = false;
					return move(source, destination, options);
				}

				// Windows
				/* istanbul ignore if */
				if (err.code === 'EPERM') {
					await setTimeoutPromise(200);
					await remove(destination);
					options.overwrite = false;
					return move(source, destination, options);
				}

				// For renaming files across devices, can't test via travis
				/* istanbul ignore if */
				if (err.code === 'EXDEV') return moveAcrossDevice(source, destination, overwrite);

				// Any other error
				throw err;
			});
	}
	return link(source, destination)
		.then(() => unlink(source))
		.catch(err => {
			if (err.code === 'EXDEV' || err.code === 'EISDIR' || err.code === 'EPERM' || err.code === 'ENOTSUP') return moveAcrossDevice(source, destination, overwrite);
			throw err;
		});
};
<|endoftext|>


<commit_before>define(["sprd/data/SprdModel", "js/data/Entity", "sprd/entity/Address", "sprd/model/ShippingType", "underscore", "js/data/validator/EmailValidator", "js/data/validator/RegExValidator", "js/data/transformer/TrimTransformer", "sprd/data/validator/LengthValidator"], function (SprdModel, Entity, Address, ShippingType, _, EmailValidator, RegExValidator, TrimTransformer, LengthValidator) {

    var Billing = Entity.inherit("sprd.model.Order.Billing", {
        defaults: {
            address: Address
        },

        schema: {
            address: Address
        },
        _commitAddress: function (address) {
            if (address) {
                address.set('isBillingAddress', true);
            }
        }
    });

    var Shipping = Entity.inherit("sprd.model.Order.Shipping", {
        defaults: {
            address: Address,
            type: null
        },

        schema: {
            address: Address,
            type: ShippingType
        },
        _commitAddress: function (address) {
            if (address) {
                address.set('isBillingAddress', false);
            }
        }
    });

    var Delivery = SprdModel.inherit("sprd.model.Delivery", {

        defaults: {
            billing: Billing,
            shipping: Shipping,

            email: null,
            phone: null,

            giftWrappingMessage: null,
            useGiftWrapping: false,

            invoiceToShippingAddress: true,
            shippingVatId: "{shipping.address.vatId}"
        },

        $isDependentObject: true,

        schema: {
            shipping: Shipping,
            billing: Billing,

            email: String,

            giftWrappingMessage: {
                required: false,
                type: String
            },

            phone: {
                required: function () {
                    // required if shipping type has phone number required
                    return this.get("shipping.type.phoneNumberRequired");
                },
                type: String
            },

            useGiftWrapping: Boolean
        },

        reset: function () {
            this.set({
                email: null,
                phone: null,
                giftWrappingMessage: null,
                useGiftWrapping: false,
                invoiceToShippingAddress: true,
                billing: new Billing()
            });
        },

        transformers: [
            new TrimTransformer()
        ],

        validators: [
            new EmailValidator({field: "email"}),
            new RegExValidator({
                field: "phone",
                errorCode: "atLeast8Digits",
                regEx: /(.*\d.*){8}/
            }),
            new RegExValidator({
                field: "email",
                errorCode: 'emailError',
                regEx: /^[^.@]+@[^.]{1,64}\.[^.]+$/
            }),
            new LengthValidator({
                field: "email",
                errorCode: 'emailError',
                maxLength: 255
            }),
            new LengthValidator({
                field: "phone",
                maxLength: 30
            })
        ],

        // TODO: add phone validator, checking DEV-68278 + shipping type determinates if optional or not

        _commitInvoiceToShippingAddress: function (invoiceToShippingAddress) {
            var address = this.get('shipping.address');
            if (address) {
                address.set('isSameAsBillingAddress', invoiceToShippingAddress);
            }
        },

        _commitShippingVatId: function (vatId) {
            var address = this.get('billing.address');
            if (address) {
                address.set('vatId', vatId);
            }
        },

        compose: function () {
            var data = this.callBase();

            if (this.$.invoiceToShippingAddress) {
                delete data.billing;
            }

            if (!this.$.phone) {
                data.phone = null;
            }

            if (!this.$.useGiftWrapping) {
                delete data.giftWrappingMessage;
            }

            return data;
        },

        parse: function (data) {
            var billingAddress = this.get(data, 'billing.address'),
                shippingAddress = this.get(data, 'shipping.address');

            /**
             * we use the ids to determin if the billing address is the same as billing address
             * its a lil bit of a hack but faster than comparing all the fields.
             *
             * */
            if (billingAddress && shippingAddress) {
                this.set('invoiceToShippingAddress', shippingAddress.$.id == billingAddress.$.id);
            }

            if (this.$.invoiceToShippingAddress) {
                this.set('billing', new Billing());
                this.$.billing.$.address.set('id', "billing");
            } else if (billingAddress) {
                billingAddress.set('id', billingAddress.$.id || "billing");
            }

            if (shippingAddress) {
                shippingAddress.set('id', shippingAddress.$.id || "shipping");
            }
            return this.callBase();
        },

        invoiceAddress: function () {
            return this.$.invoiceToShippingAddress ? this.get("shipping.address") : this.get("billing.address");
        }.onChange("invoiceToShippingAddress", "billing.address", "shipping.address")

    });

    Delivery.Shipping = Shipping;
    Delivery.Billing = Billing;

    return Delivery;

});<commit_msg>DEV-74235 - Email field limited to 30 chars in new checkout * fixed regex for email validation<commit_after>define(["sprd/data/SprdModel", "js/data/Entity", "sprd/entity/Address", "sprd/model/ShippingType", "underscore", "js/data/validator/EmailValidator", "js/data/validator/RegExValidator", "js/data/transformer/TrimTransformer", "sprd/data/validator/LengthValidator"], function (SprdModel, Entity, Address, ShippingType, _, EmailValidator, RegExValidator, TrimTransformer, LengthValidator) {

    var Billing = Entity.inherit("sprd.model.Order.Billing", {
        defaults: {
            address: Address
        },

        schema: {
            address: Address
        },
        _commitAddress: function (address) {
            if (address) {
                address.set('isBillingAddress', true);
            }
        }
    });

    var Shipping = Entity.inherit("sprd.model.Order.Shipping", {
        defaults: {
            address: Address,
            type: null
        },

        schema: {
            address: Address,
            type: ShippingType
        },
        _commitAddress: function (address) {
            if (address) {
                address.set('isBillingAddress', false);
            }
        }
    });

    var Delivery = SprdModel.inherit("sprd.model.Delivery", {

        defaults: {
            billing: Billing,
            shipping: Shipping,

            email: null,
            phone: null,

            giftWrappingMessage: null,
            useGiftWrapping: false,

            invoiceToShippingAddress: true,
            shippingVatId: "{shipping.address.vatId}"
        },

        $isDependentObject: true,

        schema: {
            shipping: Shipping,
            billing: Billing,

            email: String,

            giftWrappingMessage: {
                required: false,
                type: String
            },

            phone: {
                required: function () {
                    // required if shipping type has phone number required
                    return this.get("shipping.type.phoneNumberRequired");
                },
                type: String
            },

            useGiftWrapping: Boolean
        },

        reset: function () {
            this.set({
                email: null,
                phone: null,
                giftWrappingMessage: null,
                useGiftWrapping: false,
                invoiceToShippingAddress: true,
                billing: new Billing()
            });
        },

        transformers: [
            new TrimTransformer()
        ],

        validators: [
            new EmailValidator({field: "email"}),
            new RegExValidator({
                field: "phone",
                errorCode: "atLeast8Digits",
                regEx: /(.*\d.*){8}/
            }),
            new RegExValidator({
                field: "email",
                errorCode: 'emailError',
                regEx: /^[^@]+@.{1,64}\.[^.]+$/
            }),
            new LengthValidator({
                field: "email",
                errorCode: 'emailError',
                maxLength: 255
            }),
            new LengthValidator({
                field: "phone",
                maxLength: 30
            })
        ],

        // TODO: add phone validator, checking DEV-68278 + shipping type determinates if optional or not

        _commitInvoiceToShippingAddress: function (invoiceToShippingAddress) {
            var address = this.get('shipping.address');
            if (address) {
                address.set('isSameAsBillingAddress', invoiceToShippingAddress);
            }
        },

        _commitShippingVatId: function (vatId) {
            var address = this.get('billing.address');
            if (address) {
                address.set('vatId', vatId);
            }
        },

        compose: function () {
            var data = this.callBase();

            if (this.$.invoiceToShippingAddress) {
                delete data.billing;
            }

            if (!this.$.phone) {
                data.phone = null;
            }

            if (!this.$.useGiftWrapping) {
                delete data.giftWrappingMessage;
            }

            return data;
        },

        parse: function (data) {
            var billingAddress = this.get(data, 'billing.address'),
                shippingAddress = this.get(data, 'shipping.address');

            /**
             * we use the ids to determin if the billing address is the same as billing address
             * its a lil bit of a hack but faster than comparing all the fields.
             *
             * */
            if (billingAddress && shippingAddress) {
                this.set('invoiceToShippingAddress', shippingAddress.$.id == billingAddress.$.id);
            }

            if (this.$.invoiceToShippingAddress) {
                this.set('billing', new Billing());
                this.$.billing.$.address.set('id', "billing");
            } else if (billingAddress) {
                billingAddress.set('id', billingAddress.$.id || "billing");
            }

            if (shippingAddress) {
                shippingAddress.set('id', shippingAddress.$.id || "shipping");
            }
            return this.callBase();
        },

        invoiceAddress: function () {
            return this.$.invoiceToShippingAddress ? this.get("shipping.address") : this.get("billing.address");
        }.onChange("invoiceToShippingAddress", "billing.address", "shipping.address")

    });

    Delivery.Shipping = Shipping;
    Delivery.Billing = Billing;

    return Delivery;

});<|endoftext|>


<commit_before>module.exports = function(input) {
    return ['function', 'object', 'array']
        .indexOf(typeof input) > -1 && input.default === undefined ?
             Object.defineProperty(input, "default", {value : input, enumerable : false}) : void 0;
}<commit_msg>fix: Check for frozen object in polyfillNonStandardDefaultUsage (#850)<commit_after>module.exports = function(input) {
    console.log(input);
    return ['function', 'object', 'array']
        .indexOf(typeof input) > -1 && input.default === undefined ?
             Object.isFrozen(input) ? input.default = input : Object.defineProperty(input, "default", {value : input, enumerable : false}) : void 0;
}<|endoftext|>


<commit_before><commit_msg>Remove symlink since it breaks tests in Windows.<commit_after><|endoftext|>


<commit_before>/**

A function that makes subclassing maria.ElementView more compact.

The following example creates a checkit.TodoView constructor function
equivalent to the more verbose example shown in the documentation
for maria.ElementView.

    maria.ElementView.subclass(checkit, 'TodoView', {
        uiActions: {
            'click     .check'       : 'onClickCheck'     ,
            'dblclick  .todo-content': 'onDblclickDisplay',
            'keyup     .todo-input'  : 'onKeyupInput'     ,
            'keypress  .todo-input'  : 'onKeypressInput'  ,
            'blur      .todo-input'  : 'onBlurInput'
        },
        properties: {
            buildData: function() {
                var model = this.getModel();
                var content = model.getContent();
                this.find('.todo-content').innerHTML = checkit.escapeHTML(content);
                this.find('.check').checked = model.isDone();
                aristocrat[model.isDone() ? 'addClass' : 'removeClass'](this.find('.todo'), 'done');
            },
            update: function() {
                this.buildData();
            },
            showEdit: function() {
                var input = this.find('.todo-input');
                input.value = this.getModel().getContent();
                aristocrat.addClass(this.find('.todo'), 'editing');
                input.select();
            },
            showDisplay: function() {
                aristocrat.removeClass(this.find('.todo'), 'editing');
            },
            getInputValue: function() {
                return this.find('.todo-input').value;
            },
            showToolTip: function() {
                this.find('.ui-tooltip-top').style.display = 'block';
            },
            hideToolTip: function() {
                this.find('.ui-tooltip-top').style.display = 'none';
            }
        }
    });

This subclassing function implements options following the
"convention over configuration" philosophy. The checkit.TodoView will,
by convention, use the checkit.TodoController
and checkit.TodoTemplate objects. All of these can be configured
explicitly if these conventions do not match your view's needs.

    maria.ElementView.subclass(checkit, 'TodoView', {
        controllerConstructor: checkit.TodoController,
        template             : checkit.TodoTemplate  ,
        uiActions: {
        ...

Alternately you can use late binding by supplying string names of
objects in the application's namespace object (i.e. the checkit object
in this example).

maria.ElementView.subclass(checkit, 'TodoView', {
    controllerConstructorName: 'TodoController',
    templateName             : 'TodoTemplate'  ,
    uiActions: {
    ...

*/
maria.ElementView.subclass = function(namespace, name, options) {
    options = options || {};
    var template = options.template;
    var templateName = options.templateName || name.replace(/(View|)$/, 'Template');
    var uiActions = options.uiActions;
    var properties = options.properties || (options.properties = {});
    if (!Object.prototype.hasOwnProperty.call(properties, 'getTemplate')) {
        if (template) {
            properties.getTemplate = function() {
                return template;
            };
        }
        else if (templateName) {
            properties.getTemplate = function() {
                return namespace[templateName];
            };
        }
    }
    if (uiActions) {
        if (!Object.prototype.hasOwnProperty.call(properties, 'getUIActions')) {
            properties.getUIActions = function() {
                return uiActions;
            };
        }
        for (var key in uiActions) {
            if (Object.prototype.hasOwnProperty.call(uiActions, key)) {
                var methodName = uiActions[key];
                if ((!Object.prototype.hasOwnProperty.call(properties, methodName)) &&
                    (!(methodName in this.prototype))) {
                    (function(methodName) {
                        properties[methodName] = function(evt) {
                            this.getController()[methodName](evt);
                        };
                    }(methodName));
                }
            }
        }
    }
    maria.View.subclass.call(this, namespace, name, options);
};
<commit_msg>More informative error message when template is missing. See #17<commit_after>/**

A function that makes subclassing maria.ElementView more compact.

The following example creates a checkit.TodoView constructor function
equivalent to the more verbose example shown in the documentation
for maria.ElementView.

    maria.ElementView.subclass(checkit, 'TodoView', {
        uiActions: {
            'click     .check'       : 'onClickCheck'     ,
            'dblclick  .todo-content': 'onDblclickDisplay',
            'keyup     .todo-input'  : 'onKeyupInput'     ,
            'keypress  .todo-input'  : 'onKeypressInput'  ,
            'blur      .todo-input'  : 'onBlurInput'
        },
        properties: {
            buildData: function() {
                var model = this.getModel();
                var content = model.getContent();
                this.find('.todo-content').innerHTML = checkit.escapeHTML(content);
                this.find('.check').checked = model.isDone();
                aristocrat[model.isDone() ? 'addClass' : 'removeClass'](this.find('.todo'), 'done');
            },
            update: function() {
                this.buildData();
            },
            showEdit: function() {
                var input = this.find('.todo-input');
                input.value = this.getModel().getContent();
                aristocrat.addClass(this.find('.todo'), 'editing');
                input.select();
            },
            showDisplay: function() {
                aristocrat.removeClass(this.find('.todo'), 'editing');
            },
            getInputValue: function() {
                return this.find('.todo-input').value;
            },
            showToolTip: function() {
                this.find('.ui-tooltip-top').style.display = 'block';
            },
            hideToolTip: function() {
                this.find('.ui-tooltip-top').style.display = 'none';
            }
        }
    });

This subclassing function implements options following the
"convention over configuration" philosophy. The checkit.TodoView will,
by convention, use the checkit.TodoController
and checkit.TodoTemplate objects. All of these can be configured
explicitly if these conventions do not match your view's needs.

    maria.ElementView.subclass(checkit, 'TodoView', {
        controllerConstructor: checkit.TodoController,
        template             : checkit.TodoTemplate  ,
        uiActions: {
        ...

Alternately you can use late binding by supplying string names of
objects in the application's namespace object (i.e. the checkit object
in this example).

maria.ElementView.subclass(checkit, 'TodoView', {
    controllerConstructorName: 'TodoController',
    templateName             : 'TodoTemplate'  ,
    uiActions: {
    ...

*/
maria.ElementView.subclass = function(namespace, name, options) {
    options = options || {};
    var template = options.template;
    var templateName = options.templateName || name.replace(/(View|)$/, 'Template');
    var uiActions = options.uiActions;
    var properties = options.properties || (options.properties = {});
    if (!Object.prototype.hasOwnProperty.call(properties, 'getTemplate')) {
        if (template) {
            properties.getTemplate = function() {
                return template;
            };
        }
        else if (templateName) {
            properties.getTemplate = function() {
                /* DEBUG BEGIN */
                if (!Object.prototype.hasOwnProperty.call(namespace, templateName)) {
                    console.error('Could not find template named "' + templateName + '".');
                }
                /* DEBUG END */
                return namespace[templateName];
            };
        }
    }
    if (uiActions) {
        if (!Object.prototype.hasOwnProperty.call(properties, 'getUIActions')) {
            properties.getUIActions = function() {
                return uiActions;
            };
        }
        for (var key in uiActions) {
            if (Object.prototype.hasOwnProperty.call(uiActions, key)) {
                var methodName = uiActions[key];
                if ((!Object.prototype.hasOwnProperty.call(properties, methodName)) &&
                    (!(methodName in this.prototype))) {
                    (function(methodName) {
                        properties[methodName] = function(evt) {
                            this.getController()[methodName](evt);
                        };
                    }(methodName));
                }
            }
        }
    }
    maria.View.subclass.call(this, namespace, name, options);
};
<|endoftext|>


<commit_before>import path from 'path';
import {cosmiconfigSync} from 'cosmiconfig';
import toCamelCase from 'to-camel-case';
import mergeOptions from 'merge-options';
import normalizePath from 'normalize-path';

export default ({input, flags = {}}) => {
  const explorer = cosmiconfigSync('posthtml');
  let {
    config,
    use,
    options = {},
    output,
    root = './',
    skip = [],
    allInOutput = false
  } = flags;

  if (config) {
    ({config} = explorer.load(config));
  }

  if (use) {
    const configPluginOptions = config?.plugins ?? {};

    // Plugins defined via CLI options take precedence over the ones from config file.
    use = [].concat(use).reduce((cfg, name) => {
      let cliOptions = flags[toCamelCase(name)];
      let configOptions = configPluginOptions[name];

      // We merge this way because options can be both strings and objects.
      const merged = mergeOptions({[name]: configOptions}, {[name]: cliOptions || {}});

      // Assigning as we loop `use` makes sure that the order in cfg.plugins is correct.
      cfg.plugins[name] = merged[name];

      if (configOptions) {
        delete configPluginOptions[name];
      }

      return cfg;
    }, {plugins: {}});

    // Add the remaining plugins if there is any.
    if (config && config.plugins) {
      for (let name in configPluginOptions) {
        if (configPluginOptions[name]) {
          use.plugins[name] = configPluginOptions[name];
        }
      }

      // Now all the plugins are in `use.plugins`.
      // Delete `config.plugins` for correct merging later: mergeOptions(config, {...}, use)
      delete config.plugins;
    }
  }

  if (!config && !use) {
    ({config} = explorer.search());
  }

  if (config?.root) {
    root = config.root;
  }

  if (config?.allInOutput) {
    allInOutput = config.allInOutput;
  }

  if (config?.skip) {
    skip = skip.concat(config.skip);
  }

  input = []
    .concat(input && input.length > 0 ? input : config?.input)
    .filter(Boolean)
    .map(file => {
      const ignoreFile = file.startsWith('!');
      let ignoreSymbol = '';

      if (ignoreFile) {
        ignoreSymbol = '!';
        file = file.slice(1);
      }

      return `${ignoreSymbol}${normalizePath(path.join(path.resolve(root), file))}`;
    });

  if (input.length === 0) {
    throw new TypeError('input files not found');
  }

  output = output ?? config?.output;
  if (output) {
    output = normalizePath(output);
  }

  skip = skip.map(file => normalizePath(path.join(path.resolve(root), file)));

  return mergeOptions(config ?? {}, {
    input,
    output,
    options,
    root,
    allInOutput,
    skip
  }, use ?? {});
};
<commit_msg>perf: skip files by pattern<commit_after>import path from 'path';
import {cosmiconfigSync} from 'cosmiconfig';
import toCamelCase from 'to-camel-case';
import mergeOptions from 'merge-options';
import normalizePath from 'normalize-path';
import fg from 'fast-glob';

export default ({input, flags = {}}) => {
  const explorer = cosmiconfigSync('posthtml');
  let {
    config,
    use,
    options = {},
    output,
    root = './',
    skip = [],
    allInOutput = false
  } = flags;

  if (config) {
    ({config} = explorer.load(config));
  }

  if (use) {
    const configPluginOptions = config?.plugins ?? {};

    // Plugins defined via CLI options take precedence over the ones from config file.
    use = [].concat(use).reduce((cfg, name) => {
      let cliOptions = flags[toCamelCase(name)];
      let configOptions = configPluginOptions[name];

      // We merge this way because options can be both strings and objects.
      const merged = mergeOptions({[name]: configOptions}, {[name]: cliOptions || {}});

      // Assigning as we loop `use` makes sure that the order in cfg.plugins is correct.
      cfg.plugins[name] = merged[name];

      if (configOptions) {
        delete configPluginOptions[name];
      }

      return cfg;
    }, {plugins: {}});

    // Add the remaining plugins if there is any.
    if (config && config.plugins) {
      for (let name in configPluginOptions) {
        if (configPluginOptions[name]) {
          use.plugins[name] = configPluginOptions[name];
        }
      }

      // Now all the plugins are in `use.plugins`.
      // Delete `config.plugins` for correct merging later: mergeOptions(config, {...}, use)
      delete config.plugins;
    }
  }

  if (!config && !use) {
    ({config} = explorer.search());
  }

  if (config?.root) {
    root = config.root;
  }

  if (config?.allInOutput) {
    allInOutput = config.allInOutput;
  }

  if (config?.skip) {
    skip = skip.concat(config.skip);
  }

  input = []
    .concat(input && input.length > 0 ? input : config?.input)
    .filter(Boolean)
    .map(file => {
      const ignoreFile = file.startsWith('!');
      let ignoreSymbol = '';

      if (ignoreFile) {
        ignoreSymbol = '!';
        file = file.slice(1);
      }

      return `${ignoreSymbol}${normalizePath(path.join(path.resolve(root), file))}`;
    });

  if (input.length === 0) {
    throw new TypeError('input files not found');
  }

  output = output ?? config?.output;
  if (output) {
    output = normalizePath(output);
  }

  skip = fg.sync(skip, {cwd: path.resolve(root)}).map(file => normalizePath(path.join(path.resolve(root), file)));

  return mergeOptions(config ?? {}, {
    input,
    output,
    options,
    root,
    allInOutput,
    skip
  }, use ?? {});
};
<|endoftext|>


<commit_before>var fs = require('fs')
var format = require('util').format
var https = require('https')
var path = require('path')

module.exports = function getVersions (options) {
  var distributionListingUri = options.baseUrl + 'index.json'

  https.get(distributionListingUri, function (res) {
    if (res.statusCode !== 200) return this.emit('error', res)

    var responseData = ''

    res
    .on('data', function (data) {
      responseData = responseData + data
    })
    .on('end', function () {
      var self = this;
      JSON.parse(responseData)
        .map(function (build) {
          return Object.assign(Object.create(Build), {
            baseUrl: options.baseUrl,
            binaries: [],
            prefix: options.prefix || '',
            version: build.version
          })
        })
        .filter(function (build) {
          return !build.fileExists || options.overwrite
        })
        .forEach(function (build) {
          getChecksumsFile(build, function(err, shasumData) {
            extractShasums(build, shasumData, writeFile)
          })
        })
    })
    .on('error', this.emit.bind(this, 'error'))
  }).on('error', function (e) { console.error('Error with distribution listing', e.message) })
}

// private

var Build = {
  get basename () {
    return this.prefix + this.version.replace(/v/, '')
  },
  get filename () {
    return path.join(__dirname, '../share/node-build', this.basename)
  },
  get fileExists () {
    return fs.existsSync(this.filename)
  },
  get shasumFileUri () {
    return format('%s%s/SHASUMS256.txt', this.baseUrl, this.version)
  },
  get definition () {
    return format('%sinstall_package "%s" "%s"\n', this.distros, this.name, this.downloadUri)
  },
  get distros () {
    return this.binaries.map(function(binary){ return binary.definition }).join('') + (this.binaries.length ? '\n' : '')
  },
  get downloadUri () {
    return format('%s%s/%s#%s', this.baseUrl, this.version, this.package, this.shasum)
  }
}

var Binary = {
  get definition () {
    return format('distro %s "%s"\n', this.platform, this.downloadUri)
  },
  get downloadUri () {
    return format('%s%s/%s#%s', this.build.baseUrl, this.build.version, this.package, this.shasum)
  }
}

function getChecksumsFile (build, cb) {
  https.get(build.shasumFileUri, function (res) {
    if (res.statusCode !== 200) return this.emit('error', res)

    var shasumData = ''

    res
    .on('data', function (data) {
      shasumData = shasumData + data
    })
    .on('end', function () {
      cb(null, shasumData)
    })
    .on('error', this.emit.bind(this, 'error'))
  }).on('error', function (e) { console.error('Error with ', build.version, e.message) })
}

function extractShasums (build, shasumData, cb) {
  try {
    extractSourceChecksum(build, shasumData)
    extractBinaryChecksums(build, shasumData)
    cb(null, build)
  } catch (error) {
    cb(error)
  }
}

function extractSourceChecksum (build, shasumData) {
  var result = shasumData.match(/^(\w{64}) {2}(?:\.\/)?(((?:node|iojs)-v\d+\.\d+\.\d+).tar.gz)$/im)

  if (result) {
    build.shasum = result[1]
    build.package = result[2]
    build.name = result[3]
  } else {
    throw new Error("bad checksum data", shasumData)
  }
}

function extractBinaryChecksums (build, shasumData) {
  var result = shasumData.match(/^(\w{64}) {2}(?:\.\/)?((?:(?:node|iojs)-v\d+\.\d+\.\d+)-(?!headers)(.+).tar.gz)$/gim)
  if (!result) return

  result.forEach(function(distro) {
    var result = distro.match(/^(\w{64}) {2}(?:\.\/)?((?:(?:node|iojs)-v\d+\.\d+\.\d+)-(.+).tar.gz)$/i)
    if(!result) return
    build.binaries.push(
      Object.assign(Object.create(Binary), {
        build: build,
        shasum: result[1],
        package: result[2],
        platform: result[3]
      })
    )
  })
}

function writeFile (err, build) {
  if (err) return console.error(err)

  fs.writeFile(build.filename, build.definition, function (err) {
    if (err) return console.error(err)

    console.log(build.name + ' written')
  })
}
<commit_msg>add random delay to checksumfile request to reduce failure rate<commit_after>var fs = require('fs')
var format = require('util').format
var https = require('https')
var path = require('path')

module.exports = function getVersions (options) {
  var distributionListingUri = options.baseUrl + 'index.json'

  https.get(distributionListingUri, function (res) {
    if (res.statusCode !== 200) return this.emit('error', res)

    var responseData = ''

    res
    .on('data', function (data) {
      responseData = responseData + data
    })
    .on('end', function () {
      JSON.parse(responseData)
        .map(function (build) {
          return Object.assign(Object.create(Build), {
            baseUrl: options.baseUrl,
            binaries: [],
            prefix: options.prefix || '',
            version: build.version
          })
        })
        .filter(function (build) {
          return !build.fileExists || options.overwrite
        })
        .forEach(function (build) {
          setTimeout(getChecksumsFile, Math.random() * 10000, build, function(err, shasumData) {
            extractShasums(build, shasumData, writeFile)
          })
        })
    })
    .on('error', this.emit.bind(this, 'error'))
  }).on('error', function (e) { console.error('Error with distribution listing', e.message) })
}

// private

var Build = {
  get basename () {
    return this.prefix + this.version.replace(/v/, '')
  },
  get filename () {
    return path.join(__dirname, '../share/node-build', this.basename)
  },
  get fileExists () {
    return fs.existsSync(this.filename)
  },
  get shasumFileUri () {
    return format('%s%s/SHASUMS256.txt', this.baseUrl, this.version)
  },
  get definition () {
    return format('%sinstall_package "%s" "%s"\n', this.distros, this.name, this.downloadUri)
  },
  get distros () {
    return this.binaries.map(function(binary){ return binary.definition }).join('') + (this.binaries.length ? '\n' : '')
  },
  get downloadUri () {
    return format('%s%s/%s#%s', this.baseUrl, this.version, this.package, this.shasum)
  }
}

var Binary = {
  get definition () {
    return format('distro %s "%s"\n', this.platform, this.downloadUri)
  },
  get downloadUri () {
    return format('%s%s/%s#%s', this.build.baseUrl, this.build.version, this.package, this.shasum)
  }
}

function getChecksumsFile (build, cb) {
  https.get(build.shasumFileUri, function (res) {
    if (res.statusCode !== 200) return this.emit('error', res)

    var shasumData = ''

    res
    .on('data', function (data) {
      shasumData = shasumData + data
    })
    .on('end', function () {
      cb(null, shasumData)
    })
    .on('error', this.emit.bind(this, 'error'))
  }).on('error', function (e) { console.error('Error with ', build.version, e.message) })
}

function extractShasums (build, shasumData, cb) {
  try {
    extractSourceChecksum(build, shasumData)
    extractBinaryChecksums(build, shasumData)
    cb(null, build)
  } catch (error) {
    cb(error)
  }
}

function extractSourceChecksum (build, shasumData) {
  var result = shasumData.match(/^(\w{64}) {2}(?:\.\/)?(((?:node|iojs)-v\d+\.\d+\.\d+).tar.gz)$/im)

  if (result) {
    build.shasum = result[1]
    build.package = result[2]
    build.name = result[3]
  } else {
    throw new Error("bad checksum data", shasumData)
  }
}

function extractBinaryChecksums (build, shasumData) {
  var result = shasumData.match(/^(\w{64}) {2}(?:\.\/)?((?:(?:node|iojs)-v\d+\.\d+\.\d+)-(?!headers)(.+).tar.gz)$/gim)
  if (!result) return

  result.forEach(function(distro) {
    var result = distro.match(/^(\w{64}) {2}(?:\.\/)?((?:(?:node|iojs)-v\d+\.\d+\.\d+)-(.+).tar.gz)$/i)
    if(!result) return
    build.binaries.push(
      Object.assign(Object.create(Binary), {
        build: build,
        shasum: result[1],
        package: result[2],
        platform: result[3]
      })
    )
  })
}

function writeFile (err, build) {
  if (err) return console.error(err)

  fs.writeFile(build.filename, build.definition, function (err) {
    if (err) return console.error(err)

    console.log(build.name + ' written')
  })
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
import meow from 'meow'
import consoleLogServer from './'
import _ from 'lodash/fp'
import prependHttp from 'prepend-http'
import url from 'url'

let unknownArgs = false

const cli = meow(
  `
  Usage
    $ console-log-server

  Options
    --port, -p Port Number
    --hostname, -h Host name
    --proxy, -P Host(s) to proxy the request to using https://www.npmjs.com/package/express-http-proxy. Syntax: [<path>>]<url>. You can provide different proxies for separate paths.
    --response-code, -c Response response code (ignored if proxied)
    --response-body, -b Response content (ignored if proxied)
    --response-header, -H Response header (ignored if proxied)
    --log-response, -r Log also the response. Enabled by default only for proxied requests. Logged response is fully read to a buffer which might change your api behaviour since response is not streamed directly to client, consider turning off if that is a problem.
    --no-color
    --version
    --date-format, -d Date format supported by https://www.npmjs.com/package/dateformat (default "yyyy-mm-dd'T'HH:MM:sso")
    --help
    --default-cors, -C Add "default" cors using https://www.npmjs.com/package/cors default values. By default only enabled for non-proxied responses. Turn on to enable also for proxy responses, turn off to disable completely.

  Examples

    # basic usage
    $ console-log-server -p 3000

    # customized response
    $ console-log-server -p 3000 -c 201 -b "cool type content" --response-header='Content-Type:application/cool' --response-header='key:value'

    # Log date with UTC date format instead of local with offset
    $ console-log-server -d "isoUtcDateTime"

    # Proxy the request to other host. Response will be the actual response from the proxy.
    $ console-log-server -P http://api.example.com

    # Proxy the requests to multiple hosts based on paths.
    $ console-log-server --proxy="/api/1>http://api-1.example.com" -proxy="/api/2>http://api-2.example.com"

    # Proxy the request to path under other host. Response will be the actual response (with cors headers injected) from the proxy.
    $ console-log-server -P http://api.example.com/v1/cats -C yes

    # Turn off response logging
    $ console-log-server -r no

    # Turn on response logging for all requests
    $ console-log-server -r yes

    # Don't add default (allow all) cors headers at all
    $ console-log-server -C no
`,
  {
    alias: {
      p: 'port',
      h: 'hostname',
      c: 'response-code',
      b: 'response-body',
      H: 'response-header',
      d: 'date-format',
      P: 'proxy',
      r: 'log-response',
      C: 'default-cors'
    },
    unknown: arg => {
      unknownArgs = !_.includes(arg, ['--no-color', '--version'])
      return true
    }
  }
)

function parseProxies (proxiesArg) {
  if (!proxiesArg) return undefined

  const proxies = _.flow(
    _.castArray,
    _.map(_.trim),
    _.compact,
    _.map(proxyArg => {
      const [pathPart, proxyPart] = _.split('>', proxyArg)
      const proxyHost = proxyPart ?? pathPart
      if (!proxyHost) {
        throw Error(`Invalid proxy arguments: ${proxyArg}`)
      }

      const parsedHost = url.URL
        ? new URL(prependHttp(proxyHost))
        : url.parse(prependHttp(proxyHost)) // eslint-disable-line node/no-deprecated-api
      const protocol = proxyHost.startsWith('https')
        ? 'https'
        : proxyHost.startsWith('http')
        ? 'http'
        : undefined
      return {
        path: proxyPart === undefined ? undefined : pathPart,
        host: parsedHost.host,
        protocol,
        hostPath: parsedHost.pathname
      }
    })
  )(proxiesArg)

  return proxies
}

function showMessageAndExit (message) {
  console.log(message)
  cli.showHelp(1)
  return undefined
}

const parseOnOff = (value, flagName) =>
  value === undefined
    ? undefined
    : /^(?:y|yes|true|1|on)$/i.test(value)
    ? true
    : /^(?:n|no|false|0|off)$/i.test(value)
    ? false
    : showMessageAndExit(`Invalid value '${value}' for ${flagName}`)

if (unknownArgs) {
  cli.showHelp()
} else {
  consoleLogServer({
    ...cli.flags,
    proxy: parseProxies(cli.flags.proxy),
    logResponse: parseOnOff(cli.flags.logResponse, '--log-response'),
    defaultCors: parseOnOff(cli.flags.defaultCors, '--default-cors'),
    responseHeader: cli.flags.responseHeader,
    hostname: cli.flags.hostname,
    ignoreUncaughtErrors: true
  }).start()
}
<commit_msg>Document multihost<commit_after>#!/usr/bin/env node
import meow from 'meow'
import consoleLogServer from './'
import _ from 'lodash/fp'
import prependHttp from 'prepend-http'
import url from 'url'

let unknownArgs = false

const cli = meow(
  `
  Usage
    $ console-log-server

  Options
    --port, -p Port Number
    --hostname, -h Host name. You can provide multiple hostname flags (with optional matching port flags) to listen many hostnames.
    --proxy, -P Host(s) to proxy the request to using https://www.npmjs.com/package/express-http-proxy. Syntax: [<path>>]<url>. You can provide different proxies for separate paths.
    --response-code, -c Response response code (ignored if proxied)
    --response-body, -b Response content (ignored if proxied)
    --response-header, -H Response header (ignored if proxied)
    --log-response, -r Log also the response. Enabled by default only for proxied requests. Logged response is fully read to a buffer which might change your api behaviour since response is not streamed directly to client, consider turning off if that is a problem.
    --no-color
    --version
    --date-format, -d Date format supported by https://www.npmjs.com/package/dateformat (default "yyyy-mm-dd'T'HH:MM:sso")
    --help
    --default-cors, -C Add "default" cors using https://www.npmjs.com/package/cors default values. By default only enabled for non-proxied responses. Turn on to enable also for proxy responses, turn off to disable completely.

  Examples

    # basic usage
    $ console-log-server -p 3000

    # customized response
    $ console-log-server -p 3000 -c 201 -b "cool type content" --response-header='Content-Type:application/cool' --response-header='key:value'

    # Log date with UTC date format instead of local with offset
    $ console-log-server -d "isoUtcDateTime"

    # Proxy the request to other host. Response will be the actual response from the proxy.
    $ console-log-server -P http://api.example.com

    # Proxy the requests to multiple hosts based on paths.
    $ console-log-server --proxy="/api/1>http://api-1.example.com" -proxy="/api/2>http://api-2.example.com"

    # Proxy the request to path under other host. Response will be the actual response (with cors headers injected) from the proxy.
    $ console-log-server -P http://api.example.com/v1/cats -C yes

    # Turn off response logging
    $ console-log-server -r no

    # Turn on response logging for all requests
    $ console-log-server -r yes

    # Don't add default (allow all) cors headers at all
    $ console-log-server -C no

    # Start server to your local IP and locahost. Might be useful when debugging devices connected to your own machine. Ports can be given for each hostname with --port flag(s).
    $ console-log-server -h localhost -h 192.168.0.2
`,
  {
    alias: {
      p: 'port',
      h: 'hostname',
      c: 'response-code',
      b: 'response-body',
      H: 'response-header',
      d: 'date-format',
      P: 'proxy',
      r: 'log-response',
      C: 'default-cors'
    },
    unknown: arg => {
      unknownArgs = !_.includes(arg, ['--no-color', '--version'])
      return true
    }
  }
)

function parseProxies (proxiesArg) {
  if (!proxiesArg) return undefined

  const proxies = _.flow(
    _.castArray,
    _.map(_.trim),
    _.compact,
    _.map(proxyArg => {
      const [pathPart, proxyPart] = _.split('>', proxyArg)
      const proxyHost = proxyPart ?? pathPart
      if (!proxyHost) {
        throw Error(`Invalid proxy arguments: ${proxyArg}`)
      }

      const parsedHost = url.URL
        ? new URL(prependHttp(proxyHost))
        : url.parse(prependHttp(proxyHost)) // eslint-disable-line node/no-deprecated-api
      const protocol = proxyHost.startsWith('https')
        ? 'https'
        : proxyHost.startsWith('http')
        ? 'http'
        : undefined
      return {
        path: proxyPart === undefined ? undefined : pathPart,
        host: parsedHost.host,
        protocol,
        hostPath: parsedHost.pathname
      }
    })
  )(proxiesArg)

  return proxies
}

function showMessageAndExit (message) {
  console.log(message)
  cli.showHelp(1)
  return undefined
}

const parseOnOff = (value, flagName) =>
  value === undefined
    ? undefined
    : /^(?:y|yes|true|1|on)$/i.test(value)
    ? true
    : /^(?:n|no|false|0|off)$/i.test(value)
    ? false
    : showMessageAndExit(`Invalid value '${value}' for ${flagName}`)

if (unknownArgs) {
  cli.showHelp()
} else {
  consoleLogServer({
    ...cli.flags,
    proxy: parseProxies(cli.flags.proxy),
    logResponse: parseOnOff(cli.flags.logResponse, '--log-response'),
    defaultCors: parseOnOff(cli.flags.defaultCors, '--default-cors'),
    responseHeader: cli.flags.responseHeader,
    hostname: cli.flags.hostname,
    ignoreUncaughtErrors: true
  }).start()
}
<|endoftext|>


<commit_before>require('app').directive('documentList', function ($http) {
        return {
            restrict: 'EAC',
            templateUrl: '/app/views/directives/document-list.partial.html',
            replace: true,
            // require : "?ngModel",
            scope: {
                  // placeholder: '@',
                  // ngDisabledFn : '&ngDisabled',
                  // binding    : '=ngModel',
                  // locales    : '=',
                  // required   : "@"
                  documents : '=',
                  filter: '@',
                  showPagination: '@',
                  currentPage: '=',
                  documentCount: '='
            },
            controller: ['$scope', function ($scope){

              $scope.loaded = false;
              $scope.itemsPerPage = 25;
              $scope.pageCount = 0;
              $scope.currentPage = 0;
              $scope.transformedDocuments = [];

                $scope.load = function(item) {
                 console.log(item);
                      item.data = {'schema':item.schema, 'url_ss': item.url_ss, 'data': []};
                        $http.get("/api/v2013/documents/"+item.identifier_s).then(function (result) {
                            item.data = result.data;

                            $http.get("/api/v2013/documents/"+item.identifier_s + "?info").then(function (result) {
                                item.data.info = result.data;
                            });

                        });

                    }

                $scope.filterCategory = function(item) {
                            //console.log($scope.filter);
                            if($scope.filter == '*' || item.schema.toUpperCase() == $scope.filter.toUpperCase() )
                                return true;

                            return false;

                  }

                $scope.actionSetPage = function (pageNumber) {
                  //debugger;
                                  $scope.currentPage = Math.min($scope.pageCount-1, Math.max(0, pageNumber));
                              };

                $scope.range = function (start, end) {

                    var ret = [];
                    if (!end) {
                        end = start;
                        start = 0;
                    }

                    var maxCount = 10;
                    var middle = 5;
                    var count = end - start;

                    if (count > maxCount) {
                        if ($scope.currentPage > middle)
                            start = $scope.currentPage - middle;

                        end = Math.min(count, start + maxCount);
                        start = Math.max(0, end - maxCount);
                    }

                    for (var i = start; i < end; i++) {
                        ret.push(i);
                    }
                    return ret;
                };

                $scope.$watch('currentPage', function (newValue, oldValue) {
                     if (newValue != oldValue)
                     {
                       console.log('current page changed');
                        $scope.currentPage = newValue;
                    }
                });

                $scope.$watch('documents', function (newValue, oldValue) {

                     if (newValue != oldValue)
                     {
                        $scope.pageCount = Math.ceil($scope.documentCount / $scope.itemsPerPage);

                       $scope.transformedDocuments = [];
                       $scope.documents.forEach(function (doc) {
                           $scope.transformedDocuments.push(transformDocument(doc));
                        });

                       console.log( $scope.transformedDocuments);
                    }
                });

                function transformDocument (document) {

                  var output = {};

                  var formatDate = function formatDate (date) {
                        return date+'';//moment(date).format('MMMM Do YYYY');
                    };

                    output.id          = document.id;
                    output.schema      = document.schema_EN_t.toUpperCase();
                    output.title       = document.title_t;
                    output.description = document.description_t;
                    output.source      = document.government_EN_t;
                    output.url_ss      = document.url_ss;
                    output.identifier_s = document.identifier_s;
                    output.doc = document;

                    if(document.schema_s=='focalPoint') {
                        output.description  = document.function_t||'';
                        output.description += (document.function_t && document.department_t) ? ', ' : '';
                        output.description += document.department_t||'';
                        output.description2 = document.organization_t||'';
                    }

                    if(document.schema_s=='decision' && document.body_s=='XXVII8-COP' ) output.source = 'COP TO THE CONVENTION';
                    if(document.schema_s=='decision' && document.body_s=='XXVII8b-MOP') output.source = 'COP-MOP TO THE CARTAGENA PROTOCOL ON BIOSAFETY';
                    if(document.schema_s=='decision') output.title       = 'Decision ' + document.code_s;
                    if(document.schema_s=='decision') output.description = document.title_t;

                    if(document.schema_s=='recommendation' && document.body_s=='XXVII8-SBSTTA') { output.source = 'SBSTTA'; output.sourceTooltip = 'Subsidiary Body on Scientific, Technical and Technological Advice'; }
                    if(document.schema_s=='recommendation' && document.body_s=='XXVII8-WGRI'  ) { output.source = 'WGRI';   output.sourceTooltip = 'Working Group on the Review of Implementation'; }
                    if(document.schema_s=='recommendation' && document.body_s=='XXVII8b-ICCP' ) { output.source = 'ICCP';   output.sourceTooltip = 'Intergovernmental Committee for the Cartagena Protocol on Biosafety'; }
                    if(document.schema_s=='recommendation' && document.body_s=='XXVII8c-ICNP' ) { output.source = 'ICNP';   output.sourceTooltip = 'Intergovernmental Committee for the Nagoya Protocol on ABS'; }
                    if(document.schema_s=='recommendation') output.title       = 'Recommendation ' + document.code_s;
                    if(document.schema_s=='recommendation') output.description = document.title_t;

                    if(document.schema_s=='meetingDocument') output.source      = document.meeting_s;
                    if(document.schema_s=='meetingDocument') output.title       = document.symbol_s;
                    if(document.schema_s=='meetingDocument') output.description = document.title_t;
                    if(document.schema_s=='meetingDocument' && document.group_s=='INF') output.source += ' - INFORMATION';
                    if(document.schema_s=='meetingDocument' && document.group_s=='OFC') output.source += ' - PRE-SESSION';

                    if(document.schema_s=='nationalReport') output.description = document.summary_EN_t;
                    if(document.schema_s=='nationalReport') output.type        = document.reportType_EN_t;

                    if(document.schema_s=='implementationActivity') output.type = document.jurisdiction_EN_t + ' - ' + document.completion_EN_t;

                    if(document.schema_s=='marineEbsa') output.schema = 'ECOLOGICALLY OR BIOLOGICALLY SIGNIFICANT AREA';

                    if(document.schema_s=='event') {
                        output.dates = formatDate(document.startDate_s) + ' to ' + formatDate(document.endDate_s);
                        output.venue = document.eventCity_EN_t + ', ' + document.eventCountry_EN_t;
                    }

                    return output;
                }

            }]

        };
    });<commit_msg>added date format function<commit_after>require('app').directive('documentList', function ($http) {
        return {
            restrict: 'EAC',
            templateUrl: '/app/views/directives/document-list.partial.html',
            replace: true,
            // require : "?ngModel",
            scope: {
                  // placeholder: '@',
                  // ngDisabledFn : '&ngDisabled',
                  // binding    : '=ngModel',
                  // locales    : '=',
                  // required   : "@"
                  documents : '=',
                  filter: '@',
                  showPagination: '@',
                  currentPage: '=',
                  documentCount: '='
            },
            controller: ['$scope', function ($scope){

              $scope.formatDate = function formatDate (date) {
                    return moment(date).format('MMMM Do YYYY');
              };

              $scope.loaded = false;
              $scope.itemsPerPage = 25;
              $scope.pageCount = 0;
              $scope.currentPage = 0;
              $scope.transformedDocuments = [];

                $scope.load = function(item) {
                 console.log(item);
                      item.data = {'schema':item.schema, 'url_ss': item.url_ss, 'data': []};
                        $http.get("/api/v2013/documents/"+item.identifier_s).then(function (result) {
                            item.data = result.data;

                            $http.get("/api/v2013/documents/"+item.identifier_s + "?info").then(function (result) {
                                item.data.info = result.data;
                            });

                        });

                    }

                $scope.filterCategory = function(item) {
                            //console.log($scope.filter);
                            if($scope.filter == '*' || item.schema.toUpperCase() == $scope.filter.toUpperCase() )
                                return true;

                            return false;

                  }

                $scope.actionSetPage = function (pageNumber) {
                  //debugger;
                                  $scope.currentPage = Math.min($scope.pageCount-1, Math.max(0, pageNumber));
                              };

                $scope.range = function (start, end) {

                    var ret = [];
                    if (!end) {
                        end = start;
                        start = 0;
                    }

                    var maxCount = 10;
                    var middle = 5;
                    var count = end - start;

                    if (count > maxCount) {
                        if ($scope.currentPage > middle)
                            start = $scope.currentPage - middle;

                        end = Math.min(count, start + maxCount);
                        start = Math.max(0, end - maxCount);
                    }

                    for (var i = start; i < end; i++) {
                        ret.push(i);
                    }
                    return ret;
                };

                $scope.$watch('currentPage', function (newValue, oldValue) {
                     if (newValue != oldValue)
                     {
                       console.log('current page changed');
                        $scope.currentPage = newValue;
                    }
                });

                $scope.$watch('documents', function (newValue, oldValue) {

                     if (newValue != oldValue)
                     {
                        $scope.pageCount = Math.ceil($scope.documentCount / $scope.itemsPerPage);

                       $scope.transformedDocuments = [];
                       $scope.documents.forEach(function (doc) {
                           $scope.transformedDocuments.push(transformDocument(doc));
                        });

                       console.log( $scope.transformedDocuments);
                    }
                });

                function transformDocument (document) {

                  var output = {};

                  var formatDate = function formatDate (date) {
                        return date+'';//moment(date).format('MMMM Do YYYY');
                    };

                    output.id          = document.id;
                    output.schema      = document.schema_EN_t.toUpperCase();
                    output.title       = document.title_t;
                    output.description = document.description_t;
                    output.source      = document.government_EN_t;
                    output.url_ss      = document.url_ss;
                    output.identifier_s = document.identifier_s;
                    output.doc = document;

                    if(document.schema_s=='focalPoint') {
                        output.description  = document.function_t||'';
                        output.description += (document.function_t && document.department_t) ? ', ' : '';
                        output.description += document.department_t||'';
                        output.description2 = document.organization_t||'';
                    }

                    if(document.schema_s=='decision' && document.body_s=='XXVII8-COP' ) output.source = 'COP TO THE CONVENTION';
                    if(document.schema_s=='decision' && document.body_s=='XXVII8b-MOP') output.source = 'COP-MOP TO THE CARTAGENA PROTOCOL ON BIOSAFETY';
                    if(document.schema_s=='decision') output.title       = 'Decision ' + document.code_s;
                    if(document.schema_s=='decision') output.description = document.title_t;

                    if(document.schema_s=='recommendation' && document.body_s=='XXVII8-SBSTTA') { output.source = 'SBSTTA'; output.sourceTooltip = 'Subsidiary Body on Scientific, Technical and Technological Advice'; }
                    if(document.schema_s=='recommendation' && document.body_s=='XXVII8-WGRI'  ) { output.source = 'WGRI';   output.sourceTooltip = 'Working Group on the Review of Implementation'; }
                    if(document.schema_s=='recommendation' && document.body_s=='XXVII8b-ICCP' ) { output.source = 'ICCP';   output.sourceTooltip = 'Intergovernmental Committee for the Cartagena Protocol on Biosafety'; }
                    if(document.schema_s=='recommendation' && document.body_s=='XXVII8c-ICNP' ) { output.source = 'ICNP';   output.sourceTooltip = 'Intergovernmental Committee for the Nagoya Protocol on ABS'; }
                    if(document.schema_s=='recommendation') output.title       = 'Recommendation ' + document.code_s;
                    if(document.schema_s=='recommendation') output.description = document.title_t;

                    if(document.schema_s=='meetingDocument') output.source      = document.meeting_s;
                    if(document.schema_s=='meetingDocument') output.title       = document.symbol_s;
                    if(document.schema_s=='meetingDocument') output.description = document.title_t;
                    if(document.schema_s=='meetingDocument' && document.group_s=='INF') output.source += ' - INFORMATION';
                    if(document.schema_s=='meetingDocument' && document.group_s=='OFC') output.source += ' - PRE-SESSION';

                    if(document.schema_s=='nationalReport') output.description = document.summary_EN_t;
                    if(document.schema_s=='nationalReport') output.type        = document.reportType_EN_t;

                    if(document.schema_s=='implementationActivity') output.type = document.jurisdiction_EN_t + ' - ' + document.completion_EN_t;

                    if(document.schema_s=='marineEbsa') output.schema = 'ECOLOGICALLY OR BIOLOGICALLY SIGNIFICANT AREA';

                    if(document.schema_s=='event') {
                        output.dates = formatDate(document.startDate_s) + ' to ' + formatDate(document.endDate_s);
                        output.venue = document.eventCity_EN_t + ', ' + document.eventCountry_EN_t;
                    }

                    return output;
                }

            }]

        };
    });<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var Connection = require('./connection')
  , events = require('events')
  , util = require('util')
  , crypto = require('crypto')
  , net = require('net');

/**
 * Defaults
 */

var defaultPort = 1883
  , defaultHost = 'localhost';

var defaultConnectOptions = {
  keepalive: 10000,
  client: 'mqttjs_' + crypto.randomBytes(16).toString('hex')
};

var nop = function(){};

/**
 * MqttClient constructor
 *
 * @param <Number> [port] - broker port
 * @param <String> [host] - broker hostname
 * @param <Object> [options] - connection options (see Connection#connect)
 */
var MqttClient = module.exports =
function MqttClient(port, host, options) {
  if (!this instanceof MqttClient) {
    return new MqttClient(port, host, options);
  }

  var self = this;

  if ('object' === typeof port) {
    // new MqttClient({client: asdf, keepalive:1234})
    options = port;
    port = defaultPort;
    host = defaultHost;
  } else if ('object' === typeof host) {
    // new MqttClient(1234, {client:asdf, keepalive:1234})
    options = host;
    host = defaultHost;
  }

  // Defaults
  this.options = options || defaultConnectOptions;

  this.net_client = new net.Socket();
  this.mqtt_conn = new Connection(this.net_client, null);
  this.nextId = 0;

  // Inflight messages
  this.inflight = {
    puback: {},
    pubrec: {},
    pubcomp: {},
    suback: {}
  }

  // Incoming messages
  this.incoming = {
    pubrel: {}
  };

  this.net_client.connect(port, host, function () {
    self.mqtt_conn.connect(options);
  });

  this.mqtt_conn.on('connack', function(packet) {
    var rc = packet.returnCode;

    if (rc === 0) {
      self.emit('connect');
    } else {
      // TODO: more informative
      self.emit('error', new Error('Connect error: ' + rc));
    }
  });

  // Handle incoming publish
  this.mqtt_conn.on('publish', this._handlePublish.bind(this));

  // Handle incoming acks
  this.mqtt_conn.on('puback', this._handleAck.bind(this));
  this.mqtt_conn.on('pubrec', this._handleAck.bind(this));
  this.mqtt_conn.on('pubcomp', this._handleAck.bind(this));
  this.mqtt_conn.on('suback', this._handleAck.bind(this));

  // Handle outgoing acks
  this.mqtt_conn.on('pubrel', function(packet) {
    var mid = packet.messageId
      , data = self.incoming.pubrel[mid];

    if (!data) self.emit('error', new Error('Unknown message id'));
    self.mqtt_conn.pubcomp({messageId: mid});
    self.emit('message', data.topic, data.message);
  });

  // Pingreq timer
  var pingreqTimer = setInterval(
      this.mqtt_conn.pingreq.bind(this.mqtt_conn),
      this.options.keepalive / 2
  );

  events.EventEmitter.call(this);
};
util.inherits(MqttClient, events.EventEmitter);

/**
 * publish - publish <message> to <topic>
 *
 * @param <String> topic - topic to publish to
 * @param <String, Buffer> message - message to publish
 * @param <Object> [opts] - publish options, includes:
 *    <Number> qos - qos level to publish on
 *    <Boolean> retain - whether or not to retain the message
 * @param <Function> [callback] - function(err, success){}
 *    called when publish succeeds or fails
 * @api public
 */
MqttClient.prototype.publish =
function(topic, message, opts, callback) {
  var packet;

  // .publish(topic, payload, cb);
  if ('function' === typeof opts) {
    callback = opts;
    opts = null;
  }

  // Default opts
  if(!opts) opts = {qos: 0, retain: false};

  callback = callback || nop;

  packet = {
    topic: topic,
    payload: message,
    qos: opts.qos,
    retain: opts.retain,
    messageId: this.nextId
  }

  this.mqtt_conn.publish(packet);

  switch (opts.qos) {
    case 0:
      // Immediately callback
      callback(null, true);
      break;
    case 1:
      // Add to puback callbacks
      this.inflight.puback[this.nextId++] = callback;
      break;
    case 2:
      // Add to pubrec callbacks
      this.inflight.pubrec[this.nextId++] = callback;
      break
    default:
      break;
  }
};

/**
 * subscribe - subscribe to <topic>
 *
 * @param <String, Array> topic - topic(s) to subscribe to
 * @param <Object> [opts] - subscription options, includes:
 *    <Number> qos - subscribe qos level
 * @param <Function> [callback] - fires on suback
 * @api public
 */
MqttClient.prototype.subscribe =
function(topic, opts, callback) {
  var subs = [];

  // .subscribe('topic', callback)
  if ('function' === typeof opts) {
    callback = opts;
    opts = null;
  }

  // Defaults
  opts = opts || {qos: 0};
  callback = callback || nop;

  if ('string' === typeof topic) {
    subs.push({topic: topic, qos: opts.qos});
  } else if ('object' === typeof topic) {
    // TODO: harder array check
    for (var i = 0; i < topic.length; i += 1) {
      var t = topic[i];
      subs.push({topic: t, qos: opts.qos});
    }
  } else {
    // Error!
  }

  var packet = {
    subscriptions: subs,
    qos: 1,
    messageId: this.nextId,
    retain: false,
    dup: false
  };

  this.mqtt_conn.subscribe(packet);
  this.inflight.suback[this.nextId++] = callback;
};

/**
 * _handlePublish
 *
 * @param <Object> packet
 * @api private
 */

MqttClient.prototype._handlePublish = function(packet) {
  var topic = packet.topic
    , message = packet.payload
    , qos = packet.qos
    , mid = packet.messageId;

  switch (qos) {
    case 0:
      this.emit('message', topic, message);
      break;
    case 1:
      this.mqtt_conn.puback({messageId: mid});
      this.emit('message', topic, message);
      break;
    case 2:
      this.mqtt_conn.pubrec({messageId: mid});
      this.incoming.pubrel[mid] = {topic: topic, message: message};
      break;
    default:
      break;
  }
};

/**
 * _handleAck
 *
 * @param <Object> packet
 * @api private
 */

MqttClient.prototype._handleAck = function(packet) {
  var mid = packet.messageId
    , type = packet.cmd
    , cb = this.inflight[type][mid];

  // Check if callback exists
  if(!cb) this.emit('error', new Error('Unknown message id'));

  // Process
  switch (type) {
    case 'puback':
      // Callback - we're done
      cb(null, true);
      break;
    case 'pubrec':
      // Pubrel and add to pubcomp list
      this.mqtt_conn.pubrel(packet);
      this.inflight.pubcomp[mid] = cb;
      break;
    case 'pubcomp':
      // Callback - we're done
      cb(null, true);
      break;
    case 'suback':
      cb(null, true);
    default:
      // code
  }

  // Remove from queue
  delete this.inflight[type][mid];
};
<commit_msg>Missing break<commit_after>/**
 * Module dependencies
 */

var Connection = require('./connection')
  , events = require('events')
  , util = require('util')
  , crypto = require('crypto')
  , net = require('net');

/**
 * Defaults
 */

var defaultPort = 1883
  , defaultHost = 'localhost';

var defaultConnectOptions = {
  keepalive: 10000,
  client: 'mqttjs_' + crypto.randomBytes(16).toString('hex')
};

var nop = function(){};

/**
 * MqttClient constructor
 *
 * @param <Number> [port] - broker port
 * @param <String> [host] - broker hostname
 * @param <Object> [options] - connection options (see Connection#connect)
 */
var MqttClient = module.exports =
function MqttClient(port, host, options) {
  if (!this instanceof MqttClient) {
    return new MqttClient(port, host, options);
  }

  var self = this;

  if ('object' === typeof port) {
    // new MqttClient({client: asdf, keepalive:1234})
    options = port;
    port = defaultPort;
    host = defaultHost;
  } else if ('object' === typeof host) {
    // new MqttClient(1234, {client:asdf, keepalive:1234})
    options = host;
    host = defaultHost;
  }

  // Defaults
  this.options = options || defaultConnectOptions;

  this.net_client = new net.Socket();
  this.mqtt_conn = new Connection(this.net_client, null);
  this.nextId = 0;

  // Inflight messages
  this.inflight = {
    puback: {},
    pubrec: {},
    pubcomp: {},
    suback: {}
  }

  // Incoming messages
  this.incoming = {
    pubrel: {}
  };

  this.net_client.connect(port, host, function () {
    self.mqtt_conn.connect(options);
  });

  this.mqtt_conn.on('connack', function(packet) {
    var rc = packet.returnCode;

    if (rc === 0) {
      self.emit('connect');
    } else {
      // TODO: more informative
      self.emit('error', new Error('Connect error: ' + rc));
    }
  });

  // Handle incoming publish
  this.mqtt_conn.on('publish', this._handlePublish.bind(this));

  // Handle incoming acks
  this.mqtt_conn.on('puback', this._handleAck.bind(this));
  this.mqtt_conn.on('pubrec', this._handleAck.bind(this));
  this.mqtt_conn.on('pubcomp', this._handleAck.bind(this));
  this.mqtt_conn.on('suback', this._handleAck.bind(this));

  // Handle outgoing acks
  this.mqtt_conn.on('pubrel', function(packet) {
    var mid = packet.messageId
      , data = self.incoming.pubrel[mid];

    if (!data) self.emit('error', new Error('Unknown message id'));
    self.mqtt_conn.pubcomp({messageId: mid});
    self.emit('message', data.topic, data.message);
  });

  // Pingreq timer
  var pingreqTimer = setInterval(
      this.mqtt_conn.pingreq.bind(this.mqtt_conn),
      this.options.keepalive / 2
  );

  events.EventEmitter.call(this);
};
util.inherits(MqttClient, events.EventEmitter);

/**
 * publish - publish <message> to <topic>
 *
 * @param <String> topic - topic to publish to
 * @param <String, Buffer> message - message to publish
 * @param <Object> [opts] - publish options, includes:
 *    <Number> qos - qos level to publish on
 *    <Boolean> retain - whether or not to retain the message
 * @param <Function> [callback] - function(err, success){}
 *    called when publish succeeds or fails
 * @api public
 */
MqttClient.prototype.publish =
function(topic, message, opts, callback) {
  var packet;

  // .publish(topic, payload, cb);
  if ('function' === typeof opts) {
    callback = opts;
    opts = null;
  }

  // Default opts
  if(!opts) opts = {qos: 0, retain: false};

  callback = callback || nop;

  packet = {
    topic: topic,
    payload: message,
    qos: opts.qos,
    retain: opts.retain,
    messageId: this.nextId
  }

  this.mqtt_conn.publish(packet);

  switch (opts.qos) {
    case 0:
      // Immediately callback
      callback(null, true);
      break;
    case 1:
      // Add to puback callbacks
      this.inflight.puback[this.nextId++] = callback;
      break;
    case 2:
      // Add to pubrec callbacks
      this.inflight.pubrec[this.nextId++] = callback;
      break
    default:
      break;
  }
};

/**
 * subscribe - subscribe to <topic>
 *
 * @param <String, Array> topic - topic(s) to subscribe to
 * @param <Object> [opts] - subscription options, includes:
 *    <Number> qos - subscribe qos level
 * @param <Function> [callback] - fires on suback
 * @api public
 */
MqttClient.prototype.subscribe =
function(topic, opts, callback) {
  var subs = [];

  // .subscribe('topic', callback)
  if ('function' === typeof opts) {
    callback = opts;
    opts = null;
  }

  // Defaults
  opts = opts || {qos: 0};
  callback = callback || nop;

  if ('string' === typeof topic) {
    subs.push({topic: topic, qos: opts.qos});
  } else if ('object' === typeof topic) {
    // TODO: harder array check
    for (var i = 0; i < topic.length; i += 1) {
      var t = topic[i];
      subs.push({topic: t, qos: opts.qos});
    }
  } else {
    // Error!
  }

  var packet = {
    subscriptions: subs,
    qos: 1,
    messageId: this.nextId,
    retain: false,
    dup: false
  };

  this.mqtt_conn.subscribe(packet);
  this.inflight.suback[this.nextId++] = callback;
};

/**
 * _handlePublish
 *
 * @param <Object> packet
 * @api private
 */

MqttClient.prototype._handlePublish = function(packet) {
  var topic = packet.topic
    , message = packet.payload
    , qos = packet.qos
    , mid = packet.messageId;

  switch (qos) {
    case 0:
      this.emit('message', topic, message);
      break;
    case 1:
      this.mqtt_conn.puback({messageId: mid});
      this.emit('message', topic, message);
      break;
    case 2:
      this.mqtt_conn.pubrec({messageId: mid});
      this.incoming.pubrel[mid] = {topic: topic, message: message};
      break;
    default:
      break;
  }
};

/**
 * _handleAck
 *
 * @param <Object> packet
 * @api private
 */

MqttClient.prototype._handleAck = function(packet) {
  var mid = packet.messageId
    , type = packet.cmd
    , cb = this.inflight[type][mid];

  // Check if callback exists
  if(!cb) this.emit('error', new Error('Unknown message id'));

  // Process
  switch (type) {
    case 'puback':
      // Callback - we're done
      cb(null, true);
      break;
    case 'pubrec':
      // Pubrel and add to pubcomp list
      this.mqtt_conn.pubrel(packet);
      this.inflight.pubcomp[mid] = cb;
      break;
    case 'pubcomp':
      // Callback - we're done
      cb(null, true);
      break;
    case 'suback':
      cb(null, true);
      break;
    default:
      // code
  }

  // Remove from queue
  delete this.inflight[type][mid];
};
<|endoftext|>


<commit_before>

import { Found } from "./astravel"

var ForInStatement, FunctionDeclaration, RestElement, BinaryExpression, ArrayExpression

const ignore = Function.prototype

export default {

	// Basic methods
	go( node, state ) {
		/*
		Starts travelling through the specified AST `node` with the provided `state`.
		This method is recursively called by each node handler.
		*/
		this[ node.type ]( node, state )
	},
	find( node, state ) {
		/*
		Starts travelling through the specified AST `node` with the provided `state`.
		If it catches a `Found` instance, returns it. Otherwise, returns `undefined`.
		*/
			try {
				 this.go( node, state );
			} catch ( error ) {
				 if ( error instanceof Found )
						return error;
				 else
						throw error;
			}
	 },
	makeChild( properties = {} ) {
		/*
		Returns a custom AST traveler that inherits from `this` traveler with its own provided `properties` and the property `super` that points to the parent traveler object.
		*/
		let traveler = Object.create( this )
		traveler.super = this
		for ( let key in properties )
			traveler[ key ] = properties[ key ]
		return traveler
	},

	// JavaScript 5
	Program( node, state ) {
		let statements = node.body
		for ( let i = 0, { length } = statements; i < length; i++ )
			this.go( statements[ i ], state )
	},
	BlockStatement( node, state ) {
		let statements = node.body
		if ( statements != null )
			for ( let i = 0, { length } = statements; i < length; i++ )
				this.go( statements[ i ], state )
	},
	EmptyStatement: ignore,
	ExpressionStatement( node, state ) {
		this.go( node.expression, state )
	},
	IfStatement( node, state ) {
		this.go( node.test, state )
		this.go( node.consequent, state )
		if ( node.alternate != null )
			this.go( node.alternate, state )
	},
	LabeledStatement( node, state ) {
		this.go( node.label, state )
		this.go( node.body, state )
	},
	BreakStatement( node, state ) {
		if ( node.label )
			this.go( node.label, state )
	},
	ContinueStatement( node, state ) {
		if ( node.label )
			this.go( node.label, state )
	},
	WithStatement( node, state ) {
		this.go( node.object, state )
		this.go( node.body, state )
	},
	SwitchStatement( node, state ) {
		this.go( node.discriminant, state )
		const { cases } = node;
		for ( let i = 0, { length } = cases; i < length; i++ )
			this.go( cases[ i ], state )
	},
	SwitchCase( node, state ) {
		if ( node.test != null )
			this.go( node.test, state )
		let statements = node.consequent
		for ( let i = 0, { length } = statements; i < length; i++ )
			this.go( statements[ i ], state )
	},
	ReturnStatement( node, state ) {
		if ( node.argument )
			this.go( node.argument, state )
	},
	ThrowStatement( node, state ) {
		this.go( node.argument, state )
	},
	TryStatement( node, state ) {
		this.go( node.block, state )
		if ( node.handler != null )
			this.go( node.handler, state )
		if ( node.finalizer != null )
			this.go( node.finalizer, state )
	},
	CatchClause( node, state ) {
		this.go( node.param, state )
		this.go( node.body, state )
	},
	WhileStatement( node, state ) {
		this.go( node.test, state )
		this.go( node.body, state )
	},
	DoWhileStatement( node, state ) {
		this.go( node.body, state )
		this.go( node.test, state )
	},
	ForStatement( node, state ) {
		if ( node.init != null )
			this.go( node.init, state )
		if ( node.test != null )
			this.go( node.test, state )
		if ( node.update != null )
			this.go( node.update, state )
		this.go( node.body, state )
	},
	ForInStatement: ForInStatement = function( node, state ) {
		this.go( node.left, state )
		this.go( node.right, state )
		this.go( node.body, state )
	},
	DebuggerStatement: ignore,
	FunctionDeclaration: FunctionDeclaration = function( node, state ) {
		if ( node.id != null )
			this.go( node.id, state )
		const { params } = node
		if ( params != null && params.length !== 0 )
			for ( let i = 0, { length } = params; i < length; i++ )
				this.go( params[ i ], state )
		this.go( node.body, state )
	},
	VariableDeclaration( node, state ) {
		const { declarations } = node
		for ( let i = 0, { length } = declarations; i < length; i++ )
			this.go( declarations[ i ], state )
	},
	VariableDeclarator( node, state ) {
		this.go( node.id, state )
		if ( node.init != null )
			this.go( node.init, state )
	},
	ArrowFunctionExpression( node, state ) {
		const { params } = node
		if ( params != null && params.length !== 0 ) {
			for ( let i = 0, { length } = params; i < length; i++ ) {
				let param = params[ i ]
				this.go( param, state )
			}
		}
		this.go( node.body, state )
	},
	ThisExpression: ignore,
	ArrayExpression: ArrayExpression = function( node, state ) {
		for ( let i = 0, { elements } = node, { length } = elements; i < length; i++ ) {
			let element = elements[ i ]
			this.go( element, state )
		}
	},
	ObjectExpression( node, state ) {
		const { properties } = node, { length } = properties
		for ( let i = 0; i < length; i++ )
			this.go( properties[ i ], state )
	},
	Property( node, state ) {
		this.go( node.key, state )
		if ( !node.shorthand )
			this.go( node.value, state )
	},
	FunctionExpression: FunctionDeclaration,
	SequenceExpression( node, state ) {
		const { expressions } = node
		for ( let i = 0, { length } = expressions; i < length; i++ ) {
			let expression = expressions[ i ]
			this.go( expression, state )
		}
	},
	UnaryExpression( node, state ) {
		this.go( node.argument, state )
	},
	UpdateExpression( node, state ) {
		this.go( node.argument, state )
	},
	AssignmentExpression( node, state ) {
		this.go( node.left, state )
		this.go( node.right, state )
	},
	BinaryExpression: BinaryExpression = function( node, state ) {
		this.go( node.left, state )
		this.go( node.right, state )
	},
	LogicalExpression: BinaryExpression,
	ConditionalExpression( node, state ) {
		this.go( node.test, state )
		this.go( node.consequent, state )
		this.go( node.alternate, state )
	},
	NewExpression( node, state ) {
		this.CallExpression( node, state )
	},
	CallExpression( node, state ) {
		this.go( node.callee, state )
		const args = node[ 'arguments' ]
		for ( let i = 0, { length } = args; i < length; i++ )
			this.go( args[ i ], state )
	},
	MemberExpression( node, state ) {
		this.go( node.object, state )
		this.go( node.property, state )
	},
	Identifier: ignore,
	Literal: ignore,

	// JavaScript 6
	ForOfStatement: ForInStatement,
	ClassDeclaration( node, state ) {
		this.go( node.id, state )
		if ( node.superClass )
			this.go( node.superClass, state )
		// ClassBody
		this.BlockStatement( node.body, state )
	},
	ImportDeclaration( node, state ) {
		const { specifiers } = node, { length } = specifiers
		if ( length > 0 )
			for ( let i = 0; i < length; i++ )
				this.go( specifiers[ i ], state )
		this.go( node.source, state )
	},
	ImportNamespaceSpecifier( node, state ) {
		this.go( node.local, state )
	},
	ImportDefaultSpecifier( node, state ) {
		this.go( node.local, state )
	},
	ImportSpecifier( node, state ) {
		this.go( node.imported, state )
		this.go( node.local, state )
	},
	ExportDefaultDeclaration( node, state ) {
		this.go( node.declaration, state )
	},
	ExportNamedDeclaration( node, state ) {
		if ( node.declaration ) {
			this.go( node.declaration, state )
		} else {
			const { specifiers } = node, { length } = specifiers
			for ( let i = 0; i < length; i++ )
				this.go( specifiers[ i ], state )
			if ( node.source )
				this.go( node.source, state )
		}
	},
	ExportSpecifier( node, state ) {
		this.go( node.exported, state )
	},
	ExportAllDeclaration( node, state ) {
		this.go( node.source, state )
	},
	MethodDefinition( node, state ) {
		this.go( node.key, state )
		const { params } = node.value
		if ( params ) {
			for ( let i = 0, { length } = params; i < length; i++ )
				this.go( params[ i ], state )
		}
		this.go( node.value.body, state )
	},
	ClassExpression( node, state ) {
		this.ClassDeclaration( node, state )
	},
	Super: ignore,
	RestElement: RestElement = function( node, state ) {
		this.go( node.argument, state )
	},
	SpreadElement: RestElement,
	YieldExpression( node, state ) {
		if ( node.argument )
			this.go( node.argument, state )
	},
	TemplateLiteral( node, state ) {
		const { quasis, expressions } = node
		for ( let i = 0, { length } = expressions; i < length; i++ )
			this.go( expressions[ i ], state )
	},
	TaggedTemplateExpression( node, state ) {
		this.go( node.tag, state )
		this.go( node.quasi, state )
	},
	ObjectPattern( node, state ) {
		const { properties } = node, { length } = properties
		for ( let i = 0; i < length; i++ )
			this.go( properties[ i ], state )
	},
	ArrayPattern: ArrayExpression,
	AssignmentPattern( node, state ) {
		this.go( node.left, state )
		this.go( node.right, state )
	}

}

// TODO: Add JS7 nodes
<commit_msg>Added missing property in `ExportSpecifier` node traveler<commit_after>

import { Found } from "./astravel"

var ForInStatement, FunctionDeclaration, RestElement, BinaryExpression, ArrayExpression

const ignore = Function.prototype

export default {

	// Basic methods
	go( node, state ) {
		/*
		Starts travelling through the specified AST `node` with the provided `state`.
		This method is recursively called by each node handler.
		*/
		this[ node.type ]( node, state )
	},
	find( node, state ) {
		/*
		Starts travelling through the specified AST `node` with the provided `state`.
		If it catches a `Found` instance, returns it. Otherwise, returns `undefined`.
		*/
			try {
				 this.go( node, state );
			} catch ( error ) {
				 if ( error instanceof Found )
						return error;
				 else
						throw error;
			}
	 },
	makeChild( properties = {} ) {
		/*
		Returns a custom AST traveler that inherits from `this` traveler with its own provided `properties` and the property `super` that points to the parent traveler object.
		*/
		let traveler = Object.create( this )
		traveler.super = this
		for ( let key in properties )
			traveler[ key ] = properties[ key ]
		return traveler
	},

	// JavaScript 5
	Program( node, state ) {
		let statements = node.body
		for ( let i = 0, { length } = statements; i < length; i++ )
			this.go( statements[ i ], state )
	},
	BlockStatement( node, state ) {
		let statements = node.body
		if ( statements != null )
			for ( let i = 0, { length } = statements; i < length; i++ )
				this.go( statements[ i ], state )
	},
	EmptyStatement: ignore,
	ExpressionStatement( node, state ) {
		this.go( node.expression, state )
	},
	IfStatement( node, state ) {
		this.go( node.test, state )
		this.go( node.consequent, state )
		if ( node.alternate != null )
			this.go( node.alternate, state )
	},
	LabeledStatement( node, state ) {
		this.go( node.label, state )
		this.go( node.body, state )
	},
	BreakStatement( node, state ) {
		if ( node.label )
			this.go( node.label, state )
	},
	ContinueStatement( node, state ) {
		if ( node.label )
			this.go( node.label, state )
	},
	WithStatement( node, state ) {
		this.go( node.object, state )
		this.go( node.body, state )
	},
	SwitchStatement( node, state ) {
		this.go( node.discriminant, state )
		const { cases } = node;
		for ( let i = 0, { length } = cases; i < length; i++ )
			this.go( cases[ i ], state )
	},
	SwitchCase( node, state ) {
		if ( node.test != null )
			this.go( node.test, state )
		let statements = node.consequent
		for ( let i = 0, { length } = statements; i < length; i++ )
			this.go( statements[ i ], state )
	},
	ReturnStatement( node, state ) {
		if ( node.argument )
			this.go( node.argument, state )
	},
	ThrowStatement( node, state ) {
		this.go( node.argument, state )
	},
	TryStatement( node, state ) {
		this.go( node.block, state )
		if ( node.handler != null )
			this.go( node.handler, state )
		if ( node.finalizer != null )
			this.go( node.finalizer, state )
	},
	CatchClause( node, state ) {
		this.go( node.param, state )
		this.go( node.body, state )
	},
	WhileStatement( node, state ) {
		this.go( node.test, state )
		this.go( node.body, state )
	},
	DoWhileStatement( node, state ) {
		this.go( node.body, state )
		this.go( node.test, state )
	},
	ForStatement( node, state ) {
		if ( node.init != null )
			this.go( node.init, state )
		if ( node.test != null )
			this.go( node.test, state )
		if ( node.update != null )
			this.go( node.update, state )
		this.go( node.body, state )
	},
	ForInStatement: ForInStatement = function( node, state ) {
		this.go( node.left, state )
		this.go( node.right, state )
		this.go( node.body, state )
	},
	DebuggerStatement: ignore,
	FunctionDeclaration: FunctionDeclaration = function( node, state ) {
		if ( node.id != null )
			this.go( node.id, state )
		const { params } = node
		if ( params != null && params.length !== 0 )
			for ( let i = 0, { length } = params; i < length; i++ )
				this.go( params[ i ], state )
		this.go( node.body, state )
	},
	VariableDeclaration( node, state ) {
		const { declarations } = node
		for ( let i = 0, { length } = declarations; i < length; i++ )
			this.go( declarations[ i ], state )
	},
	VariableDeclarator( node, state ) {
		this.go( node.id, state )
		if ( node.init != null )
			this.go( node.init, state )
	},
	ArrowFunctionExpression( node, state ) {
		const { params } = node
		if ( params != null && params.length !== 0 ) {
			for ( let i = 0, { length } = params; i < length; i++ ) {
				let param = params[ i ]
				this.go( param, state )
			}
		}
		this.go( node.body, state )
	},
	ThisExpression: ignore,
	ArrayExpression: ArrayExpression = function( node, state ) {
		for ( let i = 0, { elements } = node, { length } = elements; i < length; i++ ) {
			let element = elements[ i ]
			this.go( element, state )
		}
	},
	ObjectExpression( node, state ) {
		const { properties } = node, { length } = properties
		for ( let i = 0; i < length; i++ )
			this.go( properties[ i ], state )
	},
	Property( node, state ) {
		this.go( node.key, state )
		if ( !node.shorthand )
			this.go( node.value, state )
	},
	FunctionExpression: FunctionDeclaration,
	SequenceExpression( node, state ) {
		const { expressions } = node
		for ( let i = 0, { length } = expressions; i < length; i++ ) {
			let expression = expressions[ i ]
			this.go( expression, state )
		}
	},
	UnaryExpression( node, state ) {
		this.go( node.argument, state )
	},
	UpdateExpression( node, state ) {
		this.go( node.argument, state )
	},
	AssignmentExpression( node, state ) {
		this.go( node.left, state )
		this.go( node.right, state )
	},
	BinaryExpression: BinaryExpression = function( node, state ) {
		this.go( node.left, state )
		this.go( node.right, state )
	},
	LogicalExpression: BinaryExpression,
	ConditionalExpression( node, state ) {
		this.go( node.test, state )
		this.go( node.consequent, state )
		this.go( node.alternate, state )
	},
	NewExpression( node, state ) {
		this.CallExpression( node, state )
	},
	CallExpression( node, state ) {
		this.go( node.callee, state )
		const args = node[ 'arguments' ]
		for ( let i = 0, { length } = args; i < length; i++ )
			this.go( args[ i ], state )
	},
	MemberExpression( node, state ) {
		this.go( node.object, state )
		this.go( node.property, state )
	},
	Identifier: ignore,
	Literal: ignore,

	// JavaScript 6
	ForOfStatement: ForInStatement,
	ClassDeclaration( node, state ) {
		this.go( node.id, state )
		if ( node.superClass )
			this.go( node.superClass, state )
		// ClassBody
		this.BlockStatement( node.body, state )
	},
	ImportDeclaration( node, state ) {
		const { specifiers } = node, { length } = specifiers
		if ( length > 0 )
			for ( let i = 0; i < length; i++ )
				this.go( specifiers[ i ], state )
		this.go( node.source, state )
	},
	ImportNamespaceSpecifier( node, state ) {
		this.go( node.local, state )
	},
	ImportDefaultSpecifier( node, state ) {
		this.go( node.local, state )
	},
	ImportSpecifier( node, state ) {
		this.go( node.imported, state )
		this.go( node.local, state )
	},
	ExportDefaultDeclaration( node, state ) {
		this.go( node.declaration, state )
	},
	ExportNamedDeclaration( node, state ) {
		if ( node.declaration ) {
			this.go( node.declaration, state )
		} else {
			const { specifiers } = node, { length } = specifiers
			for ( let i = 0; i < length; i++ )
				this.go( specifiers[ i ], state )
			if ( node.source )
				this.go( node.source, state )
		}
	},
	ExportSpecifier( node, state ) {
		this.go( node.local, state )
		this.go( node.exported, state )
	},
	ExportAllDeclaration( node, state ) {
		this.go( node.source, state )
	},
	MethodDefinition( node, state ) {
		this.go( node.key, state )
		const { params } = node.value
		if ( params ) {
			for ( let i = 0, { length } = params; i < length; i++ )
				this.go( params[ i ], state )
		}
		this.go( node.value.body, state )
	},
	ClassExpression( node, state ) {
		this.ClassDeclaration( node, state )
	},
	Super: ignore,
	RestElement: RestElement = function( node, state ) {
		this.go( node.argument, state )
	},
	SpreadElement: RestElement,
	YieldExpression( node, state ) {
		if ( node.argument )
			this.go( node.argument, state )
	},
	TemplateLiteral( node, state ) {
		const { quasis, expressions } = node
		for ( let i = 0, { length } = expressions; i < length; i++ )
			this.go( expressions[ i ], state )
	},
	TaggedTemplateExpression( node, state ) {
		this.go( node.tag, state )
		this.go( node.quasi, state )
	},
	ObjectPattern( node, state ) {
		const { properties } = node, { length } = properties
		for ( let i = 0; i < length; i++ )
			this.go( properties[ i ], state )
	},
	ArrayPattern: ArrayExpression,
	AssignmentPattern( node, state ) {
		this.go( node.left, state )
		this.go( node.right, state )
	}

}

// TODO: Add JS7 nodes
<|endoftext|>