<commit_before>/**
 * math.js factory function.
 *
 * Usage:
 *
 *     var math = mathFactory();
 *     var math = mathFactory(options);
 *
 * @param {Object} [options]  Available options:
 *                            {Number} format.precision
 *                              A number in the range 0-16. Default value is 5.
 *                            {String} matrix.defaultType
 *                              A string 'array' or 'matrix' (default).
 */
function mathFactory (options) {
  // create new namespace
  var math = {};

  // options (global configuration settings)
  math.options = {
    format: {
      precision: 5   // number of digits in formatted output
    },
    matrix: {
      'defaultType': 'matrix' // type of default matrix output. Choose 'array' or 'matrix' (default)
    }
  };

  // merge options
  if (options && options.format && options.format.precision) {
    math.options.format.precision = options.format.precision;
  }
  if (options && options.matrix && options.matrix.defaultType) {
    math.options.matrix.defaultType = options.matrix.defaultType;
  }

  // TODO: change options to properties with getters to validate the input value

  // TODO: remove deprecated options some day (deprecated since version 0.15.0)
  if (Object.defineProperty) {
    var fnPrecision = function () {
      throw new Error('Option math.options.precision is deprecated. ' +
          'Use math.options.format.precision instead.')
    };

    Object.defineProperty(math.options, 'precision', {
      get: fnPrecision,
      set: fnPrecision,
      enumerable: false,
      configurable: false
    });

    var fnDefault = function () {
      throw new Error('Option math.options.matrix.default is deprecated. ' +
          'Use math.options.matrix.defaultType instead.')
    };

    Object.defineProperty(math.options.matrix, 'default', {
      get: fnDefault,
      set: fnDefault,
      enumerable: false,
      configurable: false
    });
  }

  // expression (Parser, Scope, nodes, docs)
  math.expression = {};
  math.expression.node = require('./lib/expression/node/index.js');
  math.expression.Scope = require('./lib/expression/Scope.js');
  math.expression.Parser = require('./lib/expression/Parser.js');
  math.expression.docs = require('./lib/expression/docs/index.js');

  // TODO: deprecated since version 0.13.0. cleanup deprecated stuff some day
  math.expr = {};
  math.expr.Scope = function () {
    throw new Error('Moved to math.expression.Scope');
  };
  math.expr.Parser = function () {
    throw new Error('Moved to math.expression.Parser');
  };

  // types (Matrix, Complex, Unit, ...)
  math.type = {};
  math.type.Complex = require('./lib/type/Complex.js');
  math.type.Range = require('./lib/type/Range.js');
  math.type.Index = require('./lib/type/Index.js');
  math.type.Matrix = require('./lib/type/Matrix.js');
  math.type.Unit = require('./lib/type/Unit.js');
  math.type.Help = require('./lib/type/Help.js');

  math.collection = require('./lib/type/collection.js');

  // expression parser
  require('./lib/function/expression/eval.js')(math);
  require('./lib/function/expression/help.js')(math);
  require('./lib/function/expression/parse.js')(math);

  // functions - arithmetic
  require('./lib/function/arithmetic/abs.js')(math);
  require('./lib/function/arithmetic/add.js')(math);
  require('./lib/function/arithmetic/add.js')(math);
  require('./lib/function/arithmetic/ceil.js')(math);
  require('./lib/function/arithmetic/cube.js')(math);
  require('./lib/function/arithmetic/divide.js')(math);
  require('./lib/function/arithmetic/edivide.js')(math);
  require('./lib/function/arithmetic/emultiply.js')(math);
  require('./lib/function/arithmetic/epow.js')(math);
  require('./lib/function/arithmetic/equal.js')(math);
  require('./lib/function/arithmetic/exp.js')(math);
  require('./lib/function/arithmetic/fix.js')(math);
  require('./lib/function/arithmetic/floor.js')(math);
  require('./lib/function/arithmetic/gcd.js')(math);
  require('./lib/function/arithmetic/larger.js')(math);
  require('./lib/function/arithmetic/largereq.js')(math);
  require('./lib/function/arithmetic/lcm.js')(math);
  require('./lib/function/arithmetic/log.js')(math);
  require('./lib/function/arithmetic/log10.js')(math);
  require('./lib/function/arithmetic/mod.js')(math);
  require('./lib/function/arithmetic/multiply.js')(math);
  require('./lib/function/arithmetic/pow.js')(math);
  require('./lib/function/arithmetic/round.js')(math);
  require('./lib/function/arithmetic/sign.js')(math);
  require('./lib/function/arithmetic/smaller.js')(math);
  require('./lib/function/arithmetic/smallereq.js')(math);
  require('./lib/function/arithmetic/sqrt.js')(math);
  require('./lib/function/arithmetic/square.js')(math);
  require('./lib/function/arithmetic/subtract.js')(math);
  require('./lib/function/arithmetic/unary.js')(math);
  require('./lib/function/arithmetic/unequal.js')(math);
  require('./lib/function/arithmetic/xgcd.js')(math);

  // functions - complex
  require('./lib/function/complex/arg.js')(math);
  require('./lib/function/complex/conj.js')(math);
  require('./lib/function/complex/re.js')(math);
  require('./lib/function/complex/im.js')(math);

  // functions - construction
  require('./lib/function/construction/boolean.js')(math);
  require('./lib/function/construction/complex.js')(math);
  require('./lib/function/construction/index.js')(math);
  require('./lib/function/construction/matrix.js')(math);
  require('./lib/function/construction/number.js')(math);
  require('./lib/function/construction/parser.js')(math);
  require('./lib/function/construction/string.js')(math);
  require('./lib/function/construction/unit.js')(math);

  // functions - matrix
  require('./lib/function/matrix/concat.js')(math);
  require('./lib/function/matrix/det.js')(math);
  require('./lib/function/matrix/diag.js')(math);
  require('./lib/function/matrix/eye.js')(math);
  require('./lib/function/matrix/inv.js')(math);
  require('./lib/function/matrix/ones.js')(math);
  require('./lib/function/matrix/range.js')(math);
  require('./lib/function/matrix/size.js')(math);
  require('./lib/function/matrix/squeeze.js')(math);
  require('./lib/function/matrix/subset.js')(math);
  require('./lib/function/matrix/transpose.js')(math);
  require('./lib/function/matrix/zeros.js')(math);

  // functions - probability
  require('./lib/function/probability/factorial.js')(math);
  require('./lib/function/probability/random.js')(math);

  // functions - statistics
  require('./lib/function/statistics/min.js')(math);
  require('./lib/function/statistics/max.js')(math);
  require('./lib/function/statistics/mean.js')(math);

  // functions - trigonometry
  require('./lib/function/trigonometry/acos.js')(math);
  require('./lib/function/trigonometry/asin.js')(math);
  require('./lib/function/trigonometry/atan.js')(math);
  require('./lib/function/trigonometry/atan2.js')(math);
  require('./lib/function/trigonometry/cos.js')(math);
  require('./lib/function/trigonometry/cot.js')(math);
  require('./lib/function/trigonometry/csc.js')(math);
  require('./lib/function/trigonometry/sec.js')(math);
  require('./lib/function/trigonometry/sin.js')(math);
  require('./lib/function/trigonometry/tan.js')(math);

  // functions - units
  require('./lib/function/units/in.js')(math);

  // functions - utils
  require('./lib/function/utils/clone.js')(math);
  require('./lib/function/utils/format.js')(math);
  require('./lib/function/utils/import.js')(math);
  require('./lib/function/utils/map.js')(math);
  require('./lib/function/utils/print.js')(math);
  require('./lib/function/utils/select.js')(math);
  require('./lib/function/utils/typeof.js')(math);
  require('./lib/function/utils/forEach.js')(math);

  // constants
  require('./lib/constants.js')(math);

  // selector (we initialize after all functions are loaded)
  math.chaining = {};
  math.chaining.Selector = require('./lib/chaining/Selector.js')(math);

  // TODO: deprecated since version 0.13.0. Cleanup some day
  math.expr.Selector = function () {
    throw new Error('Moved to math.expression.Selector');
  };

  // return the new instance
  return math;
}

// return a new instance
// TODO: return the mathFactory itself
module.exports = mathFactory();
<commit_msg>Simplified loading options<commit_after>var object = require('./lib/util/object');

/**
 * math.js factory function.
 *
 * Usage:
 *
 *     var math = mathFactory();
 *     var math = mathFactory(options);
 *
 * @param {Object} [options]  Available options:
 *                            {Number} format.precision
 *                              A number in the range 0-16. Default value is 5.
 *                            {String} matrix.defaultType
 *                              A string 'array' or 'matrix' (default).
 */
