<commit_before>var fs = require('fs');
var path = require('path');
var glob = require('glob');

/**
 * Shallow copy two objects into a new object
 *
 * Objects are merged from left to right. Thus, properties in objects further
 * to the right are preferred over those on the left.
 *
 * @param {object} obj1
 * @param {object} obj2
 * @returns {object}
 * @api private
 */

var merge = function (obj1, obj2) {
  var c = {};
  var keys = Object.keys(obj2);
  for(var i=0; i!==keys.length; i++) {
    c[keys[i]] = obj2[keys[i]];
  }

  keys = Object.keys(obj1);
  for(i=0; i!==keys.length; i++) {
    if (!c.hasOwnProperty(keys[i])) {
      c[keys[i]] = obj1[keys[i]];
    }
  }

  return c;
};

/* Capture the layout name; thanks express-hbs */
var rLayoutPattern = /{{!<\s+([A-Za-z0-9\._\-\/]+)\s*}}/;

/**
 * file reader returning a thunk
 * @param filename {String} Name of file to read
 */

var read = function (filename) {
  return function(done) {
    fs.readFile(filename, {encoding: 'utf8'}, done);
  };
};

/**
 * expose default instance of `Hbs`
 */

exports = module.exports = new Hbs();

/**
 * expose method to create additional instances of `Hbs`
 */

exports.create = function() {
  return new Hbs();
};

/**
 * Create new instance of `Hbs`
 *
 * @api public
 */

function Hbs() {
  if(!(this instanceof Hbs)) return new Hbs();

  this.handlebars = require('handlebars').create();

  this.Utils = this.handlebars.Utils;
  this.SafeString = this.handlebars.SafeString;
}

/**
 * Configure the instance.
 *
 * @api private
 */

Hbs.prototype.configure = function (options) {

  var self = this;

  if(!options.viewPath) throw new Error("must specify view path");

  // Attach options
  var options = options || {};
  this.viewPath = options.viewPath;
  this.handlebars = options.handlebars || this.handlebars;
  this.templateOptions = options.templateOptions || {};
  this.extname = options.extname || '.hbs';
  this.partialsPath = options.partialsPath || '';
  this.contentHelperName = options.contentHelperName || 'contentFor';
  this.blockHelperName = options.blockHelperName || 'block';
  this.defaultLayout = options.defaultLayout || '';
  this.layoutsPath = options.layoutsPath || '';
  this.locals = options.locals || {};
  this.disableTemplateCaching = options.disableTemplateCaching;

  this.partialsRegistered = false;

  // Cache templates and layouts
  this.cache = {};

  this.blocks = {};

  // block helper
  this.registerHelper(this.blockHelperName, function(name, options) {
    // instead of returning self.block(name), render the default content if no
    // block is given
    val = self.block(name);
    if(val == '' && typeof options.fn === 'function') val = options.fn(this);

    return val;
  })

  // contentFor helper
  this.registerHelper(this.contentHelperName, function(name, options) {
    return self.content(name, options, this);
  })

  return this;
};

/**
 * Middleware for koa
 *
 * @api public
 */

Hbs.prototype.middleware = function(options) {
  this.configure(options);

  var render = this.createRenderer();

  return function *(next) {
    this.render = render;
    yield next;
  };
}

/**
 * Create a render generator to be attached to koa context
 */

Hbs.prototype.createRenderer = function() {
  var hbs = this;

  return function *(tpl, locals, templateOptions) {
    var tplPath = path.join(hbs.viewPath, tpl + hbs.extname),
      template, rawTemplate, layoutTemplate;

    locals = merge(hbs.locals, locals || {});
    templateOptions = merge(hbs.templateOptions, templateOptions || {});

    // conditionally clear cache
    if (hbs.disableTemplateCaching) hbs.cache = {};

    // clear blocks
    hbs.blocks = {};

    // Initialization... move these actions into another function to remove
    // unnecessary checks
    if((!hbs.partialsRegistered || hbs.disableTemplateCaching) && hbs.partialsPath !== '')
      yield hbs.registerPartials();

    if(!hbs.layoutTemplate)
      hbs.layoutTemplate = yield hbs.cacheLayout();

    // Load the template
    if(!hbs.cache[tpl]) {
      rawTemplate = yield read(tplPath);
      hbs.cache[tpl] = {
        template: hbs.handlebars.compile(rawTemplate)
      };

      // Load layout if specified
      if(rLayoutPattern.test(rawTemplate)) {
        var layout = rLayoutPattern.exec(rawTemplate)[1];
        var rawLayout = yield hbs.loadLayoutFile(layout);
        if (!hbs.cache[tpl]) hbs.cache[tpl] = {
          template: hbs.handlebars.compile(rawTemplate)
        };
        hbs.cache[tpl].layoutTemplate = hbs.handlebars.compile(rawLayout);
      }
    }

    template = hbs.cache[tpl].template;
    layoutTemplate = hbs.cache[tpl].layoutTemplate || hbs.layoutTemplate;

    // Run the compiled templates
    locals.body = template(locals, templateOptions);
    this.body = layoutTemplate(locals, templateOptions);
  };
}

/**
 * Get layout path
 */

Hbs.prototype.getLayoutPath = function(layout) {
  if(this.layoutsPath)
    return path.join(this.layoutsPath, layout + this.extname);

  return path.join(this.viewPath, layout + this.extname);
}

/**
 * Get a default layout. If none is provided, make a noop
 */

Hbs.prototype.cacheLayout = function(layout) {
  var hbs = this;
  return function* () {
    // Create a default layout to always use
    if(!layout && !hbs.defaultLayout)
      return hbs.handlebars.compile("{{{body}}}");

    // Compile the default layout if one not passed
    if(!layout) layout = hbs.defaultLayout;

    var layoutTemplate;
    try {
      var rawLayout = yield hbs.loadLayoutFile(layout);
      layoutTemplate = hbs.handlebars.compile(rawLayout);
    } catch (err) {
      console.error(err.stack);
    }

    return layoutTemplate;
  };
}

/**
 * Load a layout file
 */

Hbs.prototype.loadLayoutFile = function(layout) {
  var hbs = this;
  return function(done) {
    var file = hbs.getLayoutPath(layout);
    read(file)(done);
  };
}

/**
 * Register helper to internal handlebars instance
 */

Hbs.prototype.registerHelper = function() {
  this.handlebars.registerHelper.apply(this.handlebars, arguments);
}

/**
 * Register partial with internal handlebars instance
 */

Hbs.prototype.registerPartial = function() {
  this.handlebars.registerPartial.apply(this.handlebars, arguments);
}

/**
 * Register directory of partials
 */

Hbs.prototype.registerPartials = function () {
  var self = this;

  if(this.partialsPath == '')
    throw new Error('registerPartials requires partialsPath');

  if(!(this.partialsPath instanceof Array))
    this.partialsPath = [this.partialsPath];

  /* thunk creator for readdirp */
  var readdir = function(root) {
    return function(done) {
      glob("**/*"+self.extname, {
        cwd: root,
      }, done);
    };
  };

  /* Read in partials and register them */
  return function *() {
    try {
      var resultList = yield self.partialsPath.map( readdir );
      var files = [];
      var names = [];

      // Generate list of files and template names
      resultList.forEach(function(result,i) {
        result.forEach(function(file) {
          files.push(path.join(self.partialsPath[i], file));
          names.push(file.slice(0,-1*self.extname.length));
        });
      });

      // Read all the partial from disk
      partials = yield files.map(read);
      for(var i=0; i!=partials.length; i++) {
        self.registerPartial(names[i], partials[i]);
      }

      self.partialsRegistered = true;
    } catch(e) {
      console.error('Error caught while registering partials');
      console.error(e);
    }

  };
};

/**
 * The contentFor helper delegates to here to populate block content
 */

Hbs.prototype.content = function(name, options, context) {
  // fetch block
  var block = this.blocks[name] || (this.blocks[name] = []);

  // render block and save for layout render
  block.push(options.fn(context));
}

/**
 * block helper delegates to this function to retreive content
 */

Hbs.prototype.block = function(name) {
  // val = block.toString
  var val = (this.blocks[name] || []).join('\n');

  return val;
}
<commit_msg>Fixing race conditions with clearing blocks<commit_after>var fs = require('fs');
var path = require('path');
var glob = require('glob');

/**
 * Shallow copy two objects into a new object
 *
 * Objects are merged from left to right. Thus, properties in objects further
 * to the right are preferred over those on the left.
 *
 * @param {object} obj1
 * @param {object} obj2
 * @returns {object}
 * @api private
 */

var merge = function (obj1, obj2) {
  var c = {};
  var keys = Object.keys(obj2);
  for(var i=0; i!==keys.length; i++) {
    c[keys[i]] = obj2[keys[i]];
  }

  keys = Object.keys(obj1);
  for(i=0; i!==keys.length; i++) {
    if (!c.hasOwnProperty(keys[i])) {
      c[keys[i]] = obj1[keys[i]];
    }
  }

  return c;
};

/* Capture the layout name; thanks express-hbs */
var rLayoutPattern = /{{!<\s+([A-Za-z0-9\._\-\/]+)\s*}}/;

/**
 * file reader returning a thunk
 * @param filename {String} Name of file to read
 */

var read = function (filename) {
  return function(done) {
    fs.readFile(filename, {encoding: 'utf8'}, done);
  };
};

/**
 * expose default instance of `Hbs`
 */

exports = module.exports = new Hbs();

/**
 * expose method to create additional instances of `Hbs`
 */

exports.create = function() {
  return new Hbs();
};

/**
 * Create new instance of `Hbs`
 *
 * @api public
 */

function Hbs() {
  if(!(this instanceof Hbs)) return new Hbs();

  this.handlebars = require('handlebars').create();

  this.Utils = this.handlebars.Utils;
  this.SafeString = this.handlebars.SafeString;
}

/**
 * Configure the instance.
 *
 * @api private
 */

Hbs.prototype.configure = function (options) {

  var self = this;

  if(!options.viewPath) throw new Error("must specify view path");

  // Attach options
  var options = options || {};
  this.viewPath = options.viewPath;
  this.handlebars = options.handlebars || this.handlebars;
  this.templateOptions = options.templateOptions || {};
  this.extname = options.extname || '.hbs';
  this.partialsPath = options.partialsPath || '';
  this.contentHelperName = options.contentHelperName || 'contentFor';
  this.blockHelperName = options.blockHelperName || 'block';
  this.defaultLayout = options.defaultLayout || '';
  this.layoutsPath = options.layoutsPath || '';
  this.locals = options.locals || {};
  this.disableTemplateCaching = options.disableTemplateCaching;

  this.partialsRegistered = false;

  // Cache templates and layouts
  this.cache = {};

  this.blocks = {};

  // block helper
  this.registerHelper(this.blockHelperName, function(name, options) {
    // instead of returning self.block(name), render the default content if no
    // block is given
    val = self.block(name);
    if(val == '' && typeof options.fn === 'function') val = options.fn(this);

    return val;
  })

  // contentFor helper
  this.registerHelper(this.contentHelperName, function(name, options) {
    return self.content(name, options, this);
  })

  return this;
};

/**
 * Middleware for koa
 *
 * @api public
 */

Hbs.prototype.middleware = function(options) {
  this.configure(options);

  var render = this.createRenderer();

  return function *(next) {
    this.render = render;
    yield next;
  };
}

/**
 * Create a render generator to be attached to koa context
 */

