<commit_before>/*!
 * base-generators <https://github.com/jonschlinkert/base-generators>
 *
 * Copyright (c) 2016, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var async = require('async');
var debug = require('debug')('base:generators');
var register = require('./lib/register');
var tasks = require('./lib/tasks');
var cache = require('./lib/cache');
var utils = require('./lib/utils');
var env = require('./lib/env');

/**
 * Expose `generators`
 */

module.exports = function generators(options) {
  return function(app) {
    if (this.isRegistered('base-generators')) return;
    this.isGenerator = true;

    /**
     * Add plugins necessary for running generators.
     * Plugins will only be registered once.
     */

    this.define('initGenerators', function() {
      this.set('env.alias', 'base');
      if (typeof this.task !== 'function') {
        this.use(utils.task());
      }
      this.use(register(options));
      this.use(utils.cwd());
      this.use(tasks());
      this.use(cache(options));
      this.use(env());
    });

    /**
     * Register generator `name` with the given `fn`, or get generator `name`
     * if only one argument is passed. This method calls the `.getGenerator` method
     * but goes one step further: if `name` is not already registered, it will try
     * to resolve and register the generator before returning it (or `undefined`
     * if unsuccessful).
     *
     * ```js
     * base.generator('foo', function(app, base) {
     *   // "app" is a private instance created for the generator
     *   // "base" is a shared instance
     * });
     * ```
     * @name .generator
     * @param {String} `name`
     * @param {Function|Object} `fn` Generator function or instance. When `fn` is defined, this method is just a proxy for the `.register` method.
     * @return {Object} Returns the generator instance or undefined if not resolved.
     * @api public
     */

    this.define('generator', function(name, fn) {
      debug('generator: "%s"', name);
      this.emit('generator', name);

      if (arguments.length === 1 && typeof name === 'string') {
        var generator = this.getGenerator(name);
        if (generator) return generator;
      }

      this.register(name, fn);
      return this.getGenerator(name);
    });

    /**
     * Return true if the given `name` exists on the `generators`
     * object. Dot-notation may be used to check for sub-generators.
     *
     * ```js
     * base.register('foo', function(app) {
     *   app.register('bar', function() {});
     * });
     *
     * base.hasGenerator('foo');
     * //=> true
     * base.hasGenerator('bar');
     * //=> false
     * base.hasGenerator('foo.bar');
     * //=> true
     * ```
     *
     * @name .hasGenerator
     * @param {String} `name`
     * @return {Boolean} Returns true if the generator exists.
     * @api public
     */

    this.define('hasGenerator', function(name) {
      return this.has(utils.toGeneratorPath(name));
    });

    /**
     * Get generator `name` from `app.generators`. Dot-notation
     * may be used to get a sub-generator.
     *
     * ```js
     * var foo = app.getGenerator('foo');
     *
     * // get a sub-generator
     * var baz = app.getGenerator('foo.bar.baz');
     * ```
     * @name .getGenerator
     * @param {String} `name` Generator name.
     * @return {Object|undefined} Returns the generator instance or undefined.
     * @api public
     */

    this.define('getGenerator', function(name) {
      debug('getting generator: "%s"', name);

      var fn = this.alias.bind(this);
      var names = name.split('.');
      var app = this;

      while ((name = names.shift())) {
        app = app.generators.get(name, fn);

        // if generator was not found, try again with `base`
        if (typeof app === 'undefined') {
          app = this.base.generators.get(name);
          if (!app) break;
        }
      }
      return app;
    });

    /**
     * Invoke the given generator in the context of the current instance.
     *
     * ```js
     * base.invoke('foo');
     * ```
     * @name .invoke
     * @param {String|Object} `app` Generator name or instance.
     * @return {Object} Returns the instance for chaining.
     * @api public
     */

    this.define('invoke', function(app) {
      if (typeof app === 'string') {
        app = this.generator(app);
      }
      return utils.invoke(app, this);
    });

    /**
     * Extend the current generator instance with the settings of other
     * generators.
     *
     * ```js
     * var foo = base.generator('foo');
     * base.extendWith(foo);
     * // or
     * base.extendWith('foo');
     * // or
     * base.extendWith(['foo', 'bar', 'baz']);
     * ```
     *
     * @name .extendWith
     * @param {String|Object} `app`
     * @return {Object} Returns the instance for chaining.
     * @api public
     */

    this.define('extendWith', function(app) {
      if (Array.isArray(app)) {
        return app.forEach(this.extendWith.bind(this));
      }
      this.invoke(app);
      return this;
    });

    /**
     * Run a `generator` and `tasks`, calling the given `callback` function
     * upon completion.
     *
     * ```js
     * // run tasks `bar` and `baz` on generator `foo`
     * base.generate('foo', ['bar', 'baz'], function(err) {
     *   if (err) throw err;
     * });
     *
     * // or use shorthand
     * base.generate('foo:bar,baz', function(err) {
     *   if (err) throw err;
     * });
     *
     * // run the `default` task on generator `foo`
     * base.generate('foo', function(err) {
     *   if (err) throw err;
     * });
     *
     * // run the `default` task on the `default` generator, if defined
     * base.generate(function(err) {
     *   if (err) throw err;
     * });
     * ```
     * @name .generate
     * @emits `generate` with the generator `name` and the array of `tasks` that are queued to run.
     * @param {String} `name`
     * @param {String|Array} `tasks`
     * @param {Function} `cb` Callback function that exposes `err` as the only parameter.
     * @api public
     */

    this.define('generate', function(name, tasks, cb) {
      var args = [].slice.call(arguments);
      cb = args.pop();

      var res = this.resolveTasks.apply(this, args);
      debug('generating: "%s"', res.tasks.join(', '));
      this.emit('generate', res.generator.env.alias, res.tasks);

      res.generator.build(res.tasks, function(err) {
        if (err) {
          generatorError(err, this, name, cb);
          return;
        }
        cb();
      }.bind(this));
    });

    /**
     * Iterate over an array of generators and tasks, calling [generate](#generate)
     * on each.
     *
     * ```js
     * // run tasks `a` and `b` on generator `foo`,
     * // and tasks `c` and `d` on generator `bar`
     * base.generateEach(['foo:a,b', 'bar:c,d'], function(err) {
     *   if (err) throw err;
     * });
     * ```
     * @name .generateEach
     * @param {String|Array} `tasks` Array of generators and tasks to run.
     * @param {Function} `cb` Callback function that exposes `err` as the only parameter.
     * @api public
     */

    this.define('generateEach', function(tasks, cb) {
      if (typeof tasks === 'function') {
        return this.generateEach('default', tasks);
      }

      async.each(utils.arrayify(tasks), function(task, next) {
        var args = task.split(':').concat(next);
        app.generate.apply(app, args);
      }, cb);
    });

    /**
     * Create a generator alias from the given `name`.
     *
     * @name .alias
     * @param {String} `name`
     * @param {Object} `options`
     * @return {String} Returns the alias.
     * @api public
     */

    app.define('alias', function(name, options) {
      debug('creating alias for: "%s"', name);
      var opts = utils.extend({}, this.options, options);
      return utils.toAlias(name, opts);
    });

    // initialize base-generators
    this.initGenerators();
  };
};

/**
 * Handle generator errors
 */

function generatorError(err, app, name, cb) {
  if (!/Invalid/.test(err.message)) {
    return cb(err);
  }

  var msg = 'Cannot find generator or task: "' + name + '"';
  var cwd = app.get('options.argv.cwd');
  if (cwd) msg += ' in "' + cwd + '/' + app.configfile + '"';
  return cb(new Error(msg));
}
<commit_msg>move `extendWith` arrayify code to `invoke`<commit_after>/*!
 * base-generators <https://github.com/jonschlinkert/base-generators>
 *
 * Copyright (c) 2016, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var async = require('async');
var debug = require('debug')('base:generators');
var register = require('./lib/register');
var tasks = require('./lib/tasks');
var cache = require('./lib/cache');
var utils = require('./lib/utils');
var env = require('./lib/env');

/**
 * Expose `generators`
 */

module.exports = function generators(options) {
  return function(app) {
    if (this.isRegistered('base-generators')) return;
    this.isGenerator = true;

    /**
     * Add plugins necessary for running generators.
     * Plugins will only be registered once.
     */

    this.define('initGenerators', function() {
      this.set('env.alias', 'base');
      if (typeof this.task !== 'function') {
        this.use(utils.task());
      }
      this.use(register(options));
      this.use(utils.cwd());
      this.use(tasks());
      this.use(cache(options));
      this.use(env());
    });

    /**
     * Register generator `name` with the given `fn`, or get generator `name`
     * if only one argument is passed. This method calls the `.getGenerator` method
     * but goes one step further: if `name` is not already registered, it will try
     * to resolve and register the generator before returning it (or `undefined`
     * if unsuccessful).
     *
     * ```js
     * base.generator('foo', function(app, base) {
     *   // "app" is a private instance created for the generator
     *   // "base" is a shared instance
     * });
     * ```
     * @name .generator
     * @param {String} `name`
     * @param {Function|Object} `fn` Generator function or instance. When `fn` is defined, this method is just a proxy for the `.register` method.
     * @return {Object} Returns the generator instance or undefined if not resolved.
     * @api public
     */

    this.define('generator', function(name, fn) {
      debug('generator: "%s"', name);
      this.emit('generator', name);

      if (arguments.length === 1 && typeof name === 'string') {
        var generator = this.getGenerator(name);
        if (generator) return generator;
      }

      this.register(name, fn);
      return this.getGenerator(name);
    });

    /**
     * Return true if the given `name` exists on the `generators`
     * object. Dot-notation may be used to check for sub-generators.
     *
     * ```js
     * base.register('foo', function(app) {
     *   app.register('bar', function() {});
     * });
     *
     * base.hasGenerator('foo');
     * //=> true
     * base.hasGenerator('bar');
     * //=> false
     * base.hasGenerator('foo.bar');
     * //=> true
     * ```
     *
     * @name .hasGenerator
     * @param {String} `name`
     * @return {Boolean} Returns true if the generator exists.
     * @api public
     */

    this.define('hasGenerator', function(name) {
      return this.has(utils.toGeneratorPath(name));
    });

    /**
     * Get generator `name` from `app.generators`. Dot-notation
     * may be used to get a sub-generator.
     *
     * ```js
     * var foo = app.getGenerator('foo');
     *
     * // get a sub-generator
     * var baz = app.getGenerator('foo.bar.baz');
     * ```
     * @name .getGenerator
     * @param {String} `name` Generator name.
     * @return {Object|undefined} Returns the generator instance or undefined.
     * @api public
     */

    this.define('getGenerator', function(name) {
      debug('getting generator: "%s"', name);

      var fn = this.alias.bind(this);

      var names = name.split('.');
      var app = this;

      while ((name = names.shift())) {
        app = app.generators.get(name, fn);

        // if generator was not found, try again with `base`
        if (typeof app === 'undefined') {
          app = this.base.generators.get(name);
          if (!app) break;
        }
      }
      return app;
    });

    /**
     * Invoke the given generator in the context of the current instance.
     *
     * ```js
     * base.invoke('foo');
     * ```
     * @name .invoke
     * @param {String|Object} `app` Generator name or instance.
     * @return {Object} Returns the instance for chaining.
     * @api public
     */

    this.define('invoke', function(app) {
      if (Array.isArray(app)) {
        return app.forEach(this.invoke.bind(this));
      }
      if (typeof app === 'string') {
        app = this.generator(app);
      }
      return utils.invoke(app, this);
    });

    /**
     * Alias for `.invoke`, Extend the current generator instance with the settings of other
     * generators.
     *
     * ```js
     * var foo = base.generator('foo');
     * base.extendWith(foo);
     * // or
     * base.extendWith('foo');
     * // or
     * base.extendWith(['foo', 'bar', 'baz']);
     * ```
     *
     * @name .extendWith
     * @param {String|Object} `app`
     * @return {Object} Returns the instance for chaining.
     * @api public
     */

    this.define('extendWith', function(app) {
      this.invoke(app);
      return this;
    });

    /**
     * Run a `generator` and `tasks`, calling the given `callback` function
     * upon completion.
     *
     * ```js
     * // run tasks `bar` and `baz` on generator `foo`
     * base.generate('foo', ['bar', 'baz'], function(err) {
     *   if (err) throw err;
     * });
     *
     * // or use shorthand
     * base.generate('foo:bar,baz', function(err) {
     *   if (err) throw err;
     * });
     *
     * // run the `default` task on generator `foo`
     * base.generate('foo', function(err) {
     *   if (err) throw err;
     * });
     *
     * // run the `default` task on the `default` generator, if defined
     * base.generate(function(err) {
     *   if (err) throw err;
     * });
     * ```
     * @name .generate
     * @emits `generate` with the generator `name` and the array of `tasks` that are queued to run.
     * @param {String} `name`
     * @param {String|Array} `tasks`
     * @param {Function} `cb` Callback function that exposes `err` as the only parameter.
     * @api public
     */

    this.define('generate', function(name, tasks, cb) {
      var args = [].slice.call(arguments);
      cb = args.pop();

      var res = this.resolveTasks.apply(this, args);
      debug('generating: "%s"', res.tasks.join(', '));
      this.emit('generate', res.generator.env.alias, res.tasks);

      res.generator.build(res.tasks, function(err) {
        if (err) {
          generatorError(err, this, name, cb);
          return;
        }
        cb();
      }.bind(this));
    });

    /**
     * Iterate over an array of generators and tasks, calling [generate](#generate)
     * on each.
     *
     * ```js
     * // run tasks `a` and `b` on generator `foo`,
     * // and tasks `c` and `d` on generator `bar`
     * base.generateEach(['foo:a,b', 'bar:c,d'], function(err) {
     *   if (err) throw err;
     * });
     * ```
     * @name .generateEach
     * @param {String|Array} `tasks` Array of generators and tasks to run.
     * @param {Function} `cb` Callback function that exposes `err` as the only parameter.
     * @api public
     */

    this.define('generateEach', function(tasks, cb) {
      if (typeof tasks === 'function') {
        return this.generateEach('default', tasks);
      }

      async.each(utils.arrayify(tasks), function(task, next) {
        var args = task.split(':').concat(next);
        app.generate.apply(app, args);
      }, cb);
    });

    /**
     * Create a generator alias from the given `name`.
     *
     * @name .alias
     * @param {String} `name`
     * @param {Object} `options`
     * @return {String} Returns the alias.
     * @api public
     */

    app.define('alias', function(name, options) {
      debug('creating alias for: "%s"', name);
      var opts = utils.extend({}, this.options, options);
      return utils.toAlias(name, opts);
    });

    // initialize base-generators
    this.initGenerators();
  };
};

