<commit_before>/**
  * vue-typed 2.1.1
  * Sets of ECMAScript / Typescript decorators that helps you write Vue component easily.
  * http://vue-typed.github.io/vue-typed/

  * Copyright 2016, Budi Adiono
  * Released under the MIT license.
  '*/
(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue')) :
	typeof define === 'function' && define.amd ? define(['exports', 'vue'], factory) :
	(factory((global.VueTyped = {}),global.Vue));
}(this, (function (exports,Vue) { 'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  return typeof obj;
} : function (obj) {
  return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};

var vueInternalPropNames = Object.getOwnPropertyNames(new Vue());
var vueInternalHooks = ['data', 'props', 'watch', 'beforeCreate', 'created', 'beforeMount', 'mounted', 'beforeUpdate', 'updated', 'activated', 'deactivated', 'beforeDestroy', 'destroyed', 'render'];
function BuildOptions(Component, options) {
    if (!options) {
        options = {};
    }
    options.name = options.name || Component.name;
    var proto = Component.prototype;
    if (Object.getPrototypeOf(proto) instanceof Vue) Object.setPrototypeOf(proto.constructor, function () {});
    var constructor = new proto.constructor();
    var vueKeys = [];
    if (proto.vuex) {
        var protoVue = proto.vuex;
        if (protoVue['getters']) {
            Object.getOwnPropertyNames(protoVue['getters']).forEach(function (k) {
                vueKeys.push(k);
            });
        }
        if (protoVue['actions']) {
            Object.getOwnPropertyNames(protoVue['actions']).forEach(function (k) {
                vueKeys.push(k);
            });
        }
    }
    var propAttrs = proto['$_vt_props'];
    var propNames = undefined;
    delete proto['$_vt_props'];
    if (propAttrs) {
        var key = 'props';
        var props = {};
        propNames = Object.getOwnPropertyNames(propAttrs);
        for (var i = 0; i < propNames.length; i++) {
            var prop = propNames[i];
            var propVal = undefined;
            var descriptor = Object.getOwnPropertyDescriptor(propAttrs, prop);
            var constructorDefault = constructor[prop];
            if (_typeof(descriptor.value) === 'object') {
                propVal = descriptor.value;
                if (!propVal.default) propVal.default = constructorDefault;
            } else if (constructorDefault) {
                propVal = {
                    default: constructorDefault
                };
            }
            if (typeof propVal === 'undefined') {
                propVal = true;
            }
            props[prop] = propVal;
        }
        if (!options.props) {
            options.props = {};
        }
        for (var p in props) {
            options.props[p] = props[p];
        }
    }
    Object.getOwnPropertyNames(proto).forEach(function (key) {
        if (key === 'constructor') {
            return;
        }
        if (vueInternalHooks.indexOf(key) > -1) {
            options[key] = proto[key];
            return;
        }
        var descriptor = Object.getOwnPropertyDescriptor(proto, key);
        if (typeof descriptor.value === 'function') {
            if (vueKeys.indexOf(key) > -1) return;
            (options.methods || (options.methods = {}))[key] = descriptor.value;
        } else if (descriptor.get || descriptor.set) {
            (options.computed || (options.computed = {}))[key] = {
                get: descriptor.get,
                set: descriptor.set
            };
        }
    });
    var dataNames = [];
    var restrictedNames = vueInternalPropNames;
    if (propNames) restrictedNames = restrictedNames.concat(propNames);
    if (vueKeys && vueKeys.length) restrictedNames = restrictedNames.concat(vueKeys);
    Object.getOwnPropertyNames(constructor).forEach(function (key) {
        if (restrictedNames.indexOf(key) === -1) {
            dataNames.push(key);
        }
    });
    if (dataNames.length > 0) {
        var parentData = undefined;
        var parentDataType = _typeof(options['data']);
        if (parentDataType === 'function') {
            parentData = options['data']();
        } else if (parentDataType === 'object') {
            parentData = options['data'];
        }
        options['data'] = function () {
            var data_obj = parentData || {};
            dataNames.forEach(function (prop) {
                var descriptor = Object.getOwnPropertyDescriptor(constructor, prop);
                if (!descriptor.get && !descriptor.set && typeof descriptor.value !== 'function') {
                    data_obj[prop] = constructor[prop];
                }
            });
            return data_obj;
        };
    }
    return options;
}
function Virtual() {
    return function () {};
}

function Component(options) {
    var factory = function factory(Component, options) {
        var superProto = Object.getPrototypeOf(Component.prototype);
        var Super = superProto instanceof Vue ? superProto.constructor : Vue;
        return Super['extend'](BuildOptions(Component, options));
    };
    if (options instanceof Function) {
        return factory(options);
    }
    return function (Component) {
        return factory(Component, options);
    };
}

function Options(options) {
    return function (Component) {
        function chainUp(component) {
            var Super = Object.getPrototypeOf(component);
            if (Super instanceof Object && Super.prototype) {
                var keys = Object.getOwnPropertyNames(Super.prototype);
                for (var i = 0; i < keys.length; i++) {
                    var key = keys[i];
                    var descriptor = Object.getOwnPropertyDescriptor(Super.prototype, key);
                    if (!Component.prototype.hasOwnProperty(key)) Object.defineProperty(Component.prototype, key, descriptor);
                }
                chainUp(Super);
            }
        }
        chainUp(Component);
        return BuildOptions(Component, options);
    };
}

function Prop(options) {
    return function (target, key) {
        var id = '$_vt_props';
        if (!target[id]) {
            target[id] = {};
        }
        if (!target[id][key]) {
            if (options) {
                target[id][key] = options;
            } else {
                target[id][key] = true;
            }
        }
    };
}

function Watch(property, deep) {
    return function (target, key) {
        if (_typeof(target['watch']) !== 'object') {
            target['watch'] = {};
        }
        if (!target['watch'][property]) {
            var watcher;
            if (deep !== undefined) {
                watcher = {
                    handler: target[key],
                    deep: deep
                };
            } else {
                watcher = target[key];
            }
            target['watch'][property] = watcher;
        }
    };
}

function Mixin(component) {
    return Vue.extend({
        mixins: [component]
    });
}
function Mixins() {
    var components = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        components[_i] = arguments[_i];
    }
    return Vue.extend({
        mixins: components
    });
}

function GlobalMixin(options) {
    var factory = function factory(Component, options) {
        Vue.mixin(BuildOptions(Component, options));
    };
    return function (Component) {
        return factory(Component, options);
    };
}

exports.Component = Component;
exports.Options = Options;
exports.Prop = Prop;
exports.Watch = Watch;
exports.Mixin = Mixin;
exports.Mixins = Mixins;
exports.GlobalMixin = GlobalMixin;
exports.Virtual = Virtual;

Object.defineProperty(exports, '__esModule', { value: true });

})));
<commit_msg>v2.1.2<commit_after>/**
  * vue-typed 2.1.2
  * Sets of ECMAScript / Typescript decorators that helps you write Vue component easily.
  * http://vue-typed.github.io/vue-typed/

  * Copyright 2016, Budi Adiono
  * Released under the MIT license.
  '*/
(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue')) :
	typeof define === 'function' && define.amd ? define(['exports', 'vue'], factory) :
	(factory((global.VueTyped = {}),global.Vue));
}(this, (function (exports,Vue) { 'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  return typeof obj;
} : function (obj) {
  return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};

var vueInternalPropNames = Object.getOwnPropertyNames(new Vue());
var vueInternalHooks = ['data', 'props', 'watch', 'beforeCreate', 'created', 'beforeMount', 'mounted', 'beforeUpdate', 'updated', 'activated', 'deactivated', 'beforeDestroy', 'destroyed', 'render'];
function BuildOptions(Component, options) {
    if (!options) {
        options = {};
    }
    options.name = options.name || Component.name;
    var proto = Component.prototype;
    if (Object.getPrototypeOf(proto) instanceof Vue) Object.setPrototypeOf(proto.constructor, function () {});
    var constructor = new proto.constructor();
    var vueKeys = [];
    if (proto.vuex) {
        var protoVue = proto.vuex;
        if (protoVue['getters']) {
            Object.getOwnPropertyNames(protoVue['getters']).forEach(function (k) {
                vueKeys.push(k);
            });
        }
        if (protoVue['actions']) {
            Object.getOwnPropertyNames(protoVue['actions']).forEach(function (k) {
                vueKeys.push(k);
            });
        }
    }
    var propAttrs = proto['$_vt_props'];
    var propNames = undefined;
    delete proto['$_vt_props'];
    if (propAttrs) {
        var key = 'props';
        var props = {};
        propNames = Object.getOwnPropertyNames(propAttrs);
        for (var i = 0; i < propNames.length; i++) {
            var prop = propNames[i];
            var propVal = undefined;
            var descriptor = Object.getOwnPropertyDescriptor(propAttrs, prop);
            var constructorDefault = constructor[prop];
            if (_typeof(descriptor.value) === 'object') {
                propVal = descriptor.value;
                if (!propVal.default) propVal.default = constructorDefault;
            } else if (constructorDefault) {
                propVal = {
                    default: constructorDefault
                };
            }
            if (typeof propVal === 'undefined') {
                propVal = true;
            }
            props[prop] = propVal;
        }
        if (!options.props) {
            options.props = {};
        }
        for (var p in props) {
            options.props[p] = props[p];
        }
    }
    Object.getOwnPropertyNames(proto).forEach(function (key) {
        if (key === 'constructor') {
            return;
        }
        if (vueInternalHooks.indexOf(key) > -1) {
            options[key] = proto[key];
            return;
        }
        var descriptor = Object.getOwnPropertyDescriptor(proto, key);
        if (typeof descriptor.value === 'function') {
            if (vueKeys.indexOf(key) > -1) return;
            (options.methods || (options.methods = {}))[key] = descriptor.value;
        } else if (descriptor.get || descriptor.set) {
            (options.computed || (options.computed = {}))[key] = {
                get: descriptor.get,
                set: descriptor.set
            };
        }
    });
    var dataNames = [];
    var restrictedNames = vueInternalPropNames;
    if (propNames) restrictedNames = restrictedNames.concat(propNames);
    if (vueKeys && vueKeys.length) restrictedNames = restrictedNames.concat(vueKeys);
    Object.getOwnPropertyNames(constructor).forEach(function (key) {
        if (restrictedNames.indexOf(key) === -1) {
            dataNames.push(key);
        }
    });
    if (dataNames.length > 0) {
        var parentData = undefined;
        var parentDataType = _typeof(options['data']);
        if (parentDataType === 'function') {
            parentData = options['data']();
        } else if (parentDataType === 'object') {
            parentData = options['data'];
        }
        options['data'] = function () {
            var data_obj = parentData || {};
            dataNames.forEach(function (prop) {
                var descriptor = Object.getOwnPropertyDescriptor(constructor, prop);
                if (!descriptor.get && !descriptor.set && typeof descriptor.value !== 'function') {
                    data_obj[prop] = constructor[prop];
                }
            });
            return data_obj;
        };
    }
    return options;
}
function Virtual() {
    return function () {};
}

function Component(options) {
    var factory = function factory(Component, options) {
        var superProto = Object.getPrototypeOf(Component.prototype);
        var Super = superProto instanceof Vue ? superProto.constructor : Vue;
        return Super['extend'](BuildOptions(Component, options));
    };
    if (options instanceof Function) {
        return factory(options);
    }
    return function (Component) {
        return factory(Component, options);
    };
}

function Options(options) {
    return function (Component) {
        function chainUp(component) {
            var Super = Object.getPrototypeOf(component);
            if (Super instanceof Object && Super.prototype) {
                var keys = Object.getOwnPropertyNames(Super.prototype);
                for (var i = 0; i < keys.length; i++) {
                    var key = keys[i];
                    var descriptor = Object.getOwnPropertyDescriptor(Super.prototype, key);
                    if (!Component.prototype.hasOwnProperty(key)) Object.defineProperty(Component.prototype, key, descriptor);
                }
                chainUp(Super);
            }
        }
        chainUp(Component);
        return BuildOptions(Component, options);
    };
}

function Prop(options) {
    return function (target, key) {
        var id = '$_vt_props';
        if (!target[id]) {
            target[id] = {};
        }
        if (!target[id][key]) {
            if (options) {
                target[id][key] = options;
            } else {
                target[id][key] = true;
            }
        }
    };
}

function Watch(property, deep) {
    return function (target, key) {
        if (_typeof(target['watch']) !== 'object') {
            target['watch'] = {};
        }
        if (!target['watch'][property]) {
            var watcher;
            if (deep !== undefined) {
                watcher = {
                    handler: target[key],
                    deep: deep
                };
            } else {
                watcher = target[key];
            }
            target['watch'][property] = watcher;
        }
    };
}

function Mixin(component) {
    return Vue.extend({
        mixins: [component]
    });
}
function Mixins() {
    var components = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        components[_i] = arguments[_i];
    }
    return Vue.extend({
        mixins: components
    });
}

function GlobalMixin(options) {
    var factory = function factory(Component, options) {
        Vue.mixin(BuildOptions(Component, options));
    };
    return function (Component) {
        return factory(Component, options);
    };
}

exports.Component = Component;
exports.Options = Options;
exports.Prop = Prop;
exports.Watch = Watch;
exports.Mixin = Mixin;
exports.Mixins = Mixins;
exports.GlobalMixin = GlobalMixin;
exports.Virtual = Virtual;

Object.defineProperty(exports, '__esModule', { value: true });

})));
<|endoftext|>