Hbs.prototype.createRenderer = function() {
  var hbs = this;

  return function *(tpl, locals, templateOptions) {
    var tplPath = path.join(hbs.viewPath, tpl + hbs.extname),
      template, rawTemplate, layoutTemplate;

    locals = merge(hbs.locals, locals || {});
    templateOptions = merge(hbs.templateOptions, templateOptions || {});

    // conditionally clear cache
    if (hbs.disableTemplateCaching) hbs.cache = {};

    // Initialization... move these actions into another function to remove
    // unnecessary checks
    if((!hbs.partialsRegistered || hbs.disableTemplateCaching) && hbs.partialsPath !== '')
      yield hbs.registerPartials();

    if(!hbs.layoutTemplate)
      hbs.layoutTemplate = yield hbs.cacheLayout();

    // Load the template
    if(!hbs.cache[tpl]) {
      rawTemplate = yield read(tplPath);
      hbs.cache[tpl] = {
        template: hbs.handlebars.compile(rawTemplate)
      };

      // Load layout if specified
      if(rLayoutPattern.test(rawTemplate)) {
        var layout = rLayoutPattern.exec(rawTemplate)[1];
        var rawLayout = yield hbs.loadLayoutFile(layout);
        if (!hbs.cache[tpl]) hbs.cache[tpl] = {
          template: hbs.handlebars.compile(rawTemplate)
        };
        hbs.cache[tpl].layoutTemplate = hbs.handlebars.compile(rawLayout);
      }
    }

    template = hbs.cache[tpl].template;
    layoutTemplate = hbs.cache[tpl].layoutTemplate || hbs.layoutTemplate;

    // clear blocks, right before executing templates
    hbs.blocks = {};

    // Run the compiled templates
    locals.body = template(locals, templateOptions);
    this.body = layoutTemplate(locals, templateOptions);
  };
}

/**
 * Get layout path
 */

Hbs.prototype.getLayoutPath = function(layout) {
  if(this.layoutsPath)
    return path.join(this.layoutsPath, layout + this.extname);

  return path.join(this.viewPath, layout + this.extname);
}

/**
 * Get a default layout. If none is provided, make a noop
 */

Hbs.prototype.cacheLayout = function(layout) {
  var hbs = this;
  return function* () {
    // Create a default layout to always use
    if(!layout && !hbs.defaultLayout)
      return hbs.handlebars.compile("{{{body}}}");

    // Compile the default layout if one not passed
    if(!layout) layout = hbs.defaultLayout;

    var layoutTemplate;
    try {
      var rawLayout = yield hbs.loadLayoutFile(layout);
      layoutTemplate = hbs.handlebars.compile(rawLayout);
    } catch (err) {
      console.error(err.stack);
    }

    return layoutTemplate;
  };
}

/**
 * Load a layout file
 */

Hbs.prototype.loadLayoutFile = function(layout) {
  var hbs = this;
  return function(done) {
    var file = hbs.getLayoutPath(layout);
    read(file)(done);
  };
}

/**
 * Register helper to internal handlebars instance
 */

Hbs.prototype.registerHelper = function() {
  this.handlebars.registerHelper.apply(this.handlebars, arguments);
}

/**
 * Register partial with internal handlebars instance
 */

Hbs.prototype.registerPartial = function() {
  this.handlebars.registerPartial.apply(this.handlebars, arguments);
}

/**
 * Register directory of partials
 */

Hbs.prototype.registerPartials = function () {
  var self = this;

  if(this.partialsPath == '')
    throw new Error('registerPartials requires partialsPath');

  if(!(this.partialsPath instanceof Array))
    this.partialsPath = [this.partialsPath];

  /* thunk creator for readdirp */
  var readdir = function(root) {
    return function(done) {
      glob("**/*"+self.extname, {
        cwd: root,
      }, done);
    };
  };

  /* Read in partials and register them */
  return function *() {
    try {
      var resultList = yield self.partialsPath.map( readdir );
      var files = [];
      var names = [];

      // Generate list of files and template names
      resultList.forEach(function(result,i) {
        result.forEach(function(file) {
          files.push(path.join(self.partialsPath[i], file));
          names.push(file.slice(0,-1*self.extname.length));
        });
      });

      // Read all the partial from disk
      partials = yield files.map(read);
      for(var i=0; i!=partials.length; i++) {
        self.registerPartial(names[i], partials[i]);
      }

      self.partialsRegistered = true;
    } catch(e) {
      console.error('Error caught while registering partials');
      console.error(e);
    }

  };
};

/**
 * The contentFor helper delegates to here to populate block content
 */

Hbs.prototype.content = function(name, options, context) {
  // fetch block
  var block = this.blocks[name] || (this.blocks[name] = []);

  // render block and save for layout render
  block.push(options.fn(context));
}

/**
 * block helper delegates to this function to retreive content
 */

Hbs.prototype.block = function(name) {
  // val = block.toString
  var val = (this.blocks[name] || []).join('\n');

  return val;
}
<|endoftext|>


<commit_before>'use strict';

var util = require('util');
var chalk = require('chalk');
var typeOf = require('kind-of');
var Options = require('option-cache');
var omit = require('object.omit');
var pick = require('object.pick');
var get = require('get-value');
var _ = require('lodash');

/**
 * Expose `Cache`
 */

module.exports = Cache;

/**
 * Create a new instance of `Cache`
 *
 * ```js
 * var app = new Cache();
 * ```
 *
 * @class Cache
 * @param {Object} `cache` Optionally pass an object to initialize with.
 * @constructor
 * @api public
 */

function Cache(cache) {
  Options.call(this);
  this.cache = cache || {};
}

util.inherits(Cache, Options);

/**
 * Assign `value` to `key` or return the value of `key`.
 *
 * ```js
 * app.set(key, value);
 *
 * // extend
 * app.set({a: 'b'});
 * ```
 *
 * @param {String} `key`
 * @param {*} `value`
 * @return {Cache} for chaining
 * @api public
 */

Cache.prototype.set = function (key, value) {
  if (typeOf(key) === 'object') {
    _.extend(this.cache, key);
  } else {
    this.cache[key] = value;
  }
  return this;
};

/**
 * Return the stored value of `key`. If `key` is not defined,
 * the `cache` is returned.
 *
 * ```js
 * app.set('foo', 'bar');
 * app.get('foo');
 * // => "bar"
 * ```
 *
 * @param {String} `key`
 * @api public
 */

Cache.prototype.get = function (key) {
  if (!key) {
    return _.cloneDeep(this.cache);
  }
  if (key.indexOf('.') !== -1) {
    return get(this.cache, key, true);
  }
  return this.cache[key];
};

/*
 * Return `true` if the element exists. Dot notation
 * may be used for nested properties.
 *
 * **Example**
 *
 * ```js
 * app.exists('author.name');
 * //=> true
 * ```
 *
 * @param {String} `key`
 * @return {Boolean}
 * @api public
 */

Cache.prototype.exists = function(key) {
  if (this.hasOwn(key)) {
    return true;
  }
  return get(this.cache, key, true) !== undefined;
};

/**
 * Extend the `cache` with the given object.
 *
 * **Example**
 *
 * ```js
 * app
 *   .extend({a: 'b'}, {c: 'd'});
 *   .extend('e', {f: 'g'});
 * ```
 *
 * @chainable
 * @return {Object} `Cache` to enable chaining.
 * @api public
 */

Cache.prototype.extend = function(val) {
  var args = [].concat.apply([], arguments);

  if (typeof val === 'string') {
    var rest = args.slice(1);
    var o = this.get(val) || {};
    o = _.extend.apply(_, [o].concat(rest));
    this.cache[val] = o;
    return this;
  }

  _.extend.apply(_, [this.cache].concat(args));
  return this;
};

/**
 * Deep merge an object onto the `cache`.
 *
 * **Example**
 *
 * ```js
 * app.merge({a: {one: 'one'}}, {a: {two: 'two'}});
 * console.log(app.get('a'));
 * //=> {a: {one: 'one', two: 'two'}}
 * ```
 *
 * @chainable
 * @return {Object} `Cache` to enable chaining.
 * @api public
 */

Cache.prototype.merge = function(val) {
  var args = [].concat.apply([], arguments);

  if (typeof val === 'string') {
    var rest = args.slice(1);
    var o = this.get(val) || {};
    o = _.merge.apply(_, [o].concat(rest));
    this.cache[val] = o;
    return this;
  }

  _.merge.apply(_, [this.cache].concat(args));
  return this;
};

/**
 * Extend the cache with only the specified values from the given
 * object.
 *
 * ```js
 * var obj = {a: 'a', b: 'b', c: 'c'};
 * app.pick(obj, 'a');
 * //=> {a: 'a'}
 *
 * app.pick(obj, ['a', 'b']);
 * //=> {a: 'a', b: 'b'}
 * ```
 *
 * @param {String|Array} `key` The key(s) to pick from the object and extend onto `app.cache`
 * @api public
 */

Cache.prototype.pick = function(o, keys) {
  this.extend(pick(o, keys));
};

/**
 * Omit a property or array of properties from the cache
 *
 * ```js
 * app.omit('foo');
 * // or
 * app.omit(['foo', 'bar']);
 * ```
 *
 * @param {String|Array} `key` The key(s) to omit from the cache
 * @api public
 */

Cache.prototype.omit = function(keys) {
  this.cache = omit(this.cache, keys);
};

/**
 * Return the keys on `obj` or `this.cache`.
 *
 * ```js
 * app.forOwn();
 * ```
 *
 * @param {Object} `obj` Optionally pass an object.
 * @return {Array} Array of keys.
 * @api public
 */

Cache.prototype.forOwn = function (o, fn, thisArg) {
  if (typeof o === 'function') {
    thisArg = fn; fn = o; o = this.cache;
  }
  return _.forOwn(o, fn, thisArg || this);
};

/**
 * Return the keys on `obj` or `this.cache`.
 *
 *
 * ```js
 * app.keys();
 * ```
 *
 * @param {Object} `obj` Optionally pass an object.
 * @return {Array} Array of keys.
 * @api public
 */

Cache.prototype.keys = function (o) {
  return Object.keys(o || this.cache);
};

/**
 * Return an object of only the properties on `this.cache` or the given `obj`
 * that have function values.
 *
 * ```js
 * app.functions('foo')
 * //=> {set: [function], get: [function], functions: [function]}
 * ```
 *
 * @param {Object} `obj`
 * @return {Array}
 * @api public
 */

Cache.prototype.functions = function(o) {
  o = o || this.cache;
  var fns = [];

  _.forIn(o, function (val, key) {
    if (typeof val === 'function') {
      fns[key] = val;
    }
  });

  return fns;
};

/**
 * Return true if a deep property is on the given object or
 * `this.cache`.
 *
 * ```js
 * app.has('a.b.c');
 * ```
 *
 * @param {Object} `obj` Optionally pass an object.
 * @return {String} `lookup` Prop string to use for the lookup, e.g. `a.b`
 * @api public
 */

Cache.prototype.has = function (val, lookup) {
  if (arguments.length === 1 && typeof val === 'string') {
    return get(this.cache, val) !== undefined;
  }
  return get(val, lookup) !== undefined;
};

/**
 * Return true if `key` is an own, enumerable property
 * of `this.cache` or the given `obj`.
 *
 * ```js
 * app.hasOwn(key);
 * // or
 * app.hasOwn(obj, key);
 * ```
 *
 * @param  {String} `key`
 * @param  {Object} `obj` Optionally pass an object to check.
 * @return {Boolean}
 * @api public
 */

Cache.prototype.hasOwn = function (o, key) {
  if (typeof o === 'string') {
    key = o; o = this.cache;
  }
  return {}.hasOwnProperty.call(o, key);
};