/**
 * Handle generator errors
 */

function generatorError(err, app, name, cb) {
  if (!/Invalid/.test(err.message)) {
    return cb(err);
  }

  var msg = 'Cannot find generator or task: "' + name + '"';
  var cwd = app.get('options.argv.cwd');
  if (cwd) msg += ' in "' + cwd + '/' + app.configfile + '"';
  return cb(new Error(msg));
}
<|endoftext|>


<commit_before>'use strict';

var TextOMConstructor = require('textom');

function fromAST(TextOM, ast) {
    var iterator = -1,
        children, node;

    node = new TextOM[ast.type]();

    if ('children' in ast) {
        iterator = -1;
        children = ast.children;

        while (children[++iterator]) {
            node.append(fromAST(TextOM, children[iterator]));
        }
    } else {
        node.fromString(ast.value);
    }

    return node;
}

function useImmediately(rootNode, use) {
    return function (plugin) {
        var self = this,
            length = self.plugins.length;

        use.apply(self, arguments);

        if (length !== self.plugins.length) {
            plugin(rootNode, self);
        }

        return self;
    };
}

/**
 * Define `Retext`. Exported above, and used to instantiate a new
 * `Retext`.
 *
 * @param {(Object|String)?} parser - the parser, or its name, to use.
 *                                    Defaults to "parse-latin".
 * @api public
 * @constructor
 */
function Retext(parser) {
    var self = this;

    if (!parser) {
        parser = 'parse-latin';
    }

    if (typeof parser === 'string') {
        /* istanbul ignore else: TODO / TOSPEC */
        /* Load the parser for vendors without dynamic-require's */
        if (parser === 'parse-latin') {
            parser = require('parse-latin');
        } else {
            parser = require(parser);
        }

        parser = parser();
    }

    self.parser = parser;
    self.TextOM = parser.TextOM = new TextOMConstructor();
    self.plugins = [];
}

/**
 * `Retext#use` takes a plugin—a humble function—and when the parse
 * method of the Retext instance is called, the plugin will be called
 * with the parsed tree, and the retext instance as arguments.
 *
 * Note that, during the parsing stage, when the `use` method is called
 * by a plugin, the nested plugin is immediately called, before continuing
 * on with its parent plugin.
 *
 * @param {Function} plugin - the plugin to call when parsing.
 * @param {Function?} plugin.attach - called only once with a Retext
 *                                    instance. If you're planning on
 *                                    modifying TextOM or a parser, do it
 *                                    in this method.
 * @return this
 * @api public
 */
Retext.prototype.use = function (plugin) {
    if (typeof plugin !== 'function') {
        throw new TypeError('Illegal invocation: \'' + plugin +
            '\' is not a valid argument for \'Retext.prototype.use\'');
    }

    var self = this,
        plugins = self.plugins;

    if (plugins.indexOf(plugin) === -1) {
        if (plugin.attach) {
            plugin.attach(self);
        }

        plugins.push(plugin);
    }

    return self;
};

/**
 * `Retext#parse` takes a source to be given (and parsed) by the parser.
 * Then, `parse` iterates over all plugins, and allows them to modify the
 * TextOM tree created by the parser.
 *
 * Note that, during the parsing stage, when the `use` plugin is called
 * by a plugin, the nested plugin is immediately called, before continuing
 * on with its parent plugin.
 *
 * @param {(String|Node)?} source - The source to convert.
 * @return {Node} - A RootNode containing the tokenised source.
 * @api public
 */
Retext.prototype.parse = function (source) {
    var self = this,
        parser = self.parser,
        plugins = self.plugins.concat(),
        iterator = -1,
        use = self.use,
        rootNode = fromAST(self.TextOM, parser.tokenizeRoot(source));

    self.use = useImmediately(rootNode, use);

    while (plugins[++iterator]) {
        plugins[iterator](rootNode, this);
    }

    self.use = use;

    return rootNode;
};

/**
 * Expose `Retext`. Used to instantiate a new Retext object.
 */