<commit_before>/*jslint node: true */

exports.register = function (server, options, next) {
    // Start the plugin routing table
    var routingTable = {};
    // Set length of routing table for checking later if new routes get added.
    var routingLength =  [];

    // Setup route names object to be used in the view context.
    var namedRoutes = {};

    // Hook onto the 'onPostHandler'
    server.ext('onPostHandler', function (request, reply) {
        // Get the response object
        var response = request.response;

        // Check to see if the response is a view
        if (response.variety === 'view') {

            // Get current routing table
            var checkRoutingTable = request.connection.table();
            // Get length of current route table
            var checkRoutingLength =  Object.keys(checkRoutingTable);

            // Check to see if the current route table has any new routes since plugin loaded
            if (checkRoutingLength > routingLength) {
                // If new routes then update routingTableLength and the routingTable
                routingLength = checkRoutingLength;
                routingTable = checkRoutingTable;

                // Setup the path object for the route names to be added to in the view
                response.source.context.path = {};

                // Loop over the routingTable
                for(var item in routingTable){
                    //  Look for any routes with app.name defined in the config object
                    if(typeof routingTable[item].settings.app.name !== 'undefined') {
                        // Get the route name from the config object and assign it to routeName
                        var routeName = routingTable[item].settings.app.name;
                        // Get the route path from the config object, remove path wildcard, and assign it to routePath
                        var routePath = routingTable[item].path.replace(/{(.*?)}/g, '');

                        // Put the current route and path being looped over into the view layer variable path
                        response.source.context.path[routeName] = routePath;
                        namedRoutes = response.source.context.path;
                    }
                }
            } else {
                // if no new routes then use the current named routes for the views
                response.source.context.path = namedRoutes;
            }
        }
        return reply.continue();
    });
    return next();
};

exports.register.attributes = {
    pkg: require('./package.json')
};
<commit_msg>Initialize when view context is not given<commit_after>/*jslint node: true */

exports.register = function (server, options, next) {
    // Start the plugin routing table
    var routingTable = {};
    // Set length of routing table for checking later if new routes get added.
    var routingLength =  [];

    // Setup route names object to be used in the view context.
    var namedRoutes = {};

    // Hook onto the 'onPostHandler'
    server.ext('onPostHandler', function (request, reply) {
        // Get the response object
        var response = request.response;

        // Check to see if the response is a view
        if (response.variety === 'view') {

            // Get current routing table
            var checkRoutingTable = request.connection.table();
            // Get length of current route table
            var checkRoutingLength =  Object.keys(checkRoutingTable);

            // Initialize if context is not defined
            response.source.context = response.source.context || {};
            // Check to see if the current route table has any new routes since plugin loaded
            if (checkRoutingLength > routingLength) {
                // If new routes then update routingTableLength and the routingTable
                routingLength = checkRoutingLength;
                routingTable = checkRoutingTable;

                // Setup the path object for the route names to be added to in the view
                response.source.context.path = {};

                // Loop over the routingTable
                for(var item in routingTable){
                    //  Look for any routes with app.name defined in the config object
                    if(typeof routingTable[item].settings.app.name !== 'undefined') {
                        // Get the route name from the config object and assign it to routeName
                        var routeName = routingTable[item].settings.app.name;
                        // Get the route path from the config object, remove path wildcard, and assign it to routePath
                        var routePath = routingTable[item].path.replace(/{(.*?)}/g, '');

                        // Put the current route and path being looped over into the view layer variable path
                        response.source.context.path[routeName] = routePath;
                        namedRoutes = response.source.context.path;
                    }
                }
            } else {
                // if no new routes then use the current named routes for the views
                response.source.context.path = namedRoutes;
            }
        }
        return reply.continue();
    });
    return next();
};

exports.register.attributes = {
    pkg: require('./package.json')
};
<|endoftext|>


<commit_before>require("./messages");
var steam = require("steam");

const DOTA_APP_ID = 570;

var EventEmitter = require('events').EventEmitter,
    fs = require("fs"),
    path = require("path"),
    util = require("util"),
    bignumber = require("bignumber.js"),
    ProtoBuf = require('protobufjs'),
    Dota2 = exports;

ProtoBuf.convertFieldsToCamelCase = true;
var builder = ProtoBuf.newBuilder();
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/base_gcmessages.proto'), builder);
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/gcsdk_gcmessages.proto'), builder);
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/dota_gcmessages_client_fantasy.proto'), builder);
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/dota_gcmessages_client.proto'), builder);
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/dota_gcmessages_common.proto'), builder);
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/steammessages.proto'), builder);
Dota2.schema = builder.build();

var Dota2Client = function Dota2Client(steamUser, debug, debugMore) {
  EventEmitter.call(this);

  this.debug = debug || false;
  this.debugMore = debugMore || false;
  this._user = steamUser;
  this._client = steamUser._client;
  this._gc = new steam.SteamGameCoordinator(this._client, DOTA_APP_ID);
  this._appid = DOTA_APP_ID;
  this.chatChannels = []; // Map channel names to channel data.
  this._gcReady = false;
  this._gcClientHelloIntervalId = null;
  this._gcConnectionStatus = Dota2.GCConnectionStatus.GCConnectionStatus_NO_SESSION;
  // This should probably be reworked to use a CMsgProtoBufHeader object
  this.protoBufHeader = {
    "msg":    "",
    "proto":  {
      "client_steam_id": this._client.steamID,
      "source_app_id":  this._appid
    }
  };

  var self = this;
  this._gc.on("message", function fromGC(header, body, callback) {
    /* Routes messages from Game Coordinator to their handlers. */
    callback = callback || null;

    var kMsg = header.msg;
    if (self.debugMore) util.log("Dota2 fromGC: " + kMsg);  // TODO:  Turn type-protoMask into key name.

    if (kMsg in self._handlers) {
      if (callback) {
        self._handlers[kMsg].call(self, body, callback);
      }
      else {
        self._handlers[kMsg].call(self, body);
      }
    }
    else {
      self.emit("unhandled", kMsg);
    }
  });
  //util.log(steamUser);

  this._sendClientHello = function() {
    if(self._gcReady)
    {
      if(self._gcClientHelloIntervalId)
      {
        clearInterval(self._gcClientHelloIntervalId);
        self._gcClientHelloIntervalId = null;
      }
      return;
    }
    if(self._gcClientHelloCount > 10)
    {
      if(self.debug) util.log("ClientHello has taken longer than 30 seconds! Reporting timeout...");
      self._gcClientHelloCount = 0;
      self.emit("hellotimeout");
    }

    if (self.debug) util.log("Sending ClientHello");
    if (!self._gc) {
      util.log("Where the fuck is _gc?");
    }
    else {self._gc.send(
        {
          "msg":    Dota2.EGCBaseClientMsg.k_EMsgGCClientHello,
          "proto":  {
            "client_steam_id": self._client.steamID,
            "source_app_id":  self._appid
          }
        },
        new Dota2.schema.CMsgClientHello({}).toBuffer()
      );
    }

    self._gcClientHelloCount++;
  };
};
util.inherits(Dota2Client, EventEmitter);

// Expose enums
Dota2Client.prototype.ServerRegion = Dota2.ServerRegion;
Dota2Client.prototype.GameMode = Dota2.GameMode;
Dota2Client.prototype.ToAccountID = function(accid){
  return new bignumber(accid).minus('76561197960265728')-0;
};
Dota2Client.prototype.ToSteamID = function(accid){
  return new bignumber(accid).plus('76561197960265728')+"";
};

// Methods
Dota2Client.prototype.launch = function() {
  /* Reports to Steam that we are running Dota 2. Initiates communication with GC with EMsgGCClientHello */
  if (this.debug) util.log("Launching Dota 2");
  this.AccountID = this.ToAccountID(this._client.steamID);
  this.Party = null;
  this.Lobby = null;
  this.PartyInvite = null;
  this._user.gamesPlayed([{"game_id": this._appid}]);

  // Keep knocking on the GCs door until it accepts us.
  // This is very bad practice and quite trackable.
  // The real client tends to send only one of these.
  // Really we should just send one when the connection status is GC online
  this._gcClientHelloCount = 0;
  this._gcClientHelloIntervalId = setInterval(this._sendClientHello, 6000);

  //Also immediately send clienthello
  setTimeout(this._sendClientHello, 1000);
};

Dota2Client.prototype.exit = function() {
  /* Reports to Steam we are not running any apps. */
  if (this.debug) util.log("Exiting Dota 2");

  /* stop knocking if exit comes before ready event */
  if (this._gcClientHelloIntervalId) {
      clearInterval(this._gcClientHelloIntervalId);
      this._gcClientHelloIntervalId = null;
  }
  this._gcReady = false;

  if(this._client.loggedOn) this._client.gamesPlayed([]);
};

// Handlers

var handlers = Dota2Client.prototype._handlers = {};

handlers[Dota2.EGCBaseClientMsg.k_EMsgGCClientWelcome] = function clientWelcomeHandler(message) {
  /* Response to our k_EMsgGCClientHello, now we can execute other GC commands. */

  // Only execute if _gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'ready');
  if (this._gcClientHelloIntervalId) {
    clearInterval(this._gcClientHelloIntervalId);
    this._gcClientHelloIntervalId = null;
  }

  if (this.debug) util.log("Received client welcome.");

  // Parse any caches
  this._gcReady = true;
  //this._handleWelcomeCaches(message);
  this.emit("ready");
};

handlers[Dota2.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus] = function gcClientConnectionStatus(message) {
  /* Catch and handle changes in connection status, cuz reasons u know. */

  var status = Dota2.schema.CMsgConnectionStatus.decode(message).status;
  if(status) this._gcConnectionStatus = status;

  switch (status) {
    case Dota2.GCConnectionStatus.GCConnectionStatus_HAVE_SESSION:
      if (this.debug) util.log("GC Connection Status regained.");

      // Only execute if _gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'ready');
      if (this._gcClientHelloIntervalId) {
        clearInterval(this._gcClientHelloIntervalId);
        this._gcClientHelloIntervalId = null;

        this._gcReady = true;
        this.emit("ready");
      }
      break;

    default:
      if (this.debug) util.log("GC Connection Status unreliable - " + status);

      // Only execute if !_gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'unready');
      if (!this._gcClientHelloIntervalId) {
        this._gcClientHelloIntervalId = setInterval(this._sendClientHello, 5000); // Continually try regain GC session

        this._gcReady = false;
        this.emit("unready");
      }
      break;
  }
};