/**
 * Clone the given `obj` or `cache`.
 *
 * ```js
 * app.clone();
 * ```
 *
 * @param  {Object} `obj` Optionally pass an object to clone.
 * @return {Boolean}
 * @api public
 */

Cache.prototype.clone = function(o) {
  return _.cloneDeep(o || this.cache);
};

/**
 * Remove `key` from the cache, or if no value is
 * specified the entire cache is reset.
 *
 * **Example:**
 *
 * ```js
 * app.clear();
 * ```
 *
 * @param {String} `key` The property to remove.
 * @api public
 */

Cache.prototype.clear = function (key) {
  if (key) {
    delete this.cache[key];
  } else {
    this.cache = {};
  }
};<commit_msg>get rid of deps<commit_after>'use strict';

var util = require('util');
var typeOf = require('kind-of');
var Options = require('option-cache');
var get = require('get-value');
var _ = require('lodash');

/**
 * Expose `Cache`
 */

module.exports = Cache;

/**
 * Create a new instance of `Cache`
 *
 * ```js
 * var app = new Cache();
 * ```
 *
 * @class Cache
 * @param {Object} `cache` Optionally pass an object to initialize with.
 * @constructor
 * @api public
 */

function Cache(cache) {
  Options.call(this);
  this.cache = cache || {};
}

util.inherits(Cache, Options);

/**
 * Assign `value` to `key` or return the value of `key`.
 *
 * ```js
 * app.set(key, value);
 *
 * // extend
 * app.set({a: 'b'});
 * ```
 *
 * @param {String} `key`
 * @param {*} `value`
 * @return {Cache} for chaining
 * @api public
 */

Cache.prototype.set = function (key, value) {
  if (typeOf(key) === 'object') {
    _.extend(this.cache, key);
  } else {
    this.cache[key] = value;
  }
  return this;
};

/**
 * Return the stored value of `key`. If `key` is not defined,
 * the `cache` is returned.
 *
 * ```js
 * app.set('foo', 'bar');
 * app.get('foo');
 * // => "bar"
 * ```
 *
 * @param {String} `key`
 * @api public
 */

Cache.prototype.get = function (key) {
  if (!key) return this.clone();

  if (key.indexOf('.') !== -1) {
    return get(this.cache, key, true);
  }
  return this.cache[key];
};

/*
 * Return `true` if the element exists. Dot notation
 * may be used for nested properties.
 *
 * ```js
 * app.exists('author.name');
 * //=> true
 * ```
 *
 * @param {String} `key`
 * @return {Boolean}
 * @api public
 */

Cache.prototype.exists = function(key) {
  if (this.hasOwn(key)) {
    return true;
  }
  return get(this.cache, key, true) !== undefined;
};

/**
 * Extend the `cache` with the given object.
 *
 * ```js
 * app
 *   .extend({a: 'b'}, {c: 'd'});
 *   .extend('e', {f: 'g'});
 * ```
 *
 * @chainable
 * @return {Object} `Cache` to enable chaining.
 * @api public
 */

Cache.prototype.extend = function(val) {
  var args = [].concat.apply([], arguments);

  if (typeof val === 'string') {
    var rest = args.slice(1);
    var o = this.get(val) || {};
    o = extend(o, rest);
    this.cache[val] = o;
  } else {
    extend(this.cache, args);
  }

  return this;
};

/**
 * Deep merge an object onto the `cache`.
 *
 * ```js
 * app.merge({a: {one: 'one'}}, {a: {two: 'two'}});
 * console.log(app.get('a'));
 * //=> {a: {one: 'one', two: 'two'}}
 * ```
 *
 * @chainable
 * @return {Object} `Cache` to enable chaining.
 * @api public
 */

Cache.prototype.merge = function(val) {
  var args = [].concat.apply([], arguments);

  if (typeof val === 'string') {
    var rest = args.slice(1);
    var o = this.get(val) || {};
    o = merge(o, rest);
    this.cache[val] = o;
  } else {
    merge(this.cache, args);
  }

  return this;
};

/**
 * Extend the cache with only the specified values from the given
 * object.
 *
 * ```js
 * var obj = {a: 'a', b: 'b', c: 'c'};
 * app.pick(obj, 'a');
 * //=> {a: 'a'}
 *
 * app.pick(obj, ['a', 'b']);
 * //=> {a: 'a', b: 'b'}
 * ```
 *
 * @param {String|Array} `key` The key(s) to pick from the object and extend onto `app.cache`
 * @api public
 */

Cache.prototype.pick = function(o, keys) {
  this.extend(_.pick(o, keys));
};

/**
 * Omit a property or array of properties from the cache
 *
 * ```js
 * app.omit('foo');
 * // or
 * app.omit(['foo', 'bar']);
 * ```
 *
 * @param {String|Array} `key` The key(s) to omit from the cache
 * @api public
 */

Cache.prototype.omit = function(keys) {
  this.cache = _.omit(this.cache, keys);
};

/**
 * Return the keys on `obj` or `this.cache`.
 *
 * ```js
 * app.forOwn();
 * ```
 *
 * @param {Object} `obj` Optionally pass an object.
 * @return {Array} Array of keys.
 * @api public
 */

Cache.prototype.forOwn = function (o, fn, thisArg) {
  if (typeof o === 'function') {
    thisArg = fn; fn = o; o = this.cache;
  }
  return _.forOwn(o, fn, thisArg || this);
};

/**
 * Return the keys on `obj` or `this.cache`.
 *
 *
 * ```js
 * app.keys();
 * ```
 *
 * @param {Object} `obj` Optionally pass an object.
 * @return {Array} Array of keys.
 * @api public
 */

Cache.prototype.keys = function (o) {
  return Object.keys(o || this.cache);
};

/**
 * Return an object of only the properties on `this.cache` or the given `obj`
 * that have function values.
 *
 * ```js
 * app.functions('foo')
 * //=> {set: [function], get: [function], functions: [function]}
 * ```
 *
 * @param {Object} `obj`
 * @return {Array}
 * @api public
 */

Cache.prototype.functions = function(o) {
  o = o || this.cache;
  var fns = [];

  _.forIn(o, function (val, key) {
    if (typeof val === 'function') {
      fns[key] = val;
    }
  });

  return fns;
};

/**
 * Return true if a deep property is on the given object or
 * `this.cache`.
 *
 * ```js
 * app.has('a.b.c');
 * ```
 *
 * @param {Object} `obj` Optionally pass an object.
 * @return {String} `lookup` Prop string to use for the lookup, e.g. `a.b`
 * @api public
 */

Cache.prototype.has = function (val, lookup) {
  if (arguments.length === 1 && typeof val === 'string') {
    return get(this.cache, val) !== undefined;
  }
  return get(val, lookup) !== undefined;
};

/**
 * Return true if `key` is an own, enumerable property
 * of `this.cache` or the given `obj`.
 *
 * ```js
 * app.hasOwn(key);
 * // or
 * app.hasOwn(obj, key);
 * ```
 *
 * @param  {String} `key`
 * @param  {Object} `obj` Optionally pass an object to check.
 * @return {Boolean}
 * @api public
 */

Cache.prototype.hasOwn = function (o, key) {
  if (typeof o === 'string') {
    key = o; o = this.cache;
  }
  return {}.hasOwnProperty.call(o, key);
};

/**
 * Clone the given `obj` or `cache`.
 *
 * ```js
 * app.clone();
 * ```
 *
 * @param  {Object} `obj` Optionally pass an object to clone.
 * @return {Boolean}
 * @api public
 */

Cache.prototype.clone = function(o) {
  return _.cloneDeep(o || this.cache);
};

/**
 * Remove `key` from the cache, or if no value is
 * specified the entire cache is reset.
 *
 * **Example:**
 *
 * ```js
 * app.clear();
 * ```
 *
 * @param {String} `key` The property to remove.
 * @api public
 */

Cache.prototype.clear = function (key) {
  if (key) {
    delete this.cache[key];
  } else {
    this.cache = {};
  }
};

/**
 * Utils
 */

function extend(o, objects) {
  return _.extend.apply(_, [o].concat(objects));
}

function merge(o, objects) {
  return _.merge.apply(_, [o].concat(objects));
}

function union () {
  return [].concat.apply([], arguments);
}
<|endoftext|>


<commit_before>var multiparty = require('multiparty');
var fs = require('fs.extra');
var path = require('path');
var _ = require('underscore');

var steghide = require('./steghide');

/**
 * Build a request handler around steghide embed
 *
 * @param options: Object the settings to use for the request handler. Expects
 *   an object with zero or more of the following keys. The format for the below
 *   is `name`: type (default).
 *
 *    - `uploadDir`: String (`/tmp/stegosaurus`) the path under which to store
 *      temporary files
 *    - `imageFileParamName`: String (`coverImage`) the name of the HTTP query
 *      parameter containing the cover image data
 *    - `messageFileParamName`: String (`secretFile`) the name of the HTTP
 *      query parameter containing the message file data
 *    - `extractionPasswordParamName`: String (`extractionPassword`) the name of the
 *      HTTP query parameter containing the extraction password
 *    - `responseFileNamePrefix`: String (`steghidden-`) the prefix to prepend
 *      to the uploaded image file name for the result file
 */
module.exports.embedHandler = function(options) {
  options = options || {};
  _.defaults(options, {
    uploadDir: '/tmp/stegosaurus',
    imageFileParamName: 'coverImage',
    messageFileParamName: 'secretFile',
    extractionPasswordParamName: 'extractionPassword',
    responseFileNamePrefix: 'steghidden-',
  });

  fs.mkdirp(options.uploadDir);

  return function(req, res) {
    var form = new multiparty.Form({
      uploadDir: options.uploadDir,
    });

    form.parse(req, function(err, fields, files) {
      if(err) {
        res.status(401).send('401 Bad request');
        console.log('Bad request', err);
        return false;
      }
      var imageFile = files[options.imageFileParamName][0];
      var secretFile = files[options.messageFileParamName][0];

      var imagePath = imageFile.path;
      var secretPath = secretFile.path;
      var secretDir = secretPath + '.d';

      var prettySecretPath = path.join(secretDir, path.basename(secretFile.originalFilename));

      fs.mkdirSync(secretDir);
      fs.move(secretPath, prettySecretPath, function(err) {
        if(err) {
          res.status(503).send('503 Internal server error');
          console.log(err);
          return false;
        }

        var steghiddenPath = steghide.embed(
          imagePath,
          prettySecretPath,
          fields[options.extractionPasswordParamName][0]
        );

        function cleanup() {
          _([imagePath, secretPath, secretDir, steghiddenPath]).each(function(path) { fs.rmrfSync(path); });
        }

        res.download(steghiddenPath, options.responseFileNamePrefix + imageFile.originalFilename, cleanup);
      });
    });
  }
};

module.exports.extractHandler = function(options) {
  options = options || {};
  _.defaults(options, {
    uploadDir: '/tmp/stegosaurus',
    imageFileParamName: 'stegoImage',
    extractionPasswordParamName: 'extractionPassword',
  });

  fs.mkdirp(options.uploadDir);

  return function(req, res) {
    var form = new multiparty.Form({
      uploadDir: options.uploadDir,
    });

    form.parse(req, function(err, fields, files) {
      if(err) {
        res.status(401).send('401 Bad request');
        console.log('Bad request', err);
        return false;
      }
      var imageFile = files[options.imageFileParamName][0];

      var imagePath = imageFile.path;

      steghide.extract(
        imagePath,
        fields[options.extractionPasswordParamName][0],
        function(extractedPath, steghideCleanup) {
          function cleanup() {
            _([imagePath, extractedPath]).each(function(path) { fs.rmrfSync(path); });
            steghideCleanup();
          }

          res.download(extractedPath, path.basename(extractedPath), cleanup);
        }
      );
    });
  }
};
<commit_msg>Add docstring to stegosaurus.extractHandler<commit_after>var multiparty = require('multiparty');
var fs = require('fs.extra');
var path = require('path');
var _ = require('underscore');

