<commit_before>/**
 *
 * This module provides routines for dealing with arrays.
 *
 * @module dex/array
 *
 */

module.exports = function array(dex) {

  return {
    'unique': function (array) {
      return _.uniq(array);
    },
    /**
     *
     * Take a slice of an array without modifying the original array.
     *
     * dex.array.slice(array) - Return a copy of the array.
     * dex.array.slice(array, rowRange) - Copy the array, then return a slice
     * within the specified range.
     * dex.array.slice(array, rowRange, maxRows) - Copy the array, then return a slice
     * within the specified range up to, but not exceeding, maxRows rows.
     *
     * @param (array) array - The array to slice.
     * @param (array|number) rowRange - If supplied an array, the range defined by the of rows to slice.
     * @param {number} maxRows - The maximum number of rows to return.
     *
     * @example {@lang javascript}
     * var myArray = [ 1, 2, 3, 4, 5 ];
     *
     * // Returns: [ 3, 4, 5]
     * slice(myArray, 2);
     *
     * // Returns: [ 1, 3, 5 ]
     * slice(myArray, [0, 2, 4]);
     *
     * // I am not sure why you would do this, but in the interest of supporting
     * // the Principle of Least Surprise, this returns the array unchanged.
     * // Returns: [ 1, 2, 3, 4, 5 ]
     * slice(myArray)
     *
     */
    'slice': function (array, rowRange, maxRows) {
      var arraySlice = [];
      var range;
      var i;

      var arrayCopy = dex.array.copy(array);

      // Numeric.
      // Array.
      // Object.  Numeric with start and end.
      if (arguments.length === 2) {
        if (Array.isArray(rowRange)) {
          range = rowRange;
        }
        else {
          range = dex.range(rowRange, arrayCopy.length - rowRange);
        }
      }
      else if (arguments.length < 2) {
        return arrayCopy;
      }
      else {
        if (Array.isArray(rowRange)) {
          range = rowRange;
        }
        else {
          range = dex.range(rowRange, maxRows);
        }
      }

      //dex.console.log("BEFORE: array.slice(range=" + range + "): arraySlice=" + arraySlice);
      for (i = 0; i < range.length; i++) {
        arraySlice.push(arrayCopy[range[i]]);
      }
      //dex.console.log("AFTER: array.slice(range=" + range + "): arraySlice=" + arraySlice);
      return arraySlice;
    },

    'getPermutations': function (list, maxLen) {
      // Copy initial values as arrays
      var perm = list.map(function (val) {
        return [val];
      });
      // Our permutation generator
      var generate = function (perm, maxLen, currLen) {
        // Reached desired length
        if (currLen === maxLen) {
          return perm;
        }
        // For each existing permutation
        for (var i = 0, len = perm.length; i < len; i++) {
          var currPerm = perm.shift();
          // Create new permutation
          for (var k = 0; k < list.length; k++) {
            perm.push(currPerm.concat(list[k]));
          }
        }
        // Recurse
        return generate(perm, maxLen, currLen + 1);
      };
      // Start with size 1 because of initial values
      return generate(perm, maxLen, 1);
    },

    'getCombinations': function (list, comboLength) {
      var i, j, combs, head, tailcombs;

      // There is no way to take e.g. sets of 5 elements from
      // a set of 4.
      if (comboLength > list.length || comboLength <= 0) {
        return [];
      }

      // K-sized set has only one K-sized subset.
      if (comboLength == list.length) {
        return [list];
      }

      // There is N 1-sized subsets in a N-sized set.
      if (comboLength == 1) {
        combs = [];
        for (i = 0; i < list.length; i++) {
          combs.push([list[i]]);
        }
        return combs;
      }

      // Assert {1 < k < set.length}

      // Algorithm description:
      // To get k-combinations of a set, we want to join each element
      // with all (k-1)-combinations of the other elements. The set of
      // these k-sized sets would be the desired result. However, as we
      // represent sets with lists, we need to take duplicates into
      // account. To avoid producing duplicates and also unnecessary
      // computing, we use the following approach: each element i
      // divides the list into three: the preceding elements, the
      // current element i, and the subsequent elements. For the first
      // element, the list of preceding elements is empty. For element i,
      // we compute the (k-1)-computations of the subsequent elements,
      // join each with the element i, and store the joined to the set of
      // computed k-combinations. We do not need to take the preceding
      // elements into account, because they have already been the i:th
      // element so they are already computed and stored. When the length
      // of the subsequent list drops below (k-1), we cannot find any
      // (k-1)-combs, hence the upper limit for the iteration:
      combs = [];
      for (i = 0; i < list.length - comboLength + 1; i++) {
        // head is a list that includes only our current element.
        head = list.slice(i, i + 1);
        // We take smaller combinations from the subsequent elements
        tailcombs = dex.array.getCombinations(list.slice(i + 1), comboLength - 1);
        // For each (k-1)-combination we join it with the current
        // and store it to the set of k-combinations.
        for (j = 0; j < tailcombs.length; j++) {
          combs.push(head.concat(tailcombs[j]));
        }
      }
      return combs;
    },

    /**
     *
     * Returns an array of the mathematically smallest and largest
     * elements within the array.
     *
     * @param matrix The array to evaluate.
     * @param indices The array indices to be considered in the evaluation.
     *
     * @returns {Array} - An array consisting of [ min, max ] of the array.
     *
     */
    'extent': function (matrix, indices) {
      if (!matrix || matrix.length <= 0 || !indices || indices.length <= 0) {
        return [0, 0];
      }

      var min = matrix[0][indices[0]];
      var max = min;

      indices.forEach(function (ci) {
        matrix.forEach(function (row) {
          if (min > row[ci]) {
            min = row[ci];
          }
          if (max < row[ci]) {
            max = row[ci];
          }
        });
      });
      return [min, max];
    },

    /**
     *
     * Return a distinct copy of an array.
     *
     * @param {Array} array The array to copy.
     * @returns {Array} The copy of the array.
     *
     */
    'copy': function (array) {
      // Shallow copy
      return _.clone(array);
      // Deep copy:
      //return $.extend(true, {}, array);
    },
    'isNumeric': function (array) {
      return array.every(dex.object.isNumeric);
    }
  };
};<commit_msg>New methods: orderedUnique, combine<commit_after>/**
 *
 * This module provides routines for dealing with arrays.
 *
 * @module dex/array
 *
 */

module.exports = function array(dex) {

  return {
    'unique': function (array) {
      return _.uniq(array);
    },
    'orderedUnique': function (array) {
      var map = {};
      var uniqueArray = [];
      if (Array.isArray(array)) {
        array.forEach(function (elt) {
          if ((typeof map[elt]) == "undefined") {
            uniqueArray.push(elt);
            map[elt] = 1;
          }
        });
      }
      return uniqueArray;
    },
    /**
     *
     * Take a slice of an array without modifying the original array.
     *
     * dex.array.slice(array) - Return a copy of the array.
     * dex.array.slice(array, rowRange) - Copy the array, then return a slice
     * within the specified range.
     * dex.array.slice(array, rowRange, maxRows) - Copy the array, then return a slice
     * within the specified range up to, but not exceeding, maxRows rows.
     *
     * @param (array) array - The array to slice.
     * @param (array|number) rowRange - If supplied an array, the range defined by the of rows to slice.
     * @param {number} maxRows - The maximum number of rows to return.
     *
     * @example {@lang javascript}
     * var myArray = [ 1, 2, 3, 4, 5 ];
     *
     * // Returns: [ 3, 4, 5]
     * slice(myArray, 2);
     *
     * // Returns: [ 1, 3, 5 ]
     * slice(myArray, [0, 2, 4]);
     *
     * // I am not sure why you would do this, but in the interest of supporting
     * // the Principle of Least Surprise, this returns the array unchanged.
     * // Returns: [ 1, 2, 3, 4, 5 ]
     * slice(myArray)
     *
     */
    'slice': function (array, rowRange, maxRows) {
      var arraySlice = [];
      var range;
      var i;

      var arrayCopy = dex.array.copy(array);

      // Numeric.
      // Array.
      // Object.  Numeric with start and end.
      if (arguments.length === 2) {
        if (Array.isArray(rowRange)) {
          range = rowRange;
        }
        else {
          range = dex.range(rowRange, arrayCopy.length - rowRange);
        }
      }
      else if (arguments.length < 2) {
        return arrayCopy;
      }
      else {
        if (Array.isArray(rowRange)) {
          range = rowRange;
        }
        else {
          range = dex.range(rowRange, maxRows);
        }
      }

      //dex.console.log("BEFORE: array.slice(range=" + range + "): arraySlice=" + arraySlice);
      for (i = 0; i < range.length; i++) {
        arraySlice.push(arrayCopy[range[i]]);
      }
      //dex.console.log("AFTER: array.slice(range=" + range + "): arraySlice=" + arraySlice);
      return arraySlice;
    },

    'getPermutations': function (list, maxLen) {
      // Copy initial values as arrays
      var perm = list.map(function (val) {
        return [val];
      });
      // Our permutation generator
      var generate = function (perm, maxLen, currLen) {
        // Reached desired length
        if (currLen === maxLen) {
          return perm;
        }
        // For each existing permutation
        for (var i = 0, len = perm.length; i < len; i++) {
          var currPerm = perm.shift();
          // Create new permutation
          for (var k = 0; k < list.length; k++) {
            perm.push(currPerm.concat(list[k]));
          }
        }
        // Recurse
        return generate(perm, maxLen, currLen + 1);
      };
      // Start with size 1 because of initial values
      return generate(perm, maxLen, 1);
    },

    'getCombinations': function (list, comboLength) {
      var i, j, combs, head, tailcombs;

      // There is no way to take e.g. sets of 5 elements from
      // a set of 4.
      if (comboLength > list.length || comboLength <= 0) {
        return [];
      }

      // K-sized set has only one K-sized subset.
      if (comboLength == list.length) {
        return [list];
      }

      // There is N 1-sized subsets in a N-sized set.
      if (comboLength == 1) {
        combs = [];
        for (i = 0; i < list.length; i++) {
          combs.push([list[i]]);
        }
        return combs;
      }

      // Assert {1 < k < set.length}

      // Algorithm description:
      // To get k-combinations of a set, we want to join each element
      // with all (k-1)-combinations of the other elements. The set of
      // these k-sized sets would be the desired result. However, as we
      // represent sets with lists, we need to take duplicates into
      // account. To avoid producing duplicates and also unnecessary
      // computing, we use the following approach: each element i
      // divides the list into three: the preceding elements, the
      // current element i, and the subsequent elements. For the first
      // element, the list of preceding elements is empty. For element i,
      // we compute the (k-1)-computations of the subsequent elements,
      // join each with the element i, and store the joined to the set of
      // computed k-combinations. We do not need to take the preceding
      // elements into account, because they have already been the i:th
      // element so they are already computed and stored. When the length
      // of the subsequent list drops below (k-1), we cannot find any
      // (k-1)-combs, hence the upper limit for the iteration:
      combs = [];
      for (i = 0; i < list.length - comboLength + 1; i++) {
        // head is a list that includes only our current element.
        head = list.slice(i, i + 1);
        // We take smaller combinations from the subsequent elements
        tailcombs = dex.array.getCombinations(list.slice(i + 1), comboLength - 1);
        // For each (k-1)-combination we join it with the current
        // and store it to the set of k-combinations.
        for (j = 0; j < tailcombs.length; j++) {
          combs.push(head.concat(tailcombs[j]));
        }
      }
      return combs;
    },

    /**
     *
     * Returns an array of the mathematically smallest and largest
     * elements within the array.
     *
     * @param matrix The array to evaluate.
     * @param indices The array indices to be considered in the evaluation.
     *
     * @returns {Array} - An array consisting of [ min, max ] of the array.
     *
     */
    'extent': function (matrix, indices) {
      if (!matrix || matrix.length <= 0 || !indices || indices.length <= 0) {
        return [0, 0];
      }

      var min = matrix[0][indices[0]];
      var max = min;

      indices.forEach(function (ci) {
        matrix.forEach(function (row) {
          if (min > row[ci]) {
            min = row[ci];
          }
          if (max < row[ci]) {
            max = row[ci];
          }
        });
      });
      return [min, max];
    },

    /**
     *
     * Return a distinct copy of an array.
     *
     * @param {Array} array The array to copy.
     * @returns {Array} The copy of the array.
     *
     */
    'copy': function (array) {
      // Shallow copy
      return _.clone(array);
      // Deep copy:
      //return $.extend(true, {}, array);
    },
    'combine': function(array1, array2) {
      var a1 = dex.array.copy(array1);
      var a2 = dex.array.copy(array2);
      return a1.concat(a2);
    },
    'isNumeric': function (array) {
      return array.every(dex.object.isNumeric);
    }
  };
};<|endoftext|>