Dota2.Dota2Client = Dota2Client;

//require("./handlers/cache");
require("./handlers/inventory");
require("./handlers/chat");
require("./handlers/guild");
require("./handlers/community");
require("./handlers/match");
require("./handlers/lobbies");
//require("./handlers/parties");
require("./handlers/leagues");
require("./handlers/sourcetv");
<commit_msg>Restored API to original interface which takes a SteamClient<commit_after>require("./messages");
var steam = require("steam");

const DOTA_APP_ID = 570;

var EventEmitter = require('events').EventEmitter,
    fs = require("fs"),
    path = require("path"),
    util = require("util"),
    bignumber = require("bignumber.js"),
    ProtoBuf = require('protobufjs'),
    Dota2 = exports;

ProtoBuf.convertFieldsToCamelCase = true;
var builder = ProtoBuf.newBuilder();
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/base_gcmessages.proto'), builder);
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/gcsdk_gcmessages.proto'), builder);
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/dota_gcmessages_client_fantasy.proto'), builder);
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/dota_gcmessages_client.proto'), builder);
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/dota_gcmessages_common.proto'), builder);
ProtoBuf.loadProtoFile(path.join(__dirname, './proto/steammessages.proto'), builder);
Dota2.schema = builder.build();

var Dota2Client = function Dota2Client(steamClient, debug, debugMore) {
  EventEmitter.call(this);

  this.debug = debug || false;
  this.debugMore = debugMore || false;

  var steamUser = new steam.SteamUser(steamClient);
  this._user = steamUser;
  this._client = steamClient;
  this._gc = new steam.SteamGameCoordinator(steamClient, DOTA_APP_ID);
  this._appid = DOTA_APP_ID;
  this.chatChannels = []; // Map channel names to channel data.
  this._gcReady = false;
  this._gcClientHelloIntervalId = null;
  this._gcConnectionStatus = Dota2.GCConnectionStatus.GCConnectionStatus_NO_SESSION;
  // This should probably be reworked to use a CMsgProtoBufHeader object
  this.protoBufHeader = {
    "msg":    "",
    "proto":  {
      "client_steam_id": this._client.steamID,
      "source_app_id":  this._appid
    }
  };

  var self = this;
  this._gc.on("message", function fromGC(header, body, callback) {
    /* Routes messages from Game Coordinator to their handlers. */
    callback = callback || null;

    var kMsg = header.msg;
    if (self.debugMore) util.log("Dota2 fromGC: " + kMsg);  // TODO:  Turn type-protoMask into key name.

    if (kMsg in self._handlers) {
      if (callback) {
        self._handlers[kMsg].call(self, body, callback);
      }
      else {
        self._handlers[kMsg].call(self, body);
      }
    }
    else {
      self.emit("unhandled", kMsg);
    }
  });
  //util.log(steamUser);

  this._sendClientHello = function() {
    if(self._gcReady)
    {
      if(self._gcClientHelloIntervalId)
      {
        clearInterval(self._gcClientHelloIntervalId);
        self._gcClientHelloIntervalId = null;
      }
      return;
    }
    if(self._gcClientHelloCount > 10)
    {
      if(self.debug) util.log("ClientHello has taken longer than 30 seconds! Reporting timeout...");
      self._gcClientHelloCount = 0;
      self.emit("hellotimeout");
    }

    if (self.debug) util.log("Sending ClientHello");
    if (!self._gc) {
      util.log("Where the fuck is _gc?");
    }
    else {self._gc.send(
        {
          "msg":    Dota2.EGCBaseClientMsg.k_EMsgGCClientHello,
          "proto":  {
            "client_steam_id": self._client.steamID,
            "source_app_id":  self._appid
          }
        },
        new Dota2.schema.CMsgClientHello({}).toBuffer()
      );
    }

    self._gcClientHelloCount++;
  };
};
util.inherits(Dota2Client, EventEmitter);

// Expose enums
Dota2Client.prototype.ServerRegion = Dota2.ServerRegion;
Dota2Client.prototype.GameMode = Dota2.GameMode;
Dota2Client.prototype.ToAccountID = function(accid){
  return new bignumber(accid).minus('76561197960265728')-0;
};
Dota2Client.prototype.ToSteamID = function(accid){
  return new bignumber(accid).plus('76561197960265728')+"";
};

// Methods
Dota2Client.prototype.launch = function() {
  /* Reports to Steam that we are running Dota 2. Initiates communication with GC with EMsgGCClientHello */
  if (this.debug) util.log("Launching Dota 2");
  this.AccountID = this.ToAccountID(this._client.steamID);
  this.Party = null;
  this.Lobby = null;
  this.PartyInvite = null;
  this._user.gamesPlayed([{"game_id": this._appid}]);

  // Keep knocking on the GCs door until it accepts us.
  // This is very bad practice and quite trackable.
  // The real client tends to send only one of these.
  // Really we should just send one when the connection status is GC online
  this._gcClientHelloCount = 0;
  this._gcClientHelloIntervalId = setInterval(this._sendClientHello, 6000);

  //Also immediately send clienthello
  setTimeout(this._sendClientHello, 1000);
};

Dota2Client.prototype.exit = function() {
  /* Reports to Steam we are not running any apps. */
  if (this.debug) util.log("Exiting Dota 2");

  /* stop knocking if exit comes before ready event */
  if (this._gcClientHelloIntervalId) {
      clearInterval(this._gcClientHelloIntervalId);
      this._gcClientHelloIntervalId = null;
  }
  this._gcReady = false;

  if(this._client.loggedOn) this._client.gamesPlayed([]);
};

// Handlers

var handlers = Dota2Client.prototype._handlers = {};

handlers[Dota2.EGCBaseClientMsg.k_EMsgGCClientWelcome] = function clientWelcomeHandler(message) {
  /* Response to our k_EMsgGCClientHello, now we can execute other GC commands. */

  // Only execute if _gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'ready');
  if (this._gcClientHelloIntervalId) {
    clearInterval(this._gcClientHelloIntervalId);
    this._gcClientHelloIntervalId = null;
  }

  if (this.debug) util.log("Received client welcome.");

  // Parse any caches
  this._gcReady = true;
  //this._handleWelcomeCaches(message);
  this.emit("ready");
};

handlers[Dota2.EGCBaseClientMsg.k_EMsgGCClientConnectionStatus] = function gcClientConnectionStatus(message) {
  /* Catch and handle changes in connection status, cuz reasons u know. */

  var status = Dota2.schema.CMsgConnectionStatus.decode(message).status;
  if(status) this._gcConnectionStatus = status;

  switch (status) {
    case Dota2.GCConnectionStatus.GCConnectionStatus_HAVE_SESSION:
      if (this.debug) util.log("GC Connection Status regained.");

      // Only execute if _gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'ready');
      if (this._gcClientHelloIntervalId) {
        clearInterval(this._gcClientHelloIntervalId);
        this._gcClientHelloIntervalId = null;

        this._gcReady = true;
        this.emit("ready");
      }
      break;

    default:
      if (this.debug) util.log("GC Connection Status unreliable - " + status);

      // Only execute if !_gcClientHelloIntervalID, otherwise it's already been handled (and we don't want to emit multiple 'unready');
      if (!this._gcClientHelloIntervalId) {
        this._gcClientHelloIntervalId = setInterval(this._sendClientHello, 5000); // Continually try regain GC session

        this._gcReady = false;
        this.emit("unready");
      }
      break;
  }
};

Dota2.Dota2Client = Dota2Client;

//require("./handlers/cache");
require("./handlers/inventory");
require("./handlers/chat");
require("./handlers/guild");
require("./handlers/community");
require("./handlers/match");
require("./handlers/lobbies");
//require("./handlers/parties");
require("./handlers/leagues");
require("./handlers/sourcetv");
<|endoftext|>


<commit_before>'use strict';

var url = require('url');
var qs = require('qs');
var type = require('./lib/type');

// we use `qs` to support nesting but need `unescape` which is available in `querystring`
qs.unescape = qs.unescape || require('querystring').unescape;

var native = false;
var httpSync;

try {
  httpSync = require('http-sync');
  native = true;
} catch (ex) {
  httpSync = require('http-sync-win');
  native = false;
}

var hasOwnProperty = Object.prototype.hasOwnProperty;

module.exports = request;
module.exports.httpSync = httpSync;
module.exports.native = native;

/**
 * Make a web request
 *
 * Options:
 *
 *  - `uri` || `url` - fully qualified uri or parsed url object from `url.parse()`
 *  - `method` - http method (default: `"GET"`)
 *  - `qs` - object containing querystring values to be appended to the `uri`
 *  - `headers` - http headers (default: `{}`)
 *  - `body` - entity body for PATCH, POST and PUT requests. Must be a `Buffer` or `String`.
 *  - `auth` - A hash containing values `user` || `username`, `password` || `pass`
 *  - `encoding` - encoding to stringify the result body, set this to `null` to get a `Buffer`
 *
 * @param {String} uri
 * @param {Object} options
 * @return {Response}
 */
function request(uri, options) {

  // 1 - handle variable list of arguments
  if (typeof uri === 'undefined') {
    throw new TypeError('undefined is not a valid uri or options object.');
  }
  if (options && typeof options === 'object') {
    options.uri = uri;
  } else if (typeof uri === 'string') {
    options = {uri: uri};
  } else {
    options = uri;
  }
  options = copy(options);
  if (options.url && !options.uri) {
    options.uri = options.url;
    delete options.url;
  }

  // 2 - check types
  type('uri', options.uri, 'String|Object');
  type('options.method', options.method, 'String?');
  type('options.qs', options.qs, 'Object?');
  type('options.headers', options.headers, 'Object?');
  if (options.body !== undefined && !Buffer.isBuffer(options.body)) {
    type('options.body', options.body, 'String|Buffer');
  }
  type('options.auth', options.auth, 'Object?');

  // 3 - normalize types
  if (typeof options.uri === 'string') {
    options.uri = url.parse(options.uri);
  }
  options.method = (options.method || 'GET').toUpperCase();
  if (options.qs) {
    var baseQs = qs.parse(options.uri.query);
    for (var i in options.qs) {
      baseQs[i] = options.qs[i];
    }
    if (qs.stringify(baseQs) !== '') {
      options.uri = url.parse(options.uri.href.split('?')[0] + '?' + qs.stringify(baseQs));
    }
  }
  options.headers = options.headers || {};
  if (typeof options.body === 'string') {
    options.body = new Buffer(options.body);
  }
  if (!options.body) {
    options.body = new Buffer(0);
  }
  if (options.auth) {
    if (hasOwnProperty.call(options.auth, 'username'))
      options.auth.user = options.auth.username;
    if (hasOwnProperty.call(options.auth, 'password'))
      options.auth.pass = options.auth.password;
  } else if (options.uri.auth) {
    var authPieces = options.uri.auth.split(':').map(function(item){
      return qs.unescape(item);
    });
    options.auth = {
      user: authPieces[0],
      pass: authPieces.slice(1).join(':')
    };
  }
  if (options.auth) {
    var authHeader = options.auth.pass === undefined ?
        options.auth.user :
        options.auth.user + ':' + options.auth.pass;
    options.headers['authorization'] = 'Basic ' + toBase64(authHeader);
  }
  for (var key in options.headers) {
    type('options.headers[' + key + ']', options.headers[key], 'String');
    if (options.headers[key] === '') {
      delete options.headers[key];
    }
  }
  if (module.exports.native && !options.headers['content-type']) {
    options.headers['content-type'] = '';
  }
  if (module.exports.native && !options.headers['accept']) {
    options.headers['accept'] = '';
  }
  var request = new Request(options.uri, options.method, options.headers, options.body);
  var req = module.exports.httpSync.request({
    protocol: request.uri.protocol.replace(/\:$/, ''),
    host: request.uri.hostname,
    port: request.uri.port,
    path: request.uri.path,
    method: request.method,
    headers: request.headers,
    body: request.body
  });
  var res = req.end();
  if (options.encoding !== null) {
    res.body = res.body.toString(options.encoding);
  }
  return new Response(res.statusCode, res.headers, res.body);
}