var steghide = require('./steghide');

/**
 * Build a request handler around steghide embed
 *
 * @param options: Object the settings to use for the request handler. Expects
 *   an object with zero or more of the following keys. The format for the below
 *   is `name`: type (default).
 *
 *    - `uploadDir`: String (`/tmp/stegosaurus`) the path under which to store
 *      temporary files
 *    - `imageFileParamName`: String (`coverImage`) the name of the HTTP query
 *      parameter containing the cover image data
 *    - `messageFileParamName`: String (`secretFile`) the name of the HTTP
 *      query parameter containing the message file data
 *    - `extractionPasswordParamName`: String (`extractionPassword`) the name of the
 *      HTTP query parameter containing the extraction password
 *    - `responseFileNamePrefix`: String (`steghidden-`) the prefix to prepend
 *      to the uploaded image file name for the result file
 */
module.exports.embedHandler = function(options) {
  options = options || {};
  _.defaults(options, {
    uploadDir: '/tmp/stegosaurus',
    imageFileParamName: 'coverImage',
    messageFileParamName: 'secretFile',
    extractionPasswordParamName: 'extractionPassword',
    responseFileNamePrefix: 'steghidden-',
  });

  fs.mkdirp(options.uploadDir);

  return function(req, res) {
    var form = new multiparty.Form({
      uploadDir: options.uploadDir,
    });

    form.parse(req, function(err, fields, files) {
      if(err) {
        res.status(401).send('401 Bad request');
        console.log('Bad request', err);
        return false;
      }
      var imageFile = files[options.imageFileParamName][0];
      var secretFile = files[options.messageFileParamName][0];

      var imagePath = imageFile.path;
      var secretPath = secretFile.path;
      var secretDir = secretPath + '.d';

      var prettySecretPath = path.join(secretDir, path.basename(secretFile.originalFilename));

      fs.mkdirSync(secretDir);
      fs.move(secretPath, prettySecretPath, function(err) {
        if(err) {
          res.status(503).send('503 Internal server error');
          console.log(err);
          return false;
        }

        var steghiddenPath = steghide.embed(
          imagePath,
          prettySecretPath,
          fields[options.extractionPasswordParamName][0]
        );

        function cleanup() {
          _([imagePath, secretPath, secretDir, steghiddenPath]).each(function(path) { fs.rmrfSync(path); });
        }

        res.download(steghiddenPath, options.responseFileNamePrefix + imageFile.originalFilename, cleanup);
      });
    });
  }
};

/**
 * Build a request handler around steghide extract
 *
 * @param options: Object the settings to use for the request handler. Expects
 *   an object with zero or more of the following keys. The format for the below
 *   is `name`: type (default).
 *
 *    - `uploadDir`: String (`/tmp/stegosaurus`) the path under which to store
 *      temporary files
 *    - `imageFileParamName`: String (`stegoImage`) the name of the HTTP query
 *      parameter containing the image data with the hidden file
 *    - `extractionPasswordParamName`: String (`extractionPassword`) the name
 *      of the HTTP query parameter containing the extraction password
 */
module.exports.extractHandler = function(options) {
  options = options || {};
  _.defaults(options, {
    uploadDir: '/tmp/stegosaurus',
    imageFileParamName: 'stegoImage',
    extractionPasswordParamName: 'extractionPassword',
  });

  fs.mkdirp(options.uploadDir);

  return function(req, res) {
    var form = new multiparty.Form({
      uploadDir: options.uploadDir,
    });

    form.parse(req, function(err, fields, files) {
      if(err) {
        res.status(401).send('401 Bad request');
        console.log('Bad request', err);
        return false;
      }
      var imageFile = files[options.imageFileParamName][0];

      var imagePath = imageFile.path;

      steghide.extract(
        imagePath,
        fields[options.extractionPasswordParamName][0],
        function(extractedPath, steghideCleanup) {
          function cleanup() {
            _([imagePath, extractedPath]).each(function(path) { fs.rmrfSync(path); });
            steghideCleanup();
          }

          res.download(extractedPath, path.basename(extractedPath), cleanup);
        }
      );
    });
  }
};
<|endoftext|>


<commit_before>var express = require('express');
var arduino = require('duino');
var board = new arduino.Board({
  debug: true
});
var app = express();

var SerialPort = require("serialport").SerialPort;
var serialPort = new SerialPort("/dev/tty.usbserial-A400fNZR", {
  baudrate: 9600
}, false); // this is the openImmediately flag [default is true]

serialPort.open(function () {
  console.log('open');
  serialPort.on('data', function(data) {
    console.log('data received: ' + data);
  });

  app.get('/on', function(req, res) {
    serialPort.write("1", function(err, results) {
      console.log('err ' + err);
      console.log('results ' + results);
      console.log( results);
    });
    res.end();
  });

  app.get('/off', function(req, res) {
    serialPort.write("0", function(err, results) {
      console.log('err ' + err);
      console.log('results ' + results);
      console.log( results);
    });
    res.end();
    });
});

app.listen(3000);
console.log('Listening on port 3000...');<commit_msg>app working<commit_after>var express = require('express');
var app = express();

var SerialPort = require("serialport").SerialPort;
var serialPort = new SerialPort("/dev/tty.usbserial-A400fNZR", {
  baudrate: 9600
}, false); // this is the openImmediately flag [default is true]

serialPort.open(function () {
  console.log('open');
  serialPort.on('data', function(data) {
    console.log('data received: ' + data);
  });

  app.get('/on', function(req, res) {
    serialPort.write("1", function(err, results) {
      console.log('err ' + err);
      console.log('results ' + results);
      console.log( results);
    });
    res.end();
  });

  app.get('/off', function(req, res) {
    serialPort.write("0", function(err, results) {
      console.log('err ' + err);
      console.log('results ' + results);
      console.log( results);
    });
    res.end();
    });
});

app.listen(3000);
console.log('Listening on port 3000...');<|endoftext|>


<commit_before>#!/usr/bin/env node

var AWS = require('aws-sdk');
var http = require('http');
var httpProxy = require('http-proxy');
var express = require('express');
var bodyParser = require('body-parser');
var stream = require('stream');
var figlet = require('figlet');
var basicAuth = require('basic-auth-connect');
var compress = require('compression');

var yargs = require('yargs')
    .usage('usage: $0 [options] <aws-es-cluster-endpoint>')
    .option('b', {
        alias: 'bind-address',
        default: process.env.BIND_ADDRESS || '127.0.0.1',
        demand: false,
        describe: 'the ip address to bind to',
        type: 'string'
    })
    .option('p', {
        alias: 'port',
        default: process.env.PORT || 9200,
        demand: false,
        describe: 'the port to bind to',
        type: 'number'
    })
    .option('r', {
        alias: 'region',
        default: process.env.REGION,
        demand: false,
        describe: 'the region of the Elasticsearch cluster',
        type: 'string'
    })
    .option('u', {
      alias: 'user',
      default: process.env.USER,
      demand: false,
      describe: 'the username to access the proxy'
    })
    .option('a', {
      alias: 'password',
      default: process.env.PASSWORD,
      demand: false,
      describe: 'the password to access the proxy'
    })
    .option('s', {
      alias: 'silent',
      default: false,
      demand: false,
      describe: 'remove figlet banner'
    })
    .option('H', {
        alias: 'health-path',
        default: process.env.HEALTH_PATH,
        demand: false,
        describe: 'URI path for health check',
        type: 'string'
    })
    .option('l', {
      alias: 'limit',
      default: process.env.LIMIT || '1kb',
      demand: false,
      describe: 'request limit'
    })
    .help()
    .version()
    .strict();
var argv = yargs.argv;

var ENDPOINT = process.env.ENDPOINT || argv._[0];

if (!ENDPOINT) {
    yargs.showHelp();
    process.exit(1);
}

// Try to infer the region if it is not provided as an argument.
var REGION = argv.r;
if (!REGION) {
    var m = ENDPOINT.match(/\.([^.]+)\.es\.amazonaws\.com\.?$/);
    if (m) {
        REGION = m[1];
    } else {
        console.error('region cannot be parsed from endpoint address, either the endpoint must end ' +
                      'in .<region>.es.amazonaws.com or --region should be provided as an argument');
        yargs.showHelp();
        process.exit(1);
    }
}