function mathFactory (options) {
  // create new namespace
  var math = {};

  // options
  // TODO: change options to properties with getters to validate the input value
  math.options = {
    format: {
      precision: 5   // number of digits in formatted output
    },
    matrix: {
      'defaultType': 'matrix' // type of default matrix output. Choose 'array' or 'matrix' (default)
    }
  };

  // merge options
  object.deepExtend(math.options, options);

  // TODO: remove deprecated options some day (deprecated since version 0.15.0)
  if (Object.defineProperty) {
    var fnPrecision = function () {
      throw new Error('Option math.options.precision is deprecated. ' +
          'Use math.options.format.precision instead.')
    };

    Object.defineProperty(math.options, 'precision', {
      get: fnPrecision,
      set: fnPrecision,
      enumerable: false,
      configurable: false
    });

    var fnDefault = function () {
      throw new Error('Option math.options.matrix.default is deprecated. ' +
          'Use math.options.matrix.defaultType instead.')
    };

    Object.defineProperty(math.options.matrix, 'default', {
      get: fnDefault,
      set: fnDefault,
      enumerable: false,
      configurable: false
    });
  }

  // expression (Parser, Scope, nodes, docs)
  math.expression = {};
  math.expression.node = require('./lib/expression/node/index.js');
  math.expression.Scope = require('./lib/expression/Scope.js');
  math.expression.Parser = require('./lib/expression/Parser.js');
  math.expression.docs = require('./lib/expression/docs/index.js');

  // TODO: deprecated since version 0.13.0. cleanup deprecated stuff some day
  math.expr = {};
  math.expr.Scope = function () {
    throw new Error('Moved to math.expression.Scope');
  };
  math.expr.Parser = function () {
    throw new Error('Moved to math.expression.Parser');
  };

  // types (Matrix, Complex, Unit, ...)
  math.type = {};
  math.type.Complex = require('./lib/type/Complex.js');
  math.type.Range = require('./lib/type/Range.js');
  math.type.Index = require('./lib/type/Index.js');
  math.type.Matrix = require('./lib/type/Matrix.js');
  math.type.Unit = require('./lib/type/Unit.js');
  math.type.Help = require('./lib/type/Help.js');

  math.collection = require('./lib/type/collection.js');

  // expression parser
  require('./lib/function/expression/eval.js')(math);
  require('./lib/function/expression/help.js')(math);
  require('./lib/function/expression/parse.js')(math);

  // functions - arithmetic
  require('./lib/function/arithmetic/abs.js')(math);
  require('./lib/function/arithmetic/add.js')(math);
  require('./lib/function/arithmetic/add.js')(math);
  require('./lib/function/arithmetic/ceil.js')(math);
  require('./lib/function/arithmetic/cube.js')(math);
  require('./lib/function/arithmetic/divide.js')(math);
  require('./lib/function/arithmetic/edivide.js')(math);
  require('./lib/function/arithmetic/emultiply.js')(math);
  require('./lib/function/arithmetic/epow.js')(math);
  require('./lib/function/arithmetic/equal.js')(math);
  require('./lib/function/arithmetic/exp.js')(math);
  require('./lib/function/arithmetic/fix.js')(math);
  require('./lib/function/arithmetic/floor.js')(math);
  require('./lib/function/arithmetic/gcd.js')(math);
  require('./lib/function/arithmetic/larger.js')(math);
  require('./lib/function/arithmetic/largereq.js')(math);
  require('./lib/function/arithmetic/lcm.js')(math);
  require('./lib/function/arithmetic/log.js')(math);
  require('./lib/function/arithmetic/log10.js')(math);
  require('./lib/function/arithmetic/mod.js')(math);
  require('./lib/function/arithmetic/multiply.js')(math);
  require('./lib/function/arithmetic/pow.js')(math);
  require('./lib/function/arithmetic/round.js')(math);
  require('./lib/function/arithmetic/sign.js')(math);
  require('./lib/function/arithmetic/smaller.js')(math);
  require('./lib/function/arithmetic/smallereq.js')(math);
  require('./lib/function/arithmetic/sqrt.js')(math);
  require('./lib/function/arithmetic/square.js')(math);
  require('./lib/function/arithmetic/subtract.js')(math);
  require('./lib/function/arithmetic/unary.js')(math);
  require('./lib/function/arithmetic/unequal.js')(math);
  require('./lib/function/arithmetic/xgcd.js')(math);

  // functions - complex
  require('./lib/function/complex/arg.js')(math);
  require('./lib/function/complex/conj.js')(math);
  require('./lib/function/complex/re.js')(math);
  require('./lib/function/complex/im.js')(math);

  // functions - construction
  require('./lib/function/construction/boolean.js')(math);
  require('./lib/function/construction/complex.js')(math);
  require('./lib/function/construction/index.js')(math);
  require('./lib/function/construction/matrix.js')(math);
  require('./lib/function/construction/number.js')(math);
  require('./lib/function/construction/parser.js')(math);
  require('./lib/function/construction/string.js')(math);
  require('./lib/function/construction/unit.js')(math);

  // functions - matrix
  require('./lib/function/matrix/concat.js')(math);
  require('./lib/function/matrix/det.js')(math);
  require('./lib/function/matrix/diag.js')(math);
  require('./lib/function/matrix/eye.js')(math);
  require('./lib/function/matrix/inv.js')(math);
  require('./lib/function/matrix/ones.js')(math);
  require('./lib/function/matrix/range.js')(math);
  require('./lib/function/matrix/size.js')(math);
  require('./lib/function/matrix/squeeze.js')(math);
  require('./lib/function/matrix/subset.js')(math);
  require('./lib/function/matrix/transpose.js')(math);
  require('./lib/function/matrix/zeros.js')(math);

  // functions - probability
  require('./lib/function/probability/factorial.js')(math);
  require('./lib/function/probability/random.js')(math);

  // functions - statistics
  require('./lib/function/statistics/min.js')(math);
  require('./lib/function/statistics/max.js')(math);
  require('./lib/function/statistics/mean.js')(math);

  // functions - trigonometry
  require('./lib/function/trigonometry/acos.js')(math);
  require('./lib/function/trigonometry/asin.js')(math);
  require('./lib/function/trigonometry/atan.js')(math);
  require('./lib/function/trigonometry/atan2.js')(math);
  require('./lib/function/trigonometry/cos.js')(math);
  require('./lib/function/trigonometry/cot.js')(math);
  require('./lib/function/trigonometry/csc.js')(math);
  require('./lib/function/trigonometry/sec.js')(math);
  require('./lib/function/trigonometry/sin.js')(math);
  require('./lib/function/trigonometry/tan.js')(math);

  // functions - units
  require('./lib/function/units/in.js')(math);

  // functions - utils
  require('./lib/function/utils/clone.js')(math);
  require('./lib/function/utils/format.js')(math);
  require('./lib/function/utils/import.js')(math);
  require('./lib/function/utils/map.js')(math);
  require('./lib/function/utils/print.js')(math);
  require('./lib/function/utils/select.js')(math);
  require('./lib/function/utils/typeof.js')(math);
  require('./lib/function/utils/forEach.js')(math);

  // constants
  require('./lib/constants.js')(math);

  // selector (we initialize after all functions are loaded)
  math.chaining = {};
  math.chaining.Selector = require('./lib/chaining/Selector.js')(math);

  // TODO: deprecated since version 0.13.0. Cleanup some day
  math.expr.Selector = function () {
    throw new Error('Moved to math.expression.Selector');
  };

  // return the new instance
  return math;
}

// return a new instance
// TODO: return the mathFactory itself
module.exports = mathFactory();
<|endoftext|>


<commit_before>var path = require('path');
var spawn = require('child_process').spawn;
var debug = require('debug')('electron-squirrel-startup');
var app = require('app');

var run = function(args, done) {
  var updateExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe');
  debug('Spawning `%s` with args `%s`', updateExe, args);
  spawn(updateExe, args, {
    detached: true
  }).on('close', done);
};

var check = function() {
  if (process.platform === 'win32') {
    var cmd = process.argv[1];
    debug('processing squirrel command `%s`', cmd);
    var target = path.basename(process.execPath);

    if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') {
      run(['--createShortcut=' + target + ''], app.quit);
      return true;
    }
    if (cmd === '--squirrel-uninstall') {
      run(['--removeShortcut=' + target + ''], app.quit);
      return true;
    }
    if (cmd === '--squirrel-obsolete') {
      app.quit();
      return true;
    }
  }
  return false;
};

module.exports = check();
<commit_msg>Updated require for electron app.<commit_after>var path = require('path');
var spawn = require('child_process').spawn;
var debug = require('debug')('electron-squirrel-startup');
var app = require('electron').app;

var run = function(args, done) {
  var updateExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe');
  debug('Spawning `%s` with args `%s`', updateExe, args);
  spawn(updateExe, args, {
    detached: true
  }).on('close', done);
};

var check = function() {
  if (process.platform === 'win32') {
    var cmd = process.argv[1];
    debug('processing squirrel command `%s`', cmd);
    var target = path.basename(process.execPath);

    if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') {
      run(['--createShortcut=' + target + ''], app.quit);
      return true;
    }
    if (cmd === '--squirrel-uninstall') {
      run(['--removeShortcut=' + target + ''], app.quit);
      return true;
    }
    if (cmd === '--squirrel-obsolete') {
      app.quit();
      return true;
    }
  }
  return false;
};

module.exports = check();
<|endoftext|>


<commit_before>var RDX = exports.RDX = new Object();
RDX.ConnectionPool = require('./lib/connection').ConnectionPool;
RDX.Table = require('./lib/table').Table;
RDX.Query = require('./lib/table').Query;
RDX.ToMany = require('./lib/to_many').ToMany;
RDX.BelongsTo = require('./lib/belongs_to').BelongsTo;

<commit_msg>only expose model class from index<commit_after>var rdx = exports.rdx = new Object();
rdx.ConnectionPool = require('./lib/connection').ConnectionPool;
rdx.Model = require('./lib/table').Table;

<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var fs   = require('fs');
var mergeTrees = require('broccoli-merge-trees')
var pickFiles = require('broccoli-static-compiler');

function LiquidFire(project) {
  this.project = project;
  this.name    = 'Liquid Fire';
}

function unwatchedTree(dir) {
  return {
    read:    function() { return dir; },
    cleanup: function() { }
  };
}

LiquidFire.prototype.treeFor = function treeFor(name) {
  var treePath = path.join('node_modules', 'liquid-fire', name + '-addon');
  var addon;

  if (fs.existsSync(treePath)) {
    addon = unwatchedTree(treePath);
  }

  if (name === 'vendor') {
    ['velocity'].forEach(function(dep){
      var src = unwatchedTree(path.join('node_modules', 'liquid-fire', 'vendor'));
      addon = mergeTrees([addon, pickFiles(src, {srcDir: dep, destDir: dep})]);
    });
  }

  return addon;
};

LiquidFire.prototype.included = function included(app) {
  this.app = app;
  this.app.import('vendor/velocity/jquery.velocity.js');
  this.app.import('vendor/liquid-fire/liquid-fire.css');
};

module.exports = LiquidFire;
<commit_msg>Ensure EmberCLI 0.0.39 is supported.<commit_after>'use strict';

var path = require('path');
var fs   = require('fs');
var mergeTrees = require('broccoli-merge-trees')
var pickFiles = require('broccoli-static-compiler');

function LiquidFire(project) {
  this.project = project;
  this.name    = 'Liquid Fire';
}

function unwatchedTree(dir) {
  return {
    read:    function() { return dir; },
    cleanup: function() { }
  };
}

LiquidFire.prototype.treeFor = function treeFor(name) {
  var treePath = path.join('node_modules', 'liquid-fire');

  if (name === 'templates') {
    treePath = path.join(treePath, 'app-addon', 'templates');
  } else {
    treePath = path.join(treePath, name + '-addon');
  }

  var addon;

  if (fs.existsSync(treePath)) {
    addon = unwatchedTree(treePath);
  }

  if (name === 'vendor') {
    ['velocity'].forEach(function(dep){
      var src = unwatchedTree(path.join('node_modules', 'liquid-fire', 'vendor'));
      addon = mergeTrees([addon, pickFiles(src, {srcDir: dep, destDir: dep})]);
    });
  }

  return addon;
};

LiquidFire.prototype.included = function included(app) {
  this.app = app;
  this.app.import('vendor/velocity/jquery.velocity.js');
  this.app.import('vendor/liquid-fire/liquid-fire.css');
};

module.exports = LiquidFire;
<|endoftext|>


<commit_before>var _ = require('lodash'),
  Etcd = require('node-etcd'),
  Promise = require('bluebird'),
  traverse = require('traverse'),
  quack = require('quack-array');

function REnv(opts) {
  _.extend(this, {
    application: 'app',
    environment: 'development',
    etcd: {
      hosts: ['127.0.0.1:4001'],
      ssloptions: {}
    }
  }, opts);

  if (!this.client) this.client = this.createClient();
}

// create the etcd client.
REnv.prototype.createClient = function() {
  return new Etcd(
    this.etcd.hosts,
    Object.keys(this.etcd.ssloptions).length ? this.etcd.ssloptions : undefined
  );
};

// set a key in the environment.
REnv.prototype.set = function(key, value, cb) {
  var _this = this;

  if (typeof value === 'function') [cb, value] = [value, cb];

  if (Array.isArray(key)) {
    key = this._expandEquals(key);

    return Promise.all(
      _.chunk(key, 2).map(pair => {
        return this.set(pair[0], pair[1])
      })
    ).nodeify(cb);
  } else if (typeof key === 'object') {
    return this.setObject(key).nodeify(cb);
  } else if (~key.indexOf('.')) {
    var obj = {};
    traverse(obj).set(key.split('.'), value);
    return this.set(obj).nodeify(cb);
  } else {
    key = this._buildKey() + key;

    return new Promise(function(resolve, reject) {
      _this.client.set(key, value, function(err, result) {
        if (err) reject(err);
        else resolve(result);
      });
    }).nodeify(cb);
  }
};