function Request(uri, method, headers, body) {
  this.uri = uri;
  this.method = method;
  this.headers = headers;
  this.headers['content-length'] = body.length;
  this.body = body;
}

/**
 * A response from a web request
 *
 * @param {Number} statusCode
 * @param {Object} headers
 * @param {Buffer} body
 */
function Response(statusCode, headers, body) {
  this.statusCode = statusCode;
  this.headers = headers;
  this.body = body;
}

/**
 * Convert a string into its base64 representation
 *
 * @param {String} str
 * @return {String}
 */
function toBase64(str) {
  return (new Buffer(str || "", "ascii")).toString("base64")
}

function copy(obj, seen) {
  seen = seen || [];
  if (seen.indexOf(obj) !== -1) {
    throw new Error('Unexpected circular reference in options');
  }
  seen.push(obj);
  if (Array.isArray(obj)) {
    return obj.map(function (item) {
      return copy(item, seen);
    });
  } else if (obj && typeof obj === 'object' && !Buffer.isBuffer(obj)) {
    var o = {}
    Object.keys(obj).forEach(function (i) {
      o[i] = copy(obj[i], seen)
    })
    return o
  } else {
    return obj;
  }
}
<commit_msg>Lower case returned headers<commit_after>'use strict';

var url = require('url');
var qs = require('qs');
var type = require('./lib/type');

// we use `qs` to support nesting but need `unescape` which is available in `querystring`
qs.unescape = qs.unescape || require('querystring').unescape;

var native = false;
var httpSync;

try {
  httpSync = require('http-sync');
  native = true;
} catch (ex) {
  httpSync = require('http-sync-win');
  native = false;
}

var hasOwnProperty = Object.prototype.hasOwnProperty;

module.exports = request;
module.exports.httpSync = httpSync;
module.exports.native = native;

/**
 * Make a web request
 *
 * Options:
 *
 *  - `uri` || `url` - fully qualified uri or parsed url object from `url.parse()`
 *  - `method` - http method (default: `"GET"`)
 *  - `qs` - object containing querystring values to be appended to the `uri`
 *  - `headers` - http headers (default: `{}`)
 *  - `body` - entity body for PATCH, POST and PUT requests. Must be a `Buffer` or `String`.
 *  - `auth` - A hash containing values `user` || `username`, `password` || `pass`
 *  - `encoding` - encoding to stringify the result body, set this to `null` to get a `Buffer`
 *
 * @param {String} uri
 * @param {Object} options
 * @return {Response}
 */
function request(uri, options) {

  // 1 - handle variable list of arguments
  if (typeof uri === 'undefined') {
    throw new TypeError('undefined is not a valid uri or options object.');
  }
  if (options && typeof options === 'object') {
    options.uri = uri;
  } else if (typeof uri === 'string') {
    options = {uri: uri};
  } else {
    options = uri;
  }
  options = copy(options);
  if (options.url && !options.uri) {
    options.uri = options.url;
    delete options.url;
  }

  // 2 - check types
  type('uri', options.uri, 'String|Object');
  type('options.method', options.method, 'String?');
  type('options.qs', options.qs, 'Object?');
  type('options.headers', options.headers, 'Object?');
  if (options.body !== undefined && !Buffer.isBuffer(options.body)) {
    type('options.body', options.body, 'String|Buffer');
  }
  type('options.auth', options.auth, 'Object?');

  // 3 - normalize types
  if (typeof options.uri === 'string') {
    options.uri = url.parse(options.uri);
  }
  options.method = (options.method || 'GET').toUpperCase();
  if (options.qs) {
    var baseQs = qs.parse(options.uri.query);
    for (var i in options.qs) {
      baseQs[i] = options.qs[i];
    }
    if (qs.stringify(baseQs) !== '') {
      options.uri = url.parse(options.uri.href.split('?')[0] + '?' + qs.stringify(baseQs));
    }
  }
  options.headers = options.headers || {};
  if (typeof options.body === 'string') {
    options.body = new Buffer(options.body);
  }
  if (!options.body) {
    options.body = new Buffer(0);
  }
  if (options.auth) {
    if (hasOwnProperty.call(options.auth, 'username'))
      options.auth.user = options.auth.username;
    if (hasOwnProperty.call(options.auth, 'password'))
      options.auth.pass = options.auth.password;
  } else if (options.uri.auth) {
    var authPieces = options.uri.auth.split(':').map(function(item){
      return qs.unescape(item);
    });
    options.auth = {
      user: authPieces[0],
      pass: authPieces.slice(1).join(':')
    };
  }
  if (options.auth) {
    var authHeader = options.auth.pass === undefined ?
        options.auth.user :
        options.auth.user + ':' + options.auth.pass;
    options.headers['authorization'] = 'Basic ' + toBase64(authHeader);
  }
  for (var key in options.headers) {
    type('options.headers[' + key + ']', options.headers[key], 'String');
    if (options.headers[key] === '') {
      delete options.headers[key];
    }
  }
  if (module.exports.native && !options.headers['content-type']) {
    options.headers['content-type'] = '';
  }
  if (module.exports.native && !options.headers['accept']) {
    options.headers['accept'] = '';
  }
  var request = new Request(options.uri, options.method, options.headers, options.body);
  var req = module.exports.httpSync.request({
    protocol: request.uri.protocol.replace(/\:$/, ''),
    host: request.uri.hostname,
    port: request.uri.port,
    path: request.uri.path,
    method: request.method,
    headers: request.headers,
    body: request.body
  });
  var res = req.end();
  if (options.encoding !== null) {
    res.body = res.body.toString(options.encoding);
  }
  return new Response(res.statusCode, res.headers, res.body);
}

function Request(uri, method, headers, body) {
  this.uri = uri;
  this.method = method;
  this.headers = headers;
  this.headers['content-length'] = body.length;
  this.body = body;
}

/**
 * A response from a web request
 *
 * @param {Number} statusCode
 * @param {Object} headers
 * @param {Buffer} body
 */
function Response(statusCode, headers, body) {
  this.statusCode = statusCode;
  this.headers = {};
  for (var key in headers) {
    this.headers[key.toLowerCase()] = headers[key];
  }
  this.body = body;
}

/**
 * Convert a string into its base64 representation
 *
 * @param {String} str
 * @return {String}
 */
function toBase64(str) {
  return (new Buffer(str || "", "ascii")).toString("base64")
}

function copy(obj, seen) {
  seen = seen || [];
  if (seen.indexOf(obj) !== -1) {
    throw new Error('Unexpected circular reference in options');
  }
  seen.push(obj);
  if (Array.isArray(obj)) {
    return obj.map(function (item) {
      return copy(item, seen);
    });
  } else if (obj && typeof obj === 'object' && !Buffer.isBuffer(obj)) {
    var o = {}
    Object.keys(obj).forEach(function (i) {
      o[i] = copy(obj[i], seen)
    })
    return o
  } else {
    return obj;
  }
}
<|endoftext|>


<commit_before>var React = require('react');
var evaluate = require('eval');

// src can be either a filename or a chunk name
function ReactToHtmlWebpackPlugin(destPath, src, options) {
  this.src = src;
  this.destPath = destPath;
  this.options = typeof options === 'object' ? options : {};
}

ReactToHtmlWebpackPlugin.prototype.apply = function(compiler) {
  compiler.plugin('emit', function(compiler, done) {

    var webpackStatsJson = compiler.getStats().toJson();

    try {
      var asset = findAsset(this.src, compiler, webpackStatsJson);
      if (!asset) {
        throw new Error('Output file not found: "' + this.src + '"');
      }

      var source = asset.source();
      var Component = evaluate(source);
      var html = React.renderToString(React.createElement(Component));

      var template = this.options.template;

      if (template != null && typeof template !== 'function') {
        throw new Error('Template must be a function');
      }

      var output = typeof template === 'function' ?
        template({
          html: html,
          assets: getAssetsFromCompiler(compiler, webpackStatsJson)
        }) :
        html;

      compiler.assets[this.destPath] = createAssetFromContents(output);
    } catch (err) {
      return done(err);
    }

    done();
  }.bind(this));
};

var findAsset = function(src, compiler, webpackStatsJson) {
  var asset = compiler.assets[src];
  if (asset) {
    return asset;
  }

  var chunkValue = webpackStatsJson.assetsByChunkName[src];
  if (!chunkValue) {
    return null;
  }
  // Webpack outputs an array for each chunk when using sourcemaps
  if (chunkValue instanceof Array) {
    // Is the main bundle always the first element?
    chunkValue = chunkValue[0];
  }
  return compiler.assets[chunkValue];
};

// Shamelessly stolen from html-webpack-plugin - Thanks @ampedandwired :)
var getAssetsFromCompiler = function(compiler, webpackStatsJson) {
  var assets = {};
  for (var chunk in webpackStatsJson.assetsByChunkName) {
    var chunkValue = webpackStatsJson.assetsByChunkName[chunk];

    // Webpack outputs an array for each chunk when using sourcemaps
    if (chunkValue instanceof Array) {
      // Is the main bundle always the first element?
      chunkValue = chunkValue[0];
    }

    if (compiler.options.output.publicPath) {
      chunkValue = compiler.options.output.publicPath + chunkValue;
    }
    assets[chunk] = chunkValue;
  }

  return assets;
};

var createAssetFromContents = function(contents) {
  return {
    source: function() {
      return contents;
    },
    size: function() {
      return contents.length;
    }
  };
};

module.exports = ReactToHtmlWebpackPlugin;
<commit_msg>Include globals when evaluating source<commit_after>var React = require('react');
var evaluate = require('eval');

// src can be either a filename or a chunk name
function ReactToHtmlWebpackPlugin(destPath, src, options) {
  this.src = src;
  this.destPath = destPath;
  this.options = typeof options === 'object' ? options : {};
}

ReactToHtmlWebpackPlugin.prototype.apply = function(compiler) {
  compiler.plugin('emit', function(compiler, done) {

    var webpackStatsJson = compiler.getStats().toJson();

    try {
      var asset = findAsset(this.src, compiler, webpackStatsJson);
      if (!asset) {
        throw new Error('Output file not found: "' + this.src + '"');
      }

      var source = asset.source();
      var Component = evaluate(source, /* filename: */ undefined, /* scope: */ undefined, /* includeGlobals: */ true);
      var html = React.renderToString(React.createElement(Component));

      var template = this.options.template;

      if (template != null && typeof template !== 'function') {
        throw new Error('Template must be a function');
      }

      var output = typeof template === 'function' ?
        template({
          html: html,
          assets: getAssetsFromCompiler(compiler, webpackStatsJson)
        }) :
        html;

      compiler.assets[this.destPath] = createAssetFromContents(output);
    } catch (err) {
      return done(err);
    }

    done();
  }.bind(this));
};