<commit_before>/**
* service.game Module
*
* Description
*/
angular.module('service.GameManager', [
    'resource.GameData',
    'service.GridService',
    'service.Piece'
])
.factory('GameManager', [
    'GameData',
    'GridService',
    'Piece',
function (
    GameData,
    GridService,
    Piece
){
    var game = {
        currentPiece: null
    };

    game.newGame = function newGame() {
        game.currentPiece = new Piece({
            x: 4,
            y: 0
        });
        GridService.buildEmptyGameBoard();
        game.update();
    };

    game.getCurrentPiece = function getCurrentPiece() {
        return game.currentPiece;
    };

    game.update = function update() {
        var self = this;
        window.requestAnimationFrame(function () {
            self.update();
        });
    };

    return game;
}]);<commit_msg>update function to update the piece location<commit_after>/**
* service.game Module
*
* Description
*/
angular.module('service.GameManager', [
    'resource.GameData',
    'service.GridService',
    'service.Piece'
])
.factory('GameManager', [
    'GameData',
    'GridService',
    'Piece',
function (
    GameData,
    GridService,
    Piece
){
    var game = {
        currentPiece: null
    };

    game.newGame = function newGame() {
        game.currentPiece = new Piece({
            x: 4,
            y: 0
        });
        GridService.buildEmptyGameBoard();
        game.update();
    };

    game.getCurrentPiece = function getCurrentPiece() {
        return game.currentPiece;
    };

    game.getPositionX = function getPositionX() {
        return game.currentPiece.getPositionX();
    };

    game.getPositionY = function getPositionY() {
        return game.currentPiece.getPositionY();
    };

    game.moveCurrentPiece = function moveCurrentPiece() {
        var speedY = game.getPositionY() + 0.01;
        game.currentPiece.updatePosition({
            y: speedY
        });
    };

    return game;
}]);<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash')
  , usb = require('usb')
  , p = require('hw-promise')
  , logger = require('hw-logger')
  , hwError = require('hw-error')
  , events = require('events')
  , eventHandlers = require('./event-handlers')
  , util = require('./util')
  , log = logger.log
  , hidHandler;

hwError.initErrors([
  {
    constructor: function HidHandlerError(code) {
      this.code = code;
    }
  }, {
    constructor: function HidAlreadyRegisteredError(deviceKey) {
      this.deviceKey = deviceKey;
    },
    parent: 'HidHandlerError'
  }, {
    constructor: function HidEventHandlerNameError(eventHandlerName) {
      this.eventHandlerName = eventHandlerName;
    },
    parent: 'HidHandlerError'
  }
]);

hidHandler = _.extend(new events.EventEmitter(), {
  registeredHids: {},
  getRegisteredHid: function (vendorId, productId) {
    var deviceKey;
    if (typeof productId === 'undefined' && typeof vendorId === 'string') {
      deviceKey = vendorId;
    } else {
      deviceKey = util.getDevicekey(vendorId, productId);
    }
    return hidHandler.registeredHids[deviceKey];
  },
  getSupportedDevice: function (vendorId, productId) {
    var that = hidHandler;
    return _.first(_.filter(that.supportedDevices, function (supportedDevice) {
      return supportedDevice.vendorId === vendorId && supportedDevice.productId === productId;
    }));
  },
  handleEndpointData: function (data) {
    var hid = this
      , eventClassName, eventClass, event;
    eventClassName = util.format('%sEvent', _.capitalize(_.camelCase(hid.device.type)));
    eventClass = hidHandler[eventClassName] || hidHandler.GenericEvent;
    event = new eventClass(hid, data);
    event.emit([hidHandler, hid.ee]);
  },
  handleEndpointError: function (err) {
    var hid = this;
    if (err.errno === usb.LIBUSB_ERROR_NO_DEVICE) {
      log.warn(err);
      hidHandler.unregisterHid(hid);
      hid.device.reset();
      return;
    }
    logger.enabledLevels.warn && log.warn('error received :', err);
    if (hid.device) {
      hid.device.reset();
    }
  },
  handleEndpointEnd: function () {
    var hid = this;
    logger.enabledLevels.debug && log.debug('endpoint end.');
    hid.endpoint.removeListener('data', hidHandler.handleEndpointData);
    hid.endpoint.removeListener('error', hidHandler.handleEndpointError);
    hid.endpoint.removeListener('end', hidHandler.handleEndpointEnd);
  },
  handleUsbAttach: function (device) {
    var that = hidHandler
      , deviceKey, supportedDevice, deviceType;
    deviceKey = util.getDevicekey(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct);
    logger.enabledLevels.debug && log.debug('detected new attached device "%s"', deviceKey);
    if (that.supportedDevices && that.supportedDevices.length) {
      supportedDevice = that.getSupportedDevice(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct);
    }
    if (!supportedDevice) {
      logger.enabledLevels.debug && log.debug('attached device "%s" is not supported : ignore', deviceKey);
      return;
    }
    logger.enabledLevels.debug && log.debug('register attached device "%s"', deviceKey);
    deviceType = supportedDevice.type || 'generic';
    hidHandler.registerHid(deviceType, device);
  },
  handleUsbDetach: function (device) {
    var that = hidHandler
      , deviceKey, hid;
    deviceKey = util.getDevicekey(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct);
    logger.enabledLevels.debug && log.debug('detected new detached device "%s"', deviceKey);
    if (that.supportedDevices && that.supportedDevices.length && !that.getSupportedDevice(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct)) {
      logger.enabledLevels.debug && log.debug('detached device "%s" is not supported : ignore', deviceKey);
      return;
    }
    hid = that.getRegisteredHid(deviceKey);
    if (!hid) {
      logger.enabledLevels.debug && log.debug('detached device "%s" is not registered : ignore', deviceKey);
      return;
    }
    logger.enabledLevels.debug && log.debug('unregister detached device "%s"', deviceKey);
    hidHandler.unregisterHid(hid);
  },
  registerEventHandler: function (eventHandler) {
    var key = eventHandler.name;
    if (hidHandler.hasOwnProperty(key)) {
      throw new hidHandler.HidEventHandlerNameError(key);
    }
    hidHandler[key] = eventHandler;
  },
  registerHid: function (deviceType, device, cb) {
    var that = hidHandler
      , deviceKey, hid;
    deviceKey = util.getDevicekey(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct);
    logger.enabledLevels.debug && log.debug('register hid device "%s"', deviceKey);
    logger.enabledLevels.trace && log.trace('device :', util.logObject(device));
    return p.do(
      function checkAlreadyRegistered() {
        if (that.getRegisteredHid(deviceKey)) {
          throw new hidHandler.HidAlreadyRegisteredError(deviceKey);
        }
      },
      function initHid() {
        hid = {
          deviceKey: deviceKey,
          device: device
        };
        hid.device.type = deviceType;
      },
      function openDevice() {
        logger.enabledLevels.debug && log.debug('open device "%s"', hid.deviceKey);
        device.open();
      },
      function claimInterface() {
        var interfaceIndex;
        logger.enabledLevels.debug && log.debug('get first interface of device "%s"', hid.deviceKey);
        logger.enabledLevels.trace && log.trace('device has %s interfaces :', hid.device.interfaces.length, util.logObject(hid.device.interfaces));
        //fs.writeFileSync(path.join(__dirname, '..', 'tmp', '0.log'), util.inspect(hid.device.interface(0)));
        //fs.writeFileSync(path.join(__dirname, '..', 'tmp', '1.log'), util.inspect(hid.device.interface(1)));
        interfaceIndex = hid.device.interfaces.length - 1;
        hid.interface = hid.device.interface(interfaceIndex);
        if (!hid.interface) {
          logger.enabledLevels.warn && log.warn('no interface for device "%s"', hid.deviceKey);
          throw new hidHandler.HidHandlerError({code: 'NO_INTERFACE'});
        }
        logger.enabledLevels.trace && log.trace('registered device interface :', util.logObject(hid.interface));
        if (hid.interface.isKernelDriverActive()) {
          logger.enabledLevels.debug && log.debug('detach interface of device "%s" from kernel', hid.deviceKey);
          hid.interface.detachKernelDriver();
        }
        logger.enabledLevels.debug && log.debug('claim interface of device "%s"', hid.deviceKey);
        hid.interface.claim();
      },
      function handleEndpoint() {
        logger.enabledLevels.debug && log.debug('searching "in" endpoint of device "%s"', hid.deviceKey);
        logger.enabledLevels.trace && log.trace('device interface has %s endpoints :', hid.interface.endpoints.length, util.logObject(hid.interface.endpoints));
        hid.endpoint = _.first(_.filter(hid.interface.endpoints, function (endpoint) {
          return endpoint.direction === 'in';
        }));
        if (!hid.endpoint) {
          logger.enabledLevels.warn && log.warn('no "in" endpoint for device "%s"', hid.deviceKey);
          throw new hidHandler.HidHandlerError({code: 'NO_IN_ENDPOINT'});
        }
        logger.enabledLevels.trace && log.trace('registered endpoint :', util.logObject(hid.endpoint));
        logger.enabledLevels.debug && log.debug('register endpoint listeners');
        hid.endpoint.on('data', hidHandler.handleEndpointData.bind(hid));
        hid.endpoint.on('error', hidHandler.handleEndpointError.bind(hid));
        hid.endpoint.on('end', hidHandler.handleEndpointEnd.bind(hid));
        logger.enabledLevels.debug && log.debug('start endpoint polling');
        hid.endpoint.startPoll();
      },
      function registerNewHid() {
        hid.ee = new events.EventEmitter();
        hidHandler.registeredHids[hid.deviceKey] = hid;
      })
      .catch(hidHandler.HidAlreadyRegisteredError, function (err) {
        logger.enabledLevels.debug && log.debug('device "%s" already registered : ignore', err.deviceKey);
      })
      .nodeify(cb);
  },
  unregisterHid: function (hid, cb) {
    logger.enabledLevels.debug && log.debug('unregister hid device "%s"', hid.deviceKey);
    return p.do(
      function emitHidEnd() {
        hid.ee.emit('end');
        hid.ee.removeAllListeners();
      },
      function stopEndpoint() {
        if (!hid.endpoint || !hid.endpoint.pollActive) {
          return;
        }
        logger.enabledLevels.debug && log.debug('stopping endpoint polling of device "%s"', hid.deviceKey);
        return p.fromNode(hid.endpoint.stopPoll.bind(hid.endpoint))
          .then(function () {
            logger.enabledLevels.debug && log.debug('endpoint polling stopped for device "%s"', hid.deviceKey);
          });
      },
      function releaseInterface() {
        if (!hid.interface) {
          return;
        }
        logger.enabledLevels.debug && log.debug('release interface of device "%s"', hid.deviceKey);
        return p.fromNode(hid.interface.release.bind(hid.interface))
          .then(function () {
            logger.enabledLevels.debug && log.debug('interface released for device "%s"', hid.deviceKey);
          })
          .catch(function (err) {
            if (err.errno !== usb.LIBUSB_ERROR_NO_DEVICE) {
              throw err;
            }
          });
      })
      .finally(function () {
        if (hid.device) {
          logger.enabledLevels.debug && log.debug('close device "%s"', hid.deviceKey);
          hid.device.close();
        }
        logger.enabledLevels.debug && log.debug('remove device "%s" from registered', hid.deviceKey);
        delete hidHandler.registeredHids[hid.deviceKey];
      })
      .nodeify(cb);
  },
  init: function (opt) {
    var that = hidHandler;
    opt = opt || {};
    that.supportedDevices = opt.supportedDevices;
    that.initialized = true;
  },
  start: function (opt, cb) {
    var that = hidHandler;
    if (typeof cb === 'undefined' && typeof opt === 'function') {
      cb = opt;
      opt = null;
    }
    logger.enabledLevels.debug && log.debug('start hid handler');
    return p.do(
      function init() {
        if (!that.initialized) {
          that.init(opt);
        }
        logger.enabledLevels.debug && log.debug('register usb listeners');
        usb.on('attach', hidHandler.handleUsbAttach);
        usb.on('detach', hidHandler.handleUsbDetach);
      },
      function registerDevices() {
        var supportedDevices;
        logger.enabledLevels.debug && log.debug('check supported devices');
        supportedDevices = that.supportedDevices || _.map(usb.getDeviceList(), function (value) {
            return {
              vendorId: value.deviceDescriptor.idVendor,
              productId: value.deviceDescriptor.idProduct,
              type: 'generic'
            };
          });
        logger.enabledLevels.debug && log.debug('init devices');
        return p.each(_.values(supportedDevices),
          function (supportedDevice) {
            var deviceKey, device, deviceType;
            deviceKey = util.getDevicekey(supportedDevice.vendorId, supportedDevice.productId);
            logger.enabledLevels.debug && log.debug('searching usb device from "%s"', deviceKey);
            device = usb.findByIds(supportedDevice.vendorId, supportedDevice.productId);
            if (!device) {
              logger.enabledLevels.warn && log.warn('no usb device matching "%s"', deviceKey);
              return;
            }
            deviceType = supportedDevice.type || 'generic';
            logger.enabledLevels.debug && log.debug('found %s usb device matching "%s"', deviceType, deviceKey);
            return hidHandler.registerHid(deviceType, device);
          });
      })
      .nodeify(cb);
  },
  stop: function (cb) {
    logger.enabledLevels.debug && log.debug('stop hid handler');
    return p.do(
      function () {
        logger.enabledLevels.debug && log.debug('stop hid handler');
        return p.map(_.values(hidHandler.registeredHids), function (hid) {
          log.debug('hid :', hid);
          return hidHandler.unregisterHid(hid);
        });
      },
      function removeListeners() {
        logger.enabledLevels.debug && log.debug('remove listeners');
        usb.removeListener('attach', hidHandler.handleUsbAttach);
        usb.removeListener('detach', hidHandler.handleUsbDetach);
        hidHandler.removeAllListeners();
      })
      .nodeify(cb);
  }
});