exports = module.exports = Retext;
<commit_msg>Retext now exposes an `applyPlugins` method (fixes #8)<commit_after>'use strict';

var TextOMConstructor = require('textom');

function fromAST(TextOM, ast) {
    var iterator = -1,
        children, node;

    node = new TextOM[ast.type]();

    if ('children' in ast) {
        iterator = -1;
        children = ast.children;

        while (children[++iterator]) {
            node.append(fromAST(TextOM, children[iterator]));
        }
    } else {
        node.fromString(ast.value);
    }

    return node;
}

function useImmediately(rootNode, use) {
    return function (plugin) {
        var self = this,
            length = self.plugins.length;

        use.apply(self, arguments);

        if (length !== self.plugins.length) {
            plugin(rootNode, self);
        }

        return self;
    };
}

/**
 * Define `Retext`. Exported above, and used to instantiate a new
 * `Retext`.
 *
 * @param {(Object|String)?} parser - the parser, or its name, to use.
 *                                    Defaults to "parse-latin".
 * @api public
 * @constructor
 */
function Retext(parser) {
    var self = this;

    if (!parser) {
        parser = 'parse-latin';
    }

    if (typeof parser === 'string') {
        /* istanbul ignore else: TODO / TOSPEC */
        /* Load the parser for vendors without dynamic-require's */
        if (parser === 'parse-latin') {
            parser = require('parse-latin');
        } else {
            parser = require(parser);
        }

        parser = parser();
    }

    self.parser = parser;
    self.TextOM = parser.TextOM = new TextOMConstructor();
    self.plugins = [];
}

/**
 * `Retext#use` takes a plugin—a humble function—and when the parse
 * method of the Retext instance is called, the plugin will be called
 * with the parsed tree, and the retext instance as arguments.
 *
 * Note that, during the parsing stage, when the `use` method is called
 * by a plugin, the nested plugin is immediately called, before continuing
 * on with its parent plugin.
 *
 * @param {Function} plugin - the plugin to call when parsing.
 * @param {Function?} plugin.attach - called only once with a Retext
 *                                    instance. If you're planning on
 *                                    modifying TextOM or a parser, do it
 *                                    in this method.
 * @return this
 * @api public
 */
Retext.prototype.use = function (plugin) {
    if (typeof plugin !== 'function') {
        throw new TypeError('Illegal invocation: \'' + plugin +
            '\' is not a valid argument for \'Retext.prototype.use\'');
    }

    var self = this,
        plugins = self.plugins;

    if (plugins.indexOf(plugin) === -1) {
        if (plugin.attach) {
            plugin.attach(self);
        }

        plugins.push(plugin);
    }

    return self;
};

/**
 * `Retext#parse` takes a source to be given (and parsed) by the parser.
 * Then, `parse` iterates over all plugins, and allows them to modify the
 * TextOM tree created by the parser.
 *
 * @param {String?} source - The source to convert.
 * @return {Node} - A RootNode containing the tokenised source.
 * @api public
 */
Retext.prototype.parse = function (source) {
    var self = this,
        rootNode = fromAST(self.TextOM, self.parser.tokenizeRoot(source));

    self.applyPlugins(rootNode);

    return rootNode;
};

/**
 * `Retext#applyPlugins` applies the plugins bound to the retext instance to a
 * given tree.
 *
 * Note that, during the parsing stage, when the `use` plugin is called
 * by a plugin, the nested plugin is immediately called, before continuing
 * on with its parent plugin.
 *
 * @param {Node} tree - The tree to apply plugins to.
 * @api public
 */
Retext.prototype.applyPlugins = function (tree) {
    var self = this,
        plugins = self.plugins.concat(),
        iterator = -1,
        use = self.use;

    self.use = useImmediately(tree, use);

    while (plugins[++iterator]) {
        plugins[iterator](tree, this);
    }

    self.use = use;
};

/**
 * Expose `Retext`. Used to instantiate a new Retext object.
 */
exports = module.exports = Retext;
<|endoftext|>


<commit_before>module.exports = require('./lib/tap-xunit-file');
<commit_msg>update path after rename<commit_after>module.exports = require('./lib/polyglot-xunit-file');
<|endoftext|>


<commit_before>var path  = require('path'),
    read  = require('fs').readFileSync;

var binding = require('bindings')('native.node');

var version  = JSON.parse(read(path.resolve(__dirname, './package.json'))).version;

// Native classes
exports.native = binding;

// Libraries
exports.NetSpeedCell = require('./lib/netspeedcell');
exports.NetSpeed     = require('./lib/netspeed');
exports.Country6     = require('./lib/country6');
exports.Country      = require('./lib/country');
exports.Region       = require('./lib/region');
exports.City6        = require('./lib/city6');
exports.City         = require('./lib/city');
exports.Org          = require('./lib/org');

// Utilities
exports.check    = binding.check;

// Versions
exports.version  = 'v' + version;
exports.libgeoip = 'v' + binding.libgeoip; // only works on libgeoip >= 1.4.7
<commit_msg>Clean up<commit_after>var path  = require('path'),
    read  = require('fs').readFileSync;

var binding = require('bindings')('native.node');

var version  = JSON.parse(read(path.resolve(__dirname, './package.json'))).version;

// Native classes
exports.native = binding;

// Libraries
exports.NetSpeedCell = require('./lib/netspeedcell');
exports.NetSpeed     = require('./lib/netspeed');
exports.Country6     = require('./lib/country6');
exports.Country      = require('./lib/country');
exports.Region       = require('./lib/region');
exports.City6        = require('./lib/city6');
exports.City         = require('./lib/city');
exports.Org          = require('./lib/org');

// Utilities
exports.check    = binding.check;

// Versions
exports.version  = 'v' + version;
exports.libgeoip = 'v' + binding.libgeoip;
<|endoftext|>


<commit_before>"use strict"

function each(ob, f) {
    for (var i in ob) {
        if (ob.hasOwnProperty(i)) {
            f(ob[i], i)
        }
    }
}

function validate(obj, desc, parent) {
    parent = parent || '';
    //console.log('-r ' + parent, obj, desc);
    var errors = [];
    each(desc, function (val, key) {
        //console.log('v ' + key);
        if (typeof val === "string") {
            //console.log('  str');
            //check
            if (!(typeof obj[key] === val)) {
                //console.log('err found', obj[key], val)
                errors.push(parent + key+':'+(typeof obj[key]))
            }
        } else {
            //console.log('  recur');
            if (obj[key]) {
                errors = errors.concat(validate(obj[key], val, parent + key + '.'))
            } else {
                errors.push(parent + key+':missing')
            }
        }

    });
    return errors;
}

module.exports = function (desc, proto) {
    var F = function (obj) {
        var self = this;
        each(obj, function (val, key) {
            if (desc[key]) {
                self[key] = val
            } else {
                throw new TypeError("Unexpected field " + key);
            }
        });
        //console.log('self', self);
        self.validate()
    }
    F.prototype = proto || {}
    var superValidate = proto && proto.validate;
    F.prototype.validate = function () {
        var errors = validate(this, desc)
        //console.log(errors);
        if (errors.length > 0) {
            throw new TypeError("Incorrect values for fields: " + errors.join())
        }
        if (superValidate) {
            //console.log('calling proto.validate')
            return superValidate.call(this)
        }
    }

    return F
}<commit_msg>Removal of console.log comments.<commit_after>"use strict"

function each(ob, f) {
    for (var i in ob) {
        if (ob.hasOwnProperty(i)) {
            f(ob[i], i)
        }
    }
}

function validate(obj, desc, parent) {
    parent = parent || '';

    var errors = [];
    each(desc, function (val, key) {
        if (typeof val === "string") {
            //check
            if (!(typeof obj[key] === val)) {

                errors.push(parent + key+':'+(typeof obj[key]))
            }
        } else {
            if (obj[key]) {
                errors = errors.concat(validate(obj[key], val, parent + key + '.'))
            } else {
                errors.push(parent + key+':missing')
            }
        }

    });
    return errors;
}

module.exports = function (desc, proto) {
    var F = function (obj) {
        var self = this;
        each(obj, function (val, key) {
            if (desc[key]) {
                self[key] = val
            } else {
                throw new TypeError("Unexpected field " + key);
            }
        });
        self.validate()
    }
    F.prototype = proto || {}
    var superValidate = proto && proto.validate;
    F.prototype.validate = function () {
        var errors = validate(this, desc)
        if (errors.length > 0) {
            throw new TypeError("Incorrect values for fields: " + errors.join())
        }
        if (superValidate) {
            return superValidate.call(this)
        }
    }

    return F
}
<|endoftext|>


<commit_before>var Stream = require('stream')
var util = require('util')

var PassThrough = Stream.PassThrough

util.inherits(Combine, PassThrough)

module.exports = Combine

function Combine(options) {
  if (!(this instanceof Combine))
    return new Combine(options)

  PassThrough.call(this, options)

  this.queue = []
  this.destroy = this.destroy.bind(this)
}

Combine.prototype.busy = false
Combine.prototype.destroyed = false

Combine.prototype.append = function (stream) {
  if (!this._writableState.ended
    && !this.destroyed
    && this.queue.push(stream) === 1
    && !this.busy
  ) this._next()

  return this
}

Combine.prototype.destroy = function () {
  if (!this.destroyed) {
    this.emit('close')
    this.destroyed = true
    this.queue = null
  }
}

Combine.prototype._append = function (stream) {
  this.busy = true

  stream.pipe(this, {
    end: false
  })

  stream.once('error', callback)
  stream.once('end', callback)
  stream.once('close', this.destroy)
  stream.once('close', cleanup)

  var that = this

  function callback(err) {
    cleanup()

    if (err)
      that.emit('error', err)
    else
      that._next()
  }

  function cleanup() {
    that.busy = false

    stream.removeListener('error', callback)
    stream.removeListener('end', callback)
    stream.removeListener('close', that.destroy)
    stream.removeListener('close', cleanup)
  }
}

Combine.prototype._next = function (obj) {
  if (this.destroyed)
    return

  if (arguments.length === 0)
    obj = this.queue.shift()

  if (obj === null) {
    this.end()
    this.queue = null
  } else if (obj === undefined) {
    // Just ignore
  } else if (typeof obj === 'string' || Buffer.isBuffer(obj)) {
    this.write(obj)
    this._next()
  } else if (typeof obj === 'function') {
    var that = this

    this.busy = true

    obj(function (err, obj2) {
      if (err) {
        that.emit('error', err)
      } else {
        that.busy = false
        that._next(obj2)
      }
    })
  } else if (obj instanceof Stream) {
    this._append(obj)
  } else {
    throw new TypeError('You can only append streams, strings, buffers, and functions.')
  }
}<commit_msg>check if null exists in the queue<commit_after>var Stream = require('stream')
var util = require('util')

var PassThrough = Stream.PassThrough

util.inherits(Combine, PassThrough)

module.exports = Combine

function Combine(options) {
  if (!(this instanceof Combine))
    return new Combine(options)

  PassThrough.call(this, options)

  this.queue = []
  this.destroy = this.destroy.bind(this)
}

Combine.prototype.busy = false
Combine.prototype.destroyed = false

Combine.prototype.append = function (stream) {
  if (!this._writableState.ended
    && !this.destroyed
    && !~this.queue.indexOf(null)
    && this.queue.push(stream) === 1
    && !this.busy
  ) this._next()

  return this
}

Combine.prototype.destroy = function () {
  if (!this.destroyed) {
    this.emit('close')
    this.destroyed = true
    this.queue = null
  }
}

Combine.prototype._append = function (stream) {
  this.busy = true

  stream.pipe(this, {
    end: false
  })

  stream.once('error', callback)
  stream.once('end', callback)
  stream.once('close', this.destroy)
  stream.once('close', cleanup)

  var that = this

  function callback(err) {
    cleanup()

    if (err)
      that.emit('error', err)
    else
      that._next()
  }

  function cleanup() {
    that.busy = false

    stream.removeListener('error', callback)
    stream.removeListener('end', callback)
    stream.removeListener('close', that.destroy)
    stream.removeListener('close', cleanup)
  }
}

Combine.prototype._next = function (obj) {
  if (this.destroyed)
    return

  if (arguments.length === 0)
    obj = this.queue.shift()

  if (obj === null) {
    this.end()
    this.queue = null
  } else if (obj === undefined) {
    // Just ignore
  } else if (typeof obj === 'string' || Buffer.isBuffer(obj)) {
    this.write(obj)
    this._next()
  } else if (typeof obj === 'function') {
    var that = this

    this.busy = true

    obj(function (err, obj2) {
      if (err) {
        that.emit('error', err)
      } else {
        that.busy = false
        that._next(obj2)
      }
    })
  } else if (obj instanceof Stream) {
    this._append(obj)
  } else {
    throw new TypeError('You can only append streams, strings, buffers, and functions.')
  }
}<|endoftext|>


<commit_before>var Emitter = require('emitter')
  , events = require('event');

/**
 * Expose Emoji Analyser
 */
module.exports = EmojiAnalyser;

function EmojiAnalyser (el) {
  if (!(this instanceof EmojiAnalyser)) return new EmojiAnalyser(el);
  this.bind(el);
}

EmojiAnalyser.prototype.bind = function (el) {
  events.bind(el, 'keypress', function (e) {
    if (e.keyCode == 13) {
      analyse(el.value);
    }
  });
}

function analyse (string) {
  var split = string.toLowerCase().split(/\s/g);
  var words = createOrderedArray(split);
}

function createOrderedArray (arr) {
  var uniqueWords = []
    , words = {};

  // add to helper array
  for (i= 0; i < arr.length; i++) {
    word = arr[i];
    if (uniqueWords.indexOf(word) !== -1) {
      words[word] = words[word] + 1;
    } else {
      words[word] = 1;
      uniqueWords.push(word);
    }
  }

  // now sort unique words by count
  uniqueWords.sort(function(a, b){
    return words[b] - words[a]; // ASC -> a - b; DESC -> b - a
  });

  console.log(uniqueWords);

  for (i = 0; i < uniqueWords.length; i++) {
    console.log(uniqueWords[i], words[uniqueWords[i]]);
  }

  return words;
}

<commit_msg>return both args<commit_after>var Emitter = require('emitter')
  , events = require('event');

/**
 * Expose Emoji Analyser
 */
module.exports = EmojiAnalyser;

function EmojiAnalyser (el) {
  if (!(this instanceof EmojiAnalyser)) return new EmojiAnalyser(el);
  this.bind(el);
}

EmojiAnalyser.prototype.bind = function (el) {
  events.bind(el, 'keypress', function (e) {
    if (e.keyCode == 13) {
      analyse(el.value);
    }
  });
}

function analyse (string) {
  var split = string.toLowerCase().split(/\s/g);
  var w = createOrderedArray(split);

  var uniqueWords = w[0];
  var words = w[1];

  prettyOutput(uniqueWords, words);
}

function createOrderedArray (arr) {
  var uniqueWords = []
    , words = {};

  // add to helper array
  for (i= 0; i < arr.length; i++) {
    word = arr[i];
    if (uniqueWords.indexOf(word) !== -1) {
      words[word] = words[word] + 1;
    } else {
      words[word] = 1;
      uniqueWords.push(word);
    }
  }

  // now sort unique words by count
  uniqueWords.sort(function(a, b){
    return words[b] - words[a]; // ASC -> a - b; DESC -> b - a
  });

  return [uniqueWords, words];
}

function prettyOutput (uniqueWords, words) {
  // output
  for (i = 0; i < uniqueWords.length; i++) {
    console.log(uniqueWords[i], words[uniqueWords[i]]);
  }
}

<|endoftext|>


<commit_before>(function(){
  'use strict';
  var tree = require('./walker');
  var dirPath = process.cwd();
  var dir = dirPath.split('/').pop();
  var indentation = 0;

  var output = '- ' + dir + '\n';

  var addIndentation = function(){
    return new Array((indentation*2)+1).join(' ');
  };

  var parseResult = function(result){
    indentation++;
    for (var i in result) {
      if (typeof result[i] === 'string') {
        output += addIndentation() + '- [' + i + '](' + result[i] + ')\n';
      } else if (typeof result[i] === 'object'){
        output += addIndentation() + '- ' + i + '\n';
        parseResult(result[i]);
        indentation--;
      }
    }
  };
  tree(dirPath, function(err, result){
    parseResult(result);
    console.log(output);
  });

})();
<commit_msg>:gift: add home dir to the results<commit_after>(function(){
  'use strict';
  var tree = require('./walker');
  var dirPath = process.cwd();
  var dir = dirPath.split('/').pop();
  var indentation = 0;

  var output = '- ' + dir + '\n';

  var addIndentation = function(){
    return new Array((indentation*2)+1).join(' ');
  };

  var parseResult = function(result){
    indentation++;
    for (var i in result) {
      if (typeof result[i] === 'string') {
        output += addIndentation() + '- [' + i + '](' + dir + result[i] + ')\n';
      } else if (typeof result[i] === 'object'){
        output += addIndentation() + '- ' + i + '\n';
        parseResult(result[i]);
        indentation--;
      }
    }
  };
  tree(dirPath, function(err, result){
    parseResult(result);
    console.log(output);
  });

})();
<|endoftext|>


<commit_before>var after = require('after-all')
var through = require('through2')
var pump = require('pump')
var lexint = require('lexicographic-integer')
var mutexify = require('mutexify')
var collect = require('stream-collector')
var crypto = require('crypto')
var cuid = require('cuid')
var events = require('events')
var util = require('util')
var from = require('from2')
var logs = require('./lib/logs')
var replicator = require('./lib/replicator')

var ID = 'id!'
var CHANGES = 'changes!'
var NODE = 'node!'
var HEAD = 'head!'

var Hyperlog = function(db, opts) {
  if (!(this instanceof Hyperlog)) return new Hyperlog(db, opts)
  if (!opts) opts = {}

  events.EventEmitter.call(this)

  this.id = opts.id
  this.db = db
  this.change = -1
  this.logs = logs('logs', db)
  this.tmp = logs('tmp', db)
  this.lock = mutexify()
  this.setMaxListeners(0)

  var self = this
  this.lock(function(release) {
    var onid = function(err) {
      if (err) return self.emit('error', err)
      collect(db.createKeyStream({gt:CHANGES, lt:CHANGES+'\xff', limit:1, reverse:true}), function(err, keys) {
        if (err) return self.emit('error', err)
        self.change = keys.length ? lexint.unpack(keys[0].slice(CHANGES.length), 'hex') : 0
        self.emit('ready')
        release()
      })
    }

    db.get(ID, {valueEncoding:'utf-8'}, function(err, id) {
      if (err && !err.notFound) return onid(err)
      self.id = id || opts.id || cuid()
      if (self.id === id) return onid()
      db.put(ID, self.id, onid)
    })
  })
}

util.inherits(Hyperlog, events.EventEmitter)

var getRef = function(self, ref, cb) {
  var i = ref.indexOf('!')
  self.logs.get(ref.slice(0, i), lexint.unpack(ref.slice(i+1), 'hex'), cb)
}

Hyperlog.prototype.ready = function(cb) {
  if (this.change >= 0) return cb()
  this.once('ready', cb)
}

Hyperlog.prototype.createChangesStream = function(opts) {
  if (!opts) opts = {}

  var self = this
  var since = opts.since || 0
  var live = !!opts.live
  var tail = !!opts.tail

  var wait
  var notify = function() {
    if (!wait) return
    var cb = wait
    wait = null
    read(0, cb)
  }

  var read = function(size, cb) {
    if (tail) {
      tail = false
      self.lock(function(release) {
        read(size, cb)
        release()
      })
      return
    }

    self.db.get(CHANGES+lexint.pack(since+1, 'hex'), function(err, ref) {
      if (err && !err.notFound) return cb(err)

      if (err) {
        if (self.change > since) return read(size, cb)
        wait = cb
        return
      }

      since++
      cb(null, ref)
    })
  }

  var rs

  if (live) {
    rs = from.obj(read)
    if (tail) {
      self.lock(function(release) {
        since = self.change
        release()
      })
    }
    self.on('add', notify)
    rs.on('close', function() {
      self.removeListener('add', notify)
    })
  } else {
    rs = self.db.createValueStream({
      gt:CHANGES+lexint.pack(since, 'hex'),
      lt:CHANGES+'\xff',
      reverse: opts.reverse
    })
  }

  var format = through.obj(function(ref, enc, cb) {
    getRef(self, ref, cb)
  })

  return pump(rs, format)
}

Hyperlog.prototype.heads = function(opts, cb) {
  if (typeof opts === 'function') return this.heads(null, opts)
  if (!opts) opts = {}

  var self = this
  var values = opts.values !== false
  var rs = this.db.createValueStream({
    reverse: opts.reverse,
    gt: HEAD,
    lt: HEAD+'\xff',
    valueEncoding: 'utf-8'
  })

  var format = function(ref, enc, cb) {
    var i = ref.indexOf('!')
    var log = ref.slice(0, i)
    var seq = lexint.unpack(ref.slice(i+1), 'hex')
    if (values) self.logs.get(log, seq, cb)
    else cb(null, {log:log, seq:seq})
  }

  return collect(pump(rs, through.obj(format)), cb)
}

Hyperlog.prototype.createReplicationStream = function(opts) {
  return replicator(this, opts)
}

Hyperlog.prototype.get = function(hash, cb) {
  var self = this
  this.db.get(NODE+hash, {valueEncoding:'utf-8'}, function(err, ref) {
    if (err) return cb(err)
    getRef(self, ref, cb)
  })
}

var hash = function(value, links) {
  var sha = crypto.createHash('sha1')

  sha.update(''+value.length+'\n')
  sha.update(value)
  for (var i = 0; i < links.length; i++) sha.update(links[i].hash+'\n')

  return sha.digest('hex')
}

var add = function(self, log, cksum, links, value, cb) {
  var self = self

  var node = {
    change: 0,
    hash: null,
    log: log,
    seq: 0,
    sort: 0,
    links: links,
    value: value
  }

  var next = after(function(err) {
    if (err) return cb(err)

    node.hash = hash(value, links)
    if (cksum && node.hash !== cksum) return cb(new Error('checksum failed'))

    node.change = self.change+1

    var batch = []
    var ref = node.log+'!'+lexint.pack(node.seq, 'hex')

    batch.push({
      type: 'put',
      key: self.logs.key(log, node.seq),
      value: self.logs.value(node)
    })

    batch.push({
      type: 'put',
      key: CHANGES+lexint.pack(node.change, 'hex'),
      value: ref
    })

    batch.push({
      type: 'put',
      key: HEAD+ref,
      value: ref
    })

    batch.push({
      type: 'put',
      key: NODE+node.hash,
      value: ref
    })

    for (var i = 0; i < links.length; i++) batch.push({type:'del', key:HEAD+links[i].log+'!'+lexint.pack(links[i].seq, 'hex')})

    self.get(node.hash, function(err, oldNode) {
      if (!err) return cb(err, oldNode)
      self.db.batch(batch, function(err) {
        if (err) return cb(err)

        self.change++
        self.emit('add', node)
        cb(null, node)
      })
    })
  })

  links.forEach(function(link, i) {
    var n = next()

    self.get(typeof link === 'string' ? link : link.hash, function(err, resolved) {
      if (err) return n(err)
      node.sort = Math.max(node.sort, resolved.sort+1)
      links[i] = resolved
      n()
    })
  })

  var n = next()
  self.logs.tail(log, function(err, seq) {
    if (err) return n(err)
    node.seq = 1+seq

    if (!seq) {
      node.sort = Math.max(node.sort, 1)
      return n()
    }

    self.logs.get(log, seq, function(err, prev) {
      if (err) return n(err)
      node.sort = Math.max(node.sort, prev.sort+1)
      n()
    })
  })
}

Hyperlog.prototype.add = function(links, value, opts, cb) {
  if (typeof opts === 'function') return this.add(links, value, null, opts)
  if (!links) links = []
  if (!Array.isArray(links)) links = [links]
  if (!Buffer.isBuffer(value)) value = new Buffer(value)
  if (!cb) cb = noop
  if (!opts) opts = {}

  var self = this

  this.lock(function(release) {
    add(self, opts.log || self.id, opts.hash || null, links, value, function(err, node) {
      if (err) return release(cb, err)
      release(cb, null, node)
    })
  })
}

module.exports = Hyperlog<commit_msg>fix ref error<commit_after>var after = require('after-all')
var through = require('through2')
var pump = require('pump')
var lexint = require('lexicographic-integer')
var mutexify = require('mutexify')
var collect = require('stream-collector')
var crypto = require('crypto')
var cuid = require('cuid')
var events = require('events')
var util = require('util')
var from = require('from2')
var logs = require('./lib/logs')
var replicator = require('./lib/replicator')

var ID = 'id!'
var CHANGES = 'changes!'
var NODE = 'node!'
var HEAD = 'head!'

var noop = function() {}

var Hyperlog = function(db, opts) {
  if (!(this instanceof Hyperlog)) return new Hyperlog(db, opts)
  if (!opts) opts = {}

  events.EventEmitter.call(this)

  this.id = opts.id
  this.db = db
  this.change = -1
  this.logs = logs('logs', db)
  this.tmp = logs('tmp', db)
  this.lock = mutexify()
  this.setMaxListeners(0)

  var self = this
  this.lock(function(release) {
    var onid = function(err) {
      if (err) return self.emit('error', err)
      collect(db.createKeyStream({gt:CHANGES, lt:CHANGES+'\xff', limit:1, reverse:true}), function(err, keys) {
        if (err) return self.emit('error', err)
        self.change = keys.length ? lexint.unpack(keys[0].slice(CHANGES.length), 'hex') : 0
        self.emit('ready')
        release()
      })
    }

    db.get(ID, {valueEncoding:'utf-8'}, function(err, id) {
      if (err && !err.notFound) return onid(err)
      self.id = id || opts.id || cuid()
      if (self.id === id) return onid()
      db.put(ID, self.id, onid)
    })
  })
}

util.inherits(Hyperlog, events.EventEmitter)

var getRef = function(self, ref, cb) {
  var i = ref.indexOf('!')
  self.logs.get(ref.slice(0, i), lexint.unpack(ref.slice(i+1), 'hex'), cb)
}

Hyperlog.prototype.ready = function(cb) {
  if (this.change >= 0) return cb()
  this.once('ready', cb)
}

Hyperlog.prototype.createChangesStream = function(opts) {
  if (!opts) opts = {}

  var self = this
  var since = opts.since || 0
  var live = !!opts.live
  var tail = !!opts.tail

  var wait
  var notify = function() {
    if (!wait) return
    var cb = wait
    wait = null
    read(0, cb)
  }

  var read = function(size, cb) {
    if (tail) {
      tail = false
      self.lock(function(release) {
        read(size, cb)
        release()
      })
      return
    }

    self.db.get(CHANGES+lexint.pack(since+1, 'hex'), function(err, ref) {
      if (err && !err.notFound) return cb(err)

      if (err) {
        if (self.change > since) return read(size, cb)
        wait = cb
        return
      }

      since++
      cb(null, ref)
    })
  }

  var rs

  if (live) {
    rs = from.obj(read)
    if (tail) {
      self.lock(function(release) {
        since = self.change
        release()
      })
    }
    self.on('add', notify)
    rs.on('close', function() {
      self.removeListener('add', notify)
    })
  } else {
    rs = self.db.createValueStream({
      gt:CHANGES+lexint.pack(since, 'hex'),
      lt:CHANGES+'\xff',
      reverse: opts.reverse
    })
  }

  var format = through.obj(function(ref, enc, cb) {
    getRef(self, ref, cb)
  })

  return pump(rs, format)
}

Hyperlog.prototype.heads = function(opts, cb) {
  if (typeof opts === 'function') return this.heads(null, opts)
  if (!opts) opts = {}

  var self = this
  var values = opts.values !== false
  var rs = this.db.createValueStream({
    reverse: opts.reverse,
    gt: HEAD,
    lt: HEAD+'\xff',
    valueEncoding: 'utf-8'
  })

  var format = function(ref, enc, cb) {
    var i = ref.indexOf('!')
    var log = ref.slice(0, i)
    var seq = lexint.unpack(ref.slice(i+1), 'hex')
    if (values) self.logs.get(log, seq, cb)
    else cb(null, {log:log, seq:seq})
  }

  return collect(pump(rs, through.obj(format)), cb)
}

Hyperlog.prototype.createReplicationStream = function(opts) {
  return replicator(this, opts)
}

Hyperlog.prototype.get = function(hash, cb) {
  var self = this
  this.db.get(NODE+hash, {valueEncoding:'utf-8'}, function(err, ref) {
    if (err) return cb(err)
    getRef(self, ref, cb)
  })
}

var hash = function(value, links) {
  var sha = crypto.createHash('sha1')

  sha.update(''+value.length+'\n')
  sha.update(value)
  for (var i = 0; i < links.length; i++) sha.update(links[i].hash+'\n')

  return sha.digest('hex')
}

var add = function(self, log, cksum, links, value, cb) {
  var self = self

  var node = {
    change: 0,
    hash: null,
    log: log,
    seq: 0,
    sort: 0,
    links: links,
    value: value
  }

  var next = after(function(err) {
    if (err) return cb(err)

    node.hash = hash(value, links)
    if (cksum && node.hash !== cksum) return cb(new Error('checksum failed'))

    node.change = self.change+1

    var batch = []
    var ref = node.log+'!'+lexint.pack(node.seq, 'hex')

    batch.push({
      type: 'put',
      key: self.logs.key(log, node.seq),
      value: self.logs.value(node)
    })

    batch.push({
      type: 'put',
      key: CHANGES+lexint.pack(node.change, 'hex'),
      value: ref
    })

    batch.push({
      type: 'put',
      key: HEAD+ref,
      value: ref
    })

    batch.push({
      type: 'put',
      key: NODE+node.hash,
      value: ref
    })

    for (var i = 0; i < links.length; i++) batch.push({type:'del', key:HEAD+links[i].log+'!'+lexint.pack(links[i].seq, 'hex')})

    self.get(node.hash, function(err, oldNode) {
      if (!err) return cb(err, oldNode)
      self.db.batch(batch, function(err) {
        if (err) return cb(err)

        self.change++
        self.emit('add', node)
        cb(null, node)
      })
    })
  })

  links.forEach(function(link, i) {
    var n = next()

    self.get(typeof link === 'string' ? link : link.hash, function(err, resolved) {
      if (err) return n(err)
      node.sort = Math.max(node.sort, resolved.sort+1)
      links[i] = resolved
      n()
    })
  })

  var n = next()
  self.logs.tail(log, function(err, seq) {
    if (err) return n(err)
    node.seq = 1+seq

    if (!seq) {
      node.sort = Math.max(node.sort, 1)
      return n()
    }

    self.logs.get(log, seq, function(err, prev) {
      if (err) return n(err)
      node.sort = Math.max(node.sort, prev.sort+1)
      n()
    })
  })
}

Hyperlog.prototype.add = function(links, value, opts, cb) {
  if (typeof opts === 'function') return this.add(links, value, null, opts)
  if (!links) links = []
  if (!Array.isArray(links)) links = [links]
  if (!Buffer.isBuffer(value)) value = new Buffer(value)
  if (!cb) cb = noop
  if (!opts) opts = {}

  var self = this

  this.lock(function(release) {
    add(self, opts.log || self.id, opts.hash || null, links, value, function(err, node) {
      if (err) return release(cb, err)
      release(cb, null, node)
    })
  })
}

module.exports = Hyperlog<|endoftext|>


<commit_before>'use strict'
var emojiNamedCharacters = require('emoji-named-characters')
var marked = require('ssb-marked')
var ssbref = require('ssb-ref')
var mlib   = require('ssb-msgs')

var blockRenderer = new marked.Renderer()
var inlineRenderer = new marked.Renderer()

// override to only allow external links or hashes, and correctly link to ssb objects
blockRenderer.urltransform = function (url) {
  var c = url.charAt(0)
  var hasSigil = (c === '@' || c === '&' || c === '%' || c === '#')

  if (this.options.sanitize && !hasSigil) {
    // sanitize - only allow ssb refs or http/s links
    try {
      var prot = decodeURIComponent(unescape(url.replace(/[^\w:]/g, ''))).toLowerCase();
    } catch (e) {
      return false;
    }
    if (prot.indexOf('http:') !== 0 && prot.indexOf('https:') !== 0 && prot.indexOf('data:') !== 0) {
      return false;
    }
  }

  // use our own link if this is an ssb ref
  var isSsbRef = ssbref.isLink(url)
  if ((hasSigil || isSsbRef) && this.options.toUrl) {
    return this.options.toUrl(url, false)
  }
  return url
}

// override to make http/s links external
blockRenderer.link = function(href, title, text) {
  href = this.urltransform(href)
  var out
  if (href !== false) {
    if ((href.indexOf('/%26') === 0 || href.indexOf('/&') === 0) && (title || text)) // add ?name param if this is a link to a blob
      href += '?name='+encodeURIComponent(title || text)
    out = '<a href="' + href + '"';
  } else
    out = '' + text + '';
  return out;
};

blockRenderer.image  = function (href, title, text) {
  href = href.replace(/^&/, '&')
  if (ssbref.isLink(href) && this.options.toUrl) {
    var url = this.options.toUrl(href, true)
    var hrefAttr = this.options.imageLink
      ? ' href="' + this.options.imageLink(href) + '"'
      : ''
    var titleAttr = title
      ? ' title="' + title + '"'
      : ''

    return ''
  }
  return text
}

// inline renderer just spits out the text of links and images
inlineRenderer.urltransform = function (url) { return false }
inlineRenderer.link = function (href, title, text) { return unquote(shortenIfLink(text)) }
inlineRenderer.image  = function (href, title, text) { return unquote(shortenIfLink(text)) }
inlineRenderer.code = function(code, lang, escaped) { return escaped ? code : escape(code) }
inlineRenderer.blockquote = function(quote) { return unquote(quote) }
inlineRenderer.html = function(html) { return false }
inlineRenderer.heading = function(text, level, raw) { return unquote(text)+' ' }
inlineRenderer.hr = function() { return ' --- ' }
inlineRenderer.br = function() { return ' ' }
inlineRenderer.list = function(body, ordered) { return unquote(body) }
inlineRenderer.listitem = function(text) { return '- '+unquote(text) }
inlineRenderer.paragraph = function(text) { return unquote(text)+' ' }
inlineRenderer.table = function(header, body) { return unquote(header + ' ' + body) }
inlineRenderer.tablerow = function(content) { return unquote(content) }
inlineRenderer.tablecell = function(content, flags) { return unquote(content) }
inlineRenderer.strong = function(text) { return unquote(text) }
inlineRenderer.em = function(text) { return unquote(text) }
inlineRenderer.codespan = function(text) { return unquote(text) }
inlineRenderer.del = function(text) { return unquote(text) }
inlineRenderer.mention = function(preceding, id) { return shortenIfLink(unquote((preceding||'') + id)) }
inlineRenderer.hashtag = function(preceding, tag) { return unquote((preceding||'') + tag) }
function unquote (text) {
  return text.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, '\'')
}
function escape (text) {
  return text
    .replace(/&/g, '&')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"')
    .replace(/\n+/g, ' ')
}
function shortenIfLink (text) {
  return (ssbref.isLink(text.trim())) ? text.slice(0, 8) : text
}