var findAsset = function(src, compiler, webpackStatsJson) {
  var asset = compiler.assets[src];
  if (asset) {
    return asset;
  }

  var chunkValue = webpackStatsJson.assetsByChunkName[src];
  if (!chunkValue) {
    return null;
  }
  // Webpack outputs an array for each chunk when using sourcemaps
  if (chunkValue instanceof Array) {
    // Is the main bundle always the first element?
    chunkValue = chunkValue[0];
  }
  return compiler.assets[chunkValue];
};

// Shamelessly stolen from html-webpack-plugin - Thanks @ampedandwired :)
var getAssetsFromCompiler = function(compiler, webpackStatsJson) {
  var assets = {};
  for (var chunk in webpackStatsJson.assetsByChunkName) {
    var chunkValue = webpackStatsJson.assetsByChunkName[chunk];

    // Webpack outputs an array for each chunk when using sourcemaps
    if (chunkValue instanceof Array) {
      // Is the main bundle always the first element?
      chunkValue = chunkValue[0];
    }

    if (compiler.options.output.publicPath) {
      chunkValue = compiler.options.output.publicPath + chunkValue;
    }
    assets[chunk] = chunkValue;
  }

  return assets;
};

var createAssetFromContents = function(contents) {
  return {
    source: function() {
      return contents;
    },
    size: function() {
      return contents.length;
    }
  };
};

module.exports = ReactToHtmlWebpackPlugin;
<|endoftext|>


<commit_before>
const ISO3361CountryScrapper = require('./lib/ISO3361CountryScrapper')
const ISO4717CurrencyScrapper = require('./lib/ISO4717CurrencyScrapper')
const ISO4717_Into_ISO3361 = require('./lib/mergers/ISO4717_Into_ISO3361')

const { writeFileAsync } = require('./lib/utils')

async function main() {

	console.log('Scrapping started')

	const [iso4717, iso3361] = await Promise.all([ scrapISO4717(), scrapISO3361() ])

	await writeFileAsync(
		"ISO-3361-ISO-4717.json",
		JSON.stringify(await ISO4717_Into_ISO3361.merge(iso3361, iso4717), null, 4)
	)

	console.log("Successful merge of ISO-4717 into ISO-3361.")
}

async function scrapISO3361() {
	const t = Date.now()
	const data = await ISO3361CountryScrapper.scrapRemoteData()
	console.log("\nSuccessful ISO-3361 scrapping.")
	await writeFileAsync("ISO-3361.json", JSON.stringify(data, null, 4))
	console.log("Successful ISO-3361 write.")
	console.log('--- elapsed ---', Date.now() - t)
	return data
}

async function scrapISO4717() {
	const data = await ISO4717CurrencyScrapper.scrapRemoteData()
	console.log("\nSuccessful ISO-4717 scrapping.")
	await writeFileAsync("ISO-4717.json", JSON.stringify(data, null, 4))
	console.log("Successful ISO-4717 write.")
	return data
}

(async () => {
	try {
		main()
	}
	catch(error) {
		console.log(error)
	}
})()<commit_msg>Add logging<commit_after>
const ISO3361CountryScrapper = require('./lib/ISO3361CountryScrapper')
const ISO4717CurrencyScrapper = require('./lib/ISO4717CurrencyScrapper')
const ISO4717_Into_ISO3361 = require('./lib/mergers/ISO4717_Into_ISO3361')

const { writeFileAsync } = require('./lib/utils')

async function main() {

	console.log('Scrapping started')

	const [iso4717, iso3361] = await Promise.all([ scrapISO4717(), scrapISO3361() ])

	await writeFileAsync(
		"ISO-3361-ISO-4717.json",
		JSON.stringify(await ISO4717_Into_ISO3361.merge(iso3361, iso4717), null, 4)
	)

	console.log("Successful merge of ISO-4717 into ISO-3361.")
}

async function scrapISO3361() {
	console.log("\nISO-3361 scrapping started...")
	const t = Date.now()
	const data = await ISO3361CountryScrapper.scrapRemoteData()
	console.log("\nSuccessful ISO-3361 scrapping.")
	await writeFileAsync("ISO-3361.json", JSON.stringify(data, null, 4))
	console.log("Successful ISO-3361 write.")
	console.log('--- elapsed ---', Date.now() - t)
	return data
}

async function scrapISO4717() {
	console.log("\nISO-4717 scrapping started...")
	const data = await ISO4717CurrencyScrapper.scrapRemoteData()
	console.log("\nSuccessful ISO-4717 scrapping.")
	await writeFileAsync("ISO-4717.json", JSON.stringify(data, null, 4))
	console.log("Successful ISO-4717 write.")
	return data
}

(async () => {
	try {
		main()
	}
	catch(error) {
		console.log(error)
	}
})()<|endoftext|>


<commit_before>//jshint esnext:true

function isDescendant(parent, child) {
	var node = child.parentNode;
	while(node !== null) {
		if(node == parent) {
			return true;
		}
		node = node.parentNode;
	}
	return false;
}

class Menu {
	constructor(settings = {}) {
		const typeEnum = ['contextmenu', 'menubar'];
		let items = [];
		let type = isValidType(settings.type) ? settings.type : 'contextmenu';

		Object.defineProperty(this, 'items', {
			get: () => {
				return items;
			}
		});

	 	Object.defineProperty(this, 'type', {
			get: () => {
				return type;
			},
			set: (typeIn) => {
				type = isValidType(typeIn) ? typeIn : type;
			}
		});

		this.append = item => {
			if(!(item instanceof MenuItem)) {
				console.error('appended item must be an instance of MenuItem');
				return false;
			}
			item.parentMenu = this;
			return items.push(item);
		};

		this.insert = (item, index) => {
			if(!(item instanceof MenuItem)) {
				console.error('inserted item must be an instance of MenuItem');
				return false;
			}

			items.splice(index, 0, item);
			item.parentMenu = this;
			return true;
		};

		this.remove = item => {
			if(!(item instanceof MenuItem)) {
				console.error('item to be removed is not an instance of MenuItem');
				return false;
			}

			let index = items.indexOf(item);
			if(index < 0) {
				console.error('item to be removed was not found in this.items');
				return false;
			} else {
				items.splice(index, 0);
				return true;
			}
		};

		this.removeAt = index => {
			items.splice(index, 0);
			return true;
		};

		this.node = null;
		this.clickHandler = this._clickHandle_hideMenu.bind(this);
		this.currentSubmenuNode = null;
		this.parentMenuItem = null;

		function isValidType(typeIn = '', debug = false) {
			if(typeEnum.indexOf(typeIn) < 0) {
				if(debug) console.error(`${typeIn} is not a valid type`);
				return false;
			}
			return true;
		}
	}

	_clickHandle_hideMenu(e) {
		if(e.target !== this.node && !isDescendant(this.node, e.target)) {
			this.node.classList.remove('show');
		}
	}

	createMacBuiltin() {
		console.error('This method is not available in browser :(');
		return false;
	}

	popup(x, y, submenu = false) {
		let menuNode;

		if(this.node) {
			menuNode = this.node;
		} else {
			menuNode = this.buildMenu(submenu);
			this.node = menuNode;
			document.body.appendChild(menuNode);
		}

		this.items.forEach(item => {
			if(item.submenu) {
				item.node.classList.remove('submenu-active');
				item.submenu.popdown();
			}
		});

		let width = menuNode.clientWidth;
		let height = menuNode.clientHeight;

		if((x + width) > window.innerWidth) {
			x = window.innerWidth - width;
		}

		if((y + height) > window.innerHeight) {
			y = window.innerHeight - height;
		}

		menuNode.style.left = x + 'px';
		menuNode.style.top = y + 'px';
		menuNode.classList.add('show');

		document.addEventListener('click', this.clickHandler);
	}

	popdown() {
		if(this.node) this.node.classList.remove('show');

		this.items.forEach(item => {
			if(item.submenu) {
				item.node.classList.remove('submenu-active');
				item.submenu.popdown();
			}
		});
	}

	buildMenu(submenu = false) {
		let menuNode = this.menuNode;
		if(submenu) menuNode.classList.add('submenu');

		this.items.forEach(item => {
			let itemNode = item.buildItem();
			if(item.submenu) {
				let submenuNode = item.submenu.buildMenu(true);
			}
			menuNode.appendChild(itemNode);
		});

		return menuNode;
	}

	get menuNode() {
		let node = document.createElement('ul');
		node.classList.add(this.type);
		return node;
	}
}

class MenuItem {
	constructor(settings = {}) {
		const modifiersEnum = ['cmd', 'command', 'super', 'shift', 'ctrl', 'alt'];
		const typeEnum = ['separator', 'checkbox', 'normal'];
		let type = isValidType(settings.type) ? settings.type : 'normal';
		let submenu = settings.submenu || null;
		let click = settings.click || null;
		let modifiers = validModifiers(settings.modifiers) ? settings.modifiers : null;

		if(submenu) {
			submenu.parentMenuItem = this;
		}

		Object.defineProperty(this, 'type', {
			get: () => {
				return type;
			}
		});

		Object.defineProperty(this, 'submenu', {
			get: () => {
				return submenu;
			},
			set: (inputMenu) => {
				console.warn('submenu should be set on initialisation, changing this at runtime could be slow on some platforms.');
				if(!(inputMenu instanceof Menu)) {
					console.error('submenu must be an instance of Menu');
					return;
				} else {
					submenu = inputMenu;
					submenu.parentMenuItem = this;
				}
			}
		});

		Object.defineProperty(this, 'click', {
			get: () => {
				return click;
			},
			set: (inputCallback) => {
				if(typeof inputCallback !== 'function') {
					console.error('click must be a function');
					return;
				} else {
					click = inputCallback;
				}
			}
		});

		Object.defineProperty(this, 'modifiers', {
			get: () => {
				return modifiers;
			},
			set: (inputModifiers) => {
				modifiers = validModifiers(inputModifiers) ? inputModifiers : modifiers;
			}
		});

		this.label = settings.label || '';
		this.icon = settings.icon || null;
		this.iconIsTemplate = settings.iconIsTemplate || false;
		this.tooltip = settings.tooltip || '';
		this.checked = settings.checked || false;
		this.enabled = settings.enabled || true;
		this.key = settings.key || null;
		this.node = null;

		function validModifiers(modifiersIn = '') {
			let modsArr = modifiersIn.split('+');
			for(let i=0; i < modsArr; i++) {
				let mod = modsArr[i].trim();
				if(modifiersEnum.indexOf(mod) < 0) {
					console.error(`${mod} is not a valid modifier`);
					return false;
				}
			}
			return true;
		}

		function isValidType(typeIn = '', debug = false) {
			if(typeEnum.indexOf(typeIn) < 0) {
				if(debug) console.error(`${typeIn} is not a valid type`);
				return false;
			}
			return true;
		}
	}

	buildItem() {
		let node = document.createElement('li');
		node.classList.add('menu-item', this.type);

		node.addEventListener('click', () => {
			document.removeEventListener('click', this.parentMenu.clickHandler);
			this.parentMenu.popdown();
			if(this.click) this.click();
		});

		let iconWrapNode = document.createElement('div');
		iconWrapNode.classList.add('icon-wrap');

		if(this.icon) {
			let iconNode = new Image();
			iconNode.src = this.icon;
			iconNode.classList.add('icon');
			iconWrapNode.appendChild(iconNode);
		}

		let labelNode = document.createElement('div');
		labelNode.classList.add('label');
		labelNode.textContent = this.label;

		let modifierNode = document.createElement('div');
		modifierNode.classList.add('modifiers');
		modifierNode.textContent = this.modifiers;

		if(this.submenu) {
			modifierNode.textContent = '▶';

			node.addEventListener('mouseout', (e) => {
				if(!isDescendant(node, e.target)) this.submenu.popdown();

				node.classList.add('submenu-active');
			});
		}

		node.addEventListener('mouseover', (e) => {
			if(this.submenu) {
				let parentNode = node.parentNode;

				let x = parentNode.offsetWidth + parentNode.offsetLeft - 2;
				let y = parentNode.offsetTop + node.offsetHeight;
				this.submenu.popup(x, y, true);
				this.parentMenu.currentSubmenu = this.submenu;
			} else {
				if(this.parentMenu.currentSubmenu) {
					this.parentMenu.currentSubmenu.popdown();
					this.parentMenu.currentSubmenu.parentMenuItem.node.classList.remove('submenu-active');
					this.parentMenu.currentSubmenu = null;
				}
			}
		});

		node.appendChild(iconWrapNode);
		node.appendChild(labelNode);
		node.appendChild(modifierNode);

		this.node = node;
		return node;
	}
}