// treat arguments seperated by equal sign as
// two arguments.
REnv.prototype._expandEquals = function(arr) {
  var result = [];
  arr.forEach(value => {result.push.apply(result, ('' + value).split('='))});
  return result;
};

REnv.prototype.mkdir = function(dir, cb) {
  var _this = this,
    dir = this._buildKey() + dir;

  return new Promise(function(resolve, reject) {
    _this.client.mkdir(dir, function(err, result) {
      if (err && err.errorCode === 102) return resolve(); // already exists.
      else if (err) reject(err);
      else resolve(result);
    });
  }).nodeify(cb);
};

REnv.prototype._buildKey = function() {
  return '/' + this.application + '/' + this.environment + '/';
};

// fetch a single key.
REnv.prototype.get = function(key, cb) {
  var _this = this,
    key = this._buildKey() + key;

  return new Promise(function(resolve, reject) {
    _this.client.get(key, function(err, result) {
      if (err && err.errorCode === 100) resolve(null);
      else if (err) reject(err);
      else resolve(result.node.value);
    });
  }).nodeify(cb);
};

// return all key value pairs in enviornment.
REnv.prototype.getEnvironment = function(key, cb) {
  if (typeof key === 'function') [cb, key] = [key, cb];

  var _this = this,
    environment = {},
    key = key || this._buildKey(),
    node = null,
    nodes = [];

  return new Promise(function(resolve, reject) {
    _this.client.get(key, {recursive: true}, function(err, result) {
      if (err && err.errorCode === 100) resolve({});
      else if (err) reject(err);
      else {
        if (!result.node.nodes) return resolve({});

        result.node.nodes.forEach(node => {nodes.push(node)});

        // recursively walk the nodes, and
        // rebuild an object.
        while (nodes.length) {
          node = nodes.pop();
          if (node.dir && node.nodes) {
            node.nodes.forEach(node => {nodes.push(node)});
          } else {
            if (node.dir) node.value = {};
            traverse(environment).set(node.key.replace(key, '').split('/'), node.value);
          }
        }

        return resolve(quack.deep(environment));
      }
    });
  }).nodeify(cb);
};

REnv.prototype.setObject = REnv.prototype.setEnvironment = function(obj, cb) {
  var paths = traverse(obj).paths();

  return Promise.each(paths, path => {
    var key = path.join('/'),
      value = traverse(obj).get(path);

    if (typeof value === 'object') {
      return this.mkdir(key, '');
    } else {
      return this.set(key, value);
    }
  }).nodeify(cb);
};

REnv.prototype.del = function(key, cb) {
  if (Array.isArray(key)) {
    return Promise.all(
      _.map(key, k => {return this.del(k);})
    );
  } else {
    return this._del(key, {recursive: true})
      .nodeify(cb);
  }
};

// delete all keys in the environment.
REnv.prototype.deleteEnvironment = function(cb) {
  return this._del('', {recursive: true}).nodeify(cb);
};

// helper used by delete and delete environment.
REnv.prototype._del = function(key, opts) {
  var _this = this,
    path = this._buildKey() + key;

  return new Promise(function(resolve, reject) {
    _this.client.delete(path, opts, function(err, result) {
      if (err) reject(err);
      else resolve(result);
    });
  });
};

module.exports = REnv;
<commit_msg>use empty string rather than undefined.<commit_after>var _ = require('lodash'),
  Etcd = require('node-etcd'),
  Promise = require('bluebird'),
  traverse = require('traverse'),
  quack = require('quack-array');

function REnv(opts) {
  _.extend(this, {
    application: 'app',
    environment: 'development',
    etcd: {
      hosts: ['127.0.0.1:4001'],
      ssloptions: {}
    }
  }, opts);

  if (!this.client) this.client = this.createClient();
}

// create the etcd client.
REnv.prototype.createClient = function() {
  return new Etcd(
    this.etcd.hosts,
    Object.keys(this.etcd.ssloptions).length ? this.etcd.ssloptions : undefined
  );
};

// set a key in the environment.
REnv.prototype.set = function(key, value, cb) {
  var _this = this;

  if (typeof value === 'function') [cb, value] = [value, cb];

  if (Array.isArray(key)) {
    key = this._expandEquals(key);

    return Promise.all(
      _.chunk(key, 2).map(pair => {
        return this.set(pair[0], pair[1])
      })
    ).nodeify(cb);
  } else if (typeof key === 'object') {
    return this.setObject(key).nodeify(cb);
  } else if (~key.indexOf('.')) {
    var obj = {};
    traverse(obj).set(key.split('.'), value);
    return this.set(obj).nodeify(cb);
  } else {
    key = this._buildKey() + key;

    return new Promise(function(resolve, reject) {
      _this.client.set(key, value, function(err, result) {
        if (err) reject(err);
        else resolve(result);
      });
    }).nodeify(cb);
  }
};

// treat arguments seperated by equal sign as
// two arguments.
REnv.prototype._expandEquals = function(arr) {
  var result = [];
  arr.forEach(value => {result.push.apply(result, ('' + value).split('='))});
  return result;
};

REnv.prototype.mkdir = function(dir, cb) {
  var _this = this,
    dir = this._buildKey() + dir;

  return new Promise(function(resolve, reject) {
    _this.client.mkdir(dir, function(err, result) {
      if (err && err.errorCode === 102) return resolve(); // already exists.
      else if (err) reject(err);
      else resolve(result);
    });
  }).nodeify(cb);
};

REnv.prototype._buildKey = function() {
  return '/' + this.application + '/' + this.environment + '/';
};

// fetch a single key.
REnv.prototype.get = function(key, cb) {
  var _this = this,
    key = this._buildKey() + key;

  return new Promise(function(resolve, reject) {
    _this.client.get(key, function(err, result) {
      if (err && err.errorCode === 100) resolve(null);
      else if (err) reject(err);
      else resolve(result.node.value);
    });
  }).nodeify(cb);
};

// return all key value pairs in enviornment.
REnv.prototype.getEnvironment = function(key, cb) {
  if (typeof key === 'function') [cb, key] = [key, cb];

  var _this = this,
    environment = {},
    key = key || this._buildKey(),
    node = null,
    nodes = [];

  return new Promise(function(resolve, reject) {
    _this.client.get(key, {recursive: true}, function(err, result) {
      if (err && err.errorCode === 100) resolve({});
      else if (err) reject(err);
      else {
        if (!result.node.nodes) return resolve({});

        result.node.nodes.forEach(node => {nodes.push(node)});

        // recursively walk the nodes, and
        // rebuild an object.
        while (nodes.length) {
          node = nodes.pop();
          if (node.dir && node.nodes) {
            node.nodes.forEach(node => {nodes.push(node)});
          } else {
            if (node.dir) node.value = {};
            traverse(environment).set(node.key.replace(key, '').split('/'), node.value || '');
          }
        }

        return resolve(quack.deep(environment));
      }
    });
  }).nodeify(cb);
};

REnv.prototype.setObject = REnv.prototype.setEnvironment = function(obj, cb) {
  var paths = traverse(obj).paths();

  return Promise.each(paths, path => {
    var key = path.join('/'),
      value = traverse(obj).get(path);

    if (typeof value === 'object') {
      return this.mkdir(key, '');
    } else {
      return this.set(key, value);
    }
  }).nodeify(cb);
};

REnv.prototype.del = function(key, cb) {
  if (Array.isArray(key)) {
    return Promise.all(
      _.map(key, k => {return this.del(k);})
    );
  } else {
    return this._del(key, {recursive: true})
      .nodeify(cb);
  }
};

// delete all keys in the environment.
REnv.prototype.deleteEnvironment = function(cb) {
  return this._del('', {recursive: true}).nodeify(cb);
};

// helper used by delete and delete environment.
REnv.prototype._del = function(key, opts) {
  var _this = this,
    path = this._buildKey() + key;

  return new Promise(function(resolve, reject) {
    _this.client.delete(path, opts, function(err, result) {
      if (err) reject(err);
      else resolve(result);
    });
  });
};

module.exports = REnv;
<|endoftext|>


<commit_before>'use strict'

const editInVim = require('edit-in-vim')
const promisify = require('tiny-promisify')
const chalk = require('chalk')

var config = require('./config')

const Trello = new (require('node-trello'))(config.devKey)
Trello.getAsync = promisify(Trello.get, {context: Trello})
Trello.putAsync = promisify(Trello.put, {context: Trello})
Trello.postAsync = promisify(Trello.post, {context: Trello})
Trello.delAsync = promisify(Trello.del, {context: Trello})

var session = module.exports.session = {
  'user': null,
  'notifications': null,
  'current': {
    'entity': [],
    'vcommands': [],
    'boards': [],
    'lists': [],
    'cards': [],
    'card': {},
    'checklists': [],
    'comments': [],
    'attachments': []
  }
}

const helpers = require('./helpers')

const vorpal = require('vorpal')()
vorpal
  .use('vorpal-less')

/* changing default commands */
vorpal.find('help').alias('?')
vorpal.find('exit').description(`Exits ${config.name}.`)

vorpal
  .command('auth')
  .option('-t, --token [val]', `Trello API token for key ${config.devKey}`)
  .action(function (args, cb) {
    if (args.options.token) config.store.set('token', args.options.token)
    let userToken = config.store.get('token')
    if (userToken) {
      Trello.token = userToken
      logged.call(this, cb)
    } else {
      this.log(`For the first access, you will have to get an authorization token from Trello.
Please go to

    https://trello.com/1/connect?key=${config.devKey}&name=${config.name}&response_type=token&expires=never&scope=read,write

`)
      this.prompt({
        type: 'input',
        name: 'token',
        message: `and paste here the token you'll get: `
      }, (result) => {
        config.store.set('token', result.token)
        Trello.token = result.token
        logged.call(this, cb)
      })
    }
  })

vorpal
  .command('cd [path]', 'move back in the hierarchy')
  .action(function (args, cb) {
    if (args.path !== '..') {
      return cb() // only support '..' for now
    }

    session.current.entity.shift()
    let entity = session.current.entity[0]
    let level = helpers.currentLevel()
    switch (level) {
      case 'card':
        enterCard.call(this, entity, cb)
        break
      case 'list':
        enterList.call(this, entity, cb)
        break
      case 'board':
        enterBoard.call(this, entity, cb)
        break
      case 'user':
        logged.call(this, cb)
        break
    }
  })

vorpal
  .command('ls', 'show info about current board, list or card.')
  .alias('info')
  .action(function (_, cb) {
    switch (helpers.currentLevel()) {
      case 'auth':
        break
      case 'user':
        helpers.listBoards.call(this)
        break
      case 'board':
        helpers.listLists.call(this)
        break
      case 'list':
        helpers.listCards.call(this)
        break
      case 'card':
        helpers.cardInfo.call(this)
    }
    cb()
  })

module.exports = vorpal.delimiter(helpers.color(config.name) + '~$')