var TARGET = process.env.ENDPOINT || argv._[0];
if (!TARGET.match(/^https?:\/\//)) {
    TARGET = 'https://' + TARGET;
}

var BIND_ADDRESS = argv.b;
var PORT = argv.p;
var REQ_LIMIT = argv.l;

var credentials;
var chain = new AWS.CredentialProviderChain();
chain.resolve(function (err, resolved) {
    if (err) throw err;
    else credentials = resolved;
});

function getCredentials(req, res, next) {
    return credentials.get(function (err) {
        if (err) return next(err);
        else return next();
    });
}
var proxy = httpProxy.createProxyServer({
    target: TARGET,
    changeOrigin: true,
    secure: true
});

var app = express();
app.use(compress());
if (argv.u && argv.a) {
  app.use(basicAuth(argv.u, argv.a));
}
app.use(bodyParser.raw({limit: REQ_LIMIT, type: function() { return true; }}));
app.use(getCredentials);

if (argv.H) {
    app.get(argv.H, function (req, res) {
        res.setHeader('Content-Type', 'text/plain');
        res.send('ok');
    });
}

app.use(function (req, res) {
    var bufferStream;
    if (Buffer.isBuffer(req.body)) {
        var bufferStream = new stream.PassThrough();
        bufferStream.end(req.body);
    }
    proxy.web(req, res, {buffer: bufferStream});
});

proxy.on('proxyReq', function (proxyReq, req) {
    var endpoint = new AWS.Endpoint(ENDPOINT);
    var request = new AWS.HttpRequest(endpoint);
    request.method = proxyReq.method;
    request.path = proxyReq.path;
    request.region = REGION;
    if (Buffer.isBuffer(req.body)) request.body = req.body;
    if (!request.headers) request.headers = {};
    request.headers['presigned-expires'] = false;
    request.headers['Host'] = endpoint.hostname;

    var signer = new AWS.Signers.V4(request, 'es');
    signer.addAuthorization(credentials, new Date());

    proxyReq.setHeader('Host', request.headers['Host']);
    proxyReq.setHeader('X-Amz-Date', request.headers['X-Amz-Date']);
    proxyReq.setHeader('Authorization', request.headers['Authorization']);
    if (request.headers['x-amz-security-token']) proxyReq.setHeader('x-amz-security-token', request.headers['x-amz-security-token']);
});

proxy.on('proxyRes', function (proxyReq, req, res) {
    if (req.url.match(/\.(css|js|img|font)/)) {
        res.setHeader('Cache-Control', 'public, max-age=86400');
    }
});

http.createServer(app).listen(PORT, BIND_ADDRESS);

if(!argv.s) {
    console.log(figlet.textSync('AWS ES Proxy!', {
        font: 'Speed',
        horizontalLayout: 'default',
        verticalLayout: 'default'
    }));
}

console.log('AWS ES cluster available at http://' + BIND_ADDRESS + ':' + PORT);
console.log('Kibana available at http://' + BIND_ADDRESS + ':' + PORT + '/_plugin/kibana/');
if (argv.H) {
    console.log('Health endpoint enabled at http://' + BIND_ADDRESS + ':' + PORT + argv.H);
}
<commit_msg>Adding profile support.<commit_after>#!/usr/bin/env node

var AWS = require('aws-sdk');
var http = require('http');
var httpProxy = require('http-proxy');
var express = require('express');
var bodyParser = require('body-parser');
var stream = require('stream');
var figlet = require('figlet');
var basicAuth = require('basic-auth-connect');
var compress = require('compression');

var yargs = require('yargs')
    .usage('usage: $0 [options] <aws-es-cluster-endpoint>')
    .option('b', {
        alias: 'bind-address',
        default: process.env.BIND_ADDRESS || '127.0.0.1',
        demand: false,
        describe: 'the ip address to bind to',
        type: 'string'
    })
    .option('p', {
        alias: 'port',
        default: process.env.PORT || 9200,
        demand: false,
        describe: 'the port to bind to',
        type: 'number'
    })
    .option('r', {
        alias: 'region',
        default: process.env.REGION,
        demand: false,
        describe: 'the region of the Elasticsearch cluster',
        type: 'string'
    })
    .option('u', {
      alias: 'user',
      default: process.env.USER,
      demand: false,
      describe: 'the username to access the proxy'
    })
    .option('a', {
      alias: 'password',
      default: process.env.PASSWORD,
      demand: false,
      describe: 'the password to access the proxy'
    })
    .option('s', {
      alias: 'silent',
      default: false,
      demand: false,
      describe: 'remove figlet banner'
    })
    .option('H', {
        alias: 'health-path',
        default: process.env.HEALTH_PATH,
        demand: false,
        describe: 'URI path for health check',
        type: 'string'
    })
    .option('l', {
      alias: 'limit',
      default: process.env.LIMIT || '1kb',
      demand: false,
      describe: 'request limit'
    })
    .help()
    .version()
    .strict();
var argv = yargs.argv;

var ENDPOINT = process.env.ENDPOINT || argv._[0];

if (!ENDPOINT) {
    yargs.showHelp();
    process.exit(1);
}

// Try to infer the region if it is not provided as an argument.
var REGION = argv.r;
if (!REGION) {
    var m = ENDPOINT.match(/\.([^.]+)\.es\.amazonaws\.com\.?$/);
    if (m) {
        REGION = m[1];
    } else {
        console.error('region cannot be parsed from endpoint address, either the endpoint must end ' +
                      'in .<region>.es.amazonaws.com or --region should be provided as an argument');
        yargs.showHelp();
        process.exit(1);
    }
}

var TARGET = process.env.ENDPOINT || argv._[0];
if (!TARGET.match(/^https?:\/\//)) {
    TARGET = 'https://' + TARGET;
}

var BIND_ADDRESS = argv.b;
var PORT = argv.p;
var REQ_LIMIT = argv.l;

var credentials;

var PROFILE = process.env.AWS_PROFILE;

if (!PROFILE) {
    var chain = new AWS.CredentialProviderChain();
    chain.resolve(function (err, resolved) {
        if (err) throw err;
        else credentials = resolved;
    });
} else {
    credentials = new AWS.SharedIniFileCredentials({profile: PROFILE});
    AWS.config.credentials = credentials;
}

function getCredentials(req, res, next) {
    return credentials.get(function (err) {
        if (err) return next(err);
        else return next();
    });
}
var proxy = httpProxy.createProxyServer({
    target: TARGET,
    changeOrigin: true,
    secure: true
});

var app = express();
app.use(compress());
if (argv.u && argv.a) {
  app.use(basicAuth(argv.u, argv.a));
}
app.use(bodyParser.raw({limit: REQ_LIMIT, type: function() { return true; }}));
app.use(getCredentials);

if (argv.H) {
    app.get(argv.H, function (req, res) {
        res.setHeader('Content-Type', 'text/plain');
        res.send('ok');
    });
}

app.use(function (req, res) {
    var bufferStream;
    if (Buffer.isBuffer(req.body)) {
        var bufferStream = new stream.PassThrough();
        bufferStream.end(req.body);
    }
    proxy.web(req, res, {buffer: bufferStream});
});

proxy.on('proxyReq', function (proxyReq, req) {
    var endpoint = new AWS.Endpoint(ENDPOINT);
    var request = new AWS.HttpRequest(endpoint);
    request.method = proxyReq.method;
    request.path = proxyReq.path;
    request.region = REGION;
    if (Buffer.isBuffer(req.body)) request.body = req.body;
    if (!request.headers) request.headers = {};
    request.headers['presigned-expires'] = false;
    request.headers['Host'] = endpoint.hostname;

    var signer = new AWS.Signers.V4(request, 'es');
    signer.addAuthorization(credentials, new Date());

    proxyReq.setHeader('Host', request.headers['Host']);
    proxyReq.setHeader('X-Amz-Date', request.headers['X-Amz-Date']);
    proxyReq.setHeader('Authorization', request.headers['Authorization']);
    if (request.headers['x-amz-security-token']) proxyReq.setHeader('x-amz-security-token', request.headers['x-amz-security-token']);
});

proxy.on('proxyRes', function (proxyReq, req, res) {
    if (req.url.match(/\.(css|js|img|font)/)) {
        res.setHeader('Cache-Control', 'public, max-age=86400');
    }
});

http.createServer(app).listen(PORT, BIND_ADDRESS);

if(!argv.s) {
    console.log(figlet.textSync('AWS ES Proxy!', {
        font: 'Speed',
        horizontalLayout: 'default',
        verticalLayout: 'default'
    }));
}

console.log('AWS ES cluster available at http://' + BIND_ADDRESS + ':' + PORT);
console.log('Kibana available at http://' + BIND_ADDRESS + ':' + PORT + '/_plugin/kibana/');
if (argv.H) {
    console.log('Health endpoint enabled at http://' + BIND_ADDRESS + ':' + PORT + argv.H);
}
<|endoftext|>


<commit_before>'use strict';

(function(){

const ncp = require('copy-paste-win32fix');
const ago = require('s-ago');
const eskape = require('eskape');

const MAX_CLIPS = 30;
const POLL_INTERVAL_MS = 3000;
const CLIP_DISPLAY_MAX_CHARS = 100;
const PREVIEW_HTML = (text) => eskape`
    <!doctype html>

${text}

    `;

module.exports = (context) => {
    const app = context.app;
    const toast = context.toast;
    const matchutil = context.matchutil;

    const clips = [];
    let lastClips;  // a shallow copy of `clips`, kept between search/execute

    function abbr(num) {
        if (num >= 1000000) {
            return `${num/1000000}m`;
        } else if (num >= 1000) {
            return `${num/1000}k`;
        } else {
            return num;
        }
    }

    function startup() {
        var lastClip = null;
        var saveClipFn;
        setInterval(saveClipFn = () => {
            ncp.paste((err, clip) => {
                if (err) return;
                if (typeof clip !== 'string'
                        || ! clip.trim().length
                        || lastClip === clip) {
                    return;
                }
                clip = clip.toString();
                clips.unshift({
                    content: lastClip = clip,
                    size: clip.length,
                    time: new Date()
                });
                if (clips.length > MAX_CLIPS) {
                    clips.pop();
                }
            });
        }, POLL_INTERVAL_MS);
        saveClipFn();
    }

    function search(query, res) {
        const querytrim = query.replace(' ', '');
        let results;
        lastClips = clips.concat();  // shallow copy
        if (querytrim.length) {
            results = matchutil.fuzzy(clips, querytrim, x => x.content);
        } else {
            results = clips;
            res.add([{
                id: 'clear',
                payload: 'clear',
                title: 'Clear this list',
                icon: '#fa fa-trash',
                desc: ''
            }]);
        }
        res.add(results.map((clip, idx) => {
            let title, isTrimmed;
            if (clip.elem) {
                // fuzzy match
                const trimmed = clip.elem.content.trim().substr(0, CLIP_DISPLAY_MAX_CHARS);
                if (CLIP_DISPLAY_MAX_CHARS === trimmed.length) {
                    title = trimmed;  // no bold - it looks strange when trimmed
                } else {
                    title = matchutil.makeStringBoldHtml(trimmed, clip.matches);
                }
                idx = clips.indexOf(clip = clip.elem);
            } else {
                // normal result
                title = clip.content.substr(0, CLIP_DISPLAY_MAX_CHARS);
            }
            isTrimmed = CLIP_DISPLAY_MAX_CHARS === title.length;

            // TODO: remove hack to escape html but keep bolds
            title = title.replace(//gi, '%%B%%');
            title = title.replace(/<\/b>/gi, '%%EB%%');
            title = title.replace(/&/g, '&');
            title = title.replace(/</g, '<');
            title = title.replace(/%%B%%/g, '');
            title = title.replace(/%%EB%%/g, '');

            if (isTrimmed) {
                title += '…';
            }
            return {
                id: idx,
                payload: '',
                title: title.replace(/[\r\n]/g, ''),
                icon: '#fa fa-clipboard',
                desc: `Copy to clipboard (${abbr(clip.size)} characters, ${ago(clip.time)})`,
                preview: isTrimmed
            };
        }));
    }

    function execute(id, payload) {
        if (payload === 'clear') {
            clips.length = lastClips.length = 0;
            toast.enqueue('Clipboard history cleared!');
            setTimeout(() => {
                app.close();
            }, 1000);
        } else {
            ncp.copy(lastClips[id].content, () => {
                app.close();
            });
        }
    }

    function renderPreview(id, payload, render) {
        if (payload.length) return;
        render(PREVIEW_HTML(lastClips[id].content));
    }

    return { startup, search, execute, renderPreview };
};

})();
<commit_msg>Using singleLine to display titles in new API versions<commit_after>'use strict';

(function(){

const ncp = require('copy-paste-win32fix');
const ago = require('s-ago');
const eskape = require('eskape');

const MAX_CLIPS = 30;
const POLL_INTERVAL_MS = 3000;
const DEFAULT_CLIP_DISPLAY_MAX_CHARS = 100;
const CLIP_PREVIEW_WHEN_MAX_CHARS = 100;
const PREVIEW_HTML = (text) => eskape`
    <!doctype html>

${text}

    `;

module.exports = (context) => {
    const CURRENT_API_VERSION = context.CURRENT_API_VERSION;

    const app = context.app;
    const toast = context.toast;
    const matchutil = context.matchutil;

    const isLegacyAPIVersion =
            ! CURRENT_API_VERSION || ['hain0', 'hain-0.1.0', 'hain-0.3.0', 'hain-0.4.0']
                                        .indexOf(CURRENT_API_VERSION) !== -1;

    const clips = [];
    let lastClips;  // a shallow copy of `clips`, kept between search/execute

    function abbr(num) {
        if (num >= 1000000) {
            return `${num/1000000}m`;
        } else if (num >= 1000) {
            return `${num/1000}k`;
        } else {
            return num;
        }
    }

    function startup() {
        var lastClip = null;
        var saveClipFn;
        setInterval(saveClipFn = () => {
            ncp.paste((err, clip) => {
                if (err) return;
                if (typeof clip !== 'string'
                        || ! clip.trim().length
                        || lastClip === clip) {
                    return;
                }
                clip = clip.toString();
                clips.unshift({
                    content: lastClip = clip,
                    size: clip.length,
                    time: new Date()
                });
                if (clips.length > MAX_CLIPS) {
                    clips.pop();
                }
            });
        }, POLL_INTERVAL_MS);
        saveClipFn();
    }

    function search(query, res) {
        const querytrim = query.replace(' ', '');
        let results;
        lastClips = clips.concat();  // shallow copy
        if (querytrim.length) {
            results = matchutil.fuzzy(clips, querytrim, x => x.content);
        } else {
            results = clips;
            res.add([{
                id: 'clear',
                payload: 'clear',
                title: 'Clear this list',
                icon: '#fa fa-trash'
            }]);
        }
        res.add(results.map((clip, idx) => {
            let title, isTrimmed, isPreviewable;

            // only trim down the string for old hain APIs
            const maxTitleCharsToDisplay = isLegacyAPIVersion ? DEFAULT_CLIP_DISPLAY_MAX_CHARS : 1024;

            if (clip.elem) {
                // fuzzy match
                const trimmed = clip.elem.content.trim();
                const clipped = trimmed.substr(0, maxTitleCharsToDisplay);
                isPreviewable = trimmed.length >= CLIP_PREVIEW_WHEN_MAX_CHARS;
                if (maxTitleCharsToDisplay === clipped.length) {
                    title = clipped;  // no bold - it looks strange when clipped
                } else {
                    title = matchutil.makeStringBoldHtml(clipped, clip.matches);
                }
                idx = clips.indexOf(clip = clip.elem);
            } else {
                // normal result
                title = clip.content.substr(0, maxTitleCharsToDisplay);
                isPreviewable = clip.content.length >= CLIP_PREVIEW_WHEN_MAX_CHARS;
            }
            isTrimmed = maxTitleCharsToDisplay === title.length;

            // TODO: remove hack to escape html but keep bolds
            title = title.replace(//gi, '%%B%%');
            title = title.replace(/<\/b>/gi, '%%EB%%');
            title = title.replace(/&/g, '&');
            title = title.replace(/</g, '<');
            title = title.replace(/%%B%%/g, '');
            title = title.replace(/%%EB%%/g, '');

            if (isTrimmed) {
                title += '…';
            }
            title = title.replace(/[\r\n]/g, '');

            return {
                id: idx,
                payload: '',
                title: isLegacyAPIVersion ? title : { singleLine: true, text: title },
                icon: '#fa fa-clipboard',
                desc: `Copy to clipboard (${abbr(clip.size)} characters, ${ago(clip.time)})`,
                preview: isPreviewable
            };
        }));
    }

    function execute(id, payload) {
        if (payload === 'clear') {
            clips.length = lastClips.length = 0;
            toast.enqueue('Clipboard history cleared!');
            setTimeout(() => {
                app.close();
            }, 1000);
        } else {
            ncp.copy(lastClips[id].content, () => {
                app.close();
            });
        }
    }

    function renderPreview(id, payload, render) {
        if (payload.length) return;
        render(PREVIEW_HTML(lastClips[id].content));
    }

    return { startup, search, execute, renderPreview };
};

})();
<|endoftext|>


<commit_before>var express = require('express');
var app = express();
var bodyParser=require('body-parser'); // required for AJAX POST
var mongodb = require('mongodb'); // mongodb package for node
var mc = mongodb.MongoClient;
var url='mongodb://localhost:27017/test';
var mqtt=require('mqtt');
var client=mqtt.connect('mqtt://broker.hivemq.com');

// connecting to the mongo db server
mc.connect(url,function(err,db){
	if(!err){
		console.log("Connected!");
	}
	collection=db.collection('sample');
});

app.set('port',5000);

app.use(express.static(__dirname+'/public')); // directory for all css and js
app.use('/favicon.ico', express.static('images/favicon.ico'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));

app.set('views',__dirname+'/views'); // directory for all ejs files
app.set('view engine','ejs'); // using .ejs instead of .html

app.get('/ledger/login',function(req,res){
	console.log("GET /ledger/login")
	res.render("login.ejs")
});

// GET /ledger
app.get('/ledger',function(request,response){
	console.log("GET /ledger")
	response.render("ledger_home.ejs");
});

// POST /ledger (called when the button is clicked)
app.post('/ledger',function(request,response){
	console.log("POST /ledger")
	var test=request.body;
	collection.insert({"id":1,"name":test['msg']});
	console.log("Inserted!");
	collection.find({}).toArray(function(err, docs) {
    	console.log("Found the following records");
    	// Printing all the documents in the sample in a nested JSON format
    	console.dir(docs);
    	// Sending back the third JSON document
    	response.send(docs[2]);
  	});
});

/* MPCA PART */
app.get('/ledger/react-check',function(req,res){
	console.log("GET /ledger/react-check");
	res.end("Checking stuff");
});

app.post('/ledger/react-check',function(req,res){
	var data=req.body
	client.on('connect',function(){
		client.subscribe('mpca');
		client.publish('mpca','the random message');
	});
	res.send(data);
});

// Listening on 127.0.0.1:5000
app.listen(app.get('port'),function(){
	console.log("Node app is running on localhost:",app.get('port'));
});
<commit_msg>mpca mqtt check<commit_after>var express = require('express');
var app = express();
var bodyParser=require('body-parser'); // required for AJAX POST
var mongodb = require('mongodb'); // mongodb package for node
var mc = mongodb.MongoClient;
var url='mongodb://localhost:27017/test';
var mqtt=require('mqtt');
var client=mqtt.connect('mqtt://broker.hivemq.com');

// connecting to the mongo db server
mc.connect(url,function(err,db){
	if(!err){
		console.log("Connected!");
	}
	collection=db.collection('sample');
});

app.set('port',5000);

app.use(express.static(__dirname+'/public')); // directory for all css and js
app.use('/favicon.ico', express.static('images/favicon.ico'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));

app.set('views',__dirname+'/views'); // directory for all ejs files
app.set('view engine','ejs'); // using .ejs instead of .html

app.get('/ledger/login',function(req,res){
	console.log("GET /ledger/login")
	res.render("login.ejs")
});

// GET /ledger
app.get('/ledger',function(request,response){
	console.log("GET /ledger")
	response.render("ledger_home.ejs");
});

// POST /ledger (called when the button is clicked)
app.post('/ledger',function(request,response){
	console.log("POST /ledger")
	var test=request.body;
	collection.insert({"id":1,"name":test['msg']});
	console.log("Inserted!");
	collection.find({}).toArray(function(err, docs) {
    	console.log("Found the following records");
    	// Printing all the documents in the sample in a nested JSON format
    	console.dir(docs);
    	// Sending back the third JSON document
    	response.send(docs[2]);
  	});
});

/* MPCA PART (MQTT) */
app.get('/ledger/react-check',function(req,res){
	console.log("GET /ledger/react-check");
	res.end("Checking stuff");
});

app.post('/ledger/react-check',function(req,res){
	var data=req.body
	client.on('connect',function(){
		client.subscribe('mpca');
		client.publish('mpca','the random message');
	});
	res.send(data);
});

// Listening on 127.0.0.1:5000
app.listen(app.get('port'),function(){
	console.log("Node app is running on localhost:",app.get('port'));
});
<|endoftext|>


<commit_before>var quicktmp = require('quick-tmp')('smokestack')
var debug    = require('debug')('smokestack')
var spawn    = require('child_process').spawn
var chrome   = require('chrome-location')
var through  = require('through2')
var split    = require('split')
var shoe     = require('shoe')
var http     = require('http')
var path     = require('path')
var url      = require('url')
var fs       = require('fs')

var bundle = fs.readFileSync(
  path.join(__dirname, 'bundle.js')
)

var index = fs.readFileSync(
  path.join(__dirname, 'index.html')
)

module.exports = smokestack

function smokestack(opts) {
  opts = opts || {}

  var launched = null
  var listen = false
  var script = false

  var stream = through(write, flush)
  var server = http.createServer()
  var port   = opts.port || 0
  var buffer = []

  server.on('request', function(req, res) {
    var uri = url.parse(req.url).pathname
    if (uri === '/') return send(res, index, 'text/html')
    if (uri === '/script.js') return send(res, buffer, 'text/javascript')
    if (uri === '/favicon.ico') return res.end()
    res.statusCode = 302
    res.setHeader('Location', '/')
    res.end()
  })

  server.listen(port, function(err) {
    port = server.address().port
    if (err) return stream.emit('error', err)
    debug('http://localhost:'+port+'/')
    listen = true
    if (script) return open()
  })

  shoe(function(browser) {
    var handle = through(handleInput)

    browser
      .pipe(split())
      .pipe(handle)
      .pipe(browser)
      .once('close', function() {
        launched.kill()
      })
  }).install(server, '/smokestack')

  function handleInput(data, _, next) {
    data = JSON.parse(data)

    if (data.end) {
      return this.push('end\n')
    }

    var key = data.shift()
    console[key].apply(console, data)
    next()
  }

  return stream

  function write(data, _, next) {
    buffer.push(data)
    next()
  }

  function flush() {
    buffer = buffer.join('')
    buffer = [bundle, buffer].join(';\n')
    script = true
    if (listen) return open()
  }

  function open() {
    var uri = 'http://localhost:'+port+'/'
    var tmp = quicktmp()

    launched = spawn(chrome, [
        '--app=' + uri
      , '--disable-extensions'
      , '--no-first-run'
      , '--disable-translate'
      , '--no-default-browser-check'
      , '--disable-default-apps'
      , '--disable-popup-blocking'
      , '--disable-extensions'
      , '--user-data-dir=' + tmp
    ]).once('exit', function() {
      stream.emit('end')
      process.nextTick(function() {
        stream.emit('close')
        stream.emit('finish')
      })
    })
  }

  function send(res, data, type) {
    res.setHeader('content-type', type)
    res.end(data)
  }
}
<commit_msg>Close http server on stream end.<commit_after>var quicktmp = require('quick-tmp')('smokestack')
var debug    = require('debug')('smokestack')
var spawn    = require('child_process').spawn
var chrome   = require('chrome-location')
var through  = require('through2')
var split    = require('split')
var shoe     = require('shoe')
var http     = require('http')
var path     = require('path')
var url      = require('url')
var fs       = require('fs')

var bundle = fs.readFileSync(
  path.join(__dirname, 'bundle.js')
)

var index = fs.readFileSync(
  path.join(__dirname, 'index.html')
)

module.exports = smokestack

function smokestack(opts) {
  opts = opts || {}

  var launched = null
  var listen = false
  var script = false

  var stream = through(write, flush)
  var server = http.createServer()
  var port   = opts.port || 0
  var buffer = []

  server.on('request', function(req, res) {
    var uri = url.parse(req.url).pathname
    if (uri === '/') return send(res, index, 'text/html')
    if (uri === '/script.js') return send(res, buffer, 'text/javascript')
    if (uri === '/favicon.ico') return res.end()
    res.statusCode = 302
    res.setHeader('Location', '/')
    res.end()
  })

  server.listen(port, function(err) {
    port = server.address().port
    if (err) return stream.emit('error', err)
    debug('http://localhost:'+port+'/')
    listen = true
    if (script) return open()
  })

  shoe(function(browser) {
    var handle = through(handleInput)

    browser
      .pipe(split())
      .pipe(handle)
      .pipe(browser)
      .once('close', function() {
        launched.kill()
      })
  }).install(server, '/smokestack')

  function handleInput(data, _, next) {
    data = JSON.parse(data)

    if (data.end) {
      return this.push('end\n')
    }

    var key = data.shift()
    console[key].apply(console, data)
    next()
  }

  return stream

  function write(data, _, next) {
    buffer.push(data)
    next()
  }

  function flush() {
    buffer = buffer.join('')
    buffer = [bundle, buffer].join(';\n')
    script = true
    if (listen) return open()
  }

  function open() {
    var uri = 'http://localhost:'+port+'/'
    var tmp = quicktmp()

    launched = spawn(chrome, [
        '--app=' + uri
      , '--disable-extensions'
      , '--no-first-run'
      , '--disable-translate'
      , '--no-default-browser-check'
      , '--disable-default-apps'
      , '--disable-popup-blocking'
      , '--disable-extensions'
      , '--user-data-dir=' + tmp
    ]).once('close', function() {
      server.close()
      stream.emit('end')
      process.nextTick(function() {
        stream.emit('close')
        stream.emit('finish')
      })
    })
  }

  function send(res, data, type) {
    res.setHeader('content-type', type)
    res.end(data)
  }
}
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var Shell = require('child_process').exec;
var Step = require('step');

var VOLUMES = '/Volumes/';
var SHARE;

function mount(sharepath, cb) {
	SHARE = sharepath;
	Step(
		function mountSmb() {
			var command =
				['osascript -e \'mount volume "smb://',
				path.normalize(SHARE),
				"\"'"];
			Shell(command.join(''), this);
		},
		function handleShellResult(err, stdout, stderr) {
			cb(stderr, getMountedPath());
		}
	)
}

function umount(cb) {
	Shell('umount ' + getMountedPath(), function(err, stdout, stderr) {
		cb(stderr);
	});
}

function getMountedPath() {
	return path.join(VOLUMES, path.basename(SHARE));
}

module.exports = {
	mount: mount,
	umount: umount,
	getPath: getMountedPath
};<commit_msg>remove trailing slash<commit_after>var fs = require('fs');
var path = require('path');
var Shell = require('child_process').exec;
var Step = require('step');

var VOLUMES = '/Volumes';
var SHARE;

function mount(sharepath, cb) {
	SHARE = sharepath;
	Step(
		function mountSmb() {
			var command =
				['osascript -e \'mount volume "smb://',
				path.normalize(SHARE),
				"\"'"];
			Shell(command.join(''), this);
		},
		function handleShellResult(err, stdout, stderr) {
			cb(stderr, getMountedPath());
		}
	)
}

function umount(cb) {
	Shell('umount ' + getMountedPath(), function(err, stdout, stderr) {
		cb(stderr);
	});
}

function getMountedPath() {
	return path.join(VOLUMES, path.basename(SHARE));
}

module.exports = {
	mount: mount,
	umount: umount,
	getPath: getMountedPath
};<|endoftext|>


<commit_before>var es = require('event-stream');
var fs = require('fs');
var util = require('gulp-util');
var http = require('http');
var open = require('open');
var connect = require('connect');
var liveReload = require('connect-livereload');
var tiny_lr = require('tiny-lr');
var lr;
var o = {};

module.exports = {
  server: function (opt) {
    o = opt || {};
    if (!o.root) o.root = ['app'];
    if (!o.port) o.port = 3000;
    if (!o.livereload) o.livereload = false;
    if (o.open) {
      if (typeof o.open == 'boolean') o.open = {};
      if (!o.open.file) o.open.file = '';
      if (!o.open.browser) o.open.browser = undefined;
    }
    return function () {
      var middleware = o.middleware ? o.middleware.call(this, connect, o) : [];
      if (o.livereload) {
        middleware.push(liveReload({port: o.livereload.port}));
        util.log(util.colors.green('Connect LiveReload on ' + o.livereload.port + ' port'));
      }
      o.root.forEach(function (path) {
        middleware.push(connect.static(path));
      });
      var app = connect.apply(null, middleware);
      var server = http.createServer(app);
      if (o.root.length) app.use(connect.directory(o.root[0]));
      server
        .listen(o.port)
        .on('listening', function () {
          if (o.livereload) {
            if (typeof o.livereload == 'boolean') o.livereload = {};
            if (!o.livereload.port) o.livereload.port = 35729;
            lr = tiny_lr();
            lr.listen(o.livereload.port);
          }
          var url, browsername;
          util.log(util.colors.green('Server started on ' + o.port + ' port'));
          if (o.open) {
            url = 'http://localhost:' + o.port + '/' + o.open.file;
            if (o.open.browser) browsername = o.open.browser;
            else browsername = 'default browser';
            open(url, o.open.browser, function (error) {
              if (error) util.log(util.colors.red(error));
              else util.log(util.colors.green('Opened ' + url + ' in ' + browsername));
            });
          }
        })
    };
  },
  reload: function () {
    return es.map(function (file, callback) {
      if (o.livereload && typeof lr == "object") {
        lr.changed({
          body: {
            files: file.path
          }
        });
      } else {
        util.log(util.colors.bgRed('call connect.reload(), livereload is false, enable livereload'));
      }
      callback(null, file);
    });
  }
};
<commit_msg>fixed undefined livereload port.<commit_after>var es = require('event-stream');
var fs = require('fs');
var util = require('gulp-util');
var http = require('http');
var open = require('open');
var connect = require('connect');
var liveReload = require('connect-livereload');
var tiny_lr = require('tiny-lr');
var lr;
var o = {};

module.exports = {
  server: function (opt) {
    o = opt || {};
    if (!o.root) o.root = ['app'];
    if (!o.port) o.port = 3000;
    if (!o.livereload) {
      o.livereload = false;
    } else {
      if (typeof o.livereload == 'boolean') o.livereload = {};
      if (!o.livereload.port) o.livereload.port = 35729;
    }
    if (o.open) {
      if (typeof o.open == 'boolean') o.open = {};
      if (!o.open.file) o.open.file = '';
      if (!o.open.browser) o.open.browser = undefined;
    }
    return function () {
      var middleware = o.middleware ? o.middleware.call(this, connect, o) : [];
      if (o.livereload) {
        middleware.push(liveReload({port: o.livereload.port}));
        util.log(util.colors.green('Connect LiveReload on ' + o.livereload.port + ' port'));
      }
      o.root.forEach(function (path) {
        middleware.push(connect.static(path));
      });
      var app = connect.apply(null, middleware);
      var server = http.createServer(app);
      if (o.root.length) app.use(connect.directory(o.root[0]));
      server
        .listen(o.port)
        .on('listening', function () {
          if (o.livereload) {
            lr = tiny_lr();
            lr.listen(o.livereload.port);
          }
          var url, browsername;
          util.log(util.colors.green('Server started on ' + o.port + ' port'));
          if (o.open) {
            url = 'http://localhost:' + o.port + '/' + o.open.file;
            if (o.open.browser) browsername = o.open.browser;
            else browsername = 'default browser';
            open(url, o.open.browser, function (error) {
              if (error) util.log(util.colors.red(error));
              else util.log(util.colors.green('Opened ' + url + ' in ' + browsername));
            });
          }
        })
    };
  },
  reload: function () {
    return es.map(function (file, callback) {
      if (o.livereload && typeof lr == "object") {
        lr.changed({
          body: {
            files: file.path
          }
        });
      } else {
        util.log(util.colors.bgRed('call connect.reload(), livereload is false, enable livereload'));
      }
      callback(null, file);
    });
  }
};
<|endoftext|>


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

'use strict';

var minimist = require('minimist');
var toTasks = require('./lib/to-tasks');
var utils = require('./lib/utils');

module.exports = function(options) {
  return function(app) {
    var opts = utils.extend({}, options);
    if (opts.prop) {
      opts[opts.prop] = app[opts.prop];
    }

    opts.commands = app.commands || [];

    // add `keys` from base-config plugin (map-config)
    if (app.config && Array.isArray(app.config.keys)) {
      opts.commands = utils.union(opts.commands, app.config.keys);
    }
    // add `keys` from base-cli plugin (map-config)
    if (app.cli && Array.isArray(app.cli.keys)) {
      opts.commands = utils.union(opts.commands, app.cli.keys);
    }

    opts.tasks = app.tasks;
    app.define('processArgv', processArgv(opts));
  };
};

function processArgv(options) {
  var opts = utils.extend({}, options);
  var commands = opts.commands;
  var tasks = opts.tasks;
  var prop = opts.prop;

  return function(argv) {
    argv = !utils.isObject(argv)
      ? minimist(utils.arrayify(argv))
      : argv;

    var res = {};
    res.orig = utils.extend({}, argv);
    res._ = [];
    res.tasks = [];
    res.commands = {};
    res.options = {};
    if (prop) res[prop] = [];

    var appKeys = (prop && opts.hasOwnProperty(prop))
      ? Object.keys(opts[prop])
      : [];

    var taskKeys = !Array.isArray(tasks)
      ? (tasks ? Object.keys(tasks) : [])
      : tasks;

    var arr = argv._;
    var len = arr.length, i = -1;

    while (++i < len) {
      var ele = arr[i];

      if (/,/.test(ele) && !/[.|:]/.test(ele)) {
        res.tasks = utils.union(res.tasks, ele.split(','));
        continue;
      }

      if (isApp(appKeys, ele) || isTask(taskKeys, ele)) {
        if (prop) {
          var obj = toTasks(ele, opts, prop);
          res[prop] = res[prop].concat(obj);
        } else {
          res.tasks = utils.union(res.tasks, ele.split(','));
        }
        continue;
      }
      res._.push(ele);
    }

    for (var key in argv) {
      if (key === '_') {
        continue;
      }

      var argvArr = utils.arrayify(argv[key]);
      var expanded = utils.expandArgs(argvArr)[0];

      if (isCommand(commands, key)) {
        res.commands[key] = expanded;
      } else {
        res.options[key] = expanded;
      }
    }
    return res;
  };
}

module.exports.processArgv = processArgv;

/**
 * Utils
 */

function isApp(apps, key) {
  return is(apps, key);
}

function isCommand(commands, key) {
  return is(commands, key);
}

function isTask(tasks, key) {
  return is(tasks, key);
}

function is(arr, key, ch) {
  if (!arr) return false;
  if (arr.indexOf(key) > -1) {
    return true;
  }
  var seg = key.split(/\W/).shift();
  return arr.indexOf(seg) > -1;
}
<commit_msg>minor refactor, break code into smaller functions<commit_after>/*!
 * base-argv <https://github.com/jonschlinkert/base-argv>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var minimist = require('minimist');
var toTasks = require('./lib/to-tasks');
var utils = require('./lib/utils');
var toKeys = require('./lib/keys');

module.exports = function(options) {
  return function(app) {
    app.define('argv', function(argv) {
      var opts = toKeys(app, options);
      return processArgv(argv, opts);
    });
  };
};

function processArgv(argv, options) {
  var opts = options || {};
  var commands = opts.commands;
  var tasks = opts.tasks;
  var prop = opts.prop;

  if (Array.isArray(argv)) {
    argv = minimist(utils.arrayify(argv));
  }

  var res = {
    orig: utils.extend({}, argv),
    _: [],
    tasks: [],
    commands: {},
    options: {}
  };

  if (typeof prop === 'string') {
    res[prop] = [];
  }

  for (var key in argv) {
    if (key === '_') {
      res = reduceArray(argv[key], res, prop, opts);
    }
    res = reduceOptions(argv[key], key, res, commands);
  }
  return res;
};

/**
 * Utils
 */

function reduceArray(args, res, prop, opts) {
  var tasks = opts.tasks;
  var apps = opts[prop];

  var len = args.length, i = -1;
  while (++i < len) {
    var ele = args[i];

    if (/,/.test(ele) && !/[.|:]/.test(ele)) {
      res.tasks = utils.union(res.tasks, ele.split(','));
      continue;
    }
    if (isApp(apps, ele) || isTask(tasks, ele)) {
      if (prop) {
        var obj = toTasks(ele, opts, prop);
        res[prop] = res[prop].concat(obj);
      } else {
        res.tasks = utils.union(res.tasks, ele.split(','));
      }
      continue;
    }
    res._.push(ele);
  }
  return res;
}

function reduceOptions(val, key, res, commands) {
  var args = utils.expandArgs(utils.arrayify(val))[0];
  if (isCommand(commands, key)) {
    res.commands[key] = args;
  } else {
    res.options[key] = args;
  }
  return res;
}

function isApp(apps, key) {
  return is(apps, key);
}

function isCommand(commands, key) {
  return is(commands, key);
}

function isTask(tasks, key) {
  return is(tasks, key);
}

function is(arr, key, ch) {
  console.log(arr)
  if (!arr) return false;
  if (!Array.isArray(arr)) {
    return true;
  }
  if (arr.indexOf(key) > -1) {
    return true;
  }
  var seg = key.split(/\W/).shift();
  return arr.indexOf(seg) > -1;
}

/**
 * Expose `processArgv` method
 */

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


<commit_before>/*!
* vdom-virtualize
* Copyright 2014 by Marcel Klehr <mklehr@gmx.net>
*
* (MIT LICENSE)
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var VNode = require("vtree/vnode")
  , VText = require("vtree/vtext")

module.exports = createVNode

function createVNode(domNode, key) {
  key = key || null // XXX: Leave out `key` for now... merely used for (re-)ordering

  if(domNode.nodeType == 1) return createFromElement(domNode, key)
  if(domNode.nodeType == 3) return createFromTextNode(domNode, key)
  return
}

createVNode.fromHTML = function(html, key) {
  var domNode = document.createElement('div'); // create container
  domNode.innerHTML = html; // browser parses HTML into DOM tree
  domNode = domNode.children[0] || domNode; // select first node in tree
  return createVNode(domNode, key);
};

function createFromTextNode(tNode) {
  return new VText(tNode.nodeValue)
}

function createFromElement(el) {
  var tagName = el.tagName
  , namespace = el.namespaceURI == 'http://www.w3.org/1999/xhtml'? null : el.namespaceURI
  , properties = getElementProperties(el)
  , children = []

  for (var i = 0; i < el.childNodes.length; i++) {
    children.push(createVNode(el.childNodes[i]/*, i*/))
  }

  return new VNode(tagName, properties, children, null, namespace)
}