let m = new Menu();
for(let i=0; i < 10; i++) {
	let mi = new MenuItem({
		label: 'Item ' + i
	});
	m.append(mi);
}

let sm = new Menu();
for(let i=10; i < 20; i++) {
	let mi = new MenuItem({
		label: 'Item ' + i,
		click: function() { //jshint ignore:line
			alert('hello m8 - ' + i);
		}
	});
	sm.append(mi);
}

let mi = new MenuItem({
	label: 'Item with sub',
	submenu: sm
});

m.insert(mi, 1);

let sm2 = new Menu();
for(let i=20; i < 30; i++) {
	let mi = new MenuItem({
		label: 'Item ' + i
	});
	sm2.append(mi);
}

let mi2 = new MenuItem({
	label: 'Item with sub 2',
	submenu: sm2
});

let mi3 = new MenuItem({
	type: 'separator'
});

sm.insert(mi2, 1);
sm.insert(mi3, 2);

console.log(m, sm, sm2);

document.addEventListener('contextmenu', (e) => {
	e.preventDefault();
	m.popup(e.clientX, e.clientY);
	return false;
});<commit_msg>Remove index.js<commit_after><|endoftext|>


<commit_before>import 'source-map-support/register'

// NOTE: gulp is a dependency (rather than devDependency) on purpose (a fallback default)
// TODO: review if / how this works (via be-goods or hal-rc?) -- give a warning if used?
import R from 'ramda'
import sourcegate from 'sourcegate'
import {pkg, isLocal, myRequire, gulpHelpify, logger} from 'be-goods'

function req (name) {
  if (isLocal(name)) {
    return myRequire(name)
  } else {
    if (R.not(R.contains(name, ['hal-rc', 'gulp-cause', 'gulp-npm-run']))) {
      // the above list of exceptions contains modules that will remain bundled as beverage dependencies
      logger.warn(`Please install ${name} as a devDependency, future beverage will not buldle it.`)
    }
    return require(name)
  }
}

function def (opts = {}) {
  opts.dotBeverage = opts.dotBeverage || [
    'node_modules/beverage/node_modules/hal-rc',
    '.'
  ]

  let o = sourcegate([{
    build: 'build', // TODO: remove this after the deprecations are phased out
    scripts: {
      requireStrict: true
    }
  }].concat(opts.dotBeverage.map(file => file + '/.beverage'), opts))

  // TODO: becomes `if (isLocal('gulp-npm-test'))` after the deprecations are phased out
  if (o.hasOwnProperty('test') || isLocal('gulp-npm-test')) {
    // gulp-npm-test does testing better than gulp-npm-run
    return sourcegate([{
      scripts: {exclude: ['test']},
      test: {
        testsRe: '\\.spec\\.coffee$'
      }
    }, o])
  } else {
    return o
  }
}

module.exports = function (gulpIn, opts) {
  let o = def(opts)
  let gulp = gulpHelpify(gulpIn)

  gulp.task('beverage', 'The recipe of this beverage.', () => {
    console.log('\nCurrent beverage options:')
    console.log('\n' + JSON.stringify(o, null, 2) + '\n')
  })

  if (pkg.scripts) {
    if (o.scripts) req('gulp-npm-run')(gulp, o.scripts)

    if (o.test && pkg.scripts.test) {
      if (o.testWatch) {
        // TODO: this whole if should be deleted
        logger.warn('Option testWatch is deprecated, use test.watch instead.')
        o.test.watch = o.testWatch
      }
      req('gulp-npm-test')(gulp, o.test)
    }

    if (o.buildWatch && o.scripts) {
      // TODO: this whole if should be deleted as it's redundant
      logger.warn('The build & buildWatch options are deprecated, use causality instead.')
      gulp.task(o.build + ':watch', o.buildWatch.toString(), () =>
        gulp.watch(o.buildWatch, [o.build])
      )
    }
  }

  if (o.sourcegate && o.sourcegate.length) {
    o.sourceopt = o.sourceopt || {}
    // TODO: the rest of this as far as the req is temporary, for graceful upgrade...
    // delete afterwards
    let convert = {'sourcegateModule': 'module',
                   'sourcegatePrefix': 'prefix',
                   'sourcegatePreset': 'preset',
                   'sourcegateWatch': 'watch'}
    if (R.keys(R.pick(R.keys(convert), o)).length) {
      for (let key of R.keys(convert)) {
        if (o.hasOwnProperty(key)) {
          let val = convert[key]
          o.sourceopt[val] = o[key]
          logger.warn(`Deprecated ${key} option, use sourceopt.${val} instead.`)
        }
      }
    }
    req('hal-rc')(R.pick(['sourcegate', 'sourceopt'], o), gulp)
  }

  if (o.harp) req('gulp-harp')(gulp, R.pick(['harp'], o))

  if (o.causality) req('gulp-cause')(gulp, o.causality)

  return gulp
}
<commit_msg>noticed what's probably the reason why gulp is currently a dependency rather than devDependency<commit_after>import 'source-map-support/register'

// NOTE: gulp is a dependency (rather than devDependency) on purpose (a fallback default)
// TODO: review if / how this works (via be-goods or hal-rc?) -- give a warning if used?
// beverage-cli is using this as a fallback -- maybe that's where the dependency should be?
import R from 'ramda'
import sourcegate from 'sourcegate'
import {pkg, isLocal, myRequire, gulpHelpify, logger} from 'be-goods'

function req (name) {
  if (isLocal(name)) {
    return myRequire(name)
  } else {
    if (R.not(R.contains(name, ['hal-rc', 'gulp-cause', 'gulp-npm-run']))) {
      // the above list of exceptions contains modules that will remain bundled as beverage dependencies
      logger.warn(`Please install ${name} as a devDependency, future beverage will not buldle it.`)
    }
    return require(name)
  }
}

function def (opts = {}) {
  opts.dotBeverage = opts.dotBeverage || [
    'node_modules/beverage/node_modules/hal-rc',
    '.'
  ]

  let o = sourcegate([{
    build: 'build', // TODO: remove this after the deprecations are phased out
    scripts: {
      requireStrict: true
    }
  }].concat(opts.dotBeverage.map(file => file + '/.beverage'), opts))

  // TODO: becomes `if (isLocal('gulp-npm-test'))` after the deprecations are phased out
  if (o.hasOwnProperty('test') || isLocal('gulp-npm-test')) {
    // gulp-npm-test does testing better than gulp-npm-run
    return sourcegate([{
      scripts: {exclude: ['test']},
      test: {
        testsRe: '\\.spec\\.coffee$'
      }
    }, o])
  } else {
    return o
  }
}

module.exports = function (gulpIn, opts) {
  let o = def(opts)
  let gulp = gulpHelpify(gulpIn)

  gulp.task('beverage', 'The recipe of this beverage.', () => {
    console.log('\nCurrent beverage options:')
    console.log('\n' + JSON.stringify(o, null, 2) + '\n')
  })

  if (pkg.scripts) {
    if (o.scripts) req('gulp-npm-run')(gulp, o.scripts)

    if (o.test && pkg.scripts.test) {
      if (o.testWatch) {
        // TODO: this whole if should be deleted
        logger.warn('Option testWatch is deprecated, use test.watch instead.')
        o.test.watch = o.testWatch
      }
      req('gulp-npm-test')(gulp, o.test)
    }

    if (o.buildWatch && o.scripts) {
      // TODO: this whole if should be deleted as it's redundant
      logger.warn('The build & buildWatch options are deprecated, use causality instead.')
      gulp.task(o.build + ':watch', o.buildWatch.toString(), () =>
        gulp.watch(o.buildWatch, [o.build])
      )
    }
  }

  if (o.sourcegate && o.sourcegate.length) {
    o.sourceopt = o.sourceopt || {}
    // TODO: the rest of this as far as the req is temporary, for graceful upgrade...
    // delete afterwards
    let convert = {'sourcegateModule': 'module',
                   'sourcegatePrefix': 'prefix',
                   'sourcegatePreset': 'preset',
                   'sourcegateWatch': 'watch'}
    if (R.keys(R.pick(R.keys(convert), o)).length) {
      for (let key of R.keys(convert)) {
        if (o.hasOwnProperty(key)) {
          let val = convert[key]
          o.sourceopt[val] = o[key]
          logger.warn(`Deprecated ${key} option, use sourceopt.${val} instead.`)
        }
      }
    }
    req('hal-rc')(R.pick(['sourcegate', 'sourceopt'], o), gulp)
  }

  if (o.harp) req('gulp-harp')(gulp, R.pick(['harp'], o))

  if (o.causality) req('gulp-cause')(gulp, o.causality)

  return gulp
}
<|endoftext|>


<commit_before>
var assert = require('assert')
// var Transform = require('readable-stream').Transform
var Q = require('q')
var typeforce = require('typeforce')
var utils = require('@tradle/utils')
var debug = require('debug')('chainloader')
// var inherits = require('util').inherits
var extend = require('xtend/mutable')
// var clone = require('xtend/immutable')
var txd = require('@tradle/tx-data')
var TxInfo = txd.TxInfo
var TxData = txd.TxData
var Permission = require('@tradle/permission')
var Errors = require('./errors')
// var pluck = require('./pluck')
// var FILE_EVENTS = ['file:shared', 'file:public', 'file:permission']

module.exports = Loader
Loader.Errors = Errors
// inherits(Loader, Transform)

/**
 * Load data from the chain (blockchain + keeper)
 * @param {Function} lookup (optional) - function to look up identities by fingerprints
 * @param {BitKeeper|BitKeeper client} keeper
 * @param {String} networkName
 * @param {String} prefix - prefix for OP_RETURN data
 * @param {Object} options
 */
function Loader (options) {
  // var self = this

  typeforce({
    keeper: 'Object',
    networkName: 'String',
    prefix: 'String'
  }, options)

  typeforce({
    put: 'Function',
    getMany: 'Function'
  }, options.keeper)

  // Transform.call(this, {
  //   objectMode: true,
  //   highWaterMark: 16
  // })

  utils.bindPrototypeFunctions(this)

  extend(this, options)
  if (options.lookup) this.lookupWith(options.lookup)
}

Loader.prototype.load = function (txs) {
  return Array.isArray(txs)
    ? this.loadMany(txs)
    : this.loadOne(txs)
}

/**
 * Returns an aggregated promise (Q.allSettled)
 * @param  {[type]} txs [description]
 * @return {[type]}     [description]
 */
Loader.prototype.loadMany = function (txs) {
  return Q.allSettled(txs.map(this.loadOne))
}