function enterCard (card, cb) {
  this.delimiter('entering ' + card.name + '...')
  return Trello.getAsync(`/1/cards/${card.id}`, {
    fields: 'id',
    actions: 'commentCard,copyCommentCard',
    actions_limit: 5,
    actions_entities: 'true',
    action_memberCreator_fields: 'username',
    attachments: 'true',
    attachment_fields: 'name,url',
    checklists: 'all',
    checkItemStates: 'true',
    checklist_fields: 'name'
  })
  .then(res => {
    vorpal.delimiter(helpers.color(helpers.slug(card)) + '~$')
    session.current.comments = res.actions
    session.current.attachments = res.attachments
    session.current.checklists = res.checklists
    session.current.card = card
  })
  .then(() => {
    // clean old commands
    for (var k in session.current.vcommands) {
      session.current.vcommands[k].remove()
      delete session.current.vcommands[k]
    }

    // add new commands
    session.current.vcommands['edit'] = vorpal
      .command('edit', "edit this card's description.")
      .action(function (_, cb) {
        let newdesc = editInVim(card.desc)
        this.log('\n' + helpers.md(newdesc) + '\n')
        this.prompt({
          type: 'confirm',
          name: 'confirm',
          message: 'Are you really sure you want to replace the current desc with the one you just wrote?'
        }, res => {
          if (!res.confirm) return cb()
          Trello.putAsync(`/1/cards/${card.id}/desc`, {value: newdesc})
          .then(() => cb(chalk.bold('description edited!')))
          .catch(e => this.log(e.stack) && process.exit())
        })
      })

    session.current.vcommands['comment'] = vorpal
      .command('add comment [text...]', 'post a comment to this card')
      .alias('post')
      .action(function (args, cb) {
        let newcomment = editInVim((args.text || []).join(' ') || '')
        if (!newcomment.trim()) {
          cb()
        }
        this.log('\n' + helpers.md(newcomment) + '\n')
        this.prompt({
          type: 'confirm',
          name: 'confirm',
          message: 'Are you really sure you want to post this comment?'
        }, res => {
          if (!res.confirm) return cb()
          Trello.postAsync(`/1/cards/${card.id}/actions/comments`, {text: newcomment})
          .then(() => cb(chalk.bold('comment posted!')))
          .catch(e => this.log(e.stack) && process.exit())
        })
      })

    session.current.vcommands['desc'] = vorpal
      .command('desc', "show this card's description.")
      .action(function (_, cb) {
        this.log('\n' + helpers.md(session.current.card.desc) + '\n')
        cb()
      })

    session.current.vcommands['comments'] = vorpal
      .command('comments', "list this card's comments.")
      .action(function (_, cb) {
        helpers.listComments.call(this)
        cb()
      })

    session.current.vcommands['checklists'] = vorpal
      .command('checklists', "show this card's checklists.")
      .action(function (_, cb) {
        helpers.listChecklists.call(this)
        cb()
      })

    session.current.vcommands['attachments'] = vorpal
      .command('attachments', "show this card's attachments.")
      .action(function (_, cb) {
        helpers.listAttachments.call(this)
        cb()
      })
  })
  .then(() => {
    this.log(`entered card '${card.name}' ${card.due ? '(' + card.due.split('.')[0] + ')' : ''}`)
    helpers.cardInfo.call(this)
    this.log(`
type
'${chalk.underline('desc')}' to read this card's description ('${chalk.underline('desc | less')}' for long descriptions);
'${chalk.underline('edit')}' to edit and replace the description;
'${chalk.underline('comments')}' to read comments ('${chalk.underline('comments | less')}' for long comments);
'${chalk.underline('post')}' to write a new comment;
'${chalk.underline('checklists')}' to see checklists in this card;
'${chalk.underline('attachments')}' to see attachments in this card;
'${chalk.underline('ls')}' to show card information again; or
'${chalk.underline('cd ..')}' to go back to previous view.`)
  })
  .then(() => cb())
  .catch(e => this.log(e.stack) && process.exit())
}

function enterList (list, cb) {
  this.delimiter('entering ' + list.name + '...')
  return Trello.getAsync(`/1/lists/${list.id}`, {
    fields: 'id',
    cards: 'open',
    card_fields: 'name,desc,due'
  })
  .then(res => {
    vorpal.delimiter(helpers.color(helpers.slug(list)) + '~$')
    session.current.cards = res.cards
  })
  .then(() => {
    // clean old commands
    for (var k in session.current.vcommands) {
      session.current.vcommands[k].remove()
      delete session.current.vcommands[k]
    }

    // add new commands
    session.current.vcommands['add card'] = vorpal
      .command('add card <name...>', 'create a new card on this list.')
      .option('-t, --top', 'Put the card on the top of the list (default is bottom).')
      .option('-d, --due [val]', 'Set a due date.')
      .action(function (args, cb) {
        let data = {
          name: args.name.join(' '),
          desc: editInVim(''),
          pos: (args.options.top ? 'top' : 'bottom'),
          idList: list.id,
          due: (args.options.due ? (new Date(Date.parse(args.options.due))).toISOString() : null)
        }
        this.log('\n' + chalk.bold(data.name) + '\n' + helpers.md(data.desc) + '\n')
        this.prompt({
          type: 'confirm',
          name: 'confirm',
          message: 'Create this card?'
        }, res => {
          if (!res.confirm) return cb()
          Trello.postAsync(`/1/cards`, data)
          .then(() => cb(chalk.bold('card created!')))
          .catch(e => this.log(e.stack) && process.exit())
        })
      })

    session.current.cards.forEach(card => {
      let slug = helpers.slug(card)
      session.current.vcommands[slug] = vorpal
        .command(`card ${slug}`, `enters card '${card.name}'`)
        .alias(slug)
        .action(function (_, cb) {
          session.current.entity.unshift(card)
          enterCard.call(this, card, cb)
        })
    })
  })
  .then(() => {
    this.log(`entered list ${list.name}`)
    helpers.listCards.call(this)
    this.log(`\n
type the name of a card to enter it;
'${chalk.underline('add card')}' to add a card;
'${chalk.underline('ls')}' to list cards again; or
'${chalk.underline('cd ..')}' to go back to board view.`)
  })
  .then(() => cb())
  .catch(e => this.log(e.stack) && process.exit())
}

function enterBoard (board, cb) {
  this.delimiter('entering ' + board.name + '...')
  return Trello.getAsync(`/1/boards/${board.id}`, {
    fields: 'id',
    actions: 'all',
    actions_since: 'lastView',
    lists: 'open',
    list_fields: 'name',
    cards: 'open',
    card_fields: 'name,idList,desc,due'
  })
  .then(res => {
    vorpal.delimiter(helpers.color(helpers.slug(board)) + '~$')
    res.lists.forEach(l => {
      l.cards = []
      res.cards.forEach(c => {
        if (l.id === c.idList) {
          l.cards.push(c)
        }
      })
    })
    session.current.lists = res.lists
  })
  .then(() => {
    // clean old commands
    for (var k in session.current.vcommands) {
      session.current.vcommands[k].remove()
      delete session.current.vcommands[k]
    }

    // add new commands
    session.current.lists.forEach(list => {
      let slug = helpers.slug(list)
      session.current.vcommands[slug] = vorpal
        .command(`list ${slug}`, `enters list '${list.name}'`)
        .alias(slug)
        .action(function (_, cb) {
          session.current.entity.unshift(list)
          enterList.call(this, list, cb)
        })

      list.cards.forEach(card => {
        let slug = helpers.slug(card)
        session.current.vcommands[slug] = vorpal
          .command(`card ${slug}`, `enters card '${card.name}'`)
          .alias(slug)
          .action(function () {
            session.current.entity.unshift(card)
            enterCard.call(this, card, cb)
          })
      })
    })
  })
  .then(() => {
    this.log(`entered board ${board.name}`)
    helpers.listLists.call(this)
    this.log(`\n
type the name of a list to enter it;
type the name of a card to enter it;
'${chalk.underline('ls')}' to list lists again; or
'${chalk.underline('cd ..')}' to go back to board selection`)
  })
  .then(() => cb())
  .catch(e => this.log(e.stack) && process.exit())
}

function logged (cb) {
  this.delimiter('fetching your data...')
  return Trello.getAsync('/1/members/me', {
    fields: 'username',
    boards: 'open',
    board_fields: 'dateLastActivity,desc,name,memberships',
    board_memberships: 'active',
    board_lists: 'open',
    notifications: 'all',
    notifications_limit: 50
  })
  .catch(e => {
    this.log('Invalid token: "' + Trello.token + '"')
    config.store.set('token', undefined)
    this.log(`Please start ${config.name} again and provide a valid token.`)
    process.exit()
  })
  .then(res => {
    session.notifications = res.notifications.filter(d => d.unread)
    delete res.notifications
    session.current.boards = res.boards
    delete res.boards
    session.user = res
  })
  .then(() => {
    // clean old commands
    for (var k in session.current.vcommands) {
      session.current.vcommands[k].remove()
      delete session.current.vcommands[k]
    }

    // add new commands
    session.current.boards.forEach(board => {
      let slug = helpers.slug(board)
      session.current.vcommands[slug] = vorpal
        .command(`board ${slug}`, `enters board '${board.name}'`)
        .alias(slug)
        .action(function (_, cb) {
          session.current.entity.unshift(board)
          enterBoard.call(this, board, cb)
        })
    })
  })
  .then(() => {
    let authCommand = vorpal.find('auth')
    if (authCommand) authCommand.remove()
    vorpal.delimiter(helpers.color(session.user.username + '@trello') + '~$')
    this.log(`connected as ${session.user.username}`)
    helpers.listBoards.call(this)
    this.log(`
type the name of a board to enter it;
or '${chalk.underline('ls')}' to list them again.`)
    cb()
  })
  .catch(e => this.log(e.stack) && process.exit())
}
<commit_msg>update lists and cards after posting data to Trello.<commit_after>'use strict'

const editInVim = require('edit-in-vim')
const promisify = require('tiny-promisify')
const chalk = require('chalk')

var config = require('./config')

const Trello = new (require('node-trello'))(config.devKey)
Trello.getAsync = promisify(Trello.get, {context: Trello})
Trello.putAsync = promisify(Trello.put, {context: Trello})
Trello.postAsync = promisify(Trello.post, {context: Trello})
Trello.delAsync = promisify(Trello.del, {context: Trello})

global.session = module.exports.session = {
  'user': null,
  'notifications': null,
  'current': {
    'entity': [],
    'vcommands': [],
    'boards': [],
    'lists': [],
    'cards': [],
    'card': {},
    'checklists': [],
    'comments': [],
    'attachments': []
  }
}

const helpers = require('./helpers')

const vorpal = require('vorpal')()
vorpal
  .use('vorpal-less')

/* changing default commands */
vorpal.find('help').alias('?')
vorpal.find('exit').description(`Exits ${config.name}.`)

vorpal
  .command('auth')
  .option('-t, --token [val]', `Trello API token for key ${config.devKey}`)
  .action(function (args, cb) {
    if (args.options.token) config.store.set('token', args.options.token)
    let userToken = config.store.get('token')
    if (userToken) {
      Trello.token = userToken
      logged.call(this, cb)
    } else {
      this.log(`For the first access, you will have to get an authorization token from Trello.
Please go to

    https://trello.com/1/connect?key=${config.devKey}&name=${config.name}&response_type=token&expires=never&scope=read,write

`)
      this.prompt({
        type: 'input',
        name: 'token',
        message: `and paste here the token you'll get: `
      }, (result) => {
        config.store.set('token', result.token)
        Trello.token = result.token
        logged.call(this, cb)
      })
    }
  })