function getElementProperties(el) {
  var obj = {}

  props.forEach(function(propName) {
    if(!el[propName]) return

    // Special case: style
    // .style is a DOMStyleDeclaration, thus we need to iterate over all
    // rules to create a hash of applied css properties.
    //
    // You can directly set a specific .style[prop] = value so patching with vdom
    // is possible.
    if("style" == propName) {
      var css = {}
        , styleProp
      for(var i=0; i<el.style; i++) {
        styleProp = el.style[i]
        css[styleProp] = el.style.getPropertyValue(styleProp) // XXX: add support for "!important" via getPropertyPriority()!
      }

      obj[propName] = css
      return
    }

    // Special case: dataset
    // we can iterate over .dataset with a simple for..in loop.
    // The all-time foo with data-* attribs is the dash-snake to camelCase
    // conversion.
    // However, I'm not sure if this is compatible with h()
    //
    // .dataset properties are directly accessible as transparent getters/setters, so
    // patching with vdom is possible.
    if("dataset" == propName) {
      var data = {}
      for(var p in el.dataset) {
        data[p] = el.dataset[p]
      }

      obj[propName] = data
      return
    }

    // Special case: attributes
    // some properties are only accessible via .attributes, so
    // that's what we'd do, if vdom-create-element could handle this.
    if("attributes" == propName) return

    // default: just copy the property
    obj[propName] = el[propName]
    return
  })

  return obj
}