marked.setOptions({
  gfm: true,
  mentions: true,
  tables: true,
  breaks: true,
  pedantic: false,
  sanitize: true,
  smartLists: true,
  smartypants: false,
  emoji: renderEmoji(16),
  renderer: blockRenderer
})

exports.block = function(text, opts) {
  return marked(''+(text||''), opts)
}

exports.inline = function(text) {
  return marked(''+(text||''), { renderer: inlineRenderer, emoji: renderEmoji(12) })
}

var emojiRegex = /(\s|>|^)?:([A-z0-9_]+):(\s|<|$)/g;
exports.emojis = function (str) {
  return str.replace(emojiRegex, function(full, $1, $2, $3) {
    return ($1||'') + renderEmoji(16)($2) + ($3||'')
  })
}

function renderEmoji (size) {
  size = size||20
  return function (emoji) {
    return emoji in emojiNamedCharacters ?
        ''
      : ':' + emoji + ':'
    }
}

<commit_msg>Check if the url belongs to a protocol specified in the options. If so, you can render the link.<commit_after>'use strict'
var emojiNamedCharacters = require('emoji-named-characters')
var marked = require('ssb-marked')
var ssbref = require('ssb-ref')
var mlib   = require('ssb-msgs')

var blockRenderer = new marked.Renderer()
var inlineRenderer = new marked.Renderer()