vorpal
  .command('cd [path]', 'move back in the hierarchy')
  .action(function (args, cb) {
    if (args.path !== '..') {
      return cb() // only support '..' for now
    }

    global.session.current.entity.shift()
    let entity = global.session.current.entity[0]
    let level = helpers.currentLevel()
    switch (level) {
      case 'card':
        enterCard.call(this, entity, cb)
        break
      case 'list':
        enterList.call(this, entity, cb)
        break
      case 'board':
        enterBoard.call(this, entity, cb)
        break
      case 'user':
        logged.call(this, cb)
        break
    }
  })

vorpal
  .command('ls', 'show info about current board, list or card.')
  .alias('info')
  .action(function (_, cb) {
    switch (helpers.currentLevel()) {
      case 'auth':
        break
      case 'user':
        helpers.listBoards.call(this)
        break
      case 'board':
        helpers.listLists.call(this)
        break
      case 'list':
        helpers.listCards.call(this)
        break
      case 'card':
        helpers.cardInfo.call(this)
    }
    cb()
  })

module.exports = vorpal.delimiter(helpers.color(config.name) + '~$')

function enterCard (card, cb) {
  this.delimiter('entering ' + card.name + '...')
  return Trello.getAsync(`/1/cards/${card.id}`, {
    fields: 'id',
    actions: 'commentCard,copyCommentCard',
    actions_limit: 5,
    actions_entities: 'true',
    action_memberCreator_fields: 'username',
    attachments: 'true',
    attachment_fields: 'name,url',
    checklists: 'all',
    checkItemStates: 'true',
    checklist_fields: 'name'
  })
  .then(res => {
    vorpal.delimiter(helpers.color(helpers.slug(card)) + '~$')
    global.session.current.comments = res.actions
    global.session.current.attachments = res.attachments
    global.session.current.checklists = res.checklists
    global.session.current.card = card
  })
  .then(() => {
    // clean old commands
    for (var k in global.session.current.vcommands) {
      global.session.current.vcommands[k].remove()
      delete global.session.current.vcommands[k]
    }

    // add new commands
    global.session.current.vcommands['edit'] = vorpal
      .command('edit', "edit this card's description.")
      .action(function (_, cb) {
        let newdesc = editInVim(card.desc)
        this.log('\n' + helpers.md(newdesc) + '\n')
        this.prompt({
          type: 'confirm',
          name: 'confirm',
          message: 'Are you really sure you want to replace the current desc with the one you just wrote?'
        }, res => {
          if (!res.confirm) return cb()
          Trello.putAsync(`/1/cards/${card.id}/desc`, {value: newdesc})
          .then(() => this.log(chalk.bold('description edited!')))
          .then(updateCard.bind(this, card))
          .then(cb)
          .catch(e => this.log(e.stack) && process.exit())
        })
      })

    global.session.current.vcommands['comment'] = vorpal
      .command('add comment [text...]', 'post a comment to this card')
      .alias('post')
      .alias('comment')
      .action(function (args, cb) {
        let newcomment = editInVim((args.text || []).join(' ') || '')
        if (!newcomment.trim()) {
          cb()
        }
        this.log('\n' + helpers.md(newcomment) + '\n')
        this.prompt({
          type: 'confirm',
          name: 'confirm',
          message: 'Are you really sure you want to post this comment?'
        }, res => {
          if (!res.confirm) return cb()
          Trello.postAsync(`/1/cards/${card.id}/actions/comments`, {text: newcomment})
          .then(() => this.log(chalk.bold('comment posted!')))
          .then(updateCard.bind(this, card))
          .then(cb)
          .catch(e => this.log(e.stack) && process.exit())
        })
      })

    global.session.current.vcommands['desc'] = vorpal
      .command('desc', "show this card's description.")
      .action(function (_, cb) {
        this.log('\n' + helpers.md(global.session.current.card.desc) + '\n')
        cb()
      })

    global.session.current.vcommands['comments'] = vorpal
      .command('comments', "list this card's comments.")
      .action(function (_, cb) {
        helpers.listComments.call(this)
        cb()
      })

    global.session.current.vcommands['checklists'] = vorpal
      .command('checklists', "show this card's checklists.")
      .action(function (_, cb) {
        helpers.listChecklists.call(this)
        cb()
      })

    global.session.current.vcommands['attachments'] = vorpal
      .command('attachments', "show this card's attachments.")
      .action(function (_, cb) {
        helpers.listAttachments.call(this)
        cb()
      })
  })
  .then(() => {
    this.log(`entered card '${card.name}' ${card.due ? '(' + card.due.split('.')[0] + ')' : ''}`)
    helpers.cardInfo.call(this)
    this.log(`
type
'${chalk.underline('desc')}' to read this card's description ('${chalk.underline('desc | less')}' for long descriptions);
'${chalk.underline('edit')}' to edit and replace the description;
'${chalk.underline('comments')}' to read comments ('${chalk.underline('comments | less')}' for long comments);
'${chalk.underline('post')}' to write a new comment;
'${chalk.underline('checklists')}' to see checklists in this card;
'${chalk.underline('attachments')}' to see attachments in this card;
'${chalk.underline('ls')}' to show card information again; or
'${chalk.underline('cd ..')}' to go back to previous view.`)
  })
  .then(() => cb())
  .catch(e => this.log(e.stack) && process.exit())
}

function updateCard (card) {
  return Trello.getAsync(`/1/cards/${card.id}`, {
    fields: 'name,desc,due',
    actions: 'commentCard,copyCommentCard',
    actions_limit: 5,
    actions_entities: 'true',
    action_memberCreator_fields: 'username',
    attachments: 'true',
    attachment_fields: 'name,url',
    checklists: 'all',
    checkItemStates: 'true',
    checklist_fields: 'name'
  })
  .then(res => {
    global.session.current.card.desc = res.desc
    global.session.current.card.due = res.due
    global.session.current.card.name = res.name
    global.session.current.comments = res.actions
    global.session.current.attachments = res.attachments
    global.session.current.checklists = res.checklists
    global.session.current.card = card
  })
}

function updateList (list) {
  return Trello.getAsync(`/1/lists/${list.id}`, {
    fields: 'id',
    cards: 'open',
    card_fields: 'name,desc,due'
  })
  .then(res => {
    global.session.current.cards = res.cards
  })
}

function enterList (list, cb) {
  this.delimiter('entering ' + list.name + '...')
  return Trello.getAsync(`/1/lists/${list.id}`, {
    fields: 'id',
    cards: 'open',
    card_fields: 'name,desc,due'
  })
  .then(res => {
    vorpal.delimiter(helpers.color(helpers.slug(list)) + '~$')
    global.session.current.cards = res.cards
  })
  .then(() => {
    // clean old commands
    for (var k in global.session.current.vcommands) {
      global.session.current.vcommands[k].remove()
      delete global.session.current.vcommands[k]
    }

    // add new commands
    global.session.current.vcommands['add card'] = vorpal
      .command('add card <name...>', 'create a new card on this list.')
      .option('-t, --top', 'Put the card on the top of the list (default is bottom).')
      .option('-d, --due [val]', 'Set a due date.')
      .action(function (args, cb) {
        let data = {
          name: args.name.join(' '),
          desc: editInVim(''),
          pos: (args.options.top ? 'top' : 'bottom'),
          idList: list.id,
          due: (args.options.due ? (new Date(Date.parse(args.options.due))).toISOString() : null)
        }
        this.log('\n' + chalk.bold(data.name) + '\n' + helpers.md(data.desc) + '\n')
        this.prompt({
          type: 'confirm',
          name: 'confirm',
          message: 'Create this card?'
        }, res => {
          if (!res.confirm) return cb()
          Trello.postAsync(`/1/cards`, data)
          .then(() => this.log(chalk.bold('card created!')))
          .then(updateList.bind(this, list))
          .then(cb)
          .catch(e => this.log(e.stack) && process.exit())
        })
      })

    global.session.current.cards.forEach(card => {
      let slug = helpers.slug(card)
      global.session.current.vcommands[slug] = vorpal
        .command(`card ${slug}`, `enters card '${card.name}'`)
        .alias(slug)
        .action(function (_, cb) {
          global.session.current.entity.unshift(card)
          enterCard.call(this, card, cb)
        })
    })
  })
  .then(() => {
    this.log(`entered list ${list.name}`)
    helpers.listCards.call(this)
    this.log(`\n
type the name of a card to enter it;
'${chalk.underline('add card')}' to add a card;
'${chalk.underline('ls')}' to list cards again; or
'${chalk.underline('cd ..')}' to go back to board view.`)
  })
  .then(() => cb())
  .catch(e => this.log(e.stack) && process.exit())
}

function enterBoard (board, cb) {
  this.delimiter('entering ' + board.name + '...')
  return Trello.getAsync(`/1/boards/${board.id}`, {
    fields: 'id',
    actions: 'all',
    actions_since: 'lastView',
    lists: 'open',
    list_fields: 'name',
    cards: 'open',
    card_fields: 'name,idList,desc,due'
  })
  .then(res => {
    vorpal.delimiter(helpers.color(helpers.slug(board)) + '~$')
    res.lists.forEach(l => {
      l.cards = []
      res.cards.forEach(c => {
        if (l.id === c.idList) {
          l.cards.push(c)
        }
      })
    })
    global.session.current.lists = res.lists
  })
  .then(() => {
    // clean old commands
    for (var k in global.session.current.vcommands) {
      global.session.current.vcommands[k].remove()
      delete global.session.current.vcommands[k]
    }

    // add new commands
    global.session.current.lists.forEach(list => {
      let slug = helpers.slug(list)
      global.session.current.vcommands[slug] = vorpal
        .command(`list ${slug}`, `enters list '${list.name}'`)
        .alias(slug)
        .action(function (_, cb) {
          global.session.current.entity.unshift(list)
          enterList.call(this, list, cb)
        })

      list.cards.forEach(card => {
        let slug = helpers.slug(card)
        global.session.current.vcommands[slug] = vorpal
          .command(`card ${slug}`, `enters card '${card.name}'`)
          .alias(slug)
          .action(function () {
            global.session.current.entity.unshift(card)
            enterCard.call(this, card, cb)
          })
      })
    })
  })
  .then(() => {
    this.log(`entered board ${board.name}`)
    helpers.listLists.call(this)
    this.log(`\n
type the name of a list to enter it;
type the name of a card to enter it;
'${chalk.underline('ls')}' to list lists again; or
'${chalk.underline('cd ..')}' to go back to board selection`)
  })
  .then(() => cb())
  .catch(e => this.log(e.stack) && process.exit())
}

