<commit_before>const { name } = require('../../package.json');
const { version } = require('../../package.json');

const debug = require('debug')(`${name}:request`);
const got = require('got');

const userAgent = `${name}/${version} (github link)`;

const baseUrl = 'http://myanimelist.net';

module.exports = function request(url = '/', opts = {}) {
  let reqUrl = url;
  if (url.indexOf(baseUrl) > -1) {
    reqUrl = url.replace(baseUrl, '');
  }

  debug(`Requesting ${reqUrl}, options: ${JSON.stringify(opts)}`);

  return got(`http://myanimelist.net${reqUrl}`, Object.assign(opts, {
    'User-Agent': userAgent,
  }));
};
<commit_msg>Use HTTPS instead of HTTP<commit_after>const { name } = require('../../package.json');
const { version } = require('../../package.json');

const debug = require('debug')(`${name}:request`);
const got = require('got');

const userAgent = `${name}/${version} (github link)`;

const baseUrl = 'https://myanimelist.net';

module.exports = function request(url = '/', opts = {}) {
  let reqUrl = url;
  if (url.indexOf(baseUrl) > -1) {
    reqUrl = url.replace(baseUrl, '');
  }

  debug(`Requesting ${reqUrl}, options: ${JSON.stringify(opts)}`);

  return got(`https://myanimelist.net${reqUrl}`, Object.assign(opts, {
    'User-Agent': userAgent,
  }));
};
<|endoftext|>


<commit_before>var _ = require('lodash');
var URI = require('URIjs');
var request = require('superagent');
var Promise = require('es6-promise');

Promise = Promise.Promise; // unwrap

var PodioErrors = require('./PodioErrors');
var auth = require('./auth');

module.exports = {
  _getAuth: function() {
    // we have the auth object mixed in
    return this;
  },

  _addRequestData: function(data, method, req) {
    switch(method) {
      case 'get':
        if (!_.isEmpty(data)) {
          req = req.query(data);
        }
        break;
      case 'post':
      case 'put':
        if (!_.isEmpty(data)) {
          req = req.send(data);
        }
        break;
    }

    return req;
  },

  _addHeaders: function(req) {
    req = req.set('Authorization', 'OAuth2 ' + this.authObject.accessToken);

    return req;
  },

  _addCORS: function(req) {
    if (this.authType === 'client') {
      req = req.withCredentials();
    }

    return req;
  },

  _setOptions: function(options, req) {
    if (options.type && options.type === 'form') {
      req.type('form');
    }

    if (options.basicAuth) {
      req.set(
        'Authorization',
        'Basic ' + new Buffer(this.clientId + ':' + this.clientSecret).toString('base64')
      );
    }

    return req;
  },

  _onTokenRefreshed: function(request) {
    if (request.requestType === 'generic') {
      return this.request(request.method, request.path, request.data);
    } else if (request.requestType === 'file') {
      return this.uploadFile(request.filePath, request.fileName);
    }
  },

  _handleTransportError: function(options, response) {
    var request = options.requestParams;

    switch(response.status) {
      case 400:
        return new PodioErrors.PodioBadRequestError(response.body, response.status, request.url);
      case 401:
        this._getAuth()._clearAuthentication();
        return new PodioErrors.PodioAuthorizationError(response.body, response.status, request.url);
      case 403:
        return new PodioErrors.PodioForbiddenError(response.body, response.status, request.url);
      case 404:
        return new PodioErrors.PodioNotFoundError(response.body, response.status, request.url);
      case 409:
        return new PodioErrors.PodioConflictError(response.body, response.status, request.url);
      case 410:
        return new PodioErrors.PodioGoneError(response.body, response.status, request.url);
      case 420:
        return new PodioErrors.PodioRateLimitError(response.body, response.status, request.url);
      case 500:
        return new PodioErrors.PodioServerError(response.body, response.status, request.url);
      case 502:
      case 503:
      case 504:
        return new PodioErrors.PodioUnavailableError(response.body, response.status, request.url);
      default:
        return new PodioErrors.PodioError(response.body, response.status, request.url);
    }
  },

  _onResponse: function(options, err, res) {
    if (res && res.ok === true && !err) {
      options.resolve(res.body);
    } else {
      if (res && res.status === 401 && (res.body.error === 'invalid_token' || res.body.error_description === 'expired_token') && this.authObject.refreshToken) {
        this._getAuth()._refreshToken(function (err, response) {
          if (err !== null) {
            options.reject(this._handleTransportError(options, response));
          }

          if (_.isFunction(this.afterTokenRefreshed)) {
            this.afterTokenRefreshed(response);
          }

          this._onTokenRefreshed(options.requestParams).then(function (response) {
            options.resolve(response);
          }, function (err) {
            options.reject(err);
          })
        }.bind(this));
      } else {
        options.reject(this._handleTransportError(options, res));
      }
    }
  },

  _getRequestObject: function() {
    return request;
  },

  _formatMethod: function(method) {
    method = method.toLowerCase();

    if (method === 'delete') {
      return 'del';
    } else {
      return method;
    }
  },

  _getRequestURI: function(path) {
    var parsed = URI.parse(path);
    var uri = new URI(this.apiURL);

    uri.path(parsed.path);

    if (!_.isUndefined(parsed.query)) {
      uri.query(parsed.query);
    }

    return uri.toString();
  },

  request: function(method, path, data, options) {
    var url = this._getRequestURI(path);
    var request = this._getRequestObject();
    var req;

    if ((!options || !options.basicAuth) && !this._getAuth().isAuthenticated()) {
      return new Promise(function (resolve, reject) {
        reject(new PodioErrors.PodioForbiddenError('Authentication has not been performed'))
      });
    }

    method = this._formatMethod(method);

    req = request[method](url);

    if (options && options.basicAuth) {
      req = _.compose(
        this._addRequestData.bind(this, data, method),
        this._setOptions.bind(this, options || {})
      )(req);
    } else {
      req = _.compose(
        this._addRequestData.bind(this, data, method),
        this._addHeaders.bind(this),
        this._addCORS.bind(this),
        this._setOptions.bind(this, options || {})
      )(req);
    }

    return new Promise(function(resolve, reject) {
      var options = {
        resolve: resolve,
        reject: reject,
        requestParams: {
          requestType: 'generic',
          url: url,
          path: path,
          data: data,
          method: method
        }
      };

      req.end(this._onResponse.bind(this, options));
    }.bind(this));
  },

  uploadFile: function(filePath, fileName) {
    var url = new URI(this.apiURL).path('/file').toString();
    var req;

    if (!_.include(['server', 'password'], this.authType)) {
      return new Promise(function(resolve, reject) {
        reject(new PodioErrors.PodioError('File uploads are only supported on the server right now.'));
      });
    }

    req = this._getRequestObject().post(url).attach('source', filePath).field('filename', fileName);

    req = _.compose(this._addHeaders.bind(this), this._addCORS.bind(this))(req);

    return new Promise(function(resolve, reject) {
      var options = {
        resolve: resolve,
        reject: reject,
        requestParams: {
          requestType: 'file',
          filePath: filePath,
          fileName: fileName
        }
      };

      req.end(this._onResponse.bind(this, options));
    }.bind(this));
  }
};
<commit_msg>Check for response<commit_after>var _ = require('lodash');
var URI = require('URIjs');
var request = require('superagent');
var Promise = require('es6-promise');

Promise = Promise.Promise; // unwrap

var PodioErrors = require('./PodioErrors');
var auth = require('./auth');

module.exports = {
  _getAuth: function() {
    // we have the auth object mixed in
    return this;
  },

  _addRequestData: function(data, method, req) {
    switch(method) {
      case 'get':
        if (!_.isEmpty(data)) {
          req = req.query(data);
        }
        break;
      case 'post':
      case 'put':
        if (!_.isEmpty(data)) {
          req = req.send(data);
        }
        break;
    }

    return req;
  },

  _addHeaders: function(req) {
    req = req.set('Authorization', 'OAuth2 ' + this.authObject.accessToken);

    return req;
  },

  _addCORS: function(req) {
    if (this.authType === 'client') {
      req = req.withCredentials();
    }

    return req;
  },

  _setOptions: function(options, req) {
    if (options.type && options.type === 'form') {
      req.type('form');
    }

    if (options.basicAuth) {
      req.set(
        'Authorization',
        'Basic ' + new Buffer(this.clientId + ':' + this.clientSecret).toString('base64')
      );
    }

    return req;
  },

  _onTokenRefreshed: function(request) {
    if (request.requestType === 'generic') {
      return this.request(request.method, request.path, request.data);
    } else if (request.requestType === 'file') {
      return this.uploadFile(request.filePath, request.fileName);
    }
  },

  _handleTransportError: function(options, response) {
    var request = options.requestParams;

    if (!response) {
      return new PodioErrors.PodioError(null, null, request.url);
    }

    switch(response.status) {
      case 400:
        return new PodioErrors.PodioBadRequestError(response.body, response.status, request.url);
      case 401:
        this._getAuth()._clearAuthentication();
        return new PodioErrors.PodioAuthorizationError(response.body, response.status, request.url);
      case 403:
        return new PodioErrors.PodioForbiddenError(response.body, response.status, request.url);
      case 404:
        return new PodioErrors.PodioNotFoundError(response.body, response.status, request.url);
      case 409:
        return new PodioErrors.PodioConflictError(response.body, response.status, request.url);
      case 410:
        return new PodioErrors.PodioGoneError(response.body, response.status, request.url);
      case 420:
        return new PodioErrors.PodioRateLimitError(response.body, response.status, request.url);
      case 500:
        return new PodioErrors.PodioServerError(response.body, response.status, request.url);
      case 502:
      case 503:
      case 504:
        return new PodioErrors.PodioUnavailableError(response.body, response.status, request.url);
      default:
        return new PodioErrors.PodioError(response.body, response.status, request.url);
    }
  },

  _onResponse: function(options, err, res) {
    if (res && res.ok === true && !err) {
      options.resolve(res.body);
    } else {
      if (res && res.status === 401 && (res.body.error === 'invalid_token' || res.body.error_description === 'expired_token') && this.authObject.refreshToken) {
        this._getAuth()._refreshToken(function (err, response) {
          if (err !== null) {
            options.reject(this._handleTransportError(options, response));
          }

          if (_.isFunction(this.afterTokenRefreshed)) {
            this.afterTokenRefreshed(response);
          }

          this._onTokenRefreshed(options.requestParams).then(function (response) {
            options.resolve(response);
          }, function (err) {
            options.reject(err);
          })
        }.bind(this));
      } else {
        options.reject(this._handleTransportError(options, res));
      }
    }
  },

  _getRequestObject: function() {
    return request;
  },

  _formatMethod: function(method) {
    method = method.toLowerCase();

    if (method === 'delete') {
      return 'del';
    } else {
      return method;
    }
  },

  _getRequestURI: function(path) {
    var parsed = URI.parse(path);
    var uri = new URI(this.apiURL);

    uri.path(parsed.path);

    if (!_.isUndefined(parsed.query)) {
      uri.query(parsed.query);
    }

    return uri.toString();
  },

  request: function(method, path, data, options) {
    var url = this._getRequestURI(path);
    var request = this._getRequestObject();
    var req;

    if ((!options || !options.basicAuth) && !this._getAuth().isAuthenticated()) {
      return new Promise(function (resolve, reject) {
        reject(new PodioErrors.PodioForbiddenError('Authentication has not been performed'))
      });
    }

    method = this._formatMethod(method);

    req = request[method](url);

    if (options && options.basicAuth) {
      req = _.compose(
        this._addRequestData.bind(this, data, method),
        this._setOptions.bind(this, options || {})
      )(req);
    } else {
      req = _.compose(
        this._addRequestData.bind(this, data, method),
        this._addHeaders.bind(this),
        this._addCORS.bind(this),
        this._setOptions.bind(this, options || {})
      )(req);
    }

    return new Promise(function(resolve, reject) {
      var options = {
        resolve: resolve,
        reject: reject,
        requestParams: {
          requestType: 'generic',
          url: url,
          path: path,
          data: data,
          method: method
        }
      };

      req.end(this._onResponse.bind(this, options));
    }.bind(this));
  },

  uploadFile: function(filePath, fileName) {
    var url = new URI(this.apiURL).path('/file').toString();
    var req;

    if (!_.include(['server', 'password'], this.authType)) {
      return new Promise(function(resolve, reject) {
        reject(new PodioErrors.PodioError('File uploads are only supported on the server right now.'));
      });
    }

    req = this._getRequestObject().post(url).attach('source', filePath).field('filename', fileName);

    req = _.compose(this._addHeaders.bind(this), this._addCORS.bind(this))(req);

    return new Promise(function(resolve, reject) {
      var options = {
        resolve: resolve,
        reject: reject,
        requestParams: {
          requestType: 'file',
          filePath: filePath,
          fileName: fileName
        }
      };

      req.end(this._onResponse.bind(this, options));
    }.bind(this));
  }
};
<|endoftext|>