// override to only allow external links or hashes, and correctly link to ssb objects
blockRenderer.urltransform = function (url) {
  var c = url.charAt(0)
  var hasSigil = (c === '@' || c === '&' || c === '%' || c === '#')

  if (this.options.sanitize && !hasSigil) {
    // sanitize - only allow ssb refs or external links
    try {
      var prot = decodeURIComponent(unescape(url.replace(/[^\w:]/g, ''))).toLowerCase();
    } catch (e) {
      return false;
    }
    if (!isFullLink(this.options.protocols, prot)) {
      return false;
    }
  }

  // use our own link if this is an ssb ref
  var isSsbRef = ssbref.isLink(url)
  if ((hasSigil || isSsbRef) && this.options.toUrl) {
    return this.options.toUrl(url, false)
  }
  return url
}

// override to make http/s (or other specified protocol) links external
blockRenderer.link = function(href, title, text) {
  href = this.urltransform(href)
  var out
  if (href !== false) {
    if ((href.indexOf('/%26') === 0 || href.indexOf('/&') === 0) && (title || text)) // add ?name param if this is a link to a blob
      href += '?name='+encodeURIComponent(title || text)
    out = '<a href="' + href + '"';
  } else
    out = '' + text + '';
  return out;
};

blockRenderer.image  = function (href, title, text) {
  href = href.replace(/^&/, '&')
  if (ssbref.isLink(href) && this.options.toUrl) {
    var url = this.options.toUrl(href, true)
    var hrefAttr = this.options.imageLink
      ? ' href="' + this.options.imageLink(href) + '"'
      : ''
    var titleAttr = title
      ? ' title="' + title + '"'
      : ''

    return ''
  }
  return text
}

// inline renderer just spits out the text of links and images
inlineRenderer.urltransform = function (url) { return false }
inlineRenderer.link = function (href, title, text) { return unquote(shortenIfLink(text)) }
inlineRenderer.image  = function (href, title, text) { return unquote(shortenIfLink(text)) }
inlineRenderer.code = function(code, lang, escaped) { return escaped ? code : escape(code) }
inlineRenderer.blockquote = function(quote) { return unquote(quote) }
inlineRenderer.html = function(html) { return false }
inlineRenderer.heading = function(text, level, raw) { return unquote(text)+' ' }
inlineRenderer.hr = function() { return ' --- ' }
inlineRenderer.br = function() { return ' ' }
inlineRenderer.list = function(body, ordered) { return unquote(body) }
inlineRenderer.listitem = function(text) { return '- '+unquote(text) }
inlineRenderer.paragraph = function(text) { return unquote(text)+' ' }
inlineRenderer.table = function(header, body) { return unquote(header + ' ' + body) }
inlineRenderer.tablerow = function(content) { return unquote(content) }
inlineRenderer.tablecell = function(content, flags) { return unquote(content) }
inlineRenderer.strong = function(text) { return unquote(text) }
inlineRenderer.em = function(text) { return unquote(text) }
inlineRenderer.codespan = function(text) { return unquote(text) }
inlineRenderer.del = function(text) { return unquote(text) }
inlineRenderer.mention = function(preceding, id) { return shortenIfLink(unquote((preceding||'') + id)) }
inlineRenderer.hashtag = function(preceding, tag) { return unquote((preceding||'') + tag) }
function unquote (text) {
  return text.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, '\'')
}
function escape (text) {
  return text
    .replace(/&/g, '&')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"')
    .replace(/\n+/g, ' ')
}
function shortenIfLink (text) {
  return (ssbref.isLink(text.trim())) ? text.slice(0, 8) : text
}