(function registerErrors() {
  _.forIn(hwError, function (value, key) {
    if (key.match(/^Hid.*Error$/)) {
      hidHandler[key] = value;
    }
  });
})();

(function registerEventHandlers() {
  _.forIn(eventHandlers, function (eventHandler) {
    hidHandler.registerEventHandler(eventHandler);
    //[_.capitalize(_.camelCase(key + '-event'))] = eventHandler;
  });
})();

exports = module.exports = hidHandler;<commit_msg>debug<commit_after>'use strict';

var _ = require('lodash')
  , usb = require('usb')
  , p = require('hw-promise')
  , logger = require('hw-logger')
  , hwError = require('hw-error')
  , events = require('events')
  , eventHandlers = require('./event-handlers')
  , util = require('./util')
  , log = logger.log
  , hidHandler;

hwError.initErrors([
  {
    constructor: function HidHandlerError(code) {
      this.code = code;
    }
  }, {
    constructor: function HidAlreadyRegisteredError(deviceKey) {
      this.deviceKey = deviceKey;
    },
    parent: 'HidHandlerError'
  }, {
    constructor: function HidEventHandlerNameError(eventHandlerName) {
      this.eventHandlerName = eventHandlerName;
    },
    parent: 'HidHandlerError'
  }
]);

hidHandler = _.extend(new events.EventEmitter(), {
  registeredHids: {},
  getRegisteredHid: function (vendorId, productId) {
    var deviceKey;
    if (typeof productId === 'undefined' && typeof vendorId === 'string') {
      deviceKey = vendorId;
    } else {
      deviceKey = util.getDevicekey(vendorId, productId);
    }
    return hidHandler.registeredHids[deviceKey];
  },
  getSupportedDevice: function (vendorId, productId) {
    var that = hidHandler;
    return _.first(_.filter(that.supportedDevices, function (supportedDevice) {
      return supportedDevice.vendorId === vendorId && supportedDevice.productId === productId;
    }));
  },
  handleEndpointData: function (data) {
    var hid = this
      , eventClassName, eventClass, event;
    eventClassName = util.format('%sEvent', _.capitalize(_.camelCase(hid.device.type)));
    eventClass = hidHandler[eventClassName] || hidHandler.GenericEvent;
    event = new eventClass(hid, data);
    event.emit([hidHandler, hid.ee]);
  },
  handleEndpointError: function (err) {
    var hid = this;
    if (err.errno === usb.LIBUSB_ERROR_NO_DEVICE) {
      log.warn(err);
      hidHandler.unregisterHid(hid);
      hid.device.reset();
      return;
    }
    logger.enabledLevels.warn && log.warn('error received :', err);
    if (hid.device) {
      hid.device.reset();
    }
  },
  handleEndpointEnd: function () {
    var hid = this;
    logger.enabledLevels.debug && log.debug('endpoint end.');
    hid.endpoint.removeListener('data', hidHandler.handleEndpointData);
    hid.endpoint.removeListener('error', hidHandler.handleEndpointError);
    hid.endpoint.removeListener('end', hidHandler.handleEndpointEnd);
  },
  handleUsbAttach: function (device) {
    var that = hidHandler
      , deviceKey, supportedDevice, deviceType;
    deviceKey = util.getDevicekey(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct);
    logger.enabledLevels.debug && log.debug('detected new attached device "%s"', deviceKey);
    if (that.supportedDevices && that.supportedDevices.length) {
      supportedDevice = that.getSupportedDevice(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct);
    }
    if (!supportedDevice) {
      logger.enabledLevels.debug && log.debug('attached device "%s" is not supported : ignore', deviceKey);
      return;
    }
    logger.enabledLevels.debug && log.debug('register attached device "%s"', deviceKey);
    deviceType = supportedDevice.type || 'generic';
    hidHandler.registerHid(deviceType, device);
  },
  handleUsbDetach: function (device) {
    var that = hidHandler
      , deviceKey, hid;
    deviceKey = util.getDevicekey(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct);
    logger.enabledLevels.debug && log.debug('detected new detached device "%s"', deviceKey);
    if (that.supportedDevices && that.supportedDevices.length && !that.getSupportedDevice(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct)) {
      logger.enabledLevels.debug && log.debug('detached device "%s" is not supported : ignore', deviceKey);
      return;
    }
    hid = that.getRegisteredHid(deviceKey);
    if (!hid) {
      logger.enabledLevels.debug && log.debug('detached device "%s" is not registered : ignore', deviceKey);
      return;
    }
    logger.enabledLevels.debug && log.debug('unregister detached device "%s"', deviceKey);
    hidHandler.unregisterHid(hid);
  },
  registerEventHandler: function (eventHandler) {
    var key = eventHandler.name;
    if (hidHandler.hasOwnProperty(key)) {
      throw new hidHandler.HidEventHandlerNameError(key);
    }
    hidHandler[key] = eventHandler;
  },
  registerHid: function (deviceType, device, cb) {
    var that = hidHandler
      , deviceKey, hid;
    deviceKey = util.getDevicekey(device.deviceDescriptor.idVendor, device.deviceDescriptor.idProduct);
    logger.enabledLevels.debug && log.debug('register hid device "%s"', deviceKey);
    logger.enabledLevels.trace && log.trace('device :', util.logObject(device));
    return p.do(
      function checkAlreadyRegistered() {
        if (that.getRegisteredHid(deviceKey)) {
          throw new hidHandler.HidAlreadyRegisteredError(deviceKey);
        }
      },
      function initHid() {
        hid = {
          deviceKey: deviceKey,
          device: device
        };
        hid.device.type = deviceType;
      },
      function openDevice() {
        logger.enabledLevels.debug && log.debug('open device "%s"', hid.deviceKey);
        device.open();
      },
      function claimInterface() {
        var interfaceIndex;
        logger.enabledLevels.debug && log.debug('get first interface of device "%s"', hid.deviceKey);
        logger.enabledLevels.trace && log.trace('device has %s interfaces :', hid.device.interfaces.length, util.logObject(hid.device.interfaces));
        //fs.writeFileSync(path.join(__dirname, '..', 'tmp', '0.log'), util.inspect(hid.device.interface(0)));
        //fs.writeFileSync(path.join(__dirname, '..', 'tmp', '1.log'), util.inspect(hid.device.interface(1)));
        interfaceIndex = hid.device.interfaces.length - 1;
        hid.interface = hid.device.interface(interfaceIndex);
        if (!hid.interface) {
          logger.enabledLevels.warn && log.warn('no interface for device "%s"', hid.deviceKey);
          throw new hidHandler.HidHandlerError({code: 'NO_INTERFACE'});
        }
        logger.enabledLevels.trace && log.trace('registered device interface :', util.logObject(hid.interface));
        if (hid.interface.isKernelDriverActive()) {
          logger.enabledLevels.debug && log.debug('detach interface of device "%s" from kernel', hid.deviceKey);
          hid.interface.detachKernelDriver();
        }
        logger.enabledLevels.debug && log.debug('claim interface of device "%s"', hid.deviceKey);
        hid.interface.claim();
      },
      function handleEndpoint() {
        logger.enabledLevels.debug && log.debug('searching "in" endpoint of device "%s"', hid.deviceKey);
        logger.enabledLevels.trace && log.trace('device interface has %s endpoints :', hid.interface.endpoints.length, util.logObject(hid.interface.endpoints));
        hid.endpoint = _.first(_.filter(hid.interface.endpoints, function (endpoint) {
          return endpoint.direction === 'in';
        }));
        if (!hid.endpoint) {
          logger.enabledLevels.warn && log.warn('no "in" endpoint for device "%s"', hid.deviceKey);
          throw new hidHandler.HidHandlerError({code: 'NO_IN_ENDPOINT'});
        }
        logger.enabledLevels.trace && log.trace('registered endpoint :', util.logObject(hid.endpoint));
        logger.enabledLevels.debug && log.debug('register endpoint listeners');
        hid.endpoint.on('data', hidHandler.handleEndpointData.bind(hid));
        hid.endpoint.on('error', hidHandler.handleEndpointError.bind(hid));
        hid.endpoint.on('end', hidHandler.handleEndpointEnd.bind(hid));
        logger.enabledLevels.debug && log.debug('start endpoint polling');
        hid.endpoint.startPoll();
      },
      function registerNewHid() {
        hid.ee = new events.EventEmitter();
        hidHandler.registeredHids[hid.deviceKey] = hid;
      })
      .catch(hidHandler.HidAlreadyRegisteredError, function (err) {
        logger.enabledLevels.debug && log.debug('device "%s" already registered : ignore', err.deviceKey);
      })
      .nodeify(cb);
  },
  unregisterHid: function (hid, cb) {
    logger.enabledLevels.debug && log.debug('unregister hid device "%s"', hid.deviceKey);
    return p.do(
      function emitHidEnd() {
        hid.ee.emit('end');
        hid.ee.removeAllListeners();
      },
      function stopEndpoint() {
        if (!hid.endpoint || !hid.endpoint.pollActive) {
          return;
        }
        logger.enabledLevels.debug && log.debug('stopping endpoint polling of device "%s"', hid.deviceKey);
        return p.fromNode(hid.endpoint.stopPoll.bind(hid.endpoint))
          .then(function () {
            logger.enabledLevels.debug && log.debug('endpoint polling stopped for device "%s"', hid.deviceKey);
          });
      },
      function releaseInterface() {
        if (!hid.interface) {
          return;
        }
        logger.enabledLevels.debug && log.debug('release interface of device "%s"', hid.deviceKey);
        return p.fromNode(hid.interface.release.bind(hid.interface))
          .then(function () {
            logger.enabledLevels.debug && log.debug('interface released for device "%s"', hid.deviceKey);
            if (!hid.interface.isKernelDriverActive()) {
              logger.enabledLevels.debug && log.debug('reattach interface of device "%s" from kernel', hid.deviceKey);
              hid.interface.attachKernelDriver();
            }
          })
          .catch(function (err) {
            if (err.errno !== usb.LIBUSB_ERROR_NO_DEVICE) {
              throw err;
            }
          });
      })
      .finally(function () {
        if (hid.device) {
          logger.enabledLevels.debug && log.debug('close device "%s"', hid.deviceKey);
          hid.device.close();
        }
        logger.enabledLevels.debug && log.debug('remove device "%s" from registered', hid.deviceKey);
        delete hidHandler.registeredHids[hid.deviceKey];
      })
      .nodeify(cb);
  },
  init: function (opt) {
    var that = hidHandler;
    opt = opt || {};
    that.supportedDevices = opt.supportedDevices;
    that.initialized = true;
  },
  start: function (opt, cb) {
    var that = hidHandler;
    if (typeof cb === 'undefined' && typeof opt === 'function') {
      cb = opt;
      opt = null;
    }
    logger.enabledLevels.debug && log.debug('start hid handler');
    return p.do(
      function init() {
        if (!that.initialized) {
          that.init(opt);
        }
        logger.enabledLevels.debug && log.debug('register usb listeners');
        usb.on('attach', hidHandler.handleUsbAttach);
        usb.on('detach', hidHandler.handleUsbDetach);
      },
      function registerDevices() {
        var supportedDevices;
        logger.enabledLevels.debug && log.debug('check supported devices');
        supportedDevices = that.supportedDevices || _.map(usb.getDeviceList(), function (value) {
            return {
              vendorId: value.deviceDescriptor.idVendor,
              productId: value.deviceDescriptor.idProduct,
              type: 'generic'
            };
          });
        logger.enabledLevels.debug && log.debug('init devices');
        return p.each(_.values(supportedDevices),
          function (supportedDevice) {
            var deviceKey, device, deviceType;
            deviceKey = util.getDevicekey(supportedDevice.vendorId, supportedDevice.productId);
            logger.enabledLevels.debug && log.debug('searching usb device from "%s"', deviceKey);
            device = usb.findByIds(supportedDevice.vendorId, supportedDevice.productId);
            if (!device) {
              logger.enabledLevels.warn && log.warn('no usb device matching "%s"', deviceKey);
              return;
            }
            deviceType = supportedDevice.type || 'generic';
            logger.enabledLevels.debug && log.debug('found %s usb device matching "%s"', deviceType, deviceKey);
            return hidHandler.registerHid(deviceType, device);
          });
      })
      .nodeify(cb);
  },
  stop: function (cb) {
    logger.enabledLevels.debug && log.debug('stop hid handler');
    return p.do(
      function () {
        logger.enabledLevels.debug && log.debug('stop hid handler');
        return p.map(_.values(hidHandler.registeredHids), function (hid) {
          log.debug('hid :', hid);
          return hidHandler.unregisterHid(hid);
        });
      },
      function removeListeners() {
        logger.enabledLevels.debug && log.debug('remove listeners');
        usb.removeListener('attach', hidHandler.handleUsbAttach);
        usb.removeListener('detach', hidHandler.handleUsbDetach);
        hidHandler.removeAllListeners();
      })
      .nodeify(cb);
  }
});