/**
 * DOMNode property white list
 * Taken from https://github.com/Raynos/react/blob/dom-property-config/src/browser/ui/dom/DefaultDOMPropertyConfig.js
 */
var props =

module.exports.properties = [
 "accept"
,"accessKey"
,"action"
,"alt"
,"async"
,"autoComplete"
,"autoPlay"
,"cellPadding"
,"cellSpacing"
,"checked"
,"className"
,"colSpan"
,"content"
,"contentEditable"
,"controls"
,"crossOrigin"
,"data"
,"dataset"
,"defer"
,"dir"
,"download"
,"draggable"
,"encType"
,"formNoValidate"
,"href"
,"hrefLang"
,"htmlFor"
,"httpEquiv"
,"icon"
,"id"
,"label"
,"lang"
,"list"
,"loop"
,"max"
,"mediaGroup"
,"method"
,"min"
,"multiple"
,"muted"
,"name"
,"noValidate"
,"pattern"
,"placeholder"
,"poster"
,"preload"
,"radioGroup"
,"readOnly"
,"rel"
,"required"
,"rowSpan"
,"sandbox"
,"scope"
,"scrollLeft"
,"scrolling"
,"scrollTop"
,"selected"
,"span"
,"spellCheck"
,"src"
,"srcDoc"
,"srcSet"
,"start"
,"step"
,"style"
,"tabIndex"
,"target"
,"title"
,"type"
,"value"

// Non-standard Properties
,"autoCapitalize"
,"autoCorrect"
,"property"

, "attributes"
]