<commit_before><commit_msg>Fixed TR Language (#1206)<commit_after><|endoftext|>


<commit_before>const _ =require('lodash')

class TronBike {
  constructor(grid, x, y, width = 2, height = 2) {
    this.grid = grid
    this.x = x
    this.y = y
    this.width = width
    this.height = height
    this.position = 1
  }

  get moveRight() {
    if((this.x + 1) > 900) {
      return this.x = 0;
    } else {
      return this.x += this.position;
    }
  }

  get moveLeft() {
    if((this.x - 1) < 0) {
      return this.x = 900;
    } else {
      return this.x -= this.position;
    }
  }

  get moveUp() {
    if((this.y - 1) < 0) {
      return this.y = 600;
    } else {
      return this.y -= this.position;
    }
  }

  get moveDown() {
    if((this.y + 1) > 600) {
      return this.y = 0;
    } else {
      return this.y += this.position;
    }
  }

  get isAlive() {
    return !this.grid.combinedTrails.find(position => {
      return this.x === position[0] && this.y === position[1]
    });
  }

}

module.exports = TronBike
<commit_msg>restricted movement to new grid size<commit_after>const _ =require('lodash')

class TronBike {
  constructor(grid, x, y, width = 2, height = 2) {
    this.grid = grid
    this.x = x
    this.y = y
    this.width = width
    this.height = height
    this.position = 1
  }

  get moveRight() {
    if((this.x + 1) > 450) {
      return this.x = 0;
    } else {
      return this.x += this.position;
    }
  }

  get moveLeft() {
    if((this.x - 1) < 0) {
      return this.x = 450;
    } else {
      return this.x -= this.position;
    }
  }

  get moveUp() {
    if((this.y - 1) < 0) {
      return this.y = 300;
    } else {
      return this.y -= this.position;
    }
  }

  get moveDown() {
    if((this.y + 1) > 300) {
      return this.y = 0;
    } else {
      return this.y += this.position;
    }
  }

  get isAlive() {
    return !this.grid.combinedTrails.find(position => {
      return this.x === position[0] && this.y === position[1]
    });
  }

}

module.exports = TronBike
<|endoftext|>


<commit_before>/**
 * Transaction Builder (experimental)
 * ==================================
 *
 * Transaction Builder. This is a, yet unfinished, convenience class for
 * building pubkeyhash and p2sh transactions, and also for verifying arbitrary
 * transactions (and their inputs). You can (or will be able to) pay to
 * pubkeyhash to p2sh and can spend pubkeyhash or p2sh-pubkeyhash or
 * p2sh-multisig.
 */
'use strict'
let dependencies = {
  Address: require('./address'),
  Constants: require('./constants').Default.Txbuilder,
  BN: require('./bn'),
  Pubkey: require('./pubkey'),
  Script: require('./script'),
  Sig: require('./sig'),
  Struct: require('./struct'),
  Tx: require('./tx'),
  Txin: require('./txin'),
  Txout: require('./txout'),
  Txoutmap: require('./txoutmap'),
  Varint: require('./varint'),
  asink: require('asink')
}

let inject = function (deps) {
  let Address = deps.Address
  let Constants = deps.Constants
  let BN = deps.BN
  let Pubkey = deps.Pubkey
  let Script = deps.Script
  let Sig = deps.Sig
  let Struct = deps.Struct
  let Tx = deps.Tx
  let Txin = deps.Txin
  let Txout = deps.Txout
  let Txoutmap = deps.Txoutmap
  let Varint = deps.Varint
  let asink = deps.asink

  let Txbuilder = function Txbuilder (tx, txins, txouts, utxoutmap, changeAddress, feePerKBNum) {
    if (!(this instanceof Txbuilder)) {
      return new Txbuilder(tx, txins, txouts, utxoutmap, changeAddress, feePerKBNum)
    }
    this.initialize()
    this.fromObject({tx, txins, txouts, utxoutmap, changeAddress, feePerKBNum})
  }

  Txbuilder.prototype = Object.create(Struct.prototype)
  Txbuilder.prototype.constructor = Txbuilder

  Txbuilder.prototype.initialize = function () {
    this.tx = Tx()
    this.txins = []
    this.txouts = []
    this.utxoutmap = Txoutmap()
    this.feePerKBNum = Constants.feePerKBNum
    return this
  }

  Txbuilder.prototype.toJSON = function () {
    let json = {}
    json.tx = this.tx.toHex()
    json.txins = this.txins.map((txin) => txin.toHex())
    json.txouts = this.txouts.map((txout) => txout.toHex())
    json.utxoutmap = this.utxoutmap.toJSON()
    json.changeAddress = this.changeAddress.toHex()
    json.feePerKBNum = this.feePerKBNum
    return json
  }

  Txbuilder.prototype.fromJSON = function (json) {
    this.tx = Tx().fromHex(json.tx)
    this.txins = json.txins.map((txin) => Txin().fromHex(txin))
    this.txouts = json.txouts.map((txout) => Txout().fromHex(txout))
    this.utxoutmap = Txoutmap().fromJSON(json.utxoutmap)
    this.changeAddress = Address().fromHex(json.changeAddress)
    this.feePerKBNum = json.feePerKBNum
    return this
  }

  Txbuilder.prototype.setFeePerKBNum = function (feePerKBNum) {
    this.feePerKBNum = feePerKBNum
    return this
  }

  Txbuilder.prototype.setChangeAddress = function (changeAddress) {
    this.changeAddress = changeAddress
    return this
  }

  /**
   * pubkey can be either a Pubkey in the case of a pubkeyhash transaction, or
   * a Script in the case of a p2sh transaction.
   */
  Txbuilder.prototype.fromPubkeyhash = function (txhashbuf, txoutnum, txout, pubkey) {
    if (!(Buffer.isBuffer(txhashbuf)) || !(typeof txoutnum === 'number') || !(txout instanceof Txout) || !(pubkey instanceof Pubkey)) {
      throw new Error('invalid one of: txhashbuf, txoutnum, txout, pubkey')
    }
    this.txins.push(Txin().fromPubkeyhashTxout(txhashbuf, txoutnum, txout, pubkey))
    this.utxoutmap.add(txhashbuf, txoutnum, txout)
    return this
  }

  Txbuilder.prototype.fromScripthashMultisig = function (txhashbuf, txoutnum, txout, script) {
    if (!(Buffer.isBuffer(txhashbuf)) || !(typeof txoutnum === 'number') || !(txout instanceof Txout) || !(script instanceof Script)) {
      throw new Error('invalid one of: txhashbuf, txoutnum, txout, script')
    }
    this.txins.push(Txin().fromScripthashMultisigTxout(txhashbuf, txoutnum, txout, script))
    this.utxoutmap.add(txhashbuf, txoutnum, txout)
    return this
  }

  /**
   * An an address to send funds to, along with the amount. The amount should be
   * denominated in satoshis, not bitcoins.
   */
  Txbuilder.prototype.to = function (valuebn, addr) {
    if (!(addr instanceof Address) || !(valuebn instanceof BN)) {
      throw new Error('addr must be an Address, and valuebn must be a BN')
    }
    let script
    if (addr.type() === 'scripthash') {
      script = Script().fromScripthash(addr.hashbuf)
    } else if (addr.type() === 'pubkeyhash') {
      script = Script().fromPubkeyhash(addr.hashbuf)
    } else {
      throw new Error('invalid address type')
    }
    let txout = Txout(valuebn, script)
    this.txouts.push(txout)
    return this
  }

  Txbuilder.prototype.buildOutputs = function () {
    let outamount = BN(0)
    this.txouts.forEach((txout) => {
      outamount = outamount.add(txout.valuebn)
      this.tx.addTxout(txout)
    })
    return outamount
  }

  Txbuilder.prototype.buildInputs = function (outamount, extraInputsNum) {
    if (!extraInputsNum) {
      extraInputsNum = 0
    }
    let inamount = BN(0)
    for (let txin of this.txins) {
      let txout = this.utxoutmap.get(txin.txhashbuf, txin.txoutnum)
      inamount = inamount.add(txout.valuebn)
      this.tx.addTxin(txin)
      if (inamount.geq(outamount)) {
        if (extraInputsNum <= 0) {
          break
        }
        extraInputsNum--
      }
    }
    if (inamount.lt(outamount)) {
      throw new Error('not enough funds for output')
    }
    return inamount
  }

  // For now this method only supports pubkeyhash inputs. It assumes we have
  // not yet added signatures to our inputs.
  // TODO: Support it when the signatures are already on the inputs.
  // TODO: Support p2sh inputs.
  Txbuilder.prototype.estimateSize = function () {
    // largest possible sig size
    let sigsize = 1 + 1 + 1 + 1 + 32 + 1 + 1 + 32 + 1
    let size = this.tx.toBuffer().length
    size = size + sigsize * this.tx.txins.length
    size = size + 1 // assume txinsvi increases by 1 byte
    return size
  }

  Txbuilder.prototype.estimateFee = function () {
    let fee = Math.ceil(this.estimateSize() / 1000) * this.feePerKBNum
    return BN(fee)
  }

  /**
   * Builds the transaction and adds the appropriate fee.
   */
  Txbuilder.prototype.build = function () {
    let changeAmount, shouldfeebn
    for (let extraInputsNum = 0; extraInputsNum < this.txins.length; extraInputsNum++) {
      this.tx = Tx()
      let outamount = this.buildOutputs()
      let changeScript = Script().fromPubkeyhash(this.changeAddress.hashbuf)
      let changeTxout = Txout(BN(0), changeScript)
      this.tx.addTxout(changeTxout)

      let inamount = this.buildInputs(outamount, extraInputsNum)

      // TODO: What if change amount is less than dust?
      // Set change amount from inamount - outamount
      changeAmount = inamount.sub(outamount)
      this.tx.txouts[this.tx.txouts.length - 1].valuebn = changeAmount

      shouldfeebn = this.estimateFee()
      if (changeAmount.geq(shouldfeebn) && changeAmount.sub(shouldfeebn).gt(Constants.dustnum)) {
        break
      }
    }
    if (changeAmount.geq(shouldfeebn)) {
      // Subtract fee from change
      // TODO: What if change is less than dust? What if change is 0?
      changeAmount = changeAmount.sub(shouldfeebn)
      this.tx.txouts[this.tx.txouts.length - 1].valuebn = changeAmount

      if (changeAmount.lt(Constants.dustnum)) {
        throw new Error('unable to create change amount greater than dust')
      }

      return this
    } else {
      throw new Error('unable to gather enough inputs for outputs and fee')
    }
  }

  /**
   * Check if all signatures are present in a p2sh multisig input script.
   */
  Txbuilder.allSigsPresent = function (m, script) {
    // The first element is a Famous Multisig Bug OP_0, and last element is the
    // redeemScript. The rest are signatures.
    let present = 0
    for (let i = 1; i < script.chunks.length - 1; i++) {
      if (script.chunks[i].buf) {
        present++
      }
    }
    return present === m
  }

  /**
   * Remove blank signatures in a p2sh multisig input script.
   */
  Txbuilder.removeBlankSigs = function (script) {
    // The first element is a Famous Multisig Bug OP_0, and last element is the
    // redeemScript. The rest are signatures.
    script = Script(script.chunks.slice()) // copy the script
    for (let i = 1; i < script.chunks.length - 1; i++) {
      if (!script.chunks[i].buf) {
        script.chunks.splice(i, 1) // remove ith element
      }
    }
    return script
  }

  /**
   * Given the signature for a transaction, fill it in the appropriate place
   * for an input that spends a pubkeyhash output.
   */
  Txbuilder.prototype.fillPubkeyhashSig = function (i, keypair, sig) {
    let txin = this.tx.txins[i]
    txin.script.chunks[0] = Script().writeBuffer(sig.toTxFormat()).chunks[0]
    txin.scriptvi = Varint(txin.script.toBuffer().length)
    return this
  }

  Txbuilder.prototype.fillScripthashMultisigSig = function (i, keypair, sig, redeemScript) {
    let txin = this.tx.txins[i]
    let script = txin.script

    // three normal opcodes, and the rest are pubkeys
    let pubkeychunks = redeemScript.chunks.slice(1, redeemScript.chunks.length - 2)

    let pubkeybufs = pubkeychunks.map((chunk) => chunk.buf)
    let pubkeybuf = keypair.pubkey.toBuffer()

    // find which pubkey in the redeemScript is the one we are trying to sign
    let thisPubkeyIndex
    for (thisPubkeyIndex = 0; thisPubkeyIndex < pubkeybufs.length; thisPubkeyIndex++) {
      if (Buffer.compare(pubkeybuf, pubkeybufs[thisPubkeyIndex]) === 0) {
        break
      }
      if (thisPubkeyIndex >= pubkeybufs.length) {
        throw new Error('cannot sign; pubkey not found in input ' + i)
      }
    }

    script.chunks[thisPubkeyIndex + 1] = Script().writeBuffer(sig.toTxFormat()).chunks[0]
    let m = redeemScript.chunks[0].opcodenum - 0x50
    if (Txbuilder.allSigsPresent(m, script)) {
      txin.script = Txbuilder.removeBlankSigs(script)
    }
    txin.scriptvi = Varint(txin.script.toBuffer().length)
    return this
  }

  /**
   * sign ith input with keypair
   */
  Txbuilder.prototype.sign = function (i, keypair) {
    let txin = this.tx.txins[i]
    let script = txin.script
    if (script.isPubkeyhashIn()) {
      let txhashbuf = txin.txhashbuf
      let txoutnum = txin.txoutnum
      let txout = this.utxoutmap.get(txhashbuf, txoutnum)
      let outscript = txout.script
      let subscript = outscript // true for standard script types
      let sig = this.tx.sign(keypair, Sig.SIGHASH_ALL, i, subscript)
      this.fillPubkeyhashSig(i, keypair, sig, subscript)
    } else if (script.isScripthashIn()) {
      let redeemScript = Script().fromBuffer(script.chunks[script.chunks.length - 1].buf)
      let subscript = redeemScript
      if (!redeemScript.isMultisigOut()) {
        throw new Error('cannot sign non-multisig scripthash script type for input ' + i)
      }
      let sig = this.tx.sign(keypair, Sig.SIGHASH_ALL, i, subscript)
      this.fillScripthashMultisigSig(i, keypair, sig, redeemScript)
    } else {
      throw new Error('cannot sign unknown script type for input ' + i)
    }
    return this
  }

  Txbuilder.prototype.asyncSign = function (i, keypair) {
    return asink(function *() {
      let txin = this.tx.txins[i]
      let script = txin.script
      if (script.isPubkeyhashIn()) {
        let txhashbuf = txin.txhashbuf
        let txoutnum = txin.txoutnum
        let txout = this.utxoutmap.get(txhashbuf, txoutnum)
        let outscript = txout.script
        let subscript = outscript // true for standard script types
        let sig = yield this.tx.asyncSign(keypair, Sig.SIGHASH_ALL, i, subscript)
        this.fillPubkeyhashSig(i, keypair, sig, subscript)
      } else if (script.isScripthashIn()) {
        let redeemScript = Script().fromBuffer(script.chunks[script.chunks.length - 1].buf)
        let subscript = redeemScript
        if (!redeemScript.isMultisigOut()) {
          throw new Error('cannot sign non-multisig scripthash script type for input ' + i)
        }
        let sig = yield this.tx.asyncSign(keypair, Sig.SIGHASH_ALL, i, subscript)
        this.fillScripthashMultisigSig(i, keypair, sig, redeemScript)
      } else {
        throw new Error('cannot sign unknown script type for input ' + i)
      }
      return this
    }, this)
  }

  return Txbuilder
}

inject = require('./injector')(inject, dependencies)
let Txbuilder = inject()
module.exports = Txbuilder
<commit_msg>comments<commit_after>/**
 * Transaction Builder (experimental)
 * ==================================
 *
 * Transaction Builder. This is a, yet unfinished, convenience class for
 * building pubkeyhash and p2sh transactions, and also for verifying arbitrary
 * transactions (and their inputs). You can (or will be able to) pay to
 * pubkeyhash to p2sh and can spend pubkeyhash or p2sh-pubkeyhash or
 * p2sh-multisig.
 */
'use strict'
let dependencies = {
  Address: require('./address'),
  Constants: require('./constants').Default.Txbuilder,
  BN: require('./bn'),
  Pubkey: require('./pubkey'),
  Script: require('./script'),
  Sig: require('./sig'),
  Struct: require('./struct'),
  Tx: require('./tx'),
  Txin: require('./txin'),
  Txout: require('./txout'),
  Txoutmap: require('./txoutmap'),
  Varint: require('./varint'),
  asink: require('asink')
}

let inject = function (deps) {
  let Address = deps.Address
  let Constants = deps.Constants
  let BN = deps.BN
  let Pubkey = deps.Pubkey
  let Script = deps.Script
  let Sig = deps.Sig
  let Struct = deps.Struct
  let Tx = deps.Tx
  let Txin = deps.Txin
  let Txout = deps.Txout
  let Txoutmap = deps.Txoutmap
  let Varint = deps.Varint
  let asink = deps.asink

  let Txbuilder = function Txbuilder (tx, txins, txouts, utxoutmap, changeAddress, feePerKBNum) {
    if (!(this instanceof Txbuilder)) {
      return new Txbuilder(tx, txins, txouts, utxoutmap, changeAddress, feePerKBNum)
    }
    this.initialize()
    this.fromObject({tx, txins, txouts, utxoutmap, changeAddress, feePerKBNum})
  }

  Txbuilder.prototype = Object.create(Struct.prototype)
  Txbuilder.prototype.constructor = Txbuilder

  Txbuilder.prototype.initialize = function () {
    this.tx = Tx()
    this.txins = []
    this.txouts = []
    this.utxoutmap = Txoutmap()
    this.feePerKBNum = Constants.feePerKBNum
    return this
  }

  Txbuilder.prototype.toJSON = function () {
    let json = {}
    json.tx = this.tx.toHex()
    json.txins = this.txins.map((txin) => txin.toHex())
    json.txouts = this.txouts.map((txout) => txout.toHex())
    json.utxoutmap = this.utxoutmap.toJSON()
    json.changeAddress = this.changeAddress.toHex()
    json.feePerKBNum = this.feePerKBNum
    return json
  }

  Txbuilder.prototype.fromJSON = function (json) {
    this.tx = Tx().fromHex(json.tx)
    this.txins = json.txins.map((txin) => Txin().fromHex(txin))
    this.txouts = json.txouts.map((txout) => Txout().fromHex(txout))
    this.utxoutmap = Txoutmap().fromJSON(json.utxoutmap)
    this.changeAddress = Address().fromHex(json.changeAddress)
    this.feePerKBNum = json.feePerKBNum
    return this
  }

  Txbuilder.prototype.setFeePerKBNum = function (feePerKBNum) {
    this.feePerKBNum = feePerKBNum
    return this
  }

  Txbuilder.prototype.setChangeAddress = function (changeAddress) {
    this.changeAddress = changeAddress
    return this
  }

  /**
   * Pay "from" a pubkeyhash output - in other words, add an input to the
   * transaction.
   */
  Txbuilder.prototype.fromPubkeyhash = function (txhashbuf, txoutnum, txout, pubkey) {
    if (!(Buffer.isBuffer(txhashbuf)) || !(typeof txoutnum === 'number') || !(txout instanceof Txout) || !(pubkey instanceof Pubkey)) {
      throw new Error('invalid one of: txhashbuf, txoutnum, txout, pubkey')
    }
    this.txins.push(Txin().fromPubkeyhashTxout(txhashbuf, txoutnum, txout, pubkey))
    this.utxoutmap.add(txhashbuf, txoutnum, txout)
    return this
  }

  /**
   * Pay "from" a scripthash (p2sh) output - in other words, add an input to
   * the transaction.
   */
  Txbuilder.prototype.fromScripthashMultisig = function (txhashbuf, txoutnum, txout, script) {
    if (!(Buffer.isBuffer(txhashbuf)) || !(typeof txoutnum === 'number') || !(txout instanceof Txout) || !(script instanceof Script)) {
      throw new Error('invalid one of: txhashbuf, txoutnum, txout, script')
    }
    this.txins.push(Txin().fromScripthashMultisigTxout(txhashbuf, txoutnum, txout, script))
    this.utxoutmap.add(txhashbuf, txoutnum, txout)
    return this
  }

  /**
   * An an address to send funds to, along with the amount. The amount should be
   * denominated in satoshis, not bitcoins.
   */
  Txbuilder.prototype.to = function (valuebn, addr) {
    if (!(addr instanceof Address) || !(valuebn instanceof BN)) {
      throw new Error('addr must be an Address, and valuebn must be a BN')
    }
    let script
    if (addr.type() === 'scripthash') {
      script = Script().fromScripthash(addr.hashbuf)
    } else if (addr.type() === 'pubkeyhash') {
      script = Script().fromPubkeyhash(addr.hashbuf)
    } else {
      throw new Error('invalid address type')
    }
    let txout = Txout(valuebn, script)
    this.txouts.push(txout)
    return this
  }

  Txbuilder.prototype.buildOutputs = function () {
    let outamount = BN(0)
    this.txouts.forEach((txout) => {
      outamount = outamount.add(txout.valuebn)
      this.tx.addTxout(txout)
    })
    return outamount
  }

  Txbuilder.prototype.buildInputs = function (outamount, extraInputsNum) {
    if (!extraInputsNum) {
      extraInputsNum = 0
    }
    let inamount = BN(0)
    for (let txin of this.txins) {
      let txout = this.utxoutmap.get(txin.txhashbuf, txin.txoutnum)
      inamount = inamount.add(txout.valuebn)
      this.tx.addTxin(txin)
      if (inamount.geq(outamount)) {
        if (extraInputsNum <= 0) {
          break
        }
        extraInputsNum--
      }
    }
    if (inamount.lt(outamount)) {
      throw new Error('not enough funds for output')
    }
    return inamount
  }

  // For now this method only supports pubkeyhash inputs. It assumes we have
  // not yet added signatures to our inputs.
  // TODO: Support it when the signatures are already on the inputs.
  // TODO: Support p2sh inputs.
  Txbuilder.prototype.estimateSize = function () {
    // largest possible sig size
    let sigsize = 1 + 1 + 1 + 1 + 32 + 1 + 1 + 32 + 1
    let size = this.tx.toBuffer().length
    size = size + sigsize * this.tx.txins.length
    size = size + 1 // assume txinsvi increases by 1 byte
    return size
  }

  Txbuilder.prototype.estimateFee = function () {
    let fee = Math.ceil(this.estimateSize() / 1000) * this.feePerKBNum
    return BN(fee)
  }

  /**
   * Builds the transaction and adds the appropriate fee.
   */
  Txbuilder.prototype.build = function () {
    let changeAmount, shouldfeebn
    for (let extraInputsNum = 0; extraInputsNum < this.txins.length; extraInputsNum++) {
      this.tx = Tx()
      let outamount = this.buildOutputs()
      let changeScript = Script().fromPubkeyhash(this.changeAddress.hashbuf)
      let changeTxout = Txout(BN(0), changeScript)
      this.tx.addTxout(changeTxout)

      let inamount = this.buildInputs(outamount, extraInputsNum)

      // TODO: What if change amount is less than dust?
      // Set change amount from inamount - outamount
      changeAmount = inamount.sub(outamount)
      this.tx.txouts[this.tx.txouts.length - 1].valuebn = changeAmount

      shouldfeebn = this.estimateFee()
      if (changeAmount.geq(shouldfeebn) && changeAmount.sub(shouldfeebn).gt(Constants.dustnum)) {
        break
      }
    }
    if (changeAmount.geq(shouldfeebn)) {
      // Subtract fee from change
      // TODO: What if change is less than dust? What if change is 0?
      changeAmount = changeAmount.sub(shouldfeebn)
      this.tx.txouts[this.tx.txouts.length - 1].valuebn = changeAmount

      if (changeAmount.lt(Constants.dustnum)) {
        throw new Error('unable to create change amount greater than dust')
      }

      return this
    } else {
      throw new Error('unable to gather enough inputs for outputs and fee')
    }
  }

  /**
   * Check if all signatures are present in a p2sh multisig input script.
   */
  Txbuilder.allSigsPresent = function (m, script) {
    // The first element is a Famous Multisig Bug OP_0, and last element is the
    // redeemScript. The rest are signatures.
    let present = 0
    for (let i = 1; i < script.chunks.length - 1; i++) {
      if (script.chunks[i].buf) {
        present++
      }
    }
    return present === m
  }

  /**
   * Remove blank signatures in a p2sh multisig input script.
   */
  Txbuilder.removeBlankSigs = function (script) {
    // The first element is a Famous Multisig Bug OP_0, and last element is the
    // redeemScript. The rest are signatures.
    script = Script(script.chunks.slice()) // copy the script
    for (let i = 1; i < script.chunks.length - 1; i++) {
      if (!script.chunks[i].buf) {
        script.chunks.splice(i, 1) // remove ith element
      }
    }
    return script
  }

  /**
   * Given the signature for a transaction, fill it in the appropriate place
   * for an input that spends a pubkeyhash output.
   */
  Txbuilder.prototype.fillPubkeyhashSig = function (i, keypair, sig) {
    let txin = this.tx.txins[i]
    txin.script.chunks[0] = Script().writeBuffer(sig.toTxFormat()).chunks[0]
    txin.scriptvi = Varint(txin.script.toBuffer().length)
    return this
  }

  Txbuilder.prototype.fillScripthashMultisigSig = function (i, keypair, sig, redeemScript) {
    let txin = this.tx.txins[i]
    let script = txin.script

    // three normal opcodes, and the rest are pubkeys
    let pubkeychunks = redeemScript.chunks.slice(1, redeemScript.chunks.length - 2)

    let pubkeybufs = pubkeychunks.map((chunk) => chunk.buf)
    let pubkeybuf = keypair.pubkey.toBuffer()

    // find which pubkey in the redeemScript is the one we are trying to sign
    let thisPubkeyIndex
    for (thisPubkeyIndex = 0; thisPubkeyIndex < pubkeybufs.length; thisPubkeyIndex++) {
      if (Buffer.compare(pubkeybuf, pubkeybufs[thisPubkeyIndex]) === 0) {
        break
      }
      if (thisPubkeyIndex >= pubkeybufs.length) {
        throw new Error('cannot sign; pubkey not found in input ' + i)
      }
    }

    script.chunks[thisPubkeyIndex + 1] = Script().writeBuffer(sig.toTxFormat()).chunks[0]
    let m = redeemScript.chunks[0].opcodenum - 0x50
    if (Txbuilder.allSigsPresent(m, script)) {
      txin.script = Txbuilder.removeBlankSigs(script)
    }
    txin.scriptvi = Varint(txin.script.toBuffer().length)
    return this
  }

  /**
   * sign ith input with keypair
   */
  Txbuilder.prototype.sign = function (i, keypair) {
    let txin = this.tx.txins[i]
    let script = txin.script
    if (script.isPubkeyhashIn()) {
      let txhashbuf = txin.txhashbuf
      let txoutnum = txin.txoutnum
      let txout = this.utxoutmap.get(txhashbuf, txoutnum)
      let outscript = txout.script
      let subscript = outscript // true for standard script types
      let sig = this.tx.sign(keypair, Sig.SIGHASH_ALL, i, subscript)
      this.fillPubkeyhashSig(i, keypair, sig, subscript)
    } else if (script.isScripthashIn()) {
      let redeemScript = Script().fromBuffer(script.chunks[script.chunks.length - 1].buf)
      let subscript = redeemScript
      if (!redeemScript.isMultisigOut()) {
        throw new Error('cannot sign non-multisig scripthash script type for input ' + i)
      }
      let sig = this.tx.sign(keypair, Sig.SIGHASH_ALL, i, subscript)
      this.fillScripthashMultisigSig(i, keypair, sig, redeemScript)
    } else {
      throw new Error('cannot sign unknown script type for input ' + i)
    }
    return this
  }

  Txbuilder.prototype.asyncSign = function (i, keypair) {
    return asink(function *() {
      let txin = this.tx.txins[i]
      let script = txin.script
      if (script.isPubkeyhashIn()) {
        let txhashbuf = txin.txhashbuf
        let txoutnum = txin.txoutnum
        let txout = this.utxoutmap.get(txhashbuf, txoutnum)
        let outscript = txout.script
        let subscript = outscript // true for standard script types
        let sig = yield this.tx.asyncSign(keypair, Sig.SIGHASH_ALL, i, subscript)
        this.fillPubkeyhashSig(i, keypair, sig, subscript)
      } else if (script.isScripthashIn()) {
        let redeemScript = Script().fromBuffer(script.chunks[script.chunks.length - 1].buf)
        let subscript = redeemScript
        if (!redeemScript.isMultisigOut()) {
          throw new Error('cannot sign non-multisig scripthash script type for input ' + i)
        }
        let sig = yield this.tx.asyncSign(keypair, Sig.SIGHASH_ALL, i, subscript)
        this.fillScripthashMultisigSig(i, keypair, sig, redeemScript)
      } else {
        throw new Error('cannot sign unknown script type for input ' + i)
      }
      return this
    }, this)
  }

  return Txbuilder
}

inject = require('./injector')(inject, dependencies)
let Txbuilder = inject()
module.exports = Txbuilder
<|endoftext|>


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

function StateStore(store) {
  this._store = store;
}

StateStore.prototype.serializeClient = function(fn) {
  this._serializeClientFunc = fn;
}

StateStore.prototype.deserializeClient = function(fn) {
  this._deserializeClientFunc = fn;
}

StateStore.prototype.load = function(req, cb) {
  var self = this;

  function loaded(err, state) {
    if (err) { return cb(err); }
    if (!state) { return cb(null); }

    state.transactionID = state.handle;
    state.locals = {};
    if (state.webOrigin) {
      state.locals.webOrigin = state.webOrigin;
      delete state.webOrigin;
    }

    self._deserializeClientFunc(state.client, function(err, client) {
      if (err) { return cb(err); }
      if (!client) {
        return cb(new Error('Failed to deserialize client'));
      }

      state.client = client;
      return cb(null, state);
    });
  }

  if (req.state && req.state.name == 'oauth2-authorize') {
    if (req.state.name !== 'oauth2-authorize') {
      return cb(new Error('State out of sync, expected oauth2-authorize, got: ' + req.state.name));
    }
    loaded(null, clone(req.state));
  } else {
    // FIXME: The following line is a workaround for a misleading exception thrown when /authorize
    //        is missing a required parameter
    /// AuthorizationError: Missing required parameter: response_type
    if (!req.body) { return loaded(null); }

    this._store.load(req, req.body.state, loaded);
  }
}

StateStore.prototype.store = function(req, cb) {
  var txn = req.oauth2;

  var self = this;
  this._serializeClientFunc(txn.client, function(err, client) {
    if (err) { return cb(err); }

    var state = {};
    state.name = 'oauth2-authorize';
    state.client = client;
    state.redirectURI = txn.redirectURI;
    state.req = txn.req;
    if (txn.locals.webOrigin) {
      state.webOrigin = txn.locals.webOrigin;
    }

    self._store.save(req, state, function(err, h) {
      if (err) { return cb(err); }

      // A transaction has been initiated by a client.  Due to the fact that
      // this is a request by an external party, the state is necessarily an
      // initial state, rather than a continuation of state internal to the
      // OAuth 2.0 server.  Set `req.state`, allowing any subsequent states
      // to resume the transaction.
      req.state = state;
      req.state.handle = h;
      cb(null, h);
    });
  });
}

StateStore.prototype.update = function(req, h, cb) {
  var txn = req.oauth2;

  var self = this;
  this._serializeClientFunc(txn.client, function(err, client) {
    if (err) { return cb(err); }

    var state = {};
    state.name = 'oauth2-authorize';
    state.client = client;
    state.redirectURI = txn.redirectURI;
    state.req = txn.req;
    if (txn.locals.webOrigin) {
      state.webOrigin = txn.locals.webOrigin;
    }

    self._store.update(req, h, state, function(err) {
      if (err) { return cb(err); }

      req.state = state;
      req.state.handle = txn.transactionID;
      cb(null);
    });
  });
}

module.exports = StateStore;
<commit_msg>Check for locals.<commit_after>var clone = require('clone');

function StateStore(store) {
  this._store = store;
}

StateStore.prototype.serializeClient = function(fn) {
  this._serializeClientFunc = fn;
}

StateStore.prototype.deserializeClient = function(fn) {
  this._deserializeClientFunc = fn;
}

StateStore.prototype.load = function(req, cb) {
  var self = this;

  function loaded(err, state) {
    if (err) { return cb(err); }
    if (!state) { return cb(null); }

    state.transactionID = state.handle;
    state.locals = {};
    if (state.webOrigin) {
      state.locals.webOrigin = state.webOrigin;
      delete state.webOrigin;
    }

    self._deserializeClientFunc(state.client, function(err, client) {
      if (err) { return cb(err); }
      if (!client) {
        return cb(new Error('Failed to deserialize client'));
      }

      state.client = client;
      return cb(null, state);
    });
  }

  if (req.state && req.state.name == 'oauth2-authorize') {
    if (req.state.name !== 'oauth2-authorize') {
      return cb(new Error('State out of sync, expected oauth2-authorize, got: ' + req.state.name));
    }
    loaded(null, clone(req.state));
  } else {
    // FIXME: The following line is a workaround for a misleading exception thrown when /authorize
    //        is missing a required parameter
    /// AuthorizationError: Missing required parameter: response_type
    if (!req.body) { return loaded(null); }

    this._store.load(req, req.body.state, loaded);
  }
}

StateStore.prototype.store = function(req, cb) {
  var txn = req.oauth2;

  var self = this;
  this._serializeClientFunc(txn.client, function(err, client) {
    if (err) { return cb(err); }

    var state = {};
    state.name = 'oauth2-authorize';
    state.client = client;
    state.redirectURI = txn.redirectURI;
    state.req = txn.req;
    if (txn.locals) {
      if (txn.locals.webOrigin) {
        state.webOrigin = txn.locals.webOrigin;
      }
    }

    self._store.save(req, state, function(err, h) {
      if (err) { return cb(err); }

      // A transaction has been initiated by a client.  Due to the fact that
      // this is a request by an external party, the state is necessarily an
      // initial state, rather than a continuation of state internal to the
      // OAuth 2.0 server.  Set `req.state`, allowing any subsequent states
      // to resume the transaction.
      req.state = state;
      req.state.handle = h;
      cb(null, h);
    });
  });
}

StateStore.prototype.update = function(req, h, cb) {
  var txn = req.oauth2;

  var self = this;
  this._serializeClientFunc(txn.client, function(err, client) {
    if (err) { return cb(err); }

    var state = {};
    state.name = 'oauth2-authorize';
    state.client = client;
    state.redirectURI = txn.redirectURI;
    state.req = txn.req;
    if (txn.locals) {
      if (txn.locals.webOrigin) {
        state.webOrigin = txn.locals.webOrigin;
      }
    }

    self._store.update(req, h, state, function(err) {
      if (err) { return cb(err); }

      req.state = state;
      req.state.handle = txn.transactionID;
      cb(null);
    });
  });
}

module.exports = StateStore;
<|endoftext|>


<commit_before>// NOTE: we only support baseline and progressive JPGs here
// due to the structure of the loader class, we only get a buffer
// with a maximum size of 4096 bytes. so if the SOF marker is outside
// if this range we can't detect the file size correctly.

// TODO: handle the following as well
// ffe2 - Canon EOS-1D JPEG
// ffe3 - Samsung D500 JPEG
var validJFIFMarkers = {
  'ffe0': '4a46494600', // standard jpeg
  'ffe1': '4578696600', // camera jpeg, with EXIF data
  'ffe8': '5350494646', // SPIFF jpeg
  'ffdb': '0001010101', // Samsung D807 JPEG
  'ffec': '4475636b79'  // Photoshop JPEG
};

function isJPG (buffer) { //, filepath
  var SOIMarker = buffer.toString('hex', 0, 2);
  var JFIFMarker = buffer.toString('hex', 2, 4);

  // not a valid jpeg
  if ('ffd8' !== SOIMarker) {
    return false;
  }

  // TODO: validate the end-bytes of a jpeg file
  // use filepath, get the last bytes, check for ffd9

  var actual, expected;
  for (var marker in validJFIFMarkers) {
    expected = validJFIFMarkers[marker];
    actual = buffer.toString('hex', 6, 6 + (expected.length / 2));
    if (marker === JFIFMarker) {
      return validJFIFMarkers[marker] === actual;
    }
  }

  // not a valid jpeg
  return false;
}

function extractSize (buffer, i) {
  return {
    'height' : buffer.readUInt16BE(i),
    'width' : buffer.readUInt16BE(i + 2)
  };
}

function validateBuffer (buffer, i) {
  // index should be withing buffer limits
  if (i > buffer.length) {
    throw new TypeError('Corrupt JPG, exceeded buffer limits');
  }
  // Every JPEG block must begin with a 0xFF
  if (buffer[i] !== 0xFF) {
    throw new TypeError('Invalid JPG, marker table corrupted');
  }
}

function calculate (buffer) {

  // Skip 5 chars, they are for signature
  buffer = buffer.slice(4);

  var i, next;
  while (buffer.length) {
    // read length of the next block
    i = buffer.readUInt16BE(0);

    // ensure correct format
    validateBuffer(buffer, i);

    // 0xFFC0 is baseline(SOF)
    // 0xFFC2 is progressive(SOF2)
    next = buffer[i + 1];
    if (next === 0xC0 || next === 0xC2) {
      return extractSize(buffer, i + 5);
    }

    // move to the next block
    buffer = buffer.slice(i + 2);
  }

  throw new TypeError('Invalid JPG, no size found');
}

module.exports = {
  'detect': isJPG,
  'calculate': calculate
};
<commit_msg>simplify jfif validation<commit_after>// NOTE: we only support baseline and progressive JPGs here
// due to the structure of the loader class, we only get a buffer
// with a maximum size of 4096 bytes. so if the SOF marker is outside
// if this range we can't detect the file size correctly.

// TODO: handle the following as well
// ffe2 - Canon EOS-1D JPEG
// ffe3 - Samsung D500 JPEG
var validJFIFMarkers = {
  'ffe0': '4a46494600', // standard jpeg
  'ffe1': '4578696600', // camera jpeg, with EXIF data
  'ffe8': '5350494646', // SPIFF jpeg
  'ffdb': '0001010101', // Samsung D807 JPEG
  'ffec': '4475636b79'  // Photoshop JPEG
};

function isJPG (buffer) { //, filepath
  var SOIMarker = buffer.toString('hex', 0, 2);
  var JFIFMarker = buffer.toString('hex', 2, 4);

  // not a valid jpeg
  if ('ffd8' !== SOIMarker) {
    return false;
  }

  // TODO: validate the end-bytes of a jpeg file
  // use filepath, get the last bytes, check for ffd9

  var expected = JFIFMarker && validJFIFMarkers[JFIFMarker];
  return buffer.toString('hex', 6, 11) === expected;
}

function extractSize (buffer, i) {
  return {
    'height' : buffer.readUInt16BE(i),
    'width' : buffer.readUInt16BE(i + 2)
  };
}

function validateBuffer (buffer, i) {
  // index should be withing buffer limits
  if (i > buffer.length) {
    throw new TypeError('Corrupt JPG, exceeded buffer limits');
  }
  // Every JPEG block must begin with a 0xFF
  if (buffer[i] !== 0xFF) {
    throw new TypeError('Invalid JPG, marker table corrupted');
  }
}

function calculate (buffer) {

  // Skip 5 chars, they are for signature
  buffer = buffer.slice(4);

  var i, next;
  while (buffer.length) {
    // read length of the next block
    i = buffer.readUInt16BE(0);

    // ensure correct format
    validateBuffer(buffer, i);

    // 0xFFC0 is baseline(SOF)
    // 0xFFC2 is progressive(SOF2)
    next = buffer[i + 1];
    if (next === 0xC0 || next === 0xC2) {
      return extractSize(buffer, i + 5);
    }

    // move to the next block
    buffer = buffer.slice(i + 2);
  }

  throw new TypeError('Invalid JPG, no size found');
}

module.exports = {
  'detect': isJPG,
  'calculate': calculate
};
<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');
var MuteStream = require('mute-stream');
var readline = require('readline');

/**
 * Base interface class other can inherits from
 */

var UI = module.exports = function (opt) {
  // Instantiate the Readline interface
  // @Note: Don't reassign if already present (allow test to override the Stream)
  if (!this.rl) {
    this.rl = readline.createInterface(setupReadlineOptions(opt));
  }
  this.rl.resume();

  this.onForceClose = this.onForceClose.bind(this);

  // Make sure new prompt start on a newline when closing
  process.on('exit', this.onForceClose);

  // Terminate process on SIGINT (which will call process.on('exit') in return)
  this.rl.on('SIGINT', function () {
    process.exit(0);
  });
};

/**
 * Handle the ^C exit
 * @return {null}
 */

UI.prototype.onForceClose = function () {
  this.close();
  console.log('');
};

/**
 * Close the interface and cleanup listeners
 */

UI.prototype.close = function () {
  // Remove events listeners
  this.rl.removeListener('SIGINT', this.onForceClose);
  process.removeListener('exit', this.onForceClose);

  this.rl.output.unmute();

  if (this.activePrompt && typeof this.activePrompt.close === 'function') {
    this.activePrompt.close();
  }

  // Close the readline
  this.rl.output.end();
  this.rl.pause();
  this.rl.close();
};

function setupReadlineOptions(opt) {
  opt = opt || {};

  // Default `input` to stdin
  var input = opt.input || process.stdin;

  // Add mute capabilities to the output
  var ms = new MuteStream();
  ms.pipe(opt.output || process.stdout);
  var output = ms;

  return _.extend({
    terminal: true,
    input: input,
    output: output
  }, _.omit(opt, ['input', 'output']));
}
<commit_msg>Better way to kill process (#569)<commit_after>'use strict';
var _ = require('lodash');
var MuteStream = require('mute-stream');
var readline = require('readline');

/**
 * Base interface class other can inherits from
 */

var UI = module.exports = function (opt) {
  // Instantiate the Readline interface
  // @Note: Don't reassign if already present (allow test to override the Stream)
  if (!this.rl) {
    this.rl = readline.createInterface(setupReadlineOptions(opt));
  }
  this.rl.resume();

  this.onForceClose = this.onForceClose.bind(this);

  // Make sure new prompt start on a newline when closing
  process.on('exit', this.onForceClose);

  // Terminate process on SIGINT (which will call process.on('exit') in return)
  this.rl.on('SIGINT', function () {
    process.kill(process.pid, 'SIGINT');
  });
};

/**
 * Handle the ^C exit
 * @return {null}
 */

UI.prototype.onForceClose = function () {
  this.close();
  console.log('');
};

/**
 * Close the interface and cleanup listeners
 */

UI.prototype.close = function () {
  // Remove events listeners
  this.rl.removeListener('SIGINT', this.onForceClose);
  process.removeListener('exit', this.onForceClose);

  this.rl.output.unmute();

  if (this.activePrompt && typeof this.activePrompt.close === 'function') {
    this.activePrompt.close();
  }

  // Close the readline
  this.rl.output.end();
  this.rl.pause();
  this.rl.close();
};

function setupReadlineOptions(opt) {
  opt = opt || {};

  // Default `input` to stdin
  var input = opt.input || process.stdin;

  // Add mute capabilities to the output
  var ms = new MuteStream();
  ms.pipe(opt.output || process.stdout);
  var output = ms;

  return _.extend({
    terminal: true,
    input: input,
    output: output
  }, _.omit(opt, ['input', 'output']));
}
<|endoftext|>


<commit_before>/**
 * Split a delimited component property string (e.g., `material.color`) to an object
 * containing `component` name and `property` name. If there is no delimiter, just return the
 * string back.
 *
 * Cache arrays from splitting strings via delimiter to save on memory.
 *
 * @param {string} str - e.g., `material.opacity`.
 * @param {string} delimiter - e.g., `.`.
 * @returns {array} e.g., `['material', 'opacity']`.
 */
var propertyPathCache = {};
function getComponentPropertyPath (str, delimiter) {
  delimiter = delimiter || '.';
  if (!propertyPathCache[delimiter]) { propertyPathCache[delimiter] = {}; }
  propertyPathCache[delimiter][str] = str.split(delimiter);
  return propertyPathCache[delimiter][str];
}
module.exports.getComponentPropertyPath = getComponentPropertyPath;
module.exports.propertyPathCache = propertyPathCache;

/**
 * Get component property using encoded component name + component property name with a
 * delimiter.
 */
module.exports.getComponentProperty = function (el, name, delimiter) {
  var splitName;
  delimiter = delimiter || '.';
  if (name.indexOf(delimiter) !== -1) {
    splitName = getComponentPropertyPath(name, delimiter);
    return el.getAttribute(splitName[0])[splitName[1]];
  }
  return el.getAttribute(name);
};

/**
 * Set component property using encoded component name + component property name with a
 * delimiter.
 */
module.exports.setComponentProperty = function (el, name, value, delimiter) {
  var splitName;
  delimiter = delimiter || '.';
  if (name.indexOf(delimiter) !== -1) {
    splitName = getComponentPropertyPath(name, delimiter);
    el.setAttribute(splitName[0], splitName[1], value);
    return;
  }
  el.setAttribute(name, value);
};
<commit_msg>fix tests around utils.entity and delimiting<commit_after>/**
 * Split a delimited component property string (e.g., `material.color`) to an object
 * containing `component` name and `property` name. If there is no delimiter, just return the
 * string back.
 *
 * Cache arrays from splitting strings via delimiter to save on memory.
 *
 * @param {string} str - e.g., `material.opacity`.
 * @param {string} delimiter - e.g., `.`.
 * @returns {array} e.g., `['material', 'opacity']`.
 */
var propertyPathCache = {};
function getComponentPropertyPath (str, delimiter) {
  delimiter = delimiter || '.';
  if (!propertyPathCache[delimiter]) { propertyPathCache[delimiter] = {}; }
  if (str.indexOf(delimiter) !== -1) {
    propertyPathCache[delimiter][str] = str.split(delimiter);
  } else {
    propertyPathCache[delimiter][str] = str;
  }
  return propertyPathCache[delimiter][str];
}
module.exports.getComponentPropertyPath = getComponentPropertyPath;
module.exports.propertyPathCache = propertyPathCache;

/**
 * Get component property using encoded component name + component property name with a
 * delimiter.
 */
module.exports.getComponentProperty = function (el, name, delimiter) {
  var splitName;
  delimiter = delimiter || '.';
  if (name.indexOf(delimiter) !== -1) {
    splitName = getComponentPropertyPath(name, delimiter);
    if (splitName.constructor === String) {
      return el.getAttribute(splitName);
    }
    return el.getAttribute(splitName[0])[splitName[1]];
  }
  return el.getAttribute(name);
};

/**
 * Set component property using encoded component name + component property name with a
 * delimiter.
 */
module.exports.setComponentProperty = function (el, name, value, delimiter) {
  var splitName;
  delimiter = delimiter || '.';
  if (name.indexOf(delimiter) !== -1) {
    splitName = getComponentPropertyPath(name, delimiter);
    if (splitName.constructor === String) {
      el.setAttribute(splitName, value);
    } else {
      el.setAttribute(splitName[0], splitName[1], value);
    }
    return;
  }
  el.setAttribute(name, value);
};
<|endoftext|>


<commit_before>import debug from "debug"
import { flatten } from "./flatten"
const _ = debug("fly:filter")

/**
  Filter fly-* plugins from a package dependencies.
  @param {Object} package.json
  @param {Function} load handler
  @param {[String]} blacklisted plugins
  @return {[String]} list of fly plugins
*/

export function filter(pkg, load, blacklist = []) {
  _("filter fly-* plugins")
  return !pkg ? []
    : flatten(["dependencies", "devDependencies", "peerDependencies"]
      .filter((key) => key in pkg)
      .map((dep) => Object.keys(pkg[dep])))
      .filter((dep) => /^fly-[-\w]+/g.test(dep))
      .filter((dep) => !~["fly-util"].concat(blacklist).indexOf(dep))
      .reduce((prev, next) => prev.concat(load(next)), [])
}
<commit_msg>rewrite / remove utils.filter<commit_after>'use strict';

var flatten = require('flatten');
var debug = require('debug');
var _ = debug('fly:filter');

/**
	Filter fly-* plugins from a package dependencies.
	@param {Object} package.json
	@param {Function} load handler
	@param {[String]} blacklisted plugins
	@return {[String]} list of fly plugins
*/

// @todo: use `pkg-dir` & `read-pkg` libs
module.exports = function (pkg, load, blacklist) {
	blacklist = blacklist || [];

	_('filter fly-* plugins');

	// return !pkg ? []
	// 	: flatten(['dependencies', 'devDependencies', 'peerDependencies']
	// 		.filter((key) => key in pkg)
	// 		.map((dep) => Object.keys(pkg[dep])))
	// 		.filter((dep) => /^fly-[-\w]+/g.test(dep))
	// 		.filter((dep) => !~['fly-util'].concat(blacklist).indexOf(dep))
	// 		.reduce((prev, next) => prev.concat(load(next)), []);
};
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// 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.

'use strict';

var allocCluster = require('./lib/alloc-cluster');
var TChannel = require('../channel');
var RelayHandler = require('../relay_handler');
var RelayNetwork = require('./lib/relay_network');

allocCluster.test('send relay requests', {
    numPeers: 2
}, function t(cluster, assert) {
    var one = cluster.channels[0];
    var two = cluster.channels[1];

    var oneToTwo = one.makeSubChannel({
        serviceName: 'two',
        peers: [two.hostPort]
    });
    oneToTwo.handler = new RelayHandler(oneToTwo);

    var twoSvc = two.makeSubChannel({
        serviceName: 'two'
    });
    twoSvc.register('echo', echo);

    var client = TChannel({
        logger: one.logger
    });
    var twoClient = client.makeSubChannel({
        serviceName: 'two',
        peers: [one.hostPort],
        requestDefaults: {
            serviceName: 'two',
            headers: {
                as: 'raw',
                cn: 'wat'
            }
        }
    });

    twoClient.request({
        hasNoParent: true
    }).send('echo', 'foo', 'bar', function done(err, res, arg2, arg3) {
        assert.ifError(err, 'no unexpected error');
        assert.equal(String(arg2), 'foo', 'expected arg2');
        assert.equal(String(arg3), 'bar', 'expected arg3');

        client.close();
        assert.end();
    });
});

allocCluster.test('relay respects ttl', {
    numPeers: 3
}, function t(cluster, assert) {
    var relay = cluster.channels[0];
    var source = cluster.channels[1];
    var dest = cluster.channels[2];

    var relayChan = relay.makeSubChannel({
        serviceName: 'dest',
        peers: [dest.hostPort]
    });
    relayChan.handler = new RelayHandler(relayChan);

    var destChan = dest.makeSubChannel({
        serviceName: 'dest'
    });
    destChan.register('echoTTL', function echoTTL(req, res) {
        res.headers.as = 'raw';
        res.sendOk(null, String(req.ttl));
    });

    var sourceChan = source.makeSubChannel({
        serviceName: 'dest',
        peers: [relay.hostPort],
        requestDefaults: {
            headers: {
                as: 'raw',
                cn: 'wat'
            }
        }
    });

    sourceChan.request({
        serviceName: 'dest',
        hasNoParent: true,
        timeout: 250
    }).send('echoTTL', null, null, onResponse);

    function onResponse(err, res, arg2, arg3) {
        assert.ifError(err);
        assert.ok(res.ok);

        var ttl = Number(String(arg3));
        assert.ok(ttl >= 240 && ttl <= 250);

        assert.end();
    }
});

allocCluster.test('relay an error frame', {
    numPeers: 4
}, function t(cluster, assert) {
    var one = cluster.channels[0];
    var two = cluster.channels[1];
    var three = cluster.channels[2];
    var four = cluster.channels[3];

    var oneToTwo = one.makeSubChannel({
        serviceName: 'two',
        peers: [two.hostPort, three.hostPort]
    });
    oneToTwo.handler = new RelayHandler(oneToTwo);
    var fourToTwo = four.makeSubChannel({
        serviceName: 'two',
        peers: [two.hostPort, three.hostPort]
    });
    fourToTwo.handler = new RelayHandler(fourToTwo);

    var twoSvc2 = three.makeSubChannel({
        serviceName: 'two'
    });
    twoSvc2.register('decline', declineError);

    var twoSvc = two.makeSubChannel({
        serviceName: 'two'
    });
    twoSvc.register('decline', declineError);

    var client = TChannel({
        logger: one.logger
    });
    var twoClient = client.makeSubChannel({
        serviceName: 'two',
        peers: [one.hostPort, four.hostPort],
        requestDefaults: {
            serviceName: 'two',
            headers: {
                as: 'raw',
                cn: 'wat'
            }
        }
    });

    twoClient.request({
        hasNoParent: true,
        headers: {
            as: 'raw',
            cn: 'wat'
        }
    }).send('decline', 'foo', 'bar', function done(err, res, arg2, arg3) {
        assert.equal(err.type, 'tchannel.declined', 'expected declined error');

        client.close();
        assert.end();
    });

    function declineError(req, res, arg2, arg3) {
        res.sendError('Declined', 'lul');
    }
});

function echo(req, res, arg2, arg3) {
    res.headers.as = 'raw';
    res.sendOk(arg2, arg3);
}

RelayNetwork.test('relay through a network', {
    serviceNames: ['alice', 'bob'],
    numInstancesPerService: 1,
    kValue: 1,
    numRelays: 2
}, function t(network, assert) {

    network.forEachSubChannel(function register(channel, serviceName, instanceIndex) {
        channel.handler.register('ping', function ping(req, res) {
            res.headers.as = 'raw';
            res.sendOk('' + instanceIndex, serviceName);
        });
    });

    network.subChannelsByName.alice[0].request({
        hasNoParent: true,
        serviceName: 'bob',
        headers: {
            cn: 'alice',
            as: 'raw'
        }
    }).send('ping', 'foo', 'bar', function onResponse(err, res, arg2, arg3) {
        if (err) return assert.end(err);
        assert.equal(arg3.toString(), 'bob', 'response relayed to and from requested service');
        assert.end();
    });
});
<commit_msg>test for relay role transition events<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// 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.

'use strict';

var allocCluster = require('./lib/alloc-cluster');
var TChannel = require('../channel');
var RelayHandler = require('../relay_handler');
var RelayNetwork = require('./lib/relay_network');
var CountedReady = require('ready-signal/counted');

allocCluster.test('send relay requests', {
    numPeers: 2
}, function t(cluster, assert) {
    var one = cluster.channels[0];
    var two = cluster.channels[1];

    var oneToTwo = one.makeSubChannel({
        serviceName: 'two',
        peers: [two.hostPort]
    });
    oneToTwo.handler = new RelayHandler(oneToTwo);

    var twoSvc = two.makeSubChannel({
        serviceName: 'two'
    });
    twoSvc.register('echo', echo);

    var client = TChannel({
        logger: one.logger
    });
    var twoClient = client.makeSubChannel({
        serviceName: 'two',
        peers: [one.hostPort],
        requestDefaults: {
            serviceName: 'two',
            headers: {
                as: 'raw',
                cn: 'wat'
            }
        }
    });

    twoClient.request({
        hasNoParent: true
    }).send('echo', 'foo', 'bar', function done(err, res, arg2, arg3) {
        assert.ifError(err, 'no unexpected error');
        assert.equal(String(arg2), 'foo', 'expected arg2');
        assert.equal(String(arg3), 'bar', 'expected arg3');

        client.close();
        assert.end();
    });
});

allocCluster.test('relay respects ttl', {
    numPeers: 3
}, function t(cluster, assert) {
    var relay = cluster.channels[0];
    var source = cluster.channels[1];
    var dest = cluster.channels[2];

    var relayChan = relay.makeSubChannel({
        serviceName: 'dest',
        peers: [dest.hostPort]
    });
    relayChan.handler = new RelayHandler(relayChan);

    var destChan = dest.makeSubChannel({
        serviceName: 'dest'
    });
    destChan.register('echoTTL', function echoTTL(req, res) {
        res.headers.as = 'raw';
        res.sendOk(null, String(req.ttl));
    });

    var sourceChan = source.makeSubChannel({
        serviceName: 'dest',
        peers: [relay.hostPort],
        requestDefaults: {
            headers: {
                as: 'raw',
                cn: 'wat'
            }
        }
    });

    sourceChan.request({
        serviceName: 'dest',
        hasNoParent: true,
        timeout: 250
    }).send('echoTTL', null, null, onResponse);

    function onResponse(err, res, arg2, arg3) {
        assert.ifError(err);
        assert.ok(res.ok);

        var ttl = Number(String(arg3));
        assert.ok(ttl >= 240 && ttl <= 250);

        assert.end();
    }
});

allocCluster.test('relay an error frame', {
    numPeers: 4
}, function t(cluster, assert) {
    var one = cluster.channels[0];
    var two = cluster.channels[1];
    var three = cluster.channels[2];
    var four = cluster.channels[3];

    var oneToTwo = one.makeSubChannel({
        serviceName: 'two',
        peers: [two.hostPort, three.hostPort]
    });
    oneToTwo.handler = new RelayHandler(oneToTwo);
    var fourToTwo = four.makeSubChannel({
        serviceName: 'two',
        peers: [two.hostPort, three.hostPort]
    });
    fourToTwo.handler = new RelayHandler(fourToTwo);

    var twoSvc2 = three.makeSubChannel({
        serviceName: 'two'
    });
    twoSvc2.register('decline', declineError);

    var twoSvc = two.makeSubChannel({
        serviceName: 'two'
    });
    twoSvc.register('decline', declineError);

    var client = TChannel({
        logger: one.logger
    });
    var twoClient = client.makeSubChannel({
        serviceName: 'two',
        peers: [one.hostPort, four.hostPort],
        requestDefaults: {
            serviceName: 'two',
            headers: {
                as: 'raw',
                cn: 'wat'
            }
        }
    });

    twoClient.request({
        hasNoParent: true,
        headers: {
            as: 'raw',
            cn: 'wat'
        }
    }).send('decline', 'foo', 'bar', function done(err, res, arg2, arg3) {
        assert.equal(err.type, 'tchannel.declined', 'expected declined error');

        client.close();
        assert.end();
    });

    function declineError(req, res, arg2, arg3) {
        res.sendError('Declined', 'lul');
    }
});

function echo(req, res, arg2, arg3) {
    res.headers.as = 'raw';
    res.sendOk(arg2, arg3);
}

RelayNetwork.test('relay through a network', {
    serviceNames: ['alice', 'bob'],
    numInstancesPerService: 1,
    kValue: 1,
    numRelays: 2
}, function t(network, assert) {

    network.forEachSubChannel(function register(channel, serviceName, instanceIndex) {
        channel.handler.register('ping', function ping(req, res) {
            res.headers.as = 'raw';
            res.sendOk('' + instanceIndex, serviceName);
        });
    });

    network.subChannelsByName.alice[0].request({
        hasNoParent: true,
        serviceName: 'bob',
        headers: {
            cn: 'alice',
            as: 'raw'
        }
    }).send('ping', 'foo', 'bar', function onResponse(err, res, arg2, arg3) {
        if (err) return assert.end(err);
        assert.equal(arg3.toString(), 'bob', 'response relayed to and from requested service');
        assert.end();
    });
});

RelayNetwork.test('relay network changes dont break', {
    serviceNames: ['alice', 'bob'],
    numInstancesPerService: 1,
    kValue: 1,
    numRelays: 2
}, function t(network, assert) {

    network.forEachSubChannel(function register(channel, serviceName, instanceIndex) {
        channel.handler.register('ping', function ping(req, res) {
            res.headers.as = 'raw';
            res.sendOk('' + instanceIndex, serviceName);
        });
    });

    var aliceHosts = network.topology.alice;
    var bobHosts = network.topology.bob;
    network.topology.bob = aliceHosts;
    network.topology.alice = bobHosts;

    var ready = CountedReady(2);

    network.relayChannels[0].handler.roleTransitionEvent.on(function (stuff) {
        assert.equals(stuff.newMode, 'forward');
        ready.signal();
    });

    network.relayChannels[1].handler.roleTransitionEvent.on(function (stuff) {
        assert.equals(stuff.newMode, 'forward');
        ready.signal();
    });

    network.egressNodesForRelay[0].membershipChangedEvent.emit();
    network.egressNodesForRelay[1].membershipChangedEvent.emit();

    ready(assert.end);
});
<|endoftext|>


<commit_before>var nodeCache = require('node-cache');

/**
 * nodeCacheModule constructor
 * @constructor
 * @param config: {
 *    type:                 {string | 'node-cache-standalone'}
 *    verbose:              {boolean | false},
 *    expiration:           {integer | 900},
 *    readOnly:             {boolean | false},
 *    checkOnPreviousEmpty  {boolean | true}
 * }
 */
function nodeCacheModule(config){
  var self = this;
  config = config || {};
  self.verbose = config.verbose || false;
  self.expiration = config.defaultExpiration || 900;
  self.readOnly = (typeof config.readOnly === 'boolean') ? config.readOnly : false;
  self.checkOnPreviousEmpty = (typeof config.checkOnPreviousEmpty === 'boolean') ? config.checkOnPreviousEmpty : true;

  /**
   ******************************************* PUBLIC FUNCTIONS *******************************************
   */

  /**
   * Get the value associated with a given key
   * @param {string} key
   * @param {function} cb
   * @param {string} cleanKey
   */
  self.get = function(key, cb, cleanKey){
    log(false, 'Attempting to get key:', {key: key});
    try {
      cacheKey = (cleanKey) ? cleanKey : key;
      log(false, 'Attempting to get key:', {key: cacheKey});
      self.db.get(cacheKey, function(err, result){
        cb(err, result);
      });
    } catch (err) {
      cb({name: 'GetException', message: err}, null);
    }
  }

  /**
   * Get multiple values given multiple keys
   * @param {array} keys
   * @param {function} cb
   * @param {integer} index
   */
  self.mget = function(keys, cb, index){
    log(false, 'Attempting to mget keys:', {keys: keys});
    self.db.mget(keys, function (err, response){
      cb(err, response, index);
    });
  }

  /**
   * Associate a key and value and optionally set an expiration
   * @param {string} key
   * @param {string | object} value
   * @param {integer} expiration
   * @param {function} cb
   */
  self.set = function(key, value, expiration, cb){
    log(false, 'Attempting to set key:', {key: key, value: value});
    try {
      if(!self.readOnly){
        expiration = expiration || self.expiration;
        cb = cb || noop;
        self.db.set(key, value, expiration, cb);
      }
    } catch (err) {
      log(true, 'Set failed for cache of type ' + self.type, {name: 'NodeCacheSetException', message: err});
    }
  }

  /**
   * Associate multiple keys with multiple values and optionally set expirations per function and/or key
   * @param {object} obj
   * @param {integer} expiration
   * @param {function} cb
   */
  self.mset = function(obj, expiration, cb){
    log(false, 'Attempting to mset data:', {data: obj});
    for(key in obj){
      if(obj.hasOwnProperty(key)){
        var tempExpiration = expiration || self.expiration;
        var value = obj[key];
        if(typeof value === 'object' && value.cacheValue){
          tempExpiration = value.expiration || tempExpiration;
          value = value.cacheValue;
        }
        self.db.set(key, value, tempExpiration);
      }
    }
    if(cb) cb();
  }

  /**
   * Delete the provided keys and their associated values
   * @param {array} keys
   * @param {function} cb
   */
  self.del = function(keys, cb){
    log(false, 'Attempting to delete keys:', {keys: keys});
    try {
      self.db.del(keys, function (err, count){
        if(cb){
          cb(err, count);
        }
      });
    } catch (err) {
      log(true, 'Delete failed for cache of type ' + this.type, err);
    }
  }

  /**
   * Flush all keys and values
   * @param {function} cb
   */
  self.flushAll = function(cb){
    log(false, 'Attempting to flush all data.');
    try {
      self.db.flushAll();
      log(false, 'Flushing all data from cache of type ' + this.type);
    } catch (err) {
      log(true, 'Flush failed for cache of type ' + this.type, err);
    }
    if(cb) cb();
  }

  /**
   ******************************************* PRIVATE FUNCTIONS *******************************************
   */

  /**
   * Initialize nodeCacheModule given the provided constructor params
   */
  function init(){
    try {
      self.db = new nodeCache();
      log(false, 'Node-cache client created with the following defaults:', {expiration: this.expiration, verbose: this.verbose, readOnly: this.readOnly});
    } catch (err) {
      log(true, 'Node-cache client not created:', err);
      self.db = false;
    }
    self.type = config.type || 'node-cache';
  }

  /**
   * Error logging logic
   * @param {boolean} isError
   * @param {string} message
   * @param {object} data
   */
  function log(isError, message, data){
    var indentifier = 'nodeCacheModule: ';
    if(self.verbose || isError){
      if(data) console.log(indentifier + message, data);
      else console.log(indentifier + message);
    }
  }

  var noop = function(){}

  init();
}

module.exports = nodeCacheModule;
<commit_msg>Scoping a variable.<commit_after>var nodeCache = require('node-cache');

/**
 * nodeCacheModule constructor
 * @constructor
 * @param config: {
 *    type:                 {string | 'node-cache-standalone'}
 *    verbose:              {boolean | false},
 *    expiration:           {integer | 900},
 *    readOnly:             {boolean | false},
 *    checkOnPreviousEmpty  {boolean | true}
 * }
 */
function nodeCacheModule(config){
  var self = this;
  config = config || {};
  self.verbose = config.verbose || false;
  self.expiration = config.defaultExpiration || 900;
  self.readOnly = (typeof config.readOnly === 'boolean') ? config.readOnly : false;
  self.checkOnPreviousEmpty = (typeof config.checkOnPreviousEmpty === 'boolean') ? config.checkOnPreviousEmpty : true;

  /**
   ******************************************* PUBLIC FUNCTIONS *******************************************
   */

  /**
   * Get the value associated with a given key
   * @param {string} key
   * @param {function} cb
   * @param {string} cleanKey
   */
  self.get = function(key, cb, cleanKey){
    log(false, 'Attempting to get key:', {key: key});
    try {
      var cacheKey = (cleanKey) ? cleanKey : key;
      log(false, 'Attempting to get key:', {key: cacheKey});
      self.db.get(cacheKey, function(err, result){
        cb(err, result);
      });
    } catch (err) {
      cb({name: 'GetException', message: err}, null);
    }
  }

  /**
   * Get multiple values given multiple keys
   * @param {array} keys
   * @param {function} cb
   * @param {integer} index
   */
  self.mget = function(keys, cb, index){
    log(false, 'Attempting to mget keys:', {keys: keys});
    self.db.mget(keys, function (err, response){
      cb(err, response, index);
    });
  }

  /**
   * Associate a key and value and optionally set an expiration
   * @param {string} key
   * @param {string | object} value
   * @param {integer} expiration
   * @param {function} cb
   */
  self.set = function(key, value, expiration, cb){
    log(false, 'Attempting to set key:', {key: key, value: value});
    try {
      if(!self.readOnly){
        expiration = expiration || self.expiration;
        cb = cb || noop;
        self.db.set(key, value, expiration, cb);
      }
    } catch (err) {
      log(true, 'Set failed for cache of type ' + self.type, {name: 'NodeCacheSetException', message: err});
    }
  }

  /**
   * Associate multiple keys with multiple values and optionally set expirations per function and/or key
   * @param {object} obj
   * @param {integer} expiration
   * @param {function} cb
   */
  self.mset = function(obj, expiration, cb){
    log(false, 'Attempting to mset data:', {data: obj});
    for(key in obj){
      if(obj.hasOwnProperty(key)){
        var tempExpiration = expiration || self.expiration;
        var value = obj[key];
        if(typeof value === 'object' && value.cacheValue){
          tempExpiration = value.expiration || tempExpiration;
          value = value.cacheValue;
        }
        self.db.set(key, value, tempExpiration);
      }
    }
    if(cb) cb();
  }

  /**
   * Delete the provided keys and their associated values
   * @param {array} keys
   * @param {function} cb
   */
  self.del = function(keys, cb){
    log(false, 'Attempting to delete keys:', {keys: keys});
    try {
      self.db.del(keys, function (err, count){
        if(cb){
          cb(err, count);
        }
      });
    } catch (err) {
      log(true, 'Delete failed for cache of type ' + this.type, err);
    }
  }

  /**
   * Flush all keys and values
   * @param {function} cb
   */
  self.flushAll = function(cb){
    log(false, 'Attempting to flush all data.');
    try {
      self.db.flushAll();
      log(false, 'Flushing all data from cache of type ' + this.type);
    } catch (err) {
      log(true, 'Flush failed for cache of type ' + this.type, err);
    }
    if(cb) cb();
  }

  /**
   ******************************************* PRIVATE FUNCTIONS *******************************************
   */

  /**
   * Initialize nodeCacheModule given the provided constructor params
   */
  function init(){
    try {
      self.db = new nodeCache();
      log(false, 'Node-cache client created with the following defaults:', {expiration: this.expiration, verbose: this.verbose, readOnly: this.readOnly});
    } catch (err) {
      log(true, 'Node-cache client not created:', err);
      self.db = false;
    }
    self.type = config.type || 'node-cache';
  }

  /**
   * Error logging logic
   * @param {boolean} isError
   * @param {string} message
   * @param {object} data
   */
  function log(isError, message, data){
    var indentifier = 'nodeCacheModule: ';
    if(self.verbose || isError){
      if(data) console.log(indentifier + message, data);
      else console.log(indentifier + message);
    }
  }

  var noop = function(){}

  init();
}

module.exports = nodeCacheModule;
<|endoftext|>


<commit_before>import remote from "remote"
import LocalStorageManager from "../utils/local_storage_manager"

var saveDims = function () {
  LocalStorageManager.set("windowDimensions", {
    x         : window.screenX,
    y         : window.screenY,
    width     : window.outerWidth,
    height    : window.outerHeight,
    maximized : remote.getCurrentWindow().isMaximized()
  })
}

export default function initWindow() {
  window.addEventListener("unload", saveDims)
  window.addEventListener("resize", saveDims)

  var dims = LocalStorageManager.get("windowDimensions")

  if (dims) {
    if (dims.maximized === "true") {
      remote.getCurrentWindow().show()
      remote.getCurrentWindow().maximize()
    } else {
      window.resizeTo(dims.width, dims.height)
      window.moveTo(dims.x, dims.y)
    }
  }

  remote.getCurrentWindow().show()
}
<commit_msg>Better window bounds restore functionality<commit_after>import remote from "remote"
import LocalStorageManager from "../utils/local_storage_manager"
import _ from "underscore"

export default function initWindow() {
  const win = remote.getCurrentWindow()
  const dims = LocalStorageManager.get("windowDimensions")

  const saveDims = _.debounce(() => {
    LocalStorageManager.set("windowDimensions", {
      bounds    : win.getBounds(),
      maximized : win.isMaximized()
    })
  }, 100);

  ["move", "resize"].forEach((event) => {
    win.removeAllListeners(event)
    win.on(event, saveDims)
  })

  if (dims) {
    win.setBounds(dims.bounds)
    win.show()

    // Maximizing on OSX is a bit odd
    if (process.platform != "darwin" && dims.maximized) {
      win.maximize()
    }
  }
}
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var request = require('request');
var config = require('../custom_configFile.json');
var shortid = require('shortid');

function getData(user, callback) {
    request(config.apiUrl + 'account.json?screen_name=' + user, callback);
}

function updateData(user, data, callback) {
    var dataToSend = {
        screen_name: user,
        apps: data
    }
    request.post(config.apiUrl + 'account.json').form({
        action: 'update',
        data: JSON.stringify(dataToSend)
    }, callback);
}

//LIST
router.get('/:user/:app', function(req, res) {
    getData(req.params.user, function(error, response, body) {
        var data = JSON.parse(response.body).accounts[0];
        if (data.apps[req.params.app])
            res.jsonp(data.apps[req.params.app]);
        else
            res.jsonp([]);
    });
});

//READ
router.get('/:user/:app/:id', function(req, res) {
    getData(req.params.user, function(error, response, body) {
        var data = JSON.parse(response.body).accounts[0];
        if (data.apps[req.params.app]) {
            for (var i = 0; i < data.apps[req.params.app].length; i++) {
                if (data.apps[req.params.app][i].id == req.params.id) {
                    return res.jsonp(data.apps[req.params.app][i]);
                }
            }
            res.jsonp({});
        } else {
            res.jsonp({});
        }
    });
});

//CREATE
router.post('/:user/:app', function(req, res) {
    var newWall = req.body;
    getData(req.params.user, function(error, response, body) {
        var appData = JSON.parse(response.body).accounts[0].apps;
        if (!appData[req.params.app]) {
            appData[req.params.app] = [];
        }
        newWall.id = shortid.generate();
        appData[req.params.app].push(newWall);
        updateData(req.params.user, appData, function(error, response, body) {
            console.log(response.body);
            res.send({
                id: newWall.id
            });
        });
    });
});

//DELETE
router.delete('/:user/:app/:id', function(req, res) {
    getData(req.params.user, function(error, response, body) {
        var appData = JSON.parse(response.body).accounts[0].apps;
        if (!appData[req.params.app]) {
            appData[req.params.app] = [];
        }
        var found = false;
        for (var i = 0; i < appData[req.params.app].length; i++) {
            if (appData[req.params.app][i].id == req.params.id) {
                found = true;
                appData[req.params.app].splice(i, 1)
                var dataToSend = {
                    screen_name: req.params.user,
                    apps: appData
                }
                updateData(req.params.user, appData, function(error, response, body) {
                    console.log(response.body);
                    return res.json({
                        status: "OK"
                    });
                });
            }
        }
        if (found == false) {
            res.json({
                status: "ERROR"
            });
        }

    });
});

//UPDATE
router.put('/:user/:app/:id', function(req, res) {
    getData(req.params.user, function(error, response, body) {
        var appData = JSON.parse(response.body).accounts[0].apps;
        if (!appData[req.params.app]) {
            appData[req.params.app] = [];
        }
        var found = false;
        for (var i = 0; i < appData[req.params.app].length; i++) {
            if (appData[req.params.app][i].id == req.params.id) {
                found = true;
                appData[req.params.app][i] = req.body;
                var dataToSend = {
                    screen_name: req.params.user,
                    apps: appData
                }
                updateData(req.params.user, appData, function(error, response, body) {
                    console.log(response.body);
                    res.send({
                        id: req.params.id
                    });
                });
            }
        }
        if (found == false) {
            res.json({
                status: "ERROR"
            });
        }

    });
});

module.exports = router;
<commit_msg>Fixed callback bug in update and delete methods.<commit_after>var express = require('express');
var router = express.Router();
var request = require('request');
var config = require('../custom_configFile.json');
var shortid = require('shortid');

function getData(user, callback) {
    request(config.apiUrl + 'account.json?screen_name=' + user, callback);
}

function updateData(user, data, callback) {
    var dataToSend = {
        screen_name: user,
        apps: data
    }
    request.post({
            url: config.apiUrl + 'account.json',
            form: {
                action: 'update',
                data: JSON.stringify(dataToSend)
            }
        },
        callback
    );
}

//LIST
router.get('/:user/:app', function(req, res) {
    getData(req.params.user, function(error, response, body) {
        var data = JSON.parse(response.body).accounts[0];
        if (data.apps[req.params.app])
            res.jsonp(data.apps[req.params.app]);
        else
            res.jsonp([]);
    });
});

//READ
router.get('/:user/:app/:id', function(req, res) {
    getData(req.params.user, function(error, response, body) {
        var data = JSON.parse(response.body).accounts[0];
        if (data.apps[req.params.app]) {
            for (var i = 0; i < data.apps[req.params.app].length; i++) {
                if (data.apps[req.params.app][i].id == req.params.id) {
                    return res.jsonp(data.apps[req.params.app][i]);
                }
            }
            res.jsonp({});
        } else {
            res.jsonp({});
        }
    });
});

//CREATE
router.post('/:user/:app', function(req, res) {
    var newWall = req.body;
    getData(req.params.user, function(error, response, body) {
        var appData = JSON.parse(response.body).accounts[0].apps;
        if (!appData[req.params.app]) {
            appData[req.params.app] = [];
        }
        newWall.id = shortid.generate();
        appData[req.params.app].push(newWall);
        console.log(newWall.id);
        updateData(req.params.user, appData, function(error, response, body) {
            console.log(response.body);
            return res.json({
                id: newWall.id
            });
        });
    });
});

//DELETE
router.delete('/:user/:app/:id', function(req, res) {
    getData(req.params.user, function(error, response, body) {
        var appData = JSON.parse(response.body).accounts[0].apps;
        if (!appData[req.params.app]) {
            appData[req.params.app] = [];
        }
        var found = false;
        for (var i = 0; i < appData[req.params.app].length; i++) {
            if (appData[req.params.app][i].id == req.params.id) {
                found = true;
                appData[req.params.app].splice(i, 1)
                var dataToSend = {
                    screen_name: req.params.user,
                    apps: appData
                }
                updateData(req.params.user, appData, function(error, response, body) {
                    console.log(response.body);
                    return res.json({
                        status: "OK"
                    });
                });
            }
        }
        if (found == false) {
            res.json({
                status: "ERROR"
            });
        }

    });
});

//UPDATE
router.put('/:user/:app/:id', function(req, res) {
    getData(req.params.user, function(error, response, body) {
        var appData = JSON.parse(response.body).accounts[0].apps;
        if (!appData[req.params.app]) {
            appData[req.params.app] = [];
        }
        var found = false;
        for (var i = 0; i < appData[req.params.app].length; i++) {
            if (appData[req.params.app][i].id == req.params.id) {
                found = true;
                appData[req.params.app][i] = req.body;
                var dataToSend = {
                    screen_name: req.params.user,
                    apps: appData
                }
                updateData(req.params.user, appData, function(error, response, body) {
                    console.log(response.body);
                    return res.json({
                        id: req.params.id
                    });
                });
            }
        }
        if (found == false) {
            res.json({
                status: "ERROR"
            });
        }

    });
});

module.exports = router;
<|endoftext|>


<commit_before>//Factory function
function createPerson(name) {
    return {
        name: name,
        talk: function () {
            console.log('a person can talk');
        }
    }
}

const person = createPerson('ted');
person.talk();

//Constructor function
function Person(name) {
    let privateMember = 'private string';
    this.name = name;
    this.talk = function () {
        console.log('a person can talk2');
    }
    //ECMAScript 5 is also known as ES5 and ECMAScript 2009
    //Object property methods
    Object.defineProperty(this, 'showString', {
        get: function() {
            return privateMember;
        }
    });
}

const person2 = new Person('ted2');
person2.talk();
console.log('show string ' + person2.privateMember);//show string undefined
console.log('show string ' + person2.showString);
<commit_msg>Prototype example<commit_after>//Factory function
function createPerson(name) {
    return {
        name: name,
        talk: function () {
            console.log('a person can talk');
        }
    }
}

const person = createPerson('ted');
person.talk();

//Constructor function
function Person(name) {
    let privateMember = 'private string';
    this.name = name;
    this.talk = function () {
        console.log('a person can talk2');
    }
    //ECMAScript 5 is also known as ES5 and ECMAScript 2009
    //Object property methods
    Object.defineProperty(this, 'showString', {
        get: function() {
            return privateMember;
        }
    });
}

const person2 = new Person('ted2');
person2.talk();
console.log('show string ' + person2.privateMember);//show string undefined
console.log('show string ' + person2.showString);

//Using prototypes for object inheritance
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
let f = function () {
    this.a = 1;
    this.b = 2;
}
let o = new f();
f.prototype.b = 3;
f.prototype.c = 4;
console.log(o.a);
console.log(o.b);
console.log(o.c);
console.log(o.d);

function Teacher(name) {
    this.name = name;
    this.lecture = function() {
        console.log(this.name + ' i can teach');
    }
}

function talkFast() {
    console.log('I am a teacher I talk fast.');
}
//use composition inherit only what you need
//Teacher.prototype.talk = Person.talk; does not work
Teacher.prototype.talk = person2.talk;
//Teacher.prototype.talk = talkFast;//overriding
const goodTeacher = new Teacher('Mr Smith');
//goodTeacher.prototype.talk = person2.talk; does not work
goodTeacher.talk();//no prototype - goodTeacher.talk is not a function
goodTeacher.lecture();
<|endoftext|>