(function registerErrors() {
  _.forIn(hwError, function (value, key) {
    if (key.match(/^Hid.*Error$/)) {
      hidHandler[key] = value;
    }
  });
})();

(function registerEventHandlers() {
  _.forIn(eventHandlers, function (eventHandler) {
    hidHandler.registerEventHandler(eventHandler);
    //[_.capitalize(_.camelCase(key + '-event'))] = eventHandler;
  });
})();

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


<commit_before>$( document ).ready(function() {
  console.log("ready!");
  $(".realm-value").each(function(index) {
    $(this).mouseover(function() {
      console.log($(this).text());
      $(this).addClass('realm-value-hover')
    });
    $(this).mouseout(function() {
      console.log($(this).text());
      $(this).removeClass('realm-value-hover')
    });
    console.log( index + ": " + $( this ).text() );
  });
});
<commit_msg>Click vs hover for visor<commit_after>$( document ).ready(function() {
  console.log("ready!");
  $(".realm-value").each(function(index) {
    $(this).click(function() {
      $(".realm-value").each(function(index) {
        $(this).removeClass('realm-value-hover')
      })
      $(this).addClass('realm-value-hover');
      return false;
    });
    $(document).mouseout(function() {
      //$(this).removeClass('realm-value-hover')
    });
    console.log( index + ": " + $( this ).text() );
  });

  $(document).click(function() {
    $(".realm-value").each(function(index) {
      $(this).removeClass('realm-value-hover')
    })
  });

});
<|endoftext|>


<commit_before>var msiofApp = angular.module('msiofApp', ['ui.bootstrap', 'angularMoment']).config(function($interpolateProvider){
		  $interpolateProvider.startSymbol('{[{').endSymbol('}]}');
});

msiofApp.controller('HomeCtrl', function ($scope, $http, $interval) {
		  $scope.servers = {};
		  $scope.filter = '';
		  $scope.loaded = false;
		  $scope.showInstallInstructions = false;
		  $scope.sortBy = '+name';
		  $scope.sortOptions = [
					 {
								'display': 'Name',
								'value': '+name'
					 },
					 {
								'display': 'Issues',
								'value': '-hasIssues'
					 },
					 {
								'display': 'Memory Usage',
								'value': '-mem.percentage.usage'
					 },
					 {
								'display': 'CPU Usage',
								'value': '-cpu.percentage.usage'
					 },
					 {
								'display': 'Disk Usage',
								'value': '-disk.percentage.usage'
					 },
					 {
								'display': 'Network Usage',
								'value': '-network.total.totalkbps'
					 },
					 {
								'display': 'Load Average',
								'value': '-system.loadavg'
					 },
		  ];

		  $scope.setSort = function(sortValue) {
					 $scope.sortBy = sortValue;
		  }

		  $scope.updateServers = function() {
					 $http({
								method: 'GET',
								url: '/servers/' + $scope.apiKey,
					 }).then(function(response){
								var data = response.data;
								$scope.servers = data;
								$scope.loaded = true;
					 });
		  };

		  $scope.apiKeyWatcher = $scope.$watch("apiKey", function(){
					 $scope.updateServers();
					 $interval(function() {
								$scope.updateServers();
					 }, 30000);
					 $scope.apiKeyWatcher();
		  });
});
<commit_msg>added expandAll config option, defaults to false<commit_after>var msiofApp = angular.module('msiofApp', ['ui.bootstrap', 'angularMoment']).config(function($interpolateProvider){
		  $interpolateProvider.startSymbol('{[{').endSymbol('}]}');
});

msiofApp.controller('HomeCtrl', function ($scope, $http, $interval) {
		  $scope.servers = {};
		  $scope.filter = '';
		  $scope.loaded = false;
		  $scope.showInstallInstructions = false;
		  $scope.sortBy = '+name';
		  $scope.expandAll = false;
		  $scope.sortOptions = [
					 {
								'display': 'Name',
								'value': '+name'
					 },
					 {
								'display': 'Issues',
								'value': '-hasIssues'
					 },
					 {
								'display': 'Memory Usage',
								'value': '-mem.percentage.usage'
					 },
					 {
								'display': 'CPU Usage',
								'value': '-cpu.percentage.usage'
					 },
					 {
								'display': 'Disk Usage',
								'value': '-disk.percentage.usage'
					 },
					 {
								'display': 'Network Usage',
								'value': '-network.total.totalkbps'
					 },
					 {
								'display': 'Load Average',
								'value': '-system.loadavg'
					 },
		  ];

		  $scope.setSort = function(sortValue) {
					 $scope.sortBy = sortValue;
		  }

		  $scope.updateServers = function() {
					 $http({
								method: 'GET',
								url: '/servers/' + $scope.apiKey,
					 }).then(function(response){
								var data = response.data;
								$scope.servers = data;
								$scope.loaded = true;
					 });
		  };

		  $scope.apiKeyWatcher = $scope.$watch("apiKey", function(){
					 $scope.updateServers();
					 $interval(function() {
								$scope.updateServers();
					 }, 30000);
					 $scope.apiKeyWatcher();
		  });
});
<|endoftext|>


<commit_before>const generateBirthDate    = require('./attach_dom/birth_date_picker');
const BinaryPjax           = require('../base/binary_pjax');
const Client               = require('../base/client');
const localize             = require('../base/localize').localize;
const State                = require('../base/storage').State;
const makeOption           = require('../common_functions/common_functions').makeOption;
const FormManager          = require('../common_functions/form_manager');
const Cookies              = require('../../lib/js-cookie');
require('select2');