function logged (cb) {
  this.delimiter('fetching your data...')
  return Trello.getAsync('/1/members/me', {
    fields: 'username',
    boards: 'open',
    board_fields: 'dateLastActivity,desc,name,memberships',
    board_memberships: 'active',
    board_lists: 'open',
    notifications: 'all',
    notifications_limit: 50
  })
  .catch(e => {
    this.log('Invalid token: "' + Trello.token + '"')
    config.store.set('token', undefined)
    this.log(`Please start ${config.name} again and provide a valid token.`)
    process.exit()
  })
  .then(res => {
    global.session.notifications = res.notifications.filter(d => d.unread)
    delete res.notifications
    global.session.current.boards = res.boards
    delete res.boards
    global.session.user = res
  })
  .then(() => {
    // clean old commands
    for (var k in global.session.current.vcommands) {
      global.session.current.vcommands[k].remove()
      delete global.session.current.vcommands[k]
    }

    // add new commands
    global.session.current.boards.forEach(board => {
      let slug = helpers.slug(board)
      global.session.current.vcommands[slug] = vorpal
        .command(`board ${slug}`, `enters board '${board.name}'`)
        .alias(slug)
        .action(function (_, cb) {
          global.session.current.entity.unshift(board)
          enterBoard.call(this, board, cb)
        })
    })
  })
  .then(() => {
    let authCommand = vorpal.find('auth')
    if (authCommand) authCommand.remove()
    vorpal.delimiter(helpers.color(global.session.user.username + '@trello') + '~$')
    this.log(`connected as ${global.session.user.username}`)
    helpers.listBoards.call(this)
    this.log(`
type the name of a board to enter it;
or '${chalk.underline('ls')}' to list them again.`)
    cb()
  })
  .catch(e => this.log(e.stack) && process.exit())
}
<|endoftext|>


<commit_before>var request = require('request')
var mkdirp =  require('mkdirp')
var fs = require('fs')

var base = 'https://api.github.com'

var headers = {"user-agent": "offline-issues module",}
var pageNum = 1
var repoNum = 1

// {
//   _: [ 'jlord/offline-issues', 'muan/github-gmail' ],
//   by: 'jlord',
//   all: true
// }

module.exports = function getIssues(token, options, cb) {
  if (!options._) return cb("No repository given.")
  parseRepo(options)

  headers["Authorization"] = 'token ' + token.token

  // https://api.github.com/repos/github/

}

function parseRepo(options) {
  options.numberOf = options._.length
  options.repos = []

  options._.forEach(function(repo) {
    var repoDetails = {}
    repoDetails.full = repo
    var userAndRepo = repo.split('/')
    repoDetails.user = userAndRepo[0]
    if (userAndRepo[1].indexOf('#') >= 0) {
      var repoAndIssue = userAndRepo[1].split('#')
      repoDetails.name = repoAndIssue[0]
      repoDetails.issue = repoAndIssue[1]
    } else { repoDetails.name = userAndRepo[1] }
    options.repos.push(repoDetails)
  })
  console.log(options)
  // do what's next
  // route off requests
  // makeRequest(pageNum, options)
}

function makeRequest(i, options) {
  var query = '/issues?page='
  var limit = '&per_page=100'

  options.repos.forEach(function (repo) {
    var url = base + '/repos/' + user + '/' + repo + query + pageNum + limit
    // request(url, {json: true, headers: headers}, getIssues)
  })
}

// taken from other module, need to adapt
function getIssues(err, response, body) {
  if (err) console.log(err)
  // if there are no more repos to look through
  if (repoNum === nuxrepos.length) {
    console.log("Done with all, writing file")
    return writeIssues()
  }
  // if there are no more issues to look through
  if (body.length === 0) {
    console.log("Done, moving on to " + nuxrepos[r])
    return nextRepo()
  }
  var issues = body
  // add some extra info to each issue
  issues.forEach(function(issue) {
    issue.parentrepo = nuxrepos[r]
    issue.pr = false
    if (issue.pull_request) issue.pr = true

    var labels = issue.labels
    // see if issue has one of our labels
    labels.forEach(function(label) {
      if (label.name === labelPrefix) {
        return relevant.push(issue)
      }
    })
  })
  // go the the next page of issues
  i++
  requestIssues(i, nuxrepos[r])
}

function filterIssues(err, resp, body) {
  if (err) console.log(err)

}
<commit_msg>back up, just mvp it<commit_after>var request = require('request')
var mkdirp =  require('mkdirp')
var fs = require('fs')

var base = 'https://api.github.com'

var headers = {"user-agent": "offline-issues module",}
var pageNum = 1
var repoNum = 1

// {
//   _: [ 'jlord/offline-issues', 'muan/github-gmail' ],
//   by: 'jlord', l: [help, easy],
//   all: true, o: true, c: true,
//
// }

module.exports = function getIssues(token, options, cb) {
  if (!options._) return cb("No repository given.")
  parseRepo(options)

  headers["Authorization"] = 'token ' + token.token

  // https://api.github.com/repos/github/

}

function parseRepo(options) {
  options.numberOf = options._.length
  options.repos = []

  options._.forEach(function(repo) {
    var repoDetails = {}
    repoDetails.full = repo
    var userAndRepo = repo.split('/')
    repoDetails.user = userAndRepo[0]
    if (userAndRepo[1].indexOf('#') >= 0) {
      var repoAndIssue = userAndRepo[1].split('#')
      repoDetails.name = repoAndIssue[0]
      repoDetails.issue = repoAndIssue[1]
    } else { repoDetails.name = userAndRepo[1] }
    options.repos.push(repoDetails)
  })
  console.log(options)
  // do what's next
  // route off requests
  // makeRequest(pageNum, options)
  //options.repos.forEach(...)
  options.repos.forEach(getIssue)
}

function getIssue(repo) {
    var url = base + '/repos/' + repo.user + '/' + repo.name + '/issues/' + repo.issue
    console.log("url", url)
    request(url, {json: true, headers: headers}, getComments)
}

function getComments(err, resp, body) {
  if (err) return console.log(err)
  // var url = base + '/repos/' + repo.user + '/' + repo.name + '/issues/' + repo.issue + '/comments'

  console.log(body)
}

// function buildQuery(options) {
//   var issuesAll = ''
//   var issuesClosed = ''
//   var issuesOpen = ''
//   var author = ''
//   var labels = ''
//
//   options.repos.forEach(function(repo) {
//     if (options.by) repo.author = '?creator=' + options.by
//     if (options.l) repo.labels = '?labels=' + options.l
//     if (options.all) repo.state = '?state=all'
//     if (options.o) repo.state = '?state=open'
//     if (options.c) repo.state = '?state=closed'
//   })
//
// }

// function makeRequest(i, options) {
//   var query = '/issues?page='
//   var limit = '&per_page=100'
//
//   options.repos.forEach(function (repo) {
//     var url = base + '/repos/' + repo.user + '/' + repo.name + query + pageNum + limit
//     console.log("URL", url)
//     // request(url, {json: true, headers: headers}, getIssues)
//   })
// }
//
// // taken from other module, need to adapt
// function getIssues(err, response, body) {
//   if (err) console.log(err)
//   // if there are no more repos to look through
//   if (repoNum === nuxrepos.length) {
//     console.log("Done with all, writing file")
//     return writeIssues()
//   }
//   // if there are no more issues to look through
//   if (body.length === 0) {
//     console.log("Done, moving on to " + nuxrepos[r])
//     return nextRepo()
//   }
//   var issues = body
//   // add some extra info to each issue
//   issues.forEach(function(issue) {
//     issue.parentrepo = nuxrepos[r]
//     issue.pr = false
//     if (issue.pull_request) issue.pr = true
//
//     var labels = issue.labels
//     // see if issue has one of our labels
//     labels.forEach(function(label) {
//       if (label.name === labelPrefix) {
//         return relevant.push(issue)
//       }
//     })
//   })
//   // go the the next page of issues
//   i++
//   requestIssues(i, nuxrepos[r])
// }
//
// function filterIssues(err, resp, body) {
//   if (err) console.log(err)
//
// }
<|endoftext|>


<commit_before>var estraverse = require('estraverse'),
    escope = require('escope'),
    tcoLabel = {
        type: 'Identifier',
        name: 'tco'
    };

function equals(a, b, s) {
    var equal,
        k;

    if(typeof a != typeof b)
        return false;

    if(typeof a == 'object' || typeof a == 'array') {
        equal = true;

        for(k in a) {
            equal = equal && equals(a[k], b[k], s);
        }

        for(k in b) {
            equal = equal && equals(a[k], b[k], s);
        }

        return equal;
    }

    return a === b;
}

function nodeAncestry(f, ast) {
    var ancestry = [],
        result;

    estraverse.traverse(ast, {
        enter: function(n) {
            if(n == f) result = ancestry.slice();
            if(result) return;

            ancestry.push(n);
        },
        leave: function() {
            ancestry.pop();
        }
    });

    return result;
}

function returnValue(r, resultIdentifier) {
    return {
        type: 'BlockStatement',
        body: [{
            type: 'ExpressionStatement',
            expression: {
                type: 'AssignmentExpression',
                operator: '=',
                left: resultIdentifier,
                right: r.argument
            }
        }, {
            type: 'BreakStatement',
            label: tcoLabel
        }]
    };
}

function isFunctionNode(n) {
    return ['FunctionDeclaration', 'FunctionExpression'].indexOf(n.type) != -1;
}

function tailCall(f, r, scope) {
    var tmpVars = [],
        assignments = [],
        i,
        identifier;

    for(i = 0; i < f.params.length; i++) {
        identifier = {
            type: 'Identifier',
            name: freshNameWhile('__' + f.params[i].name, function(name){ return !inScope(scope, name); })
        };
        tmpVars.push({
            type: 'VariableDeclarator',
            id: identifier,
            init: r.argument['arguments'][i]
        });
        assignments.push({
            type: 'ExpressionStatement',
            expression: {
                type: 'AssignmentExpression',
                operator: '=',
                left: f.params[i],
                right: identifier
            }
        });
    }

    return {
        type: 'BlockStatement',
        body: [{
            type: 'VariableDeclaration',
            declarations: tmpVars,
            kind: 'var'
        }].concat(assignments).concat({
            type: 'ContinueStatement',
            label: tcoLabel
        })
    };
}

function inScope(scope, name){
    if(scope.set.has(name)) return true;
    for (var i = 0, iz = scope.through.length; i < iz; ++i) {
        if (scope.through[i].identifier.name === name) {
            return true;
        }
    }
    return false;
};

function freshNameWhile(prefix, test){
    name = prefix;
    // TODO: the size of this name can be optimised with a smarter algorithm
    while(!test(name)) name += "$";
    return name;
}

function optimizeFunction(f, ast, scope) {
    var id = functionId(f, ast),
        block = f.body,
        ancestry = [];

    var resultIdentifier = {
        type: 'Identifier',
        name: freshNameWhile('__tcor', function(name) {
            return !inScope(scope, name);
        })
    };

    estraverse.replace(block, {
        enter: function(n) {
            var i;

            ancestry.push(n);

            if(!n || n.type != 'ReturnStatement')
                return n;

            for(i = ancestry.length - 1; i >= 0; i--) {
                if(isFunctionNode(ancestry[i]))
                    return;
            }

            if(n.argument.type == 'CallExpression' && equals(n.argument.callee, id)) {
                return tailCall(f, n, scope);
            } else {
                return returnValue(n, resultIdentifier);
            }
        },
        leave: function(n) {
            ancestry.pop();
        }
    });

    block.body = [{
        type: 'VariableDeclaration',
        declarations: [{
            type: 'VariableDeclarator',
            id: resultIdentifier
        }],
        kind: 'var'
    }, {
        type: 'LabeledStatement',
        label: tcoLabel,
        body: {
            type: 'WhileStatement',
            test: {
                type: 'Literal',
                value: true
            },
            body: {
                type: 'BlockStatement',
                body: block.body
            }
        }
    }, {
        type: 'ReturnStatement',
        argument: resultIdentifier
    }];
}