Loader.prototype.loadOne = function (tx) {
  var self = this
  var parsed
  return this._parseTx(tx)
    .then(function (_parsed) {
      parsed = _parsed
      return self.fetch(parsed.key)
    })
    .then(function (data) {
      if (parsed.txType === TxData.types.public) {
        parsed.data = data
        // self.emit('file:public', parsed)
        return parsed
      }

      parsed.encryptedPermission = data
      return processSharedFile(data, parsed.sharedKey)
    })
    .catch(function (err) {
      throw errorWithProgress(err, parsed)
    })

  function processSharedFile (file, sharedKey) {
    return Q.ninvoke(Permission, 'recover', file, sharedKey)
      .catch(function (err) {
        debug('Failed to recover permission file contents from raw data', err)
        throw new Errors.InvalidPermission(err, {
          key: parsed.key
        })
      })
      .then(function (permission) {
        parsed.permission = permission
        parsed.key = parsed.permission.fileKeyString()
        return self.fetch(parsed.key)
      })
      .then(function (file) {
        parsed.encryptedData = file

        var decryptionKey = parsed.permission.decryptionKeyBuf()
        if (!decryptionKey) return file

        return decrypt(file, decryptionKey)
      })
  }

  function decrypt (file, decryptionKey) {
    return Q.ninvoke(utils, 'decryptAsync', {
      data: file,
      key: decryptionKey
    })
    .then(function (file) {
      parsed.data = file
      return parsed
    })
    .catch(function (err) {
      debug('Failed to decrypt ciphertext: ' + file, err)
      throw new Errors.Decrypt({
        key: parsed.key
      })
    })
  }
}

/*
 * @param {Function} fn - function to look up identities by fingerprints (must return Promise)
 *   @example
 *     function lookup (cb) {
 *       cb(err, {
 *         key: key with pub/priv props or functions
 *       })
 *     }
 */
Loader.prototype.lookupWith = function (fn) {
  this.lookup = fn
  return this
}

Loader.prototype.fetch = function (key) {
  return this.keeper.getOne(key)
    .catch(function (err) {
      debug('Error fetching file', err)
      throw new Errors.FileNotFound(err, {
        key: key
      })
    })
}

Loader.prototype._processTxInfo = function (parsed) {
  var self = this
  if (!TxInfo.validate(parsed)) {
    return Q.reject(new Errors.NotEnoughInfo({
      txId: parsed.txId
    }))
  }

  if (isOldFormatTxData(parsed)) {
    return Q.reject(new Errors.Decrypt({
      key: parsed.sharedKey
    }))

    // old format used insecure utils.decrypt
  }

  return this._lookupParties(parsed.addressesFrom, parsed.addressesTo)
    .then(function (matches) {
      if (matches) {
        parsed.from = matches.from
        parsed.to = matches.to
      }

      if (parsed.txType === TxData.types.public) {
        parsed.key = parsed.txData.toString('hex')
      } else {
        return processPermission()
      }
    })
    .then(function () {
      return parsed
    })

  function processPermission () {
    if (!(parsed.from && parsed.to)) {
      throw new Errors.ParticipantsNotFound({
        message: 'failed to derive tx participants',
        txId: parsed.txId
      })
    }

    parsed.encryptedKey = parsed.txData
    parsed.sharedKey = self._getSharedKey(parsed.from, parsed.to)
    if (!parsed.sharedKey) {
      throw new Errors.ECDH({
        message: 'failed to derive shared key',
        txId: parsed.txId
      })
    }

    return Q.ninvoke(utils, 'decryptAsync', {
      data: parsed.txData,
      key: parsed.sharedKey
    })
    .catch(function (err) {
      debug('failed to decrypt txData', err)
      throw new Errors.Decrypt({
        key: parsed.key
      })
    })
    .then(function (key) {
      parsed.key = key.toString('hex')
      parsed.permissionKey = parsed.key
    })
  }
}

Loader.prototype._getSharedKey = function (from, to) {
  if (!(from && to)) return

  var fromKey = from.key
  var toKey = to.key
  var priv = getResult(fromKey, 'priv')
  var pub = getResult(toKey, 'value')
  if (!priv) {
    priv = getResult(toKey, 'priv')
    pub = getResult(fromKey, 'value')
  }

  return priv && pub && utils.sharedEncryptionKey(priv, pub)
}

Loader.prototype._parseTxs = function (txs) {
  return Q.allSettled(txs.map(this._parseTx))
}

Loader.prototype._parseTx = function (tx, cb) {
  // may already be parsed
  var parsed = TxInfo.validate(tx)
    ? tx
    : TxInfo.parse(tx, this.networkName, this.prefix)

  if (!parsed) {
    return Q.reject(new Errors.NoData({
      txId: parsed.txId
    }))
  }

  return this._processTxInfo(parsed)
    .catch(function (err) {
      throw errorWithProgress(err, parsed)
    })
}

/**
 * lookup parties in a tx
 * @param  {Array} from - bitcoin addresses
 * @param  {Array} to - bitcoin addresses
 * @return {Promise} uses this.lookup to lookup parties, resolves with:
 *  {
 *    from: result of this.lookup,
 *    to: result of this.lookup
 *  }
 */
Loader.prototype._lookupParties = function (from, to) {
  var self = this
  var matches = {}
  if (!this.lookup) return Q.resolve(matches)

  var allAddrs = from.concat(to)

  // cache to prevent running 2 lookups for 1 address
  var promiseByAddr = {}
  var lookups = allAddrs.map(function (f) {
    if (!f) return Q.reject()

    var promise = promiseByAddr[f]
    if (!promise) {
      promise = promiseByAddr[f] = self.lookup(f, true) // private
      assert(Q.isPromiseAlike(promise), '"lookup" function should return a promise')
    }

    return promise
  })

  return Q.allSettled(lookups)
    .then(function (results) {
      results = results.map(function (r) {
        return r.value
      })

      results.slice(0, from.length)
        .some(function (result) {
          if (result) {
            matches.from = result
            return true
          }
        })

      results.slice(from.length)
        .some(function (result) {
          if (result && matches.from && matches.from.key.value !== result.key.value) {
            matches.to = result
            return true
          }
        })

      return Object.keys(matches).length ? matches : null
    })
}

function getResult (obj, p) {
  var val = obj[p]
  if (typeof val === 'function') return obj[p]()
  else return val
}

function errorWithProgress (err, parsed) {
  if (!err.progress) err.progress = parsed

  return err
}

function isOldFormatTxData (parsed) {
  return parsed.txType === TxData.types.permission &&
    parsed.txData.length === 20
}
<commit_msg>support objs with tx property<commit_after>
var assert = require('assert')
// var Transform = require('readable-stream').Transform
var Q = require('q')
var typeforce = require('typeforce')
var utils = require('@tradle/utils')
var debug = require('debug')('chainloader')
// var inherits = require('util').inherits
var extend = require('xtend/mutable')
// var clone = require('xtend/immutable')
var txd = require('@tradle/tx-data')
var TxInfo = txd.TxInfo
var TxData = txd.TxData
var Permission = require('@tradle/permission')
var Errors = require('./errors')
// var pluck = require('./pluck')
// var FILE_EVENTS = ['file:shared', 'file:public', 'file:permission']

module.exports = Loader
Loader.Errors = Errors
// inherits(Loader, Transform)

/**
 * Load data from the chain (blockchain + keeper)
 * @param {Function} lookup (optional) - function to look up identities by fingerprints
 * @param {BitKeeper|BitKeeper client} keeper
 * @param {String} networkName
 * @param {String} prefix - prefix for OP_RETURN data
 * @param {Object} options
 */
function Loader (options) {
  // var self = this

  typeforce({
    keeper: 'Object',
    networkName: 'String',
    prefix: 'String'
  }, options)

  typeforce({
    put: 'Function',
    getMany: 'Function'
  }, options.keeper)

  // Transform.call(this, {
  //   objectMode: true,
  //   highWaterMark: 16
  // })

  utils.bindPrototypeFunctions(this)

  extend(this, options)
  if (options.lookup) this.lookupWith(options.lookup)
}

Loader.prototype.load = function (txs) {
  return Array.isArray(txs)
    ? this.loadMany(txs)
    : this.loadOne(txs)
}

/**
 * Returns an aggregated promise (Q.allSettled)
 * @param  {[type]} txs [description]
 * @return {[type]}     [description]
 */
Loader.prototype.loadMany = function (txs) {
  return Q.allSettled(txs.map(this.loadOne))
}

Loader.prototype.loadOne = function (tx) {
  var self = this
  var parsed
  return this._parseTx(tx)
    .then(function (_parsed) {
      parsed = _parsed
      return self.fetch(parsed.key)
    })
    .then(function (data) {
      if (parsed.txType === TxData.types.public) {
        parsed.data = data
        // self.emit('file:public', parsed)
        return parsed
      }

      parsed.encryptedPermission = data
      return processSharedFile(data, parsed.sharedKey)
    })
    .catch(function (err) {
      throw errorWithProgress(err, parsed)
    })

  function processSharedFile (file, sharedKey) {
    return Q.ninvoke(Permission, 'recover', file, sharedKey)
      .catch(function (err) {
        debug('Failed to recover permission file contents from raw data', err)
        throw new Errors.InvalidPermission(err, {
          key: parsed.key
        })
      })
      .then(function (permission) {
        parsed.permission = permission
        parsed.key = parsed.permission.fileKeyString()
        return self.fetch(parsed.key)
      })
      .then(function (file) {
        parsed.encryptedData = file

        var decryptionKey = parsed.permission.decryptionKeyBuf()
        if (!decryptionKey) return file

        return decrypt(file, decryptionKey)
      })
  }

  function decrypt (file, decryptionKey) {
    return Q.ninvoke(utils, 'decryptAsync', {
      data: file,
      key: decryptionKey
    })
    .then(function (file) {
      parsed.data = file
      return parsed
    })
    .catch(function (err) {
      debug('Failed to decrypt ciphertext: ' + file, err)
      throw new Errors.Decrypt({
        key: parsed.key
      })
    })
  }
}

/*
 * @param {Function} fn - function to look up identities by fingerprints (must return Promise)
 *   @example
 *     function lookup (cb) {
 *       cb(err, {
 *         key: key with pub/priv props or functions
 *       })
 *     }
 */
Loader.prototype.lookupWith = function (fn) {
  this.lookup = fn
  return this
}

Loader.prototype.fetch = function (key) {
  return this.keeper.getOne(key)
    .catch(function (err) {
      debug('Error fetching file', err)
      throw new Errors.FileNotFound(err, {
        key: key
      })
    })
}

Loader.prototype._processTxInfo = function (parsed) {
  var self = this
  if (!TxInfo.validate(parsed)) {
    return Q.reject(new Errors.NotEnoughInfo({
      txId: parsed.txId
    }))
  }

  if (isOldFormatTxData(parsed)) {
    return Q.reject(new Errors.Decrypt({
      key: parsed.sharedKey
    }))

    // old format used insecure utils.decrypt
  }

  return this._lookupParties(parsed.addressesFrom, parsed.addressesTo)
    .then(function (matches) {
      if (matches) {
        parsed.from = matches.from
        parsed.to = matches.to
      }

      if (parsed.txType === TxData.types.public) {
        parsed.key = parsed.txData.toString('hex')
      } else {
        return processPermission()
      }
    })
    .then(function () {
      return parsed
    })

  function processPermission () {
    if (!(parsed.from && parsed.to)) {
      throw new Errors.ParticipantsNotFound({
        message: 'failed to derive tx participants',
        txId: parsed.txId
      })
    }

    parsed.encryptedKey = parsed.txData
    parsed.sharedKey = self._getSharedKey(parsed.from, parsed.to)
    if (!parsed.sharedKey) {
      throw new Errors.ECDH({
        message: 'failed to derive shared key',
        txId: parsed.txId
      })
    }

    return Q.ninvoke(utils, 'decryptAsync', {
      data: parsed.txData,
      key: parsed.sharedKey
    })
    .catch(function (err) {
      debug('failed to decrypt txData', err)
      throw new Errors.Decrypt({
        key: parsed.key
      })
    })
    .then(function (key) {
      parsed.key = key.toString('hex')
      parsed.permissionKey = parsed.key
    })
  }
}