const AccountOpening = (() => {
    'use strict';

    const redirectCookie = () => {
        if (Client.get('has_real')) {
            BinaryPjax.load('trading');
            return true;
        }
        return false;
    };

    const redirectAccount = () => {
        BinarySocket.wait('landing_company').then((response) => {
            const is_virtual = Client.get('is_virtual');
            const landing_company = response.landing_company;

            // redirect client to correct account opening page if needed
            if (!State.get('is_financial_opening') &&
                ((!is_virtual && Client.canUpgradeGamingToFinancial(landing_company)) ||
                Client.canUpgradeVirtualToFinancial(landing_company))) {
                BinaryPjax.load('new_account/maltainvestws');
                return false;
            }
            if (!State.get('is_japan_opening') && is_virtual && Client.canUpgradeVirtualToJapan(landing_company)) {
                BinaryPjax.load('new_account/japanws');
                return false;
            }
            return true;
        });
    };

    const populateForm = (form_id, getValidations) => {
        getResidence();
        BinarySocket.send({ states_list: Client.get('residence') }).then(data => handleState(data.states_list, form_id, getValidations));
        generateBirthDate();
    };

    const getResidence = () => {
        BinarySocket.send({ residence_list: 1 }).then(response => handleResidenceList(response.residence_list));
    };

    const handleResidenceList = (residence_list) => {
        if (residence_list.length > 0) {
            const $place_of_birth = $('#place_of_birth');
            const $tax_residence  = $('#tax_residence');
            const $phone          = $('#phone');
            const residence_value = Client.get('residence') || '';
            let residence_text = '';

            const $options = $('<div/>');
            residence_list.forEach((res) => {
                $options.append(makeOption(res.text, res.value));

                if (residence_value === res.value) {
                    residence_text = res.text;
                    if (residence_value !== 'jp' && res.phone_idd && !$phone.val()) {
                        $phone.val(`+${res.phone_idd}`);
                    }
                }
            });

            $('#lbl_residence').html($('<strong/>', { text: residence_text }));
            $place_of_birth.html($options.html()).val(residence_value);
            if ($tax_residence) {
                $tax_residence.html($options.html()).promise().done(() => {
                    setTimeout(() => {
                        $tax_residence.select2()
                            .val(getTaxResidence() || residence_value).trigger('change')
                            .removeClass('invisible');
                    }, 500);
                });
            }
        }
    };

    const getTaxResidence = () => {
        const tax_residence = State.get(['response', 'get_settings', 'get_settings'] || {}).tax_residence;
        return (tax_residence ? tax_residence.split(',') : '');
    };

    const handleState = (states_list, form_id, getValidations) => {
        const address_state_id = '#address_state';
        BinarySocket.wait('get_settings').then((response) => {
            let $address_state = $(address_state_id);

            $address_state.empty();

            const client_state = response.get_settings.address_state;

            if (states_list && states_list.length > 0) {
                states_list.forEach((state) => {
                    $address_state.append($('<option/>', { value: state.value, text: state.text }));
                });
                if (client_state) {
                    $address_state.val(client_state);
                }
            } else {
                $address_state.replaceWith($('<input/>', { id: 'address_state', name: 'address_state', type: 'text', maxlength: '35' }));
                $address_state = $(address_state_id);
                if (client_state) {
                    $address_state.text(client_state);
                }
            }
            $address_state.parent().parent().show();

            if (form_id && typeof getValidations === 'function') {
                FormManager.init(form_id, getValidations());
            }
        });
    };

    const handleNewAccount = (response, message_type) => {
        if (response.error) {
            const errorMessage = response.error.message;
            $('#submit-message').empty();
            $('#client_message').find('.notice-msg').text(response.msg_type === 'sanity_check' ? localize('There was some invalid character in an input field.') : errorMessage).end()
                .removeClass('invisible');
        } else {
            Client.processNewAccount(Client.get('email'), response[message_type].client_id, response[message_type].oauth_token, false);
        }
    };

    const commonValidations = () => {
        const req = [
            { selector: '#salutation',         validations: ['req'] },
            { selector: '#first_name',         validations: ['req', 'letter_symbol', ['length', { min: 2, max: 30 }]] },
            { selector: '#last_name',          validations: ['req', 'letter_symbol', ['length', { min: 2, max: 30 }]] },
            { selector: '#date_of_birth',      validations: ['req'] },
            { selector: '#address_line_1',     validations: ['req', 'address', ['length', { min: 1, max: 70 }]] },
            { selector: '#address_line_2',     validations: ['address', ['length', { min: 0, max: 70 }]] },
            { selector: '#address_city',       validations: ['req', 'letter_symbol', ['length', { min: 1, max: 35 }]] },
            { selector: '#address_state',      validations: $('#address_state').prop('nodeName') === 'SELECT' ? '' : ['general', ['length', { min: 0, max: 35 }]] },
            { selector: '#address_postcode',   validations: ['postcode', ['length', { min: 0, max: 20 }]] },
            { selector: '#phone',              validations: ['req', 'phone', ['length', { min: 6, max: 35 }]] },
            { selector: '#secret_question',    validations: ['req'] },
            { selector: '#secret_answer',      validations: ['req', 'general', ['length', { min: 4, max: 50 }]] },
            { selector: '#tnc',                validations: [['req', { message: 'Please accept the terms and conditions.' }]], exclude_request: 1 },

            { request_field: 'residence', value: Client.get('residence') },
        ];

        if (Cookies.get('affiliate_tracking')) {
            req.push({ request_field: 'affiliate_token', value: Cookies.getJSON('affiliate_tracking').t });
        }

        return req;
    };

    const selectCheckboxValidation = (form_id) => {
        const validations = [];
        let validation,
            id;
        $(form_id).find('select, input[type=checkbox]').each(function() {
            id = $(this).attr('id');
            if (id !== 'tnc') {
                validation = { selector: `#${id}`, validations: ['req'] };
                if (id === 'not_pep') {
                    validation.exclude_request = 1;
                }
                validations.push(validation);
            }
        });
        return validations;
    };

    return {
        redirectAccount : redirectAccount,
        populateForm    : populateForm,
        redirectCookie  : redirectCookie,
        handleNewAccount: handleNewAccount,

        commonValidations       : commonValidations,
        selectCheckboxValidation: selectCheckboxValidation,
    };
})();

module.exports = AccountOpening;
<commit_msg>Added 'Please select' option during new account creation<commit_after>const generateBirthDate    = require('./attach_dom/birth_date_picker');
const BinaryPjax           = require('../base/binary_pjax');
const Client               = require('../base/client');
const localize             = require('../base/localize').localize;
const State                = require('../base/storage').State;
const makeOption           = require('../common_functions/common_functions').makeOption;
const FormManager          = require('../common_functions/form_manager');
const Cookies              = require('../../lib/js-cookie');
require('select2');

const AccountOpening = (() => {
    'use strict';

    const redirectCookie = () => {
        if (Client.get('has_real')) {
            BinaryPjax.load('trading');
            return true;
        }
        return false;
    };

    const redirectAccount = () => {
        BinarySocket.wait('landing_company').then((response) => {
            const is_virtual = Client.get('is_virtual');
            const landing_company = response.landing_company;

            // redirect client to correct account opening page if needed
            if (!State.get('is_financial_opening') &&
                ((!is_virtual && Client.canUpgradeGamingToFinancial(landing_company)) ||
                Client.canUpgradeVirtualToFinancial(landing_company))) {
                BinaryPjax.load('new_account/maltainvestws');
                return false;
            }
            if (!State.get('is_japan_opening') && is_virtual && Client.canUpgradeVirtualToJapan(landing_company)) {
                BinaryPjax.load('new_account/japanws');
                return false;
            }
            return true;
        });
    };

    const populateForm = (form_id, getValidations) => {
        getResidence();
        BinarySocket.send({ states_list: Client.get('residence') }).then(data => handleState(data.states_list, form_id, getValidations));
        generateBirthDate();
    };

    const getResidence = () => {
        BinarySocket.send({ residence_list: 1 }).then(response => handleResidenceList(response.residence_list));
    };

    const handleResidenceList = (residence_list) => {
        if (residence_list.length > 0) {
            const $place_of_birth = $('#place_of_birth');
            const $tax_residence  = $('#tax_residence');
            const $phone          = $('#phone');
            const residence_value = Client.get('residence') || '';
            let residence_text = '';

            const $options = $('<div/>');
            residence_list.forEach((res) => {
                $options.append(makeOption(res.text, res.value));

                if (residence_value === res.value) {
                    residence_text = res.text;
                    if (residence_value !== 'jp' && res.phone_idd && !$phone.val()) {
                        $phone.val(`+${res.phone_idd}`);
                    }
                }
            });

            $('#lbl_residence').html($('<strong/>', { text: residence_text }));
            $place_of_birth.html($options.html()).val(residence_value);
            if ($tax_residence) {
                $tax_residence.html($options.html()).promise().done(() => {
                    setTimeout(() => {
                        $tax_residence.select2()
                            .val(getTaxResidence() || residence_value).trigger('change')
                            .removeClass('invisible');
                    }, 500);
                });
            }
        }
    };

    const getTaxResidence = () => {
        const tax_residence = State.get(['response', 'get_settings', 'get_settings'] || {}).tax_residence;
        return (tax_residence ? tax_residence.split(',') : '');
    };

    const handleState = (states_list, form_id, getValidations) => {
        const address_state_id = '#address_state';
        BinarySocket.wait('get_settings').then((response) => {
            let $address_state = $(address_state_id);

            $address_state.empty();

            const client_state = response.get_settings.address_state;

            if (states_list && states_list.length > 0) {
                $address_state.append($('<option/>', { value: '', text: localize('Please select') }));
                states_list.forEach((state) => {
                    $address_state.append($('<option/>', { value: state.value, text: state.text }));
                });
                if (client_state) {
                    $address_state.val(client_state);
                }
            } else {
                $address_state.replaceWith($('<input/>', { id: 'address_state', name: 'address_state', type: 'text', maxlength: '35' }));
                $address_state = $(address_state_id);
                if (client_state) {
                    $address_state.text(client_state);
                }
            }
            $address_state.parent().parent().show();

            if (form_id && typeof getValidations === 'function') {
                FormManager.init(form_id, getValidations());
            }
        });
    };

    const handleNewAccount = (response, message_type) => {
        if (response.error) {
            const errorMessage = response.error.message;
            $('#submit-message').empty();
            $('#client_message').find('.notice-msg').text(response.msg_type === 'sanity_check' ? localize('There was some invalid character in an input field.') : errorMessage).end()
                .removeClass('invisible');
        } else {
            Client.processNewAccount(Client.get('email'), response[message_type].client_id, response[message_type].oauth_token, false);
        }
    };

    const commonValidations = () => {
        const req = [
            { selector: '#salutation',         validations: ['req'] },
            { selector: '#first_name',         validations: ['req', 'letter_symbol', ['length', { min: 2, max: 30 }]] },
            { selector: '#last_name',          validations: ['req', 'letter_symbol', ['length', { min: 2, max: 30 }]] },
            { selector: '#date_of_birth',      validations: ['req'] },
            { selector: '#address_line_1',     validations: ['req', 'address', ['length', { min: 1, max: 70 }]] },
            { selector: '#address_line_2',     validations: ['address', ['length', { min: 0, max: 70 }]] },
            { selector: '#address_city',       validations: ['req', 'letter_symbol', ['length', { min: 1, max: 35 }]] },
            { selector: '#address_state',      validations: $('#address_state').prop('nodeName') === 'SELECT' ? '' : ['general', ['length', { min: 0, max: 35 }]] },
            { selector: '#address_postcode',   validations: ['postcode', ['length', { min: 0, max: 20 }]] },
            { selector: '#phone',              validations: ['req', 'phone', ['length', { min: 6, max: 35 }]] },
            { selector: '#secret_question',    validations: ['req'] },
            { selector: '#secret_answer',      validations: ['req', 'general', ['length', { min: 4, max: 50 }]] },
            { selector: '#tnc',                validations: [['req', { message: 'Please accept the terms and conditions.' }]], exclude_request: 1 },

            { request_field: 'residence', value: Client.get('residence') },
        ];

        if (Cookies.get('affiliate_tracking')) {
            req.push({ request_field: 'affiliate_token', value: Cookies.getJSON('affiliate_tracking').t });
        }

        return req;
    };

    const selectCheckboxValidation = (form_id) => {
        const validations = [];
        let validation,
            id;
        $(form_id).find('select, input[type=checkbox]').each(function() {
            id = $(this).attr('id');
            if (id !== 'tnc' && id !== 'address_state') {
                validation = { selector: `#${id}`, validations: ['req'] };
                if (id === 'not_pep') {
                    validation.exclude_request = 1;
                }
                validations.push(validation);
            }
        });
        return validations;
    };

    return {
        redirectAccount : redirectAccount,
        populateForm    : populateForm,
        redirectCookie  : redirectCookie,
        handleNewAccount: handleNewAccount,

        commonValidations       : commonValidations,
        selectCheckboxValidation: selectCheckboxValidation,
    };
})();