marked.setOptions({
  gfm: true,
  mentions: true,
  tables: true,
  breaks: true,
  pedantic: false,
  sanitize: true,
  smartLists: true,
  smartypants: false,
  emoji: renderEmoji(16),
  protocols: ['http','https','data'],
  renderer: blockRenderer
})

exports.block = function(text, opts) {
  return marked(''+(text||''), opts)
}

exports.inline = function(text) {
  return marked(''+(text||''), { renderer: inlineRenderer, emoji: renderEmoji(12) })
}

var emojiRegex = /(\s|>|^)?:([A-z0-9_]+):(\s|<|$)/g;
exports.emojis = function (str) {
  return str.replace(emojiRegex, function(full, $1, $2, $3) {
    return ($1||'') + renderEmoji(16)($2) + ($3||'')
  })
}

function renderEmoji (size) {
  size = size||20
  return function (emoji) {
    return emoji in emojiNamedCharacters ?
        ''
      : ':' + emoji + ':'
    }
}

function isFullLink (protocols, href) {
  protocols = protocols || []
  href = href.split(':')[0]
  return protocols.indexOf(href) !== -1;
}

<|endoftext|>


<commit_before>var async = require('async');

var tessel = require('tessel');
var servolib = require('servo-pca9685');

var servo = servolib.use(tessel.port['A']);

var frequency = 100;
var motorPin    = 5;
var rudderPin   = 4;

var maxForward = 0.20;
var maxReverse = 0.10;
var neutral    = 0.15;

var delay      = 3750;

function calibrate(done) {
  async.series([
    function(callback) {
      console.log('motor duty cycle: maxForward');
      servo.setDutyCycle(motorPin, maxForward, callback);
    },
    function(callback) {
      setTimeout(callback, delay);
    },
    function(callback) {
      console.log('motor duty cycle: maxReverse');
      servo.setDutyCycle(motorPin, maxReverse, callback);
    },
    function(callback) {
      setTimeout(callback, delay);
    },
    function(callback) {
      console.log('motor duty cycle: neutral');
      servo.setDutyCycle(motorPin, neutral, callback);
    },
    function(callback) {
      done();
    }
  ]);
}

servo.on('ready', function () {
  console.log('servo ready');

  async.series([
    function(callback) {
      servo.setModuleFrequency(frequency, callback);
    },
    function(callback) {
      console.log('servo module frequency set: ', frequency);
      callback();
    },
    function(callback) {
      console.log('motor duty cycle: neutral');
      servo.setDutyCycle(motorPin, neutral, callback);
    },
    function(callback) {
      console.log('rudder duty cycle: neutral');
      servo.setDutyCycle(rudderPin, neutral, callback);
    }
  ]);
});

// ?.??? -> reverse -> 1.0 ms               0.114
// 0.171 -> neutral -> 1.5 ms ??? 1.48 ms
// ?.??? -> forward -> 2.0 ms               0.228

process.stdin.resume();
process.stdin.on('data', function (data) {
  data = String(data).replace(/[\r\n]*$/, '');  //  Removes the line endings

  if (data === 'calibrate') {
    console.log('calibrating ...');
    calibrate(function() {
      console.log('calibration complete');
    });
  } else {
    var dutyCycle = parseFloat(data);

    if (dutyCycle >= 0.1 && dutyCycle <= 0.2) {
      console.log('setting duty cycle to: ', dutyCycle);
      servo.setDutyCycle(rudderPin, dutyCycle);
    }
  }
});

<commit_msg>- REST like API for motor + rudder control<commit_after>var http = require('http');
var url = require('url');

var async = require('async');

var tessel = require('tessel');
var servolib = require('servo-pca9685');

var servo = servolib.use(tessel.port['A']);

var frequency = 100;
var motorPin    = 5;
var rudderPin   = 4;

var maxForward = 0.20;
var maxReverse = 0.10;
var neutral    = 0.15;

var delay      = 3750;

function calibrate(done) {
  async.series([
    function(callback) {
      console.log('motor duty cycle: maxForward');
      servo.setDutyCycle(motorPin, maxForward, callback);
    },
    function(callback) {
      setTimeout(callback, delay);
    },
    function(callback) {
      console.log('motor duty cycle: maxReverse');
      servo.setDutyCycle(motorPin, maxReverse, callback);
    },
    function(callback) {
      setTimeout(callback, delay);
    },
    function(callback) {
      console.log('motor duty cycle: neutral');
      servo.setDutyCycle(motorPin, neutral, callback);
    },
    function(callback) {
      done();
    }
  ]);
}

servo.on('ready', function () {
  console.log('servo ready');

  async.series([
    function(callback) {
      servo.setModuleFrequency(frequency, callback);
    },
    function(callback) {
      console.log('servo module frequency set: ', frequency);
      callback();
    },
    function(callback) {
      console.log('motor duty cycle: neutral');
      servo.setDutyCycle(motorPin, neutral, callback);
    },
    function(callback) {
      console.log('rudder duty cycle: neutral');
      servo.setDutyCycle(rudderPin, neutral, callback);
    }
  ]);
});

process.stdin.resume();
process.stdin.on('data', function (data) {
  data = String(data).replace(/[\r\n]*$/, '');  //  Removes the line endings

  if (data === 'calibrate') {
    console.log('calibrating ...');
    calibrate(function() {
      console.log('calibration complete');
    });
  } else {
    var dutyCycle = parseFloat(data);

    if (dutyCycle >= 0.1 && dutyCycle <= 0.2) {
      console.log('setting duty cycle to: ', dutyCycle);
      servo.setDutyCycle(rudderPin, dutyCycle);
    }
  }
});

setImmediate(function start () {
  http.createServer(function (req, res) {
    var uri = url.parse(req.url).pathname;

    console.log(uri);
    var match = uri.match(/^\/(.*)\/(.*)$/);

    if (match) {
      if (match[1] === 'rudder') {
        var dutyCycle = parseFloat(match[2]);

        if (dutyCycle > maxForward) {
          dutyCycle = maxForward;
        } else if (dutyCycle < maxReverse) {
          dutyCycle = maxReverse;
        }

        console.log('setting rudder duty cycle to: ', dutyCycle);
        servo.setDutyCycle(rudderPin, dutyCycle);

        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('done!');
      } else if (match[1] === 'motor') {
        var dutyCycle = parseFloat(match[2]);

        if (dutyCycle > maxForward) {
          dutyCycle = maxForward;
        } else if (dutyCycle < maxReverse) {
          dutyCycle = maxReverse;
        }

        console.log('setting motor duty cycle to: ', dutyCycle);
        servo.setDutyCycle(motorPin, dutyCycle);

        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('done!');
      } else {
        console.log('Not found: ', match[1]);
        res.writeHead(404, {'Content-Type': 'text/plain'});
        res.end('Not found!');
      }
    } else {
      console.log('Not found');
      res.writeHead(404, {'Content-Type': 'text/plain'});
      res.end('Not found!');
    }
  }).listen(80);
});

<|endoftext|>


<commit_before>require('lazy-ass');
var check = require('check-types');
var istanbul = require('istanbul');
var instrumenter = new istanbul.Instrumenter();

var http = require('http'),
  httpProxy = require('http-proxy');

function shouldBeInstrumented(url) {
  la(check.unemptyString(url), 'expected url string');
  return /app\.js$/.test(url);
}

function sendCoverageBackToProxy() {
  setTimeout(function sendCoverage() {
    console.log('sending coverage to the server');
    var request = new XMLHttpRequest();
    request.open('POST', '/__coverage', true);
    request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
    request.send(JSON.stringify(__coverage__));
  }, 1000);
}

function prepareResponseSelectors(proxyRes, req, res) {
  var _write      = res.write;
  var _end        = res.end;
  var _writeHead  = res.writeHead;
  var scriptSrc = '';

  /*
  proxyRes.on('data', function (chunk) {
    // console.log('proxy response data');
    scriptSrc += chunk;
  });*/

  res.writeHead = function (code, headers) {
    var contentType = this.getHeader('content-type');
    console.log('writing head', contentType);

    // Strip off the content length since it will change.
    res.removeHeader('Content-Length');
    if (headers) {
      delete headers['content-length'];
    }
    _writeHead.apply(res, arguments);
  };

  res.write = function (chunk, encoding) {
    scriptSrc += chunk;
    // _write.apply(res, arguments);
  };

  res.end = function (data, encoding) {
    var instrumented = instrumenter.instrumentSync(scriptSrc, req.url);
    instrumented += '\n\n';
    instrumented += sendCoverageBackToProxy.toString() + '\n';
    instrumented += 'sendCoverageBackToProxy();\n';
    _write.call(res, instrumented);
    _end.call(res);
  };
}

//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});

//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http.createServer(function(req, res) {
  // You can define here your custom logic to handle the request
  // and then proxy the request.
  console.log('proxy request', req.url);
  if (req.url === '/__coverage') {
    console.log('received coverage info');
    var str = '';
    req.on('data', function (chunk) {
      str += chunk;
    });
    req.on('end', function () {
      var coverage = JSON.parse(str);
      // console.log(coverage);
      require('fs').writeFileSync('./coverage.json', JSON.stringify(coverage, null, '  '));
      console.log('saved coverage to coverage.json');
    });
    res.writeHead(200);
    res.end();
  } else {
    proxy.web(req, res, { target: 'http://127.0.0.1:3003' });
  }
});

proxy.on('proxyRes', function (proxyRes, req, res) {
  console.log('RAW Response from the target', JSON.stringify(proxyRes.headers, true, 2));
  if (shouldBeInstrumented(req.url)) {
    console.log('will instrument', req.url);
    prepareResponseSelectors(proxyRes, req, res);
  }
});

console.log("listening on port 5050")
server.listen(5050);
<commit_msg>writing summary coverage report<commit_after>require('lazy-ass');
var check = require('check-types');
var istanbul = require('istanbul');
var instrumenter = new istanbul.Instrumenter();

var http = require('http'),
  httpProxy = require('http-proxy');

function shouldBeInstrumented(url) {
  la(check.unemptyString(url), 'expected url string');
  return /app\.js$/.test(url);
}

// this function will be embedded into the client JavaScript code
// so it makes no sense to lint it here
function sendCoverageBackToProxy() {
  setTimeout(function sendCoverage() {
    console.log('sending coverage to the server');
    var request = new XMLHttpRequest();
    request.open('POST', '/__coverage', true);
    request.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
    request.send(JSON.stringify(__coverage__));
  }, 1000);
}

function writeCoverage(coverage) {
  la(check.object(coverage), 'missing coverage object');
  var Collector = istanbul.Collector;
  var Report = istanbul.Report;

  var collector = new Collector();
  collector.add(coverage);
  var summaryReport = Report.create('text-summary');
  summaryReport.writeReport(collector, true);
}