var attrs =
module.exports.attrs = [
 "allowFullScreen"
,"allowTransparency"
,"charSet"
,"cols"
,"contextMenu"
,"dateTime"
,"disabled"
,"form"
,"frameBorder"
,"height"
,"hidden"
,"maxLength"
,"role"
,"rows"
,"seamless"
,"size"
,"width"
,"wmode"

// SVG Properties
,"cx"
,"cy"
,"d"
,"dx"
,"dy"
,"fill"
,"fx"
,"fy"
,"gradientTransform"
,"gradientUnits"
,"offset"
,"points"
,"r"
,"rx"
,"ry"
,"spreadMethod"
,"stopColor"
,"stopOpacity"
,"stroke"
,"strokeLinecap"
,"strokeWidth"
,"textAnchor"
,"transform"
,"version"
,"viewBox"
,"x1"
,"x2"
,"x"
,"y1"
,"y2"
,"y"
]
<commit_msg>Properly copies style attributes<commit_after>/*!
* vdom-virtualize
* Copyright 2014 by Marcel Klehr <mklehr@gmx.net>
*
* (MIT LICENSE)
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var VNode = require("vtree/vnode")
  , VText = require("vtree/vtext")

module.exports = createVNode

function createVNode(domNode, key) {
  key = key || null // XXX: Leave out `key` for now... merely used for (re-)ordering

  if(domNode.nodeType == 1) return createFromElement(domNode, key)
  if(domNode.nodeType == 3) return createFromTextNode(domNode, key)
  return
}

createVNode.fromHTML = function(html, key) {
  var domNode = document.createElement('div'); // create container
  domNode.innerHTML = html; // browser parses HTML into DOM tree
  domNode = domNode.children[0] || domNode; // select first node in tree
  return createVNode(domNode, key);
};

function createFromTextNode(tNode) {
  return new VText(tNode.nodeValue)
}

function createFromElement(el) {
  var tagName = el.tagName
  , namespace = el.namespaceURI == 'http://www.w3.org/1999/xhtml'? null : el.namespaceURI
  , properties = getElementProperties(el)
  , children = []

  for (var i = 0; i < el.childNodes.length; i++) {
    children.push(createVNode(el.childNodes[i]/*, i*/))
  }

  return new VNode(tagName, properties, children, null, namespace)
}

function getElementProperties(el) {
  var obj = {}

  props.forEach(function(propName) {
    if(!el[propName]) return

    // Special case: style
    // .style is a DOMStyleDeclaration, thus we need to iterate over all
    // rules to create a hash of applied css properties.
    //
    // You can directly set a specific .style[prop] = value so patching with vdom
    // is possible.
    if("style" == propName) {
      var css = {}
        , styleProp
      for(var i=0; i<el.style.length; i++) {
        styleProp = el.style[i]
        css[styleProp] = el.style.getPropertyValue(styleProp) // XXX: add support for "!important" via getPropertyPriority()!
      }

      obj[propName] = css
      return
    }

    // Special case: dataset
    // we can iterate over .dataset with a simple for..in loop.
    // The all-time foo with data-* attribs is the dash-snake to camelCase
    // conversion.
    // However, I'm not sure if this is compatible with h()
    //
    // .dataset properties are directly accessible as transparent getters/setters, so
    // patching with vdom is possible.
    if("dataset" == propName) {
      var data = {}
      for(var p in el.dataset) {
        data[p] = el.dataset[p]
      }

      obj[propName] = data
      return
    }

    // Special case: attributes
    // some properties are only accessible via .attributes, so
    // that's what we'd do, if vdom-create-element could handle this.
    if("attributes" == propName) return

    // default: just copy the property
    obj[propName] = el[propName]
    return
  })

  return obj
}

/**
 * DOMNode property white list
 * Taken from https://github.com/Raynos/react/blob/dom-property-config/src/browser/ui/dom/DefaultDOMPropertyConfig.js
 */
var props =

module.exports.properties = [
 "accept"
,"accessKey"
,"action"
,"alt"
,"async"
,"autoComplete"
,"autoPlay"
,"cellPadding"
,"cellSpacing"
,"checked"
,"className"
,"colSpan"
,"content"
,"contentEditable"
,"controls"
,"crossOrigin"
,"data"
,"dataset"
,"defer"
,"dir"
,"download"
,"draggable"
,"encType"
,"formNoValidate"
,"href"
,"hrefLang"
,"htmlFor"
,"httpEquiv"
,"icon"
,"id"
,"label"
,"lang"
,"list"
,"loop"
,"max"
,"mediaGroup"
,"method"
,"min"
,"multiple"
,"muted"
,"name"
,"noValidate"
,"pattern"
,"placeholder"
,"poster"
,"preload"
,"radioGroup"
,"readOnly"
,"rel"
,"required"
,"rowSpan"
,"sandbox"
,"scope"
,"scrollLeft"
,"scrolling"
,"scrollTop"
,"selected"
,"span"
,"spellCheck"
,"src"
,"srcDoc"
,"srcSet"
,"start"
,"step"
,"style"
,"tabIndex"
,"target"
,"title"
,"type"
,"value"

// Non-standard Properties
,"autoCapitalize"
,"autoCorrect"
,"property"

, "attributes"
]

var attrs =
module.exports.attrs = [
 "allowFullScreen"
,"allowTransparency"
,"charSet"
,"cols"
,"contextMenu"
,"dateTime"
,"disabled"
,"form"
,"frameBorder"
,"height"
,"hidden"
,"maxLength"
,"role"
,"rows"
,"seamless"
,"size"
,"width"
,"wmode"

// SVG Properties
,"cx"
,"cy"
,"d"
,"dx"
,"dy"
,"fill"
,"fx"
,"fy"
,"gradientTransform"
,"gradientUnits"
,"offset"
,"points"
,"r"
,"rx"
,"ry"
,"spreadMethod"
,"stopColor"
,"stopOpacity"
,"stroke"
,"strokeLinecap"
,"strokeWidth"
,"textAnchor"
,"transform"
,"version"
,"viewBox"
,"x1"
,"x2"
,"x"
,"y1"
,"y2"
,"y"
]
<|endoftext|>