module.exports = AccountOpening;
<|endoftext|>


<commit_before>const fs = require('fs');
const { dirname, isAbsolute, join, parse } = require('path');
const path = require('path');
const EventEmitter = require('events');
const changeCase = require('change-case');
const mkdirp = require('mkdirp');

const pathBuilder = require('./path-builder');
const configureNode = require('./node-config');
const pipeline = require('./pipeline');
const { ComponentResolver, DataResolver, CSSResolver } = require('./resolvers');

const debug = require('debug')('idyll:cli');

function createDirectories(paths) {
  mkdirp.sync(paths.OUTPUT_DIR);
  mkdirp.sync(paths.STATIC_OUTPUT_DIR);
  mkdirp.sync(paths.TMP_DIR);
}

const idyll = (options = {}, cb) => {
  const opts = Object.assign(
    {},
    {
      alias: {},
      watch: false,
      open: true,
      datasets: 'data',
      minify: true,
      ssr: true,
      components: 'components',
      static: 'static',
      defaultComponents: dirname(require.resolve('idyll-components')),
      layout: 'centered',
      theme: 'github',
      output: 'build',
      outputCSS: 'idyll_styles.css',
      outputJS: 'idyll_index.js',
      port: process.env.PORT || 3000,
      temp: '.idyll',
      template: join(__dirname, 'client', '_index.html'),
      transform: [],
      compiler: {}
    },
    options
  );
  if (opts.watch) opts.minify = false; // speed!

  const paths = pathBuilder(opts);
  debug('Reading from paths:', paths);

  createDirectories(paths);
  configureNode(paths);

  const inputPackage = fs.existsSync(paths.PACKAGE_FILE)
    ? require(paths.PACKAGE_FILE)
    : {};
  const inputConfig = inputPackage.idyll || {};

  // Handle options that can be provided via options or via package.json
  opts.alias = options.alias || inputConfig.alias || opts.alias;
  opts.transform = options.transform || inputConfig.transform || opts.transform;
  opts.compiler = options.compiler || inputConfig.compiler || opts.compiler;
  opts.context = options.context || inputConfig.context || opts.context;

  // Resolve compiler plugins:
  if (opts.compiler.postProcessors) {
    opts.compiler.postProcessors = opts.compiler.postProcessors.map(
      processor => {
        try {
          return require(processor, { basedir: paths.INPUT_DIR });
        } catch (e) {
          console.log(e);
          console.warn('\n\nCould not find post-processor plugin: ', processor);
        }
      }
    );
  }

  // Resolve context:
  if (opts.context) {
    if (opts.context.indexOf('./') > -1) {
      opts.context = join(paths.INPUT_DIR, opts.context);
    }
  }

  let bs;
  let watchers;

  const createResolvers = () => {
    return new Map([
      ['components', new ComponentResolver(opts, paths)],
      ['css', new CSSResolver(opts, paths)],
      ['data', new DataResolver(opts, paths)]
    ]);
  };

  class IdyllInstance extends EventEmitter {
    getPaths() {
      return paths;
    }

    getOptions() {
      return opts;
    }

    build(src) {
      // Resolvers are recreated on each build, since new data dependencies might have been added.
      const resolvers = createResolvers();

      if (src) opts.inputString = src;

      debug('Starting the build');
      // Leaving the following timing statement in for backwards-compatibility.
      if (opts.debug) console.time('Build Time');

      pipeline
        .build(opts, paths, resolvers)
        .then(output => {
          debug('Build completed');
          // Leaving the following timing statement in for backwards-compatibility.
          if (opts.debug) console.timeEnd('Build Time');
          this.emit('update', output);
        })
        .then(() => {
          if (!bs && opts.watch && opts.inputFile) {
            bs = require('browser-sync').create();
            // any time an input files changes we will recompile .idl source
            // and write ast.json, components.js, and data.js to disk
            watchers = [
              bs.watch(paths.IDYLL_INPUT_FILE, { ignoreInitial: true }, () =>
                inst.build()
              ),
              // that will cause watchify to rebuild so we just watch the output bundle file
              // and reload when it is updated. Watch options are to prevent multiple change
              // events since the bundle file can be somewhat large
              bs.watch(
                paths.JS_OUTPUT_FILE,
                { awaitWriteFinish: { stabilityThreshold: 499 } },
                bs.reload
              ),
              // when CSS changes we reassemble and inject it
              bs.watch(paths.CSS_INPUT_FILE, { ignoreInitial: true }, () => {
                pipeline.updateCSS(paths, resolvers.get('css')).then(() => {
                  bs.reload('styles.css');
                });
              }),
              // when any static files change we do a full rebuild.
              bs.watch(paths.STATIC_DIR, { ignoreInitial: true }, () =>
                inst.build()
              )
            ];

            // Each resolver is responsible for generating a list of directories to watch for
            // their corresponding data types.
            resolvers.forEach((resolver, name) => {
              let watcher = bs.watch(
                resolver.getDirectories(),
                { ignoreInitial: true },
                () => {
                  inst.build();
                }
              );
              watchers.push(watcher);
            });

            bs.init({
              cors: true,
              logLevel: 'warn',
              logPrefix: 'Idyll',
              notify: false,
              server: [paths.OUTPUT_DIR],
              ui: false,
              port: opts.port,
              open: opts.open
            });
          }
        })
        .then(() => {
          this.emit('complete');
        })
        .catch(error => {
          // pass along errors if anyone is listening
          if (this.listenerCount('error')) {
            this.emit('error', error);
          } else {
            // otherwise dump to the console
            console.error(error);
          }
        });
      return this;
    }

    // Returns an array of the default components
    // Each element of the array is an object with keys 'name' and 'path'
    // 'name' is the file name of the component
    // 'path' is the absolute path to the component
    getComponents() {
      var components = [];
      var defaultCompsDir = this.getPaths().DEFAULT_COMPONENT_DIRS;
      var compsDir = this.getComponentsDirectory(); // grabs the `components` folder of their current directory
      var componentDirs = [defaultCompsDir, compsDir];

      componentDirs.forEach(dirs => {
        dirs.forEach(dir => {
          try {
            fs.statSync(dir);
          } catch (error) {
            // for when directory doesn't exist
            return;
          }
          fs.readdirSync(dir + '').forEach(file => {
            var compName = file.replace(/\.jsx?/g, '');
            if (compName !== 'index') { // avoid conflicts with index.js file
              components.push({
                name: compName,
                path: dir + '/' + file
              });
            }
          });
        });
      });
      return components;
    }

    // Returns the directory of the `components` folder
    // of this IdyllInstance
    // Note: this isn't guaranteed to exist
    // It just adds "component" to the directory of this idyll instance
    getComponentsDirectory() {
      return this.getPaths().COMPONENT_DIRS;
    }

    // Adds the given component (directory) to the components used
    // in this IdyllInstance
    // If there is already a component for the given componentPath,
    // it will be overwritten with the one from componentPath
    // If there is no components/ directory, then it will be created
    addComponent(componentPath) {
      const componentsDirectory = this.getComponentsDirectory();
      // We grab the name of the component, and put that in the components directory
      const componentFileName = path.basename(componentPath);
      // ensure components directory exists
      try {
        fs.statSync(componentsDirectory[0]);
      } catch (err) {
        fs.mkdirSync(componentsDirectory[0]);
      }
      fs.copyFileSync(
        componentPath,
        componentsDirectory[0] + '/' + componentFileName
      );
    }

    // Returns an array of the current datasets used in this IdyllInstance's data directory
    getDatasets() {
      var dataFolder = this.getPaths().DATA_DIR;
      var defaultData = [];
      fs.readdirSync(dataFolder).forEach(file => {
        defaultData.push(file);
      });
      // TODO return in the same format as getComponents()
      // path.extname(path) probly to get the extension
      return defaultData;
    }

    // Adds a dataset to the current datasets used in this IdyllInstance
    // It will be added to the `data` directory of this IdyllInstance
    addDataset(datasetPath) {
      const datasetDirectory = this.getPaths().DATA_DIR;
      const datasetName = path.basename(datasetPath);
      try {
        fs.statSync(datasetDirectory);
      } catch (err) {
        fs.mkdirSync(datasetDirectory);
      }
      fs.copyFileSync(datasetPath, datasetDirectory + '/' + datasetName);
    }

    getResolver() {
      // Look at the build() and perhaps add a field for the revolvers to have access to it.
      // Then can return it here
      return resolvers['components'];
    }

    stopWatching() {
      if (watchers.length) {
        watchers.forEach(w => w.close());
        watchers = null;
      }
      if (bs) bs.exit();
    }
  }

  const inst = new IdyllInstance();

  return inst;
};

module.exports = idyll;
<commit_msg>make dataset format same as component<commit_after>const fs = require('fs');
const { dirname, isAbsolute, join, parse } = require('path');
const path = require('path');
const EventEmitter = require('events');
const changeCase = require('change-case');
const mkdirp = require('mkdirp');

const pathBuilder = require('./path-builder');
const configureNode = require('./node-config');
const pipeline = require('./pipeline');
const { ComponentResolver, DataResolver, CSSResolver } = require('./resolvers');

const debug = require('debug')('idyll:cli');

function createDirectories(paths) {
  mkdirp.sync(paths.OUTPUT_DIR);
  mkdirp.sync(paths.STATIC_OUTPUT_DIR);
  mkdirp.sync(paths.TMP_DIR);
}