function topLevel(n, ast) {
    var ancestry = nodeAncestry(n, ast),
        node,
        i;

    for(i = ancestry.length - 1; i >= 0; --i) {
        node = ancestry[i];

        if(isFunctionNode(node)) {
            return equals(functionId(node, ast), n.argument.callee);
        }
    }

    return false;
}

function functionId(f, ast) {
    var ancestry,
        parent;

    if(f.id) {
        return f.id;
    }

    ancestry = nodeAncestry(f, ast);
    parent = ancestry[ancestry.length - 1];
    if(parent.type == 'VariableDeclarator') {
        return parent.id;
    } else if(parent.type == 'AssignmentExpression') {
        return parent.left;
    }
}

function hasOnlyTailCalls(f, ast) {
    var accum = {
            any: false,
            all: true
        },
        ancestry = [];

    estraverse.traverse(f, {
        enter: function(n) {
            var id;

                ancestry.push(n);

            if(!accum.all) return;
            if(n.type != 'ReturnStatement') return;
            if(!n.argument) return;
            if(n.argument.type != 'CallExpression') return;

            id = functionId(f, ast);

            if(!id || !equals(n.argument.callee, id)) return;

            accum = {
                any: true,
                all: accum.all && topLevel(n, ast)
            };
        },
        leave: function(n) {
            ancestry.pop();
        }
    });

    return accum.any && accum.all;
}

function mutateAST(ast) {
    var scopeManager = escope.analyze(ast);
    scopeManager.attach();

    estraverse.traverse(ast, {
        enter: function(n) {
            if(!isFunctionNode(n) || !hasOnlyTailCalls(n, ast))
                return;

            optimizeFunction(n, ast, scopeManager.acquire(n));
        }
    });

    scopeManager.detach();
}

function tco(content) {
    var esprima = require('esprima'),
        escodegen = require('escodegen'),
        ast = esprima.parse(content);

    mutateAST(ast);

    return escodegen.generate(ast);
}

(function(exports) {
    exports.optimizeFunction = optimizeFunction;
    exports.mutateAST = mutateAST;
    exports.tco = tco;
})(typeof exports == 'undefined' ? this.brushtail = {} : exports);
<commit_msg>Add explicit replacement with original when cancelling<commit_after>var estraverse = require('estraverse'),
    escope = require('escope'),
    tcoLabel = {
        type: 'Identifier',
        name: 'tco'
    };

function equals(a, b, s) {
    var equal,
        k;

    if(typeof a != typeof b)
        return false;

    if(typeof a == 'object' || typeof a == 'array') {
        equal = true;

        for(k in a) {
            equal = equal && equals(a[k], b[k], s);
        }

        for(k in b) {
            equal = equal && equals(a[k], b[k], s);
        }

        return equal;
    }

    return a === b;
}

function nodeAncestry(f, ast) {
    var ancestry = [],
        result;

    estraverse.traverse(ast, {
        enter: function(n) {
            if(n == f) result = ancestry.slice();
            if(result) return;

            ancestry.push(n);
        },
        leave: function() {
            ancestry.pop();
        }
    });

    return result;
}

function returnValue(r, resultIdentifier) {
    return {
        type: 'BlockStatement',
        body: [{
            type: 'ExpressionStatement',
            expression: {
                type: 'AssignmentExpression',
                operator: '=',
                left: resultIdentifier,
                right: r.argument
            }
        }, {
            type: 'BreakStatement',
            label: tcoLabel
        }]
    };
}

function isFunctionNode(n) {
    return ['FunctionDeclaration', 'FunctionExpression'].indexOf(n.type) != -1;
}

function tailCall(f, r, scope) {
    var tmpVars = [],
        assignments = [],
        i,
        identifier;

    for(i = 0; i < f.params.length; i++) {
        identifier = {
            type: 'Identifier',
            name: freshNameWhile('__' + f.params[i].name, function(name){ return !inScope(scope, name); })
        };
        tmpVars.push({
            type: 'VariableDeclarator',
            id: identifier,
            init: r.argument['arguments'][i]
        });
        assignments.push({
            type: 'ExpressionStatement',
            expression: {
                type: 'AssignmentExpression',
                operator: '=',
                left: f.params[i],
                right: identifier
            }
        });
    }

    return {
        type: 'BlockStatement',
        body: [{
            type: 'VariableDeclaration',
            declarations: tmpVars,
            kind: 'var'
        }].concat(assignments).concat({
            type: 'ContinueStatement',
            label: tcoLabel
        })
    };
}

function inScope(scope, name){
    if(scope.set.has(name)) return true;
    for (var i = 0, iz = scope.through.length; i < iz; ++i) {
        if (scope.through[i].identifier.name === name) {
            return true;
        }
    }
    return false;
};

function freshNameWhile(prefix, test){
    name = prefix;
    // TODO: the size of this name can be optimised with a smarter algorithm
    while(!test(name)) name += "$";
    return name;
}

function optimizeFunction(f, ast, scope) {
    var id = functionId(f, ast),
        block = f.body,
        ancestry = [];

    var resultIdentifier = {
        type: 'Identifier',
        name: freshNameWhile('__tcor', function(name) {
            return !inScope(scope, name);
        })
    };

    estraverse.replace(block, {
        enter: function(n) {
            var i;

            ancestry.push(n);

            if(!n || n.type != 'ReturnStatement')
                return n;

            for(i = ancestry.length - 1; i >= 0; i--) {
                if(isFunctionNode(ancestry[i]))
                    return n;
            }

            if(n.argument.type == 'CallExpression' && equals(n.argument.callee, id)) {
                return tailCall(f, n, scope);
            } else {
                return returnValue(n, resultIdentifier);
            }
        },
        leave: function(n) {
            ancestry.pop();
        }
    });

    block.body = [{
        type: 'VariableDeclaration',
        declarations: [{
            type: 'VariableDeclarator',
            id: resultIdentifier
        }],
        kind: 'var'
    }, {
        type: 'LabeledStatement',
        label: tcoLabel,
        body: {
            type: 'WhileStatement',
            test: {
                type: 'Literal',
                value: true
            },
            body: {
                type: 'BlockStatement',
                body: block.body
            }
        }
    }, {
        type: 'ReturnStatement',
        argument: resultIdentifier
    }];
}

function topLevel(n, ast) {
    var ancestry = nodeAncestry(n, ast),
        node,
        i;

    for(i = ancestry.length - 1; i >= 0; --i) {
        node = ancestry[i];

        if(isFunctionNode(node)) {
            return equals(functionId(node, ast), n.argument.callee);
        }
    }

    return false;
}

function functionId(f, ast) {
    var ancestry,
        parent;

    if(f.id) {
        return f.id;
    }

    ancestry = nodeAncestry(f, ast);
    parent = ancestry[ancestry.length - 1];
    if(parent.type == 'VariableDeclarator') {
        return parent.id;
    } else if(parent.type == 'AssignmentExpression') {
        return parent.left;
    }
}

function hasOnlyTailCalls(f, ast) {
    var accum = {
            any: false,
            all: true
        },
        ancestry = [];

    estraverse.traverse(f, {
        enter: function(n) {
            var id;

                ancestry.push(n);

            if(!accum.all) return;
            if(n.type != 'ReturnStatement') return;
            if(!n.argument) return;
            if(n.argument.type != 'CallExpression') return;

            id = functionId(f, ast);

            if(!id || !equals(n.argument.callee, id)) return;

            accum = {
                any: true,
                all: accum.all && topLevel(n, ast)
            };
        },
        leave: function(n) {
            ancestry.pop();
        }
    });

    return accum.any && accum.all;
}

function mutateAST(ast) {
    var scopeManager = escope.analyze(ast);
    scopeManager.attach();

    estraverse.traverse(ast, {
        enter: function(n) {
            if(!isFunctionNode(n) || !hasOnlyTailCalls(n, ast))
                return;

            optimizeFunction(n, ast, scopeManager.acquire(n));
        }
    });

    scopeManager.detach();
}

function tco(content) {
    var esprima = require('esprima'),
        escodegen = require('escodegen'),
        ast = esprima.parse(content);

    mutateAST(ast);

    return escodegen.generate(ast);
}

(function(exports) {
    exports.optimizeFunction = optimizeFunction;
    exports.mutateAST = mutateAST;
    exports.tco = tco;
})(typeof exports == 'undefined' ? this.brushtail = {} : exports);
<|endoftext|>


<commit_before>"use strict";
var net = require("net");
var parse = require("url-parse-lax");

module.exports = function (dest, seq, opts, cb) {
  var socket = new net.Socket(), interacting, saved = "";
  if (typeof opts === "function") cb = opts;
  opts = opts || {};

  socket.once("connect", socket.setNoDelay.bind(socket));

  dest = parse(dest);
  socket.connect(dest.port, dest.hostname);

  socket.on("error", function (err) {
    if (interacting) interacting = false;
    socket.removeAllListeners("data").removeAllListeners("error").end();
    cb(err);
  });
  socket.on("end", function () {
    if (interacting) {
      process.stdin.removeAllListeners("data");
      if (opts.exit) process.exit(0);
    }
  });
  socket.on("data", function next(chunk) {
    if (interacting) return process.stdout.write(chunk);

    var i;
    seq.some(function (entry, index) {
      i = entry.done ? undefined : index;
      return !entry.done;
    });

    if (!seq[i] || seq[i].done) {
      socket.removeAllListeners("data").removeAllListeners("error").end();
      return cb();
    }

    saved += chunk;
    if (saved.indexOf(seq[i].expect) !== -1) {
      seq[i].done = true;

      if (seq[i].out) {
        var lines = [];
        saved.split(/\r\n/).forEach(function (line) {
          if (line) lines.push(line);
        });
        lines = lines.length >= 3 ? lines.slice(1, lines.length - 1) : lines;
        seq[i].out(lines.join("\n"));
      }

      if (seq[i].send) {
        socket.write(seq[i].send);
      }

      if (seq[i].interact) {
        process.stdin.setRawMode(true);
        interacting = true;
        process.stdin.on("data", function (c) {
          if (!socket.writable) return;
          if (c.toString("hex") === "7f") c = Buffer("08", "hex"); // Convert DEL to BKSP
          socket.write(c);
        });
        socket.write("\r");
      }

      saved = "";
    }
  });
};
<commit_msg>set a socket timeout<commit_after>"use strict";
var net = require("net");
var parse = require("url-parse-lax");