Loader.prototype._getSharedKey = function (from, to) {
  if (!(from && to)) return

  var fromKey = from.key
  var toKey = to.key
  var priv = getResult(fromKey, 'priv')
  var pub = getResult(toKey, 'value')
  if (!priv) {
    priv = getResult(toKey, 'priv')
    pub = getResult(fromKey, 'value')
  }

  return priv && pub && utils.sharedEncryptionKey(priv, pub)
}

Loader.prototype._parseTxs = function (txs) {
  return Q.allSettled(txs.map(this._parseTx))
}

Loader.prototype._parseTx = function (tx, cb) {
  // may already be parsed
  var parsed = TxInfo.validate(tx)
    ? tx
    : TxInfo.parse(tx.tx || tx, this.networkName, this.prefix)

  if (!parsed) {
    return Q.reject(new Errors.NoData({
      txId: parsed.txId
    }))
  }

  return this._processTxInfo(parsed)
    .catch(function (err) {
      throw errorWithProgress(err, parsed)
    })
}

/**
 * lookup parties in a tx
 * @param  {Array} from - bitcoin addresses
 * @param  {Array} to - bitcoin addresses
 * @return {Promise} uses this.lookup to lookup parties, resolves with:
 *  {
 *    from: result of this.lookup,
 *    to: result of this.lookup
 *  }
 */
Loader.prototype._lookupParties = function (from, to) {
  var self = this
  var matches = {}
  if (!this.lookup) return Q.resolve(matches)

  var allAddrs = from.concat(to)

  // cache to prevent running 2 lookups for 1 address
  var promiseByAddr = {}
  var lookups = allAddrs.map(function (f) {
    if (!f) return Q.reject()

    var promise = promiseByAddr[f]
    if (!promise) {
      promise = promiseByAddr[f] = self.lookup(f, true) // private
      assert(Q.isPromiseAlike(promise), '"lookup" function should return a promise')
    }

    return promise
  })

  return Q.allSettled(lookups)
    .then(function (results) {
      results = results.map(function (r) {
        return r.value
      })

      results.slice(0, from.length)
        .some(function (result) {
          if (result) {
            matches.from = result
            return true
          }
        })

      results.slice(from.length)
        .some(function (result) {
          if (result && matches.from && matches.from.key.value !== result.key.value) {
            matches.to = result
            return true
          }
        })

      return Object.keys(matches).length ? matches : null
    })
}

function getResult (obj, p) {
  var val = obj[p]
  if (typeof val === 'function') return obj[p]()
  else return val
}

function errorWithProgress (err, parsed) {
  if (!err.progress) err.progress = parsed

  return err
}

function isOldFormatTxData (parsed) {
  return parsed.txType === TxData.types.permission &&
    parsed.txData.length === 20
}
<|endoftext|>


<commit_before>var spawn  = require('child_process').spawn;
var stream = require('stream');

var Qpdf = {};

Qpdf.encrypt = function(input, options, callback) {
  if (!input) return handleError(new Error('Specify input file'));
  if (!options || !options.password) return handleError(new Error('Password missing'));

  // Defaults encryption to AES 256
  options.keyLength = options.keyLength || '256';

  var args = [Qpdf.command, '--encrypt'];

  // Push twice for user-password and owner-password
  args.push(options.password);
  args.push(options.password);

  // Specifying the key length
  args.push(options.keyLength);

  // Add Resctrictions for encryption
  if (options.restrictions) {
    if (typeof options.restrictions !== 'object') return handleError(new Error('Invalid Restrictions'));

    var restrictions = options.restrictions;

    for(var restriction in restrictions) {
      var value = (restrictions.restriction !== '') ? '=' + restrictions.restriction : '';
      args.push('--' + hypenate(restriction) + value);
    }
  }

  // Marks end of --encrypt options
  args.push('--');

  // Input file path
  args.push(input);

  // Print PDf on stdout
  args.push('-');

  // Execute command and return stdout for pipe
  var outputStream = executeCommand(args, callback);
  if (outputStream) {
    return outputStream;
  }
};

Qpdf.decrypt = function(input, password, callback) {
  if (!input) return handleError(new Error('Specify input file'), callback);
  if (!password) return handleError(new Error('Password missing'), callback);

  var args = [Qpdf.command, '--decrypt'];

  // Password
  args.push('--password=' + password);

  // Input file path
  args.push(input);

  // Print PDf on stdout
  args.push('-');

  // Execute command and return stdout for pipe
  var outputStream = executeCommand(args, callback);
  if (outputStream) {
    return outputStream;
  }
};

function executeCommand(args, callback) {
  var child;

  if (process.platform === 'win32') {
    child = spawn(args[0], args.slice(1));
  } else {
    // this nasty business prevents piping problems on linux
    child = spawn('/bin/sh', ['-c', args.join(' ') + ' | cat']);
  }

  // call the callback with null error when the process exits successfully
  if (callback) {
    child.on('exit', function() { callback(null); });
  }

  var outputStream = child.stdout;

  child.once('error', function (err) {
    handleError(err, child, outputStream, callback);
  });
  child.stderr.once('data', function(err) {
    handleError(new Error(err || ''), child, outputStream, callback);
  });

  // return stdout stream so we can pipe
  if (callback) {
    return callback(null, outputStream);
  } else {
    return outputStream;
  }
}

function handleError(err, child, outputStream, callback) {
  if (child) {
    child.removeAllListeners('exit');
    child.kill();
  } else if (typeof child === 'function') {
    callback = child;
  }

  // call the callback if there is one
  if (callback) {
    callback(err);
  }

  // set a default output stream if not present
  if (typeof outputStream === 'function') {
    callback = outputStream;
    outputStream = new stream.Readable();
  } else if (typeof outputStream === 'undefined') {
    outputStream = new stream.Readable();
  }

  // if not, or there are listeners for errors, emit the error event
  if (!callback || outputStream.listeners('error').length > 0) {
    outputStream.emit('error', err);
  }
}

function hypenate(variable) {
  return variable.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}

Qpdf.command = 'qpdf';
module.exports = Qpdf;
<commit_msg>Encrypt to Output File fixed<commit_after>var spawn  = require('child_process').spawn;
var stream = require('stream');

var Qpdf = {};

Qpdf.encrypt = function(input, options, callback) {
  if (!input) return handleError(new Error('Specify input file'));
  if (!options || !options.password) return handleError(new Error('Password missing'));
  if(options && options.outputFile) {
    if(typeof options.outputFile != 'string' || options.outputFile === input) {
      return handleError(new Error('Invlaid output file'));
    }
  }

  // Defaults encryption to AES 256
  options.keyLength = options.keyLength || '256';

  var args = [Qpdf.command, '--encrypt'];

  // Push twice for user-password and owner-password
  args.push(options.password);
  args.push(options.password);

  // Specifying the key length
  args.push(options.keyLength);

  // Add Resctrictions for encryption
  if (options.restrictions) {
    if (typeof options.restrictions !== 'object') return handleError(new Error('Invalid Restrictions'));

    var restrictions = options.restrictions;

    for(var restriction in restrictions) {
      var value = (restrictions[restriction] !== '') ? '=' + restrictions[restriction] : '';
      args.push('--' + hyphenate(restriction) + value);
    }
  }

  // Marks end of --encrypt options
  args.push('--');

  // Input file path
  args.push(input);

  if (options.outputFile) {
    args.push(options.outputFile);
  } else {
  // Print PDF on stdout
    args.push('-');
  }
  // Execute command and return stdout for pipe
  if (!options.outputFile) {
    var outputStream = executeCommand(args);
    if (outputStream) {
      if (callback) {
        return callback(null, outputStream);
      } else {
        return outputStream;
      }
    }
  } else {
    if (callback) {
      executeCommand(args, callback);
    } else {
      return new Promise(function(resolve, reject) {
        executeCommand(args, function(err, filePath) {
          if (err) {
            reject(err);
          } else {
            resolve(filePath);
          }
        });
      });
    }
  }
};

Qpdf.decrypt = function(input, password, callback) {
  if (!input) return handleError(new Error('Specify input file'), callback);
  if (!password) return handleError(new Error('Password missing'), callback);

  var args = [Qpdf.command, '--decrypt'];

  // Password
  args.push('--password=' + password);

  // Input file path
  args.push(input);

  // Print PDf on stdout
  args.push('-');

  // Execute command and return stdout for pipe
  var outputStream = executeCommand(args, callback);
  if (outputStream) {
    return outputStream;
  }
};

function executeCommand(args, callback) {
  var child;

  var output = args[args.length - 1];

  // if on windows or not piping to stdout
  if (process.platform === 'win32' || output !== '-') {
    child = spawn(args[0], args.slice(1));
  } else {
    // this nasty business prevents piping problems on linux
    child = spawn('/bin/sh', ['-c', args.join(' ') + ' | cat']);
  }

  // call the callback with null error when the process exits successfully
  if (callback) {
    child.on('exit', function() { callback(null, output); });
  }

  var outputStream = child.stdout;

  child.once('error', function (err) {
    handleError(err, child, outputStream, callback);
  });
  child.stderr.once('data', function(err) {
    handleError(new Error(err || ''), child, outputStream, callback);
  });

  // return stdout stream so we can pipe
  return outputStream;
}

function handleError(err, child, outputStream, callback) {
  if (child) {
    child.removeAllListeners('exit');
    child.kill();
  } else if (typeof child === 'function') {
    callback = child;
  }

  // call the callback if there is one
  if (callback) {
    callback(err);
  }

  // set a default output stream if not present
  if (typeof outputStream === 'function') {
    callback = outputStream;
    outputStream = new stream.Readable();
  } else if (typeof outputStream === 'undefined') {
    outputStream = new stream.Readable();
  }

  // if not, or there are listeners for errors, emit the error event
  if (!callback || outputStream.listeners('error').length > 0) {
    outputStream.emit('error', err);
  }
}

function hyphenate(variable) {
  return variable.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}

Qpdf.command = 'qpdf';
module.exports = Qpdf;
<|endoftext|>


<commit_before>var Q = require('q');
var superagent = require('superagent');

function wrap(item) {
  return function() {
    var agent = item.apply(superagent, arguments);

    var agentEnd = agent.end;

    agent.end = function() {
      var doEnd = Q.defer();
      agentEnd.call(agent, function(err, res) {
        if (err) return doEnd.reject(err);
        doEnd.resolve(res);
      });
      return doEnd.promise;
    }

    return agent;
  }
}

var agentQ = wrap(superagent);

agentQ.get = wrap(superagent.get);
agentQ.put = wrap(superagent.put);
agentQ.post = wrap(superagent.post);
agentQ.del = wrap(superagent.del);
agentQ.head = wrap(superagent.head);

module.exports = agentQ;
<commit_msg>implement progress notification on promise<commit_after>var Q = require('q');
var superagent = require('superagent');

function wrap(item) {
  return function() {
    var agent = item.apply(superagent, arguments);

    var agentEnd = agent.end;

    agent.end = function() {
      var doEnd = Q.defer();

      agent.on('progress', function (e) {
        doEnd.notify(e);
      });

      agentEnd.call(agent, function(err, res) {
        if (err) return doEnd.reject(err);
        doEnd.resolve(res);
      });

      return doEnd.promise;
    }

    return agent;
  }
}

var agentQ = wrap(superagent);

agentQ.get = wrap(superagent.get);
agentQ.put = wrap(superagent.put);
agentQ.post = wrap(superagent.post);
agentQ.del = wrap(superagent.del);
agentQ.head = wrap(superagent.head);

module.exports = agentQ;
<|endoftext|>