const idyll = (options = {}, cb) => {
  const opts = Object.assign(
    {},
    {
      alias: {},
      watch: false,
      open: true,
      datasets: 'data',
      minify: true,
      ssr: true,
      components: 'components',
      static: 'static',
      defaultComponents: dirname(require.resolve('idyll-components')),
      layout: 'centered',
      theme: 'github',
      output: 'build',
      outputCSS: 'idyll_styles.css',
      outputJS: 'idyll_index.js',
      port: process.env.PORT || 3000,
      temp: '.idyll',
      template: join(__dirname, 'client', '_index.html'),
      transform: [],
      compiler: {}
    },
    options
  );
  if (opts.watch) opts.minify = false; // speed!

  const paths = pathBuilder(opts);
  debug('Reading from paths:', paths);

  createDirectories(paths);
  configureNode(paths);

  const inputPackage = fs.existsSync(paths.PACKAGE_FILE)
    ? require(paths.PACKAGE_FILE)
    : {};
  const inputConfig = inputPackage.idyll || {};

  // Handle options that can be provided via options or via package.json
  opts.alias = options.alias || inputConfig.alias || opts.alias;
  opts.transform = options.transform || inputConfig.transform || opts.transform;
  opts.compiler = options.compiler || inputConfig.compiler || opts.compiler;
  opts.context = options.context || inputConfig.context || opts.context;

  // Resolve compiler plugins:
  if (opts.compiler.postProcessors) {
    opts.compiler.postProcessors = opts.compiler.postProcessors.map(
      processor => {
        try {
          return require(processor, { basedir: paths.INPUT_DIR });
        } catch (e) {
          console.log(e);
          console.warn('\n\nCould not find post-processor plugin: ', processor);
        }
      }
    );
  }

  // Resolve context:
  if (opts.context) {
    if (opts.context.indexOf('./') > -1) {
      opts.context = join(paths.INPUT_DIR, opts.context);
    }
  }

  let bs;
  let watchers;

  const createResolvers = () => {
    return new Map([
      ['components', new ComponentResolver(opts, paths)],
      ['css', new CSSResolver(opts, paths)],
      ['data', new DataResolver(opts, paths)]
    ]);
  };

  class IdyllInstance extends EventEmitter {
    getPaths() {
      return paths;
    }

    getOptions() {
      return opts;
    }

    build(src) {
      // Resolvers are recreated on each build, since new data dependencies might have been added.
      const resolvers = createResolvers();

      if (src) opts.inputString = src;

      debug('Starting the build');
      // Leaving the following timing statement in for backwards-compatibility.
      if (opts.debug) console.time('Build Time');

      pipeline
        .build(opts, paths, resolvers)
        .then(output => {
          debug('Build completed');
          // Leaving the following timing statement in for backwards-compatibility.
          if (opts.debug) console.timeEnd('Build Time');
          this.emit('update', output);
        })
        .then(() => {
          if (!bs && opts.watch && opts.inputFile) {
            bs = require('browser-sync').create();
            // any time an input files changes we will recompile .idl source
            // and write ast.json, components.js, and data.js to disk
            watchers = [
              bs.watch(paths.IDYLL_INPUT_FILE, { ignoreInitial: true }, () =>
                inst.build()
              ),
              // that will cause watchify to rebuild so we just watch the output bundle file
              // and reload when it is updated. Watch options are to prevent multiple change
              // events since the bundle file can be somewhat large
              bs.watch(
                paths.JS_OUTPUT_FILE,
                { awaitWriteFinish: { stabilityThreshold: 499 } },
                bs.reload
              ),
              // when CSS changes we reassemble and inject it
              bs.watch(paths.CSS_INPUT_FILE, { ignoreInitial: true }, () => {
                pipeline.updateCSS(paths, resolvers.get('css')).then(() => {
                  bs.reload('styles.css');
                });
              }),
              // when any static files change we do a full rebuild.
              bs.watch(paths.STATIC_DIR, { ignoreInitial: true }, () =>
                inst.build()
              )
            ];

            // Each resolver is responsible for generating a list of directories to watch for
            // their corresponding data types.
            resolvers.forEach((resolver, name) => {
              let watcher = bs.watch(
                resolver.getDirectories(),
                { ignoreInitial: true },
                () => {
                  inst.build();
                }
              );
              watchers.push(watcher);
            });

            bs.init({
              cors: true,
              logLevel: 'warn',
              logPrefix: 'Idyll',
              notify: false,
              server: [paths.OUTPUT_DIR],
              ui: false,
              port: opts.port,
              open: opts.open
            });
          }
        })
        .then(() => {
          this.emit('complete');
        })
        .catch(error => {
          // pass along errors if anyone is listening
          if (this.listenerCount('error')) {
            this.emit('error', error);
          } else {
            // otherwise dump to the console
            console.error(error);
          }
        });
      return this;
    }

    // Returns an array of the default components
    // Each element of the array is an object with keys 'name' and 'path'
    // 'name' is the file name of the component
    // 'path' is the absolute path to the component
    getComponents() {
      var components = [];
      var defaultCompsDir = this.getPaths().DEFAULT_COMPONENT_DIRS;
      var compsDir = this.getComponentsDirectory(); // grabs the `components` folder of their current directory
      var componentDirs = [defaultCompsDir, compsDir];

      componentDirs.forEach(dirs => {
        dirs.forEach(dir => {
          try {
            fs.statSync(dir);
          } catch (error) {
            // for when directory doesn't exist
            return;
          }
          fs.readdirSync(dir + '').forEach(file => {
            var compName = file.replace(/\.jsx?/g, '');
            if (compName !== 'index') { // avoid conflicts with index.js file
              components.push({
                name: compName,
                path: dir + '/' + file
              });
            }
          });
        });
      });
      return components;
    }

    // Returns the directory of the `components` folder
    // of this IdyllInstance
    // Note: this isn't guaranteed to exist
    // It just adds "component" to the directory of this idyll instance
    getComponentsDirectory() {
      return this.getPaths().COMPONENT_DIRS;
    }

    // Adds the given component (directory) to the components used
    // in this IdyllInstance
    // If there is already a component for the given componentPath,
    // it will be overwritten with the one from componentPath
    // If there is no components/ directory, then it will be created
    addComponent(componentPath) {
      const componentsDirectory = this.getComponentsDirectory();
      // We grab the name of the component, and put that in the components directory
      const componentFileName = path.basename(componentPath);
      // ensure components directory exists
      try {
        fs.statSync(componentsDirectory[0]);
      } catch (err) {
        fs.mkdirSync(componentsDirectory[0]);
      }
      fs.copyFileSync(
        componentPath,
        componentsDirectory[0] + '/' + componentFileName
      );
    }

    // Returns an array of the current datasets used in this IdyllInstance's data directory
    getDatasets() {
      var dataFolder = this.getPaths().DATA_DIR;
      var defaultData = [];
      fs.readdirSync(dataFolder).forEach(file => {
        var fileName = file;
        var datasetPath = dataFolder + '/' + file;
        var extension = path.extname(file);
        defaultData.push({
          name: fileName,
          path: datasetPath,
          extension: extension
        });
      });
      // TODO return in the same format as getComponents()
      // path.extname(path) probly to get the extension
      return defaultData;
    }

    // Adds a dataset to the current datasets used in this IdyllInstance
    // It will be added to the `data` directory of this IdyllInstance
    addDataset(datasetPath) {
      const datasetDirectory = this.getPaths().DATA_DIR;
      const datasetName = path.basename(datasetPath);
      try {
        fs.statSync(datasetDirectory);
      } catch (err) {
        fs.mkdirSync(datasetDirectory);
      }
      fs.copyFileSync(datasetPath, datasetDirectory + '/' + datasetName);
    }

    getResolver() {
      // Look at the build() and perhaps add a field for the revolvers to have access to it.
      // Then can return it here
      return resolvers['components'];
    }

    stopWatching() {
      if (watchers.length) {
        watchers.forEach(w => w.close());
        watchers = null;
      }
      if (bs) bs.exit();
    }
  }

  const inst = new IdyllInstance();

  return inst;
};

module.exports = idyll;
<|endoftext|>


<commit_before>'use strict';

const

    fs      = require('fs'),
    telebot = require('telebot'),
    time    = require('./time'),
    Ioredis = require('ioredis'),
    path    = require('path'),
    symbols = require('./core-symbols'),

    control = {
        configFilePath: process.argv[2] || './config.json',
        shutdown: (reason = "Unknown reason", fail) => {
            console.log(`Terminated: ${reason}. [SHUTDOWN_CLEAN]`);
            process.exitCode = !fail;
            bot.api.stop(reason);
            bot.db.quit();
        }
    };

let bot = { }, authTimer, spanningTimer = time.startTimer('ready');
const {pluginName} = symbols;

control.config = require(control.configFilePath);

try {

    process.once('SIGINT', () => control.shutdown("SIGINT"));
    process.once('SIGTERM', () => control.shutdown("SIGTERM"));
    process.once('SIGBREAK', () => control.shutdown("Ctrl + Break"));
    console.log(`\nRunning on node ${process.version} with process id ${process.pid}.\nLoading config from "${control.configFilePath}".`);
    Object.freeze(control.config);

    bot.db = new Ioredis(control.config.db);

    bot.api = new telebot(control.config.auth_token);
    bot.api.start();
    time.start();
    bot.time = time;
    bot.control = control;

    time.startTimer('auth');
    bot.api.getMe().then(me => {
        console.log(`Connected. (${authTimer = time.resolveTimer('auth')} ms)`);
        bot.profile = me;
        console.log(`Profile:\n  Id: ${me.id}\n  Name: ${me.first_name}\n  Username: @${me.username}`);
        setup();
    });

} catch (e) {
    console.log(String(e));
    control.shutdown("Unable to finish authentication", true);
}

function setup () {

    bot.functions = { };

    const getPluginName = () => {
        const path_ = plugins[i].path;

        const name = path.basename(path_, path.extname(path_));

        return name.toLowerCase();
    }

    bot.register = (sth, fn) => {
        const name = getPluginName();
        bot.api.on(sth, async message => {
            if (message[symbols.handled] || await isPluginDisabled(message.chat.id, name)) {
                return;
            }
            return fn.call(this, message);
        });
    }

    bot.register.command = (commands, fn) => {
        if (typeof commands === 'string') {
            commands = [commands];
        }

        fn[pluginName] = getPluginName();

        for (const command of commands) {
            if (bot.functions.hasOwnProperty(command.toLowerCase())) {
                throw new Error(`Attempt to register ${command} command, already registered by ${bot.functions[command.toLowerCase()][pluginName]} plugin`);
            }
            bot.functions[command.toLowerCase()] = fn
        }
    };
    Object.seal(bot);
    bot.api.on('text', receive);

    let plugins = control.config.plugins, failed  = 0;
    time.startTimer('loadAll');
    for (var i = 0; i < plugins.length; i++) {
        try {
            require(plugins[i].path).init(bot, plugins[i].prefs);
        } catch (e) {
            console.log(`Failed to load plugin "${plugins[i].path}".`);
            console.log(e);
            plugins[i][symbols.error] = e;
            failed++;
        }
    }
    console.log(`Done loading plugins: ${plugins.length - failed} OK, ${failed} failed. (${time.resolveTimer('loadAll')} ms)`);

    bot.register = null; // time for registering is now over

    let spanningTimer = time.resolveTimer('ready');
    console.log(`Ready to process messages. (${(spanningTimer - authTimer).toFixed(2)} ms | ${spanningTimer} ms)`);

}

const isPluginDisabled = (chatid, name) => bot.db.sismember(`chat${chatid}:disabledPlugins`, name.toLowerCase())

async function receive (message) {

    if (bot.time.isExpired(message.date))
        return;
    if (!message.entities)
        return;
    const firstEntity = message.entities[0];
    if (firstEntity.offset || firstEntity.type != 'bot_command')
        return;
    let commandEntity = message.text.substr(1, firstEntity.length - 1).toLowerCase();
    message.args = message.text.slice(message.entities[0].length + 1)
    const botMention = commandEntity.match(/@.*/);
    if (botMention) {
        if (botMention[0].substr(1) !== bot.profile.username.toLowerCase())
            return;
        commandEntity = botMention.input.substr(0, botMention.index);
    }
    if (!bot.functions[commandEntity])
        return;

    message.tag = (response, format) => {
        switch (typeof response) {

            case 'number':
                response = String(response);
            case 'string':
                message.reply.text(response, {
                    parse: format ? 'HTML' : undefined,
                    reply: message.message_id
                }).catch(e => message.error(e.error_code, e.description));
            case 'undefined':
                break;

            case 'object':
                if (response && typeof response.then == 'function'
                    || response == null)
                    break;
            default:
                message.error("TYPE", `Function Error: returned ${typeof response} instead of string`);

        }
    };
    message.error = (code, desc) =>
        message.tag(`Failed. #E_${code} ⚠\n${desc}.`);

    const funct = bot.functions[commandEntity];
    if (message[symbols.handled] || await isPluginDisabled(message.chat.id, funct[pluginName])) {
        return;
    }
    message.tag(funct.fn(message), funct.format);
}
<commit_msg>Use console.error to log errors in code instead of console.log<commit_after>'use strict';