module.exports = function (dest, seq, opts, cb) {
  var socket = new net.Socket(), interacting, saved = "";
  if (typeof opts === "function") cb = opts;
  opts = opts || {};

  socket.setTimeout(5000);
  socket.once("connect", socket.setNoDelay.bind(socket));

  dest = parse(dest);
  socket.connect(dest.port, dest.hostname);

  socket.on("error", function (err) {
    if (interacting) interacting = false;
    socket.removeAllListeners("data").removeAllListeners("error").end();
    cb(err);
  });
  socket.on("end", function () {
    if (interacting) {
      process.stdin.removeAllListeners("data");
      if (opts.exit) process.exit(0);
    }
  });
  socket.on("data", function next(chunk) {
    if (interacting) return process.stdout.write(chunk);

    var i;
    seq.some(function (entry, index) {
      i = entry.done ? undefined : index;
      return !entry.done;
    });

    if (!seq[i] || seq[i].done) {
      socket.removeAllListeners("data").removeAllListeners("error").end();
      return cb();
    }

    saved += chunk;
    if (saved.indexOf(seq[i].expect) !== -1) {
      seq[i].done = true;

      if (seq[i].out) {
        var lines = [];
        saved.split(/\r\n/).forEach(function (line) {
          if (line) lines.push(line);
        });
        lines = lines.length >= 3 ? lines.slice(1, lines.length - 1) : lines;
        seq[i].out(lines.join("\n"));
      }

      if (seq[i].send) {
        socket.write(seq[i].send);
      }

      if (seq[i].interact) {
        process.stdin.setRawMode(true);
        interacting = true;
        process.stdin.on("data", function (c) {
          if (!socket.writable) return;
          if (c.toString("hex") === "7f") c = Buffer("08", "hex"); // Convert DEL to BKSP
          socket.write(c);
        });
        socket.write("\r");
      }

      saved = "";
    }
  });
};
<|endoftext|>


<commit_before>'use strict'

const parseArgs = require('minimist');
const Storage = require('@google-cloud/storage');
const puppeteer = require('puppeteer');

async function uploadFile(argv, data) {
  let gsoptions = {};
  if (!argv.local)  {
    gsoptions.keyFilename = '/etc/service-account.json';
  }

  let storage = Storage(gsoptions);

  let bucket = storage.bucket(argv.bucket);
  let file = bucket.file(argv.filename);
  let stream = file.createWriteStream({
    metadata: {
      contentType: 'application/pdf',
    },
  });

  return new Promise((resolve, reject) => {
    stream.on('error', err => reject(err));

    stream.on('finish', () => resolve());

    stream.end(data);
  });
}

async function main() {
  let options = {
    string: ['url', 'filename', 'bucket'],
    boolean: 'local',
    unknown: () => false,
  };
  let argv = parseArgs(process.argv.slice(2), options);

  if (!argv.url || !argv.bucket || !argv.filename) {
    console.log('Usage: node index.js --url http://www.example.com --bucket test-bucket --filename test/test.pdf');
    return;
  }

  let browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});
  let page = await browser.newPage();
  await page.goto(argv.url)

  let data = await page.pdf({
    printBackground: true,
    format: 'A4',
  });

  browser.close();

  await uploadFile(argv, data);
}

main();
<commit_msg>Change the service account file path. (#9)<commit_after>'use strict'

const parseArgs = require('minimist');
const Storage = require('@google-cloud/storage');
const puppeteer = require('puppeteer');

async function uploadFile(argv, data) {
  let gsoptions = {};
  if (!argv.local)  {
    gsoptions.keyFilename = '/etc/pdfgen/service-account.json';
  }

  let storage = Storage(gsoptions);

  let bucket = storage.bucket(argv.bucket);
  let file = bucket.file(argv.filename);
  let stream = file.createWriteStream({
    metadata: {
      contentType: 'application/pdf',
    },
  });

  return new Promise((resolve, reject) => {
    stream.on('error', err => reject(err));

    stream.on('finish', () => resolve());

    stream.end(data);
  });
}

async function main() {
  let options = {
    string: ['url', 'filename', 'bucket'],
    boolean: 'local',
    unknown: () => false,
  };
  let argv = parseArgs(process.argv.slice(2), options);

  if (!argv.url || !argv.bucket || !argv.filename) {
    console.log('Usage: node index.js --url http://www.example.com --bucket test-bucket --filename test/test.pdf');
    return;
  }

  let browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});
  let page = await browser.newPage();
  await page.goto(argv.url)

  let data = await page.pdf({
    printBackground: true,
    format: 'A4',
  });

  browser.close();

  await uploadFile(argv, data);
}

main();
<|endoftext|>


<commit_before>var Signal = require('signals').Signal;
function RenderRegion(fullWidth, fullHeight, x, y, w, h) {
	var _state = true;
	var _isFullscreen = true;
	var _fullWidth = fullWidth || 320;
	var _fullHeight = fullHeight || 240;
	var _x = x || 0;
	var _y = y || 0;
	var _w = w || fullWidth - _x;
	var _h = h || fullHeight - _y;
	var _right = _x + _w;
	var _bottom = _y + _h;

	var _halfWidth = _fullWidth * .5;
	var _halfHeight = _fullHeight * .5;
	var _wHalf = _w * .5;
	var _hHalf = _h * .5;

	var onChangeSignal = new Signal();

	var _this = this;
	function update() {
		_isFullscreen = _x === 0 && _y === 0 && _w == _fullWidth && _h == _fullHeight;
		_this.apply = (_state && !_isFullscreen) ? applyCrop : applyFull;
		onChangeSignal.dispatch(_x, _y, _w, _h);
	}

	function applyCrop(renderer) {
		// renderer.setScissor(_x, _fullHeight-_y-_h, _w, _h);
		renderer.setViewport(_x, _fullHeight-_y-_h, _w, _h, true, true);
		// renderer.enableScissorTest(true);
	}

	function applyFull(renderer) {
		// renderer.setScissor(0, 0, _fullWidth, _fullHeight);
		renderer.setViewport(0, 0, _fullWidth, _fullHeight, true, true);
		// renderer.enableScissorTest(false);
	}

	function setRegion(x, y, w, h){
		// console.log('region setRegion');
		_x = ~~x;
		_y = ~~y;
		_w = ~~w;
		_h = ~~h;
		_right = _x + _w;
		_bottom = _y + _h;
		_wHalf = _w * .5;
		_hHalf = _h * .5;
		update();
	}

	function setState(state) {
		_state = state;
		update();
	}

	function setFullSize(w, h) {
		_fullWidth = ~~w;
		_fullHeight = ~~h;
		_halfWidth = _fullWidth * .5;
		_halfHeight = _fullHeight * .5;
		update();
	}

	function setFullSizeAndRegion(fullWidth, fullHeight, x, y, w, h) {
		_x = ~~x;
		_y = ~~y;
		_w = ~~w;
		_h = ~~h;
		_right = _x + _w;
		_bottom = _y + _h;
		_wHalf = _w * .5;
		_hHalf = _h * .5;
		_fullWidth = ~~fullWidth;
		_fullHeight = ~~fullHeight;
		_halfWidth = _fullWidth * .5;
		_halfHeight = _fullHeight * .5;
		update();
	}

	var point = {
		x: 0,
		y: 0
	};

	function getScreenSpacePositionOfPixel(x, y) {
		if(_state && !_isFullscreen) {
			point.x = (x - _x) / _wHalf - 1;
			point.y = (y - _y) / _hHalf - 1;
		} else {
			point.x = x / _halfWidth - 1;
			point.y = y / _halfHeight - 1;
		}
		return point;
	}

	function contains(x, y) {
		return (x >= _x && x <= _right && y >= _y && y <= _bottom);
	}

	update();
	this.onChangeSignal = onChangeSignal;
	this.setRegion = setRegion;
	this.setState = setState;
	this.setFullSize = setFullSize;
	this.setFullSizeAndRegion = setFullSizeAndRegion;
	this.bump = update;
	this.contains = contains;
	this.getScreenSpacePositionOfPixel = getScreenSpacePositionOfPixel;

}

module.exports = RenderRegion<commit_msg>clipspace not screenspace<commit_after>var Signal = require('signals').Signal;
function RenderRegion(fullWidth, fullHeight, x, y, w, h) {
	var _state = true;
	var _isFullscreen = true;
	var _fullWidth = fullWidth || 320;
	var _fullHeight = fullHeight || 240;
	var _x = x || 0;
	var _y = y || 0;
	var _w = w || fullWidth - _x;
	var _h = h || fullHeight - _y;
	var _right = _x + _w;
	var _bottom = _y + _h;

	var _halfWidth = _fullWidth * .5;
	var _halfHeight = _fullHeight * .5;
	var _wHalf = _w * .5;
	var _hHalf = _h * .5;

	var onChangeSignal = new Signal();

	var _this = this;
	function update() {
		_isFullscreen = _x === 0 && _y === 0 && _w == _fullWidth && _h == _fullHeight;
		_this.apply = (_state && !_isFullscreen) ? applyCrop : applyFull;
		onChangeSignal.dispatch(_x, _y, _w, _h);
	}

	function applyCrop(renderer) {
		renderer.enableScissorTest(true);
		// renderer.setScissor(_x, _fullHeight-_y-_h, _w, _h);
		renderer.setViewport(_x, _fullHeight-_y-_h, _w, _h, true, true);
	}

	function applyFull(renderer) {
		// renderer.enableScissorTest(false);
		// renderer.setScissor(0, 0, _fullWidth, _fullHeight);
		renderer.setViewport(0, 0, _fullWidth, _fullHeight, true, true);
	}

	function setRegion(x, y, w, h){
		// console.log('region setRegion');
		_x = ~~x;
		_y = ~~y;
		_w = ~~w;
		_h = ~~h;
		_right = _x + _w;
		_bottom = _y + _h;
		_wHalf = _w * .5;
		_hHalf = _h * .5;
		update();
	}

	function setState(state) {
		_state = state;
		update();
	}

	function setFullSize(w, h) {
		_fullWidth = ~~w;
		_fullHeight = ~~h;
		_halfWidth = _fullWidth * .5;
		_halfHeight = _fullHeight * .5;
		update();
	}

	function setFullSizeAndRegion(fullWidth, fullHeight, x, y, w, h) {
		_x = ~~x;
		_y = ~~y;
		_w = ~~w;
		_h = ~~h;
		_right = _x + _w;
		_bottom = _y + _h;
		_wHalf = _w * .5;
		_hHalf = _h * .5;
		_fullWidth = ~~fullWidth;
		_fullHeight = ~~fullHeight;
		_halfWidth = _fullWidth * .5;
		_halfHeight = _fullHeight * .5;
		update();
	}

	var point = {
		x: 0,
		y: 0
	};

	function getClipSpacePositionOfPixel(x, y) {
		if(_state && !_isFullscreen) {
			point.x = (x - _x) / _wHalf - 1;
			point.y = (y - _y) / _hHalf - 1;
		} else {
			point.x = x / _halfWidth - 1;
			point.y = y / _halfHeight - 1;
		}
		return point;
	}

	function contains(x, y) {
		return (x >= _x && x <= _right && y >= _y && y <= _bottom);
	}

	function isVisible() {
		return !(_w === 0 || _h === 0);
	}

	update();
	this.onChangeSignal = onChangeSignal;
	this.setRegion = setRegion;
	this.setState = setState;
	this.setFullSize = setFullSize;
	this.setFullSizeAndRegion = setFullSizeAndRegion;
	this.bump = update;
	this.contains = contains;
	this.isVisible = isVisible;
	this.getClipSpacePositionOfPixel = getClipSpacePositionOfPixel;

}

module.exports = RenderRegion<|endoftext|>