function prepareResponseSelectors(proxyRes, req, res) {
  var _write      = res.write;
  var _end        = res.end;
  var _writeHead  = res.writeHead;
  var scriptSrc = '';

  /*
  proxyRes.on('data', function (chunk) {
    // console.log('proxy response data');
    scriptSrc += chunk;
  });*/

  res.writeHead = function (code, headers) {
    var contentType = this.getHeader('content-type');
    console.log('writing head', contentType);

    // Strip off the content length since it will change.
    res.removeHeader('Content-Length');
    if (headers) {
      delete headers['content-length'];
    }
    _writeHead.apply(res, arguments);
  };

  res.write = function (chunk, encoding) {
    scriptSrc += chunk;
    // _write.apply(res, arguments);
  };

  res.end = function (data, encoding) {
    var instrumented = instrumenter.instrumentSync(scriptSrc, req.url);
    instrumented += '\n\n';
    instrumented += sendCoverageBackToProxy.toString() + '\n';
    instrumented += 'sendCoverageBackToProxy();\n';
    _write.call(res, instrumented);
    _end.call(res);
  };
}

//
// Create a proxy server with custom application logic
//
var proxy = httpProxy.createProxyServer({});

//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http.createServer(function(req, res) {
  // You can define here your custom logic to handle the request
  // and then proxy the request.
  console.log('proxy request', req.url);
  if (req.url === '/__coverage') {
    console.log('received coverage info');
    var str = '';
    req.on('data', function (chunk) {
      str += chunk;
    });
    req.on('end', function () {
      var coverage = JSON.parse(str);
      // console.log(coverage);
      require('fs').writeFileSync('./coverage.json', JSON.stringify(coverage, null, '  '));
      console.log('saved coverage to coverage.json');

      writeCoverage(coverage);
    });
    res.writeHead(200);
    res.end();
  } else {
    proxy.web(req, res, { target: 'http://127.0.0.1:3003' });
  }
});

proxy.on('proxyRes', function (proxyRes, req, res) {
  console.log('RAW Response from the target', JSON.stringify(proxyRes.headers, true, 2));
  if (shouldBeInstrumented(req.url)) {
    console.log('will instrument', req.url);
    prepareResponseSelectors(proxyRes, req, res);
  }
});

console.log("listening on port 5050")
server.listen(5050);
<|endoftext|>


<commit_before>'use strict';

var chalk   = require("chalk"),
    fs      = require("fs"),
    yaml    = require("js-yaml"),
    mate    = require("first-mate"),
    jsdiff  = require("diff"),
    temp    = require("temp").track(),
    _       = require("underscore"),
    cson    = require("cson"),
    plist   = require("plist"),
    path    = require("path");

function readGrammarFile(filename) {
    function read(filename, vars) {
        var yamlSource = fs.readFileSync(filename, 'utf8'),
            hop = Object.prototype.hasOwnProperty;

        if (vars) {
            yamlSource = yamlSource.replace(
                /\$\{(\w+)\}/g,
                function(all, name) {
                    if (name && hop.call(vars, name)) {
                        return vars[name];
                    } else {
                        return all;
                    }
                });
        }

        var schema = yaml.safeLoad(yamlSource);

        if (schema.repository
            && schema.repository.$apply
            && schema.repository.$apply instanceof Array)
        {
            var specs = schema.repository.$apply;
            for (var i = 0; i < specs.length; i++) {
                var spec = specs[i];

                var inner = read(path.join(path.dirname(filename),
                                           spec.file),
                                 spec.vars);

                _.extend(schema.repository, inner.repository);
            }

            delete schema.repository.$apply;
        }

        return schema;
    }

    return read(filename);
}

function compileGrammar(grammarFile, additionalGrammars) {
    function _compile(filename, registry) {
        var tmp = temp.openSync();

        try {
            var yamlSchema = readGrammarFile(filename);

            fs.writeSync(tmp.fd, JSON.stringify(yamlSchema));
            fs.closeSync(tmp.fd);

            return registry.loadGrammarSync(tmp.path);
        }
        finally {
            temp.cleanupSync();
        }
    }

    var registry = new mate.GrammarRegistry,
        grammar = _compile(grammarFile, registry);

    if (additionalGrammars) {
        for (var i = 0; i < additionalGrammars.length; i++) {
            _compile(additionalGrammars[i], registry);
        }
    }

    return grammar;
}

function testFile(file, grammar, options) {
    function padRight(str, pad) {
        if (str.length < pad) {
            return str + (new Array(pad - str.length)).join(' ');
        }

        return str;
    }

    function stripnl(str){
        return str.replace(/^\n+/, '').replace(/\n+$/, '');
    }

    function rpartition(str, separator) {
        if (!separator) {
            throw new Error('empty separator')
        }

        var seplen = separator.length,
            lastpos = str.lastIndexOf(separator);

        if (lastpos != -1) {
            return [str.substr(0, lastpos),
                    separator,
                    str.substr(lastpos + seplen)];
        }
        else {
            return ['', '', str];
        }
    }

    function tokenize(lines) {
        var lines = grammar.tokenizeLines(stripnl(lines)),
            result = [];

        result = []
        for (var i = 0; i < lines.length; i++) {
            var line = lines[i];

            for (var j = 0; j < line.length; j++) {
                var value = line[j].value,
                    scopes = line[j].scopes;

                result.push(
                    [
                        padRight(value, 14),
                        ' : ',
                        _.chain(scopes).uniq().sort().value().join(', ')
                    ].join('')
                )
            }
        }

        return result.join('\n')
    }

    function getDiff(test, result) {
        var diff = jsdiff.structuredPatch('', '', test, result, '', ''),
            result = [];

        for (var i = 0; i < diff.hunks.length; i++) {
            var hunk = diff.hunks[i];

            for (var j = 0; j < hunk.lines.length; j++) {
                var line = hunk.lines[j];
                if (line && !options.no_color) {
                    if (line[0] == '+') {
                        line = chalk.green(line)
                    } else if (line[0] == '-') {
                        line = chalk.red(line)
                    }
                }
                result.push(line);
            }

            result.push('@@@@@@')
        }

        result.pop();
        return result.join('\n');
    }

    var buf = fs.readFileSync(file, 'utf8'),
        parts = rpartition(buf, '\n\n\n'),
        source = parts[0],
        test = parts[2];

    if (test) {
        test = stripnl(test);
    }

    if (!test) {
        test = null;
    }

    if (!source && test) {
        source = test;
        test = null;
    }

    if (!source) {
        return {
            file: file,
            status: 'fail',
            error: 'Empty file'
        }
    }

    var result = tokenize(source);

    if (test != result) {
        if (test) {
            return {
                file: file,
                status: 'fail',
                error: 'Output different from expected',
                body: getDiff(test, result)
            }
        } else {
            return {
                file: file,
                status: 'fail',
                error: 'No expected output set',
                body: result
            }
        }
    } else {
        return {
            file: file,
            status: 'pass'
        }
    }
}

function test(testFiles, grammarFile, options) {
    options = options || {};

    var grammar = compileGrammar(grammarFile, options.add_syntaxes),
        sep = '--------',
        passed = 0,
        failed = 0,
        failedRes = [];

    console.log(sep);
    console.log(testFiles.length + ' tests; grammar: ' + grammarFile);
    console.log(sep);

    for (var i = 0; i < testFiles.length; i++) {
        var res = testFile(testFiles[i], grammar, options);

        if (res.status == 'fail') {
            process.stdout.write('E');
            failed ++;
            failedRes.push(res);
        } else {
            process.stdout.write('.');
            passed ++;
        }
    }
    process.stdout.write('\n');

    console.log(sep);
    console.log(passed + ' passed; ' + failed + ' failed.');
    console.log(sep);

    for (var i = 0; i < failedRes.length; i++) {
        var res = failedRes[i];

        console.log(sep);
        console.log('Failed test ' + res.file + ': ' + res.error);
        console.log(sep);
        if (res.body) {
            console.log(res.body)
        }
    }

    if (failed) {
        process.exit(1);
    }
}

function buildCson(inName, outName) {
    var yamlSchema = readGrammarFile(inName),
        csonSource = cson.createCSONString(yamlSchema, {indent: 2});

    csonSource = '# AUTOGENERATED FROM ' + inName + '\n' + csonSource;
    fs.writeFileSync(outName, csonSource);
}

function buildPList(inName, outName) {
    var yamlSchema = readGrammarFile(inName),
        plistSource = plist.build(yamlSchema);

    plistSource = '<!-- AUTOGENERATED FROM ' + inName + ' -->\n' +
                  plistSource;

    fs.writeFileSync(outName, plistSource);
}

module.exports = {
    test: test,
    buildCson: buildCson,
    buildPList: buildPList
};
<commit_msg>Split scopes correctly<commit_after>'use strict';

var chalk   = require("chalk"),
    fs      = require("fs"),
    yaml    = require("js-yaml"),
    mate    = require("first-mate"),
    jsdiff  = require("diff"),
    temp    = require("temp").track(),
    _       = require("underscore"),
    cson    = require("cson"),
    plist   = require("plist"),
    path    = require("path");

function readGrammarFile(filename) {
    function read(filename, vars) {
        var yamlSource = fs.readFileSync(filename, 'utf8'),
            hop = Object.prototype.hasOwnProperty;

        if (vars) {
            yamlSource = yamlSource.replace(
                /\$\{(\w+)\}/g,
                function(all, name) {
                    if (name && hop.call(vars, name)) {
                        return vars[name];
                    } else {
                        return all;
                    }
                });
        }

        var schema = yaml.safeLoad(yamlSource);

        if (schema.repository
            && schema.repository.$apply
            && schema.repository.$apply instanceof Array)
        {
            var specs = schema.repository.$apply;
            for (var i = 0; i < specs.length; i++) {
                var spec = specs[i];

                var inner = read(path.join(path.dirname(filename),
                                           spec.file),
                                 spec.vars);

                _.extend(schema.repository, inner.repository);
            }

            delete schema.repository.$apply;
        }

        return schema;
    }

    return read(filename);
}

function compileGrammar(grammarFile, additionalGrammars) {
    function _compile(filename, registry) {
        var tmp = temp.openSync();

        try {
            var yamlSchema = readGrammarFile(filename);

            fs.writeSync(tmp.fd, JSON.stringify(yamlSchema));
            fs.closeSync(tmp.fd);

            return registry.loadGrammarSync(tmp.path);
        }
        finally {
            temp.cleanupSync();
        }
    }

    var registry = new mate.GrammarRegistry,
        grammar = _compile(grammarFile, registry);

    if (additionalGrammars) {
        for (var i = 0; i < additionalGrammars.length; i++) {
            _compile(additionalGrammars[i], registry);
        }
    }

    return grammar;
}