const

    fs      = require('fs'),
    telebot = require('telebot'),
    time    = require('./time'),
    Ioredis = require('ioredis'),
    path    = require('path'),
    symbols = require('./core-symbols'),

    control = {
        configFilePath: process.argv[2] || './config.json',
        shutdown: (reason = "Unknown reason", fail) => {
            console.log(`Terminated: ${reason}. [SHUTDOWN_CLEAN]`);
            process.exitCode = !fail;
            bot.api.stop(reason);
            bot.db.quit();
        }
    };

let bot = { }, authTimer, spanningTimer = time.startTimer('ready');
const {pluginName} = symbols;

control.config = require(control.configFilePath);

try {

    process.once('SIGINT', () => control.shutdown("SIGINT"));
    process.once('SIGTERM', () => control.shutdown("SIGTERM"));
    process.once('SIGBREAK', () => control.shutdown("Ctrl + Break"));
    console.log(`\nRunning on node ${process.version} with process id ${process.pid}.\nLoading config from "${control.configFilePath}".`);
    Object.freeze(control.config);

    bot.db = new Ioredis(control.config.db);

    bot.api = new telebot(control.config.auth_token);
    bot.api.start();
    time.start();
    bot.time = time;
    bot.control = control;

    time.startTimer('auth');
    bot.api.getMe().then(me => {
        console.log(`Connected. (${authTimer = time.resolveTimer('auth')} ms)`);
        bot.profile = me;
        console.log(`Profile:\n  Id: ${me.id}\n  Name: ${me.first_name}\n  Username: @${me.username}`);
        setup();
    });

} catch (e) {
    console.error(e);
    control.shutdown("Unable to finish authentication", true);
}

function setup () {

    bot.functions = { };

    const getPluginName = () => {
        const path_ = plugins[i].path;

        const name = path.basename(path_, path.extname(path_));

        return name.toLowerCase();
    }

    bot.register = (sth, fn) => {
        const name = getPluginName();
        bot.api.on(sth, async message => {
            if (message[symbols.handled] || await isPluginDisabled(message.chat.id, name)) {
                return;
            }
            return fn.call(this, message);
        });
    }

    bot.register.command = (commands, fn) => {
        if (typeof commands === 'string') {
            commands = [commands];
        }

        fn[pluginName] = getPluginName();

        for (const command of commands) {
            if (bot.functions.hasOwnProperty(command.toLowerCase())) {
                throw new Error(`Attempt to register ${command} command, already registered by ${bot.functions[command.toLowerCase()][pluginName]} plugin`);
            }
            bot.functions[command.toLowerCase()] = fn
        }
    };
    Object.seal(bot);
    bot.api.on('text', receive);

    let plugins = control.config.plugins, failed  = 0;
    time.startTimer('loadAll');
    for (var i = 0; i < plugins.length; i++) {
        try {
            require(plugins[i].path).init(bot, plugins[i].prefs);
        } catch (e) {
            console.error(`Failed to load plugin "${plugins[i].path}".`);
            console.error(e);
            plugins[i][symbols.error] = e;
            failed++;
        }
    }
    console.log(`Done loading plugins: ${plugins.length - failed} OK, ${failed} failed. (${time.resolveTimer('loadAll')} ms)`);

    bot.register = null; // time for registering is now over

    let spanningTimer = time.resolveTimer('ready');
    console.log(`Ready to process messages. (${(spanningTimer - authTimer).toFixed(2)} ms | ${spanningTimer} ms)`);

}

const isPluginDisabled = (chatid, name) => bot.db.sismember(`chat${chatid}:disabledPlugins`, name.toLowerCase())

async function receive (message) {

    if (bot.time.isExpired(message.date))
        return;
    if (!message.entities)
        return;
    const firstEntity = message.entities[0];
    if (firstEntity.offset || firstEntity.type != 'bot_command')
        return;
    let commandEntity = message.text.substr(1, firstEntity.length - 1).toLowerCase();
    message.args = message.text.slice(message.entities[0].length + 1)
    const botMention = commandEntity.match(/@.*/);
    if (botMention) {
        if (botMention[0].substr(1) !== bot.profile.username.toLowerCase())
            return;
        commandEntity = botMention.input.substr(0, botMention.index);
    }
    if (!bot.functions[commandEntity])
        return;

    message.tag = (response, format) => {
        switch (typeof response) {

            case 'number':
                response = String(response);
            case 'string':
                message.reply.text(response, {
                    parse: format ? 'HTML' : undefined,
                    reply: message.message_id
                }).catch(e => message.error(e.error_code, e.description));
            case 'undefined':
                break;

            case 'object':
                if (response && typeof response.then == 'function'
                    || response == null)
                    break;
            default:
                message.error("TYPE", `Function Error: returned ${typeof response} instead of string`);

        }
    };
    message.error = (code, desc) =>
        message.tag(`Failed. #E_${code} ⚠\n${desc}.`);

    const funct = bot.functions[commandEntity];
    if (message[symbols.handled] || await isPluginDisabled(message.chat.id, funct[pluginName])) {
        return;
    }
    message.tag(funct.fn(message), funct.format);
}
<|endoftext|>


<commit_before>/*
criticalCSS by @scottjehl. Run this on your CSS, get the styles that are applicable in the viewport (critical). The url arg should be any part of the URL of the stylesheets you'd like to parse. So, 'all.css' or '/css/' would both work.
*/
(function(exports){
	"use strict";
	/**
	 * opts
	 * opts.sheets = document.styleSheets
	 * opts.maxTop = window.innerHeight
	 * opts.querySelector = function( selector ){
	 *     return page.evaluate(function(s){
	 *       return document.querySelector( s );
	 *     },selector);
	 * opts.matchMedia = window.matchMedia
	 */
	var criticalCSS = function( url, opts ){
		var sheets = opts.sheets,
			maxTop = opts.maxTop,
			critical = [];

			var removeNull = function( el ){
				return el !== null;
			};

		var critCSSText;
		var aboveFold = function( rule ){
			if( !rule.selectorText ){
				return false;
			}
			var selectors = rule.selectorText.split(","),
				criticalSelectors = [];
			for( var k = 0, sl = selectors.length; k < sl; k++ ) {
				var elem;
				try {
					// a strict browser like Safari will error out on a non-standard selector
					elem = document.querySelector( selectors[ l ] );
				}
				catch (e){}
				if( elem && elem.offsetTop <= maxTop ){
					criticalSelectors.push( selectors[ k ] );
				}
			}
			if( criticalSelectors.length ){
				return criticalSelectors.join(",") + rule.cssText.match( /\{.+/ );
			}
			else {
				return false;
			}
		};

		sheets = Array.prototype.filter.call(sheets, removeNull);

		for( var i = 0, l = sheets.length; i < l; i++ ){
			var sheet = sheets[ i ],
				href = sheet.href,
				rules = sheet.rules;

				rules = Array.prototype.filter.call( rules, removeNull );

			if( url && href && href.indexOf( url ) > -1 ){
				for( var j = 0, rl = rules.length; j < rl; j++ ){

					var media = rules[ j ].media,
						matchingRules = [];
					if( media && opts.matchMedia( media.mediaText ).matches ){
						var innerRules = rules[ j ].rules;
						for( var k in innerRules ){
							critCSSText = aboveFold( innerRules[ k ] );
							if( critCSSText ){
								matchingRules.push( critCSSText );
							}
						}
						if( matchingRules.length ){
							matchingRules.unshift( "@media " + media.mediaText + "{" );
							matchingRules.push( "}" );
						}

					} else if( !media ){
						critCSSText = aboveFold( rules[ j ] );
						if( critCSSText && !critCSSText.match(/^\s+$/) ){
							matchingRules.push( critCSSText );
						}
					}
					critical.push( matchingRules.join( "\n" ) );
				}

			}
		}
		return critical.join( "\n" );
	};

	exports.criticalCSS = criticalCSS;

}(typeof exports === 'object' && exports || this));
<commit_msg>use window<commit_after>/*
criticalCSS by @scottjehl. Run this on your CSS, get the styles that are applicable in the viewport (critical). The url arg should be any part of the URL of the stylesheets you'd like to parse. So, 'all.css' or '/css/' would both work.
*/
/*global window:true*/
(function(exports){
	"use strict";
	/**
	 * opts
	 * opts.sheets = document.styleSheets
	 * opts.maxTop = window.innerHeight
	 * opts.querySelector = function( selector ){
	 *     return page.evaluate(function(s){
	 *       return document.querySelector( s );
	 *     },selector);
	 * opts.matchMedia = window.matchMedia
	 */
	var criticalCSS = function( url, opts ){
		var sheets = opts.sheets,
			maxTop = opts.maxTop,
			critical = [];

			var removeNull = function( el ){
				return el !== null;
			};

		var critCSSText;
		var aboveFold = function( rule ){
			if( !rule.selectorText ){
				return false;
			}
			var selectors = rule.selectorText.split(","),
				criticalSelectors = [];
			for( var k = 0, sl = selectors.length; k < sl; k++ ) {
				var elem;
				try {
					// a strict browser like Safari will error out on a non-standard selector
					elem = window.document.querySelector( selectors[ l ] );
				}
				catch (e){}
				if( elem && elem.offsetTop <= maxTop ){
					criticalSelectors.push( selectors[ k ] );
				}
			}
			if( criticalSelectors.length ){
				return criticalSelectors.join(",") + rule.cssText.match( /\{.+/ );
			}
			else {
				return false;
			}
		};

		sheets = Array.prototype.filter.call(sheets, removeNull);

		for( var i = 0, l = sheets.length; i < l; i++ ){
			var sheet = sheets[ i ],
				href = sheet.href,
				rules = sheet.rules;

				rules = Array.prototype.filter.call( rules, removeNull );

			if( url && href && href.indexOf( url ) > -1 ){
				for( var j = 0, rl = rules.length; j < rl; j++ ){

					var media = rules[ j ].media,
						matchingRules = [];
					if( media && opts.matchMedia( media.mediaText ).matches ){
						var innerRules = rules[ j ].rules;
						for( var k in innerRules ){
							critCSSText = aboveFold( innerRules[ k ] );
							if( critCSSText ){
								matchingRules.push( critCSSText );
							}
						}
						if( matchingRules.length ){
							matchingRules.unshift( "@media " + media.mediaText + "{" );
							matchingRules.push( "}" );
						}

					} else if( !media ){
						critCSSText = aboveFold( rules[ j ] );
						if( critCSSText && !critCSSText.match(/^\s+$/) ){
							matchingRules.push( critCSSText );
						}
					}
					critical.push( matchingRules.join( "\n" ) );
				}

			}
		}
		return critical.join( "\n" );
	};

	exports.criticalCSS = criticalCSS;

}(typeof exports === 'object' && exports || this));
<|endoftext|>