function testFile(file, grammar, options) {
    function padRight(str, pad) {
        if (str.length < pad) {
            return str + (new Array(pad - str.length)).join(' ');
        }

        return str;
    }

    function stripnl(str){
        return str.replace(/^\n+/, '').replace(/\n+$/, '');
    }

    function rpartition(str, separator) {
        if (!separator) {
            throw new Error('empty separator')
        }

        var seplen = separator.length,
            lastpos = str.lastIndexOf(separator);

        if (lastpos != -1) {
            return [str.substr(0, lastpos),
                    separator,
                    str.substr(lastpos + seplen)];
        }
        else {
            return ['', '', str];
        }
    }

    function tokenize(lines) {
        var lines = grammar.tokenizeLines(stripnl(lines)),
            result = [];

        result = []
        for (var i = 0; i < lines.length; i++) {
            var line = lines[i];

            for (var j = 0; j < line.length; j++) {
                var value = line[j].value,
                    scopes = line[j].scopes;

                result.push(
                    [
                        padRight(value, 14),
                        ' : ',

                        _.chain(scopes)
                         .flatten()
                         .reduce(
                            function(m, v) {
                              m.push.apply(m, v.split(/\s+/g));
                              return m;
                            },
                            []
                          )
                         .uniq()
                         .sort()
                         .value()
                         .join(', ')
                    ].join('')
                )
            }
        }

        return result.join('\n')
    }

    function getDiff(test, result) {
        var diff = jsdiff.structuredPatch('', '', test, result, '', ''),
            result = [];

        for (var i = 0; i < diff.hunks.length; i++) {
            var hunk = diff.hunks[i];

            for (var j = 0; j < hunk.lines.length; j++) {
                var line = hunk.lines[j];
                if (line && !options.no_color) {
                    if (line[0] == '+') {
                        line = chalk.green(line)
                    } else if (line[0] == '-') {
                        line = chalk.red(line)
                    }
                }
                result.push(line);
            }

            result.push('@@@@@@')
        }

        result.pop();
        return result.join('\n');
    }

    var buf = fs.readFileSync(file, 'utf8'),
        parts = rpartition(buf, '\n\n\n'),
        source = parts[0],
        test = parts[2];

    if (test) {
        test = stripnl(test);
    }

    if (!test) {
        test = null;
    }

    if (!source && test) {
        source = test;
        test = null;
    }

    if (!source) {
        return {
            file: file,
            status: 'fail',
            error: 'Empty file'
        }
    }

    var result = tokenize(source);

    if (test != result) {
        if (test) {
            return {
                file: file,
                status: 'fail',
                error: 'Output different from expected',
                body: getDiff(test, result)
            }
        } else {
            return {
                file: file,
                status: 'fail',
                error: 'No expected output set',
                body: result
            }
        }
    } else {
        return {
            file: file,
            status: 'pass'
        }
    }
}

function test(testFiles, grammarFile, options) {
    options = options || {};

    var grammar = compileGrammar(grammarFile, options.add_syntaxes),
        sep = '--------',
        passed = 0,
        failed = 0,
        failedRes = [];

    console.log(sep);
    console.log(testFiles.length + ' tests; grammar: ' + grammarFile);
    console.log(sep);

    for (var i = 0; i < testFiles.length; i++) {
        var res = testFile(testFiles[i], grammar, options);

        if (res.status == 'fail') {
            process.stdout.write('E');
            failed ++;
            failedRes.push(res);
        } else {
            process.stdout.write('.');
            passed ++;
        }
    }
    process.stdout.write('\n');

    console.log(sep);
    console.log(passed + ' passed; ' + failed + ' failed.');
    console.log(sep);

    for (var i = 0; i < failedRes.length; i++) {
        var res = failedRes[i];

        console.log(sep);
        console.log('Failed test ' + res.file + ': ' + res.error);
        console.log(sep);
        if (res.body) {
            console.log(res.body)
        }
    }

    if (failed) {
        process.exit(1);
    }
}

function buildCson(inName, outName) {
    var yamlSchema = readGrammarFile(inName),
        csonSource = cson.createCSONString(yamlSchema, {indent: 2});

    csonSource = '# AUTOGENERATED FROM ' + inName + '\n' + csonSource;
    fs.writeFileSync(outName, csonSource);
}

function buildPList(inName, outName) {
    var yamlSchema = readGrammarFile(inName),
        plistSource = plist.build(yamlSchema);

    plistSource = '<!-- AUTOGENERATED FROM ' + inName + ' -->\n' +
                  plistSource;

    fs.writeFileSync(outName, plistSource);
}

module.exports = {
    test: test,
    buildCson: buildCson,
    buildPList: buildPList
};
<|endoftext|>


<commit_before>'use strict';

function preserveCamelCase(str) {
	let isLastCharLower = false;
	let isLastCharUpper = false;
	let isLastLastCharUpper = false;

	for (let i = 0; i < str.length; i++) {
		const c = str.charAt(i);

		if (isLastCharLower && (/[a-zA-Z]/).test(c) && c.toUpperCase() === c) {
			str = str.substr(0, i) + '-' + str.substr(i);
			isLastCharLower = false;
			isLastLastCharUpper = isLastCharUpper;
			isLastCharUpper = true;
			i++;
		} else if (isLastCharUpper && isLastLastCharUpper && (/[a-zA-Z]/).test(c) && c.toLowerCase() === c) {
			str = str.substr(0, i - 1) + '-' + str.substr(i - 1);
			isLastLastCharUpper = isLastCharUpper;
			isLastCharUpper = false;
			isLastCharLower = true;
		} else {
			isLastCharLower = c.toLowerCase() === c;
			isLastLastCharUpper = isLastCharUpper;
			isLastCharUpper = c.toUpperCase() === c;
		}
	}

	return str;
}

module.exports = function () {
	let str = [].map.call(arguments, x => x.trim()).filter(x => x.length).join('-');

	if (str.length === 0) {
		return '';
	}

	if (str.length === 1) {
		return str.toLowerCase();
	}

	str = preserveCamelCase(str);

	return str
		.replace(/^[_.\- ]+/, '')
		.toLowerCase()
		.replace(/[_.\- ]+(\w|$)/g, (m, p1) => p1.toUpperCase());
};
<commit_msg>please @jdalton<commit_after>'use strict';

function preserveCamelCase(str) {
	let isLastCharLower = false;
	let isLastCharUpper = false;
	let isLastLastCharUpper = false;

	for (let i = 0; i < str.length; i++) {
		const c = str[i];

		if (isLastCharLower && (/[a-zA-Z]/).test(c) && c.toUpperCase() === c) {
			str = str.substr(0, i) + '-' + str.substr(i);
			isLastCharLower = false;
			isLastLastCharUpper = isLastCharUpper;
			isLastCharUpper = true;
			i++;
		} else if (isLastCharUpper && isLastLastCharUpper && (/[a-zA-Z]/).test(c) && c.toLowerCase() === c) {
			str = str.substr(0, i - 1) + '-' + str.substr(i - 1);
			isLastLastCharUpper = isLastCharUpper;
			isLastCharUpper = false;
			isLastCharLower = true;
		} else {
			isLastCharLower = c.toLowerCase() === c;
			isLastLastCharUpper = isLastCharUpper;
			isLastCharUpper = c.toUpperCase() === c;
		}
	}

	return str;
}

module.exports = function () {
	let str = Array
		.from(arguments)
		.map(x => x.trim())
		.filter(x => x.length)
		.join('-');

	if (str.length === 0) {
		return '';
	}

	if (str.length === 1) {
		return str.toLowerCase();
	}

	str = preserveCamelCase(str);

	return str
		.replace(/^[_.\- ]+/, '')
		.toLowerCase()
		.replace(/[_.\- ]+(\w|$)/g, (m, p1) => p1.toUpperCase());
};
<|endoftext|>


<commit_before>/*
¹
²
³
×
°
·
*/

var blessed = require('blessed');
var contrib = require('blessed-contrib');
var ttys     = require('ttys');
var geoip = require('geoip-lite');

/**/
var MAP_AR = 162 / 36; // 4.5
var terminalAr = process.stdout.columns / process.stdout.rows;

var matrix =
  terminalAr > MAP_AR
  ? /* log on left */
    /*   w      h     l      t */
    [
      ["80%", "100%", 0    , 0    ],
      ["20%", "100%", "80%", 0    ]
    ]
  : /* log on bottom */
    [
      ["100%", "80%", 0    , 0    ],
      ["100%", "20%", 0    , "80%"]
    ]

var screen = blessed.screen({
  input: ttys.stdin,
  output: process.stdout
});

var grid = new contrib.grid({rows: 2, cols: 2, screen: screen})

screen.key(['escape', 'q', 'C-c'], function(ch, key) {
 return process.exit(0);
});

//var map = grid.set(0, 0, 2, 2, contrib.map, {label: 'Map'});
var map = contrib.map({
  label: 'Map',
  width:  matrix[0][0],
  height: matrix[0][1],
  left:   matrix[0][2],
  top:    matrix[0][3],
  xPadding: 0,
  border: {type: "line", fg: "cyan"}
});
screen.append(map);

//var log = grid.set(1, 0, 1, 2, contrib.log, { fg: "green" , selectedFg: "green" , label: 'Log'});
var log = contrib.log({
  fg: "green" ,
  selectedFg: "green" ,
  label: "Log",
  width:  matrix[1][0],
  height: matrix[1][1],
  left:   matrix[1][2],
  top:    matrix[1][3],
  xPadding: 0,
  border: {type: "line", fg: "cyan"}
});
log.log(process.stdout.columns + 'x' + process.stdout.rows);
//console.log(process.stdout.columns + 'x' + process.stdout.rows);
screen.append(log);
/**/

var data = process.argv.slice(2);
if(data.length){
  drawMarkers(data);
} else {
  var input_data = [];
  var stream = process.stdin;
  stream.on('data', function(data) {
    input_data = [].concat(data.toString().split("\n").slice(0, -1));
    drawMarkers(input_data);
  });
  stream.on('end', function() {
  });
  stream.on('error', function(){});
}

function drawMarkers(ipList){

  ipList.forEach(function(ip){
    var geo = geoip.lookup(ip);
    map.addMarker({"lon" : "" + geo.ll[1], "lat" : "" + geo.ll[0], color: "red", char: "·" })
    log.log(ip + " (" + (geo.city || "<unknown city>") + ", " + geo.country + ")");
  });

  screen.render();

}

//  w        h   aspect ratio    matrix
//150-170 / 36 ~ 4                1x4
//75-105 / 36  ~ 2                1x2
//
//
// matrix formula: 1 / (apect ratio)  if AR >= 2
<commit_msg>version 1.0<commit_after>/*
¹
²
³
×
°
·
*/

var blessed = require('blessed');
var contrib = require('blessed-contrib');
var ttys     = require('ttys');
var geoip = require('geoip-lite');

var map, log, screen;
function drawApp(){
  var MAP_AR = 162 / 36; // map aspect ratio, 4.5
  var terminalAr = process.stdout.columns / process.stdout.rows; // terminal aspect ratio

  var matrix =
    terminalAr > MAP_AR
      ? /* log on left */
      /*   w      h     l      t */
      [
        ["80%", "100%", 0    , 0      ], /* map */
        ["20%", "100%", "80%", 0      ]  /* log */
      ]
        : /* log on bottom */
        [
          ["100%", "80%", 0    , 0    ],
          ["100%", "20%", 0    , "80%"]
        ]

  screen = blessed.screen({
    input: ttys.stdin,
    output: process.stdout
  });

  screen.key(['escape', 'q', 'C-c'], function(ch, key) {
    return process.exit(0);
  });

  map = contrib.map({
    label: 'Map',
    width:  matrix[0][0],
    height: matrix[0][1],
    left:   matrix[0][2],
    top:    matrix[0][3],
    xPadding: 0,
    border: {type: "line", fg: "cyan"}
  });
  screen.append(map);

  log = contrib.log({
    fg: "green" ,
    selectedFg: "green" ,
    label: "Log",
    width:  matrix[1][0],
    height: matrix[1][1],
    left:   matrix[1][2],
    top:    matrix[1][3],
    xPadding: 0,
    border: {type: "line", fg: "cyan"}
  });
  screen.append(log);
}
drawApp();

function drawMarkers(ipList){
  ipList.forEach(function(ip){
    var geo = geoip.lookup(ip);
    map.addMarker({"lon" : "" + geo.ll[1], "lat" : "" + geo.ll[0], color: "red", char: "°" })
    log.log(ip + " (" + (geo.city || "<unknown city>") + ", " + geo.country + ")");
  });
  screen.render();
}

var data = process.argv.slice(2);
if(data.length){
  drawMarkers(data);
} else {
  var input_data = [];
  var stream = process.stdin;
  stream.on('data', function(data) {
    input_data = [].concat(data.toString().split("\n").slice(0, -1));
    drawMarkers(input_data);
  });
  stream.on('end', function() {
  });
  stream.on('error', function(){});
}

<|endoftext|>