<commit_before>(function (exportName) {

  function warn() {
    if (typeof console === 'undefined' || !SafeObject.debugMode) return;
    if (console.warn) console.warn.apply(console, arguments);
    else if (console.log) console.log.apply(console, arguments);
  }

  const _registered_constructors = [];

  class PropertyDescriptor {
    constructor(value, enumerable, writable, configurable, valueIsFactory) {
      this.enumerable = typeof enumerable === 'undefined' ? true : false;
      this.writable = typeof writable === 'undefined' ? true : false;
      this.configurable = typeof configurable === 'undefined' ? true : false;
      const registeredConstructor = SafeObject.getRegisteredConstructor(value);
      if (registeredConstructor) {
        this.value = registeredConstructor.construct.bind(registeredConstructor);
        this.isFactory = true;
      } else {
        this.isFactory = typeof value === 'function' && typeof valueIsFactory === 'undefined' ? true : valueIsFactory || false;
        this.value = value;
      }
    }

    clone() {
      return new PropertyDescriptor(this.value, this.enumerable, this.writable, this.configurable, this.isFactory);
    }

    toObject() {
      return {
        value: this.isFactory ? this.value(this) : this.value,
        enumerable: this.enumerable,
        writable: this.writable,
        configurable: this.configurable
      };
    }
  }

  class RegisteredConstructor {
    constructor(ConstructorFunction) {
      this.ConstructorFunction = ConstructorFunction;
    }
    construct() {
      return new (this.ConstructorFunction)();
    }
  }

  class SafeObject {

    static debug(instance) {
      const buffer = [];
      buffer.push('----- SafeObject debug -----');
      buffer.push('Constructor: ' + String(instance.constructor.name));
      buffer.push('_isSafeObject: ' + String(!!instance._isSafeObject));
      if (instance._isSafeObject) {
        const ancestors = SafeObject.getAncestors(instance);
        buffer.push('Ancestors: ' + ancestors.map(function (d) {return d.name;}).join(' < '));
        const attributeNames = SafeObject.getRegisteredPropertyNames(instance);
        const registeredAttributeNames = instance._getIgnoredSafeObjectPropertyNames().concat(attributeNames);
        const unregisteredAttributeNames = Object.getOwnPropertyNames(instance).filter(function (d)  { return registeredAttributeNames.indexOf(d) === -1; });
        buffer.push('ignored properties: ' + instance._getIgnoredSafeObjectPropertyNames().join(', '));
        buffer.push('registered properties: ' + attributeNames.join(', '));
        buffer.push('unregistered properties: ' + unregisteredAttributeNames.join(', '));
      }
      return buffer.join('\n');
    }

    static include(instance, options = {}) {
      if (SafeObject.isSafeObject(instance)) return instance;
      if (!instance.constructor.INSTANCE_PROPERTIES) {
        instance.constructor.INSTANCE_PROPERTIES = {};
      }
      const instanceProperties = instance.constructor.INSTANCE_PROPERTIES;

      if (!('_isSafeObject' in instanceProperties)) {
        instanceProperties._isSafeObject = new PropertyDescriptor(true, false, false, false);
      }

      [
        { methodName: 'destroy', returnsMerge: 'super' },
        { methodName: '_getIgnoredSafeObjectPropertyNames', returnsMerge: 'concat' }
      ].forEach(function ({ methodName, returnsMerge }) {
        // check if property exists and is a method
        const hasProperty = methodName in instance;
        const isFunction = typeof instance[methodName] === 'function';
        const _superMethod = instance[methodName];
        if (options.force && hasProperty) {
          warn('Overriding ' + methodName + ' method');
        }
        // define the method only if it hasnt the property or 'force' is true
        if (hasProperty && options.force || !hasProperty) {
          if (!(methodName in instanceProperties)) {
            instanceProperties[methodName] = new PropertyDescriptor(
              isFunction ? overrideMethod : SafeObject.prototype[methodName],
              false, true, true, false
            );
          }
        }

        function overrideMethod() {
          const superOut = _superMethod.apply(this, arguments);
          const safeObjectOut = SafeObject.prototype[methodName].call(this);
          let out;
          switch (returnsMerge) {
            case 'super': out = superOut; break;
            case 'concat': out = (superOut || []).concat(safeObjectOut || []); break;
          }
          return out;
        }
      });

      SafeObject.setProperties(instance, SafeObject.SAFE_OBJECT_INITIALIZE, Object.assign(instanceProperties, SafeObject.INSTANCE_PROPERTIES));

      return instance;
    }

    static getRegisteredConstructor(ConstructorFunction) {
      return _registered_constructors.find((d) => { return d.ConstructorFunction === ConstructorFunction; });
    }

    static registerConstructor(ConstructorFunction) {
      _registered_constructors.push(new RegisteredConstructor(ConstructorFunction));
    }

    static unregisterConstructor(ConstructorFunction) {
      const index = _registered_constructors.findIndex((d) => { return d.ConstructorFunction === ConstructorFunction; });
      return _registered_constructors.splice(index, 1)[0];
    }

    static isSafeObject(object) {
      return object && object._isSafeObject === true;
    }

    static getAncestors(object) {
      let current = object.constructor;
      const out = [];
      while (current = Object.getPrototypeOf(current.prototype) ? Object.getPrototypeOf(current.prototype).constructor : null) {
        out.push(current || []);
      }
      return out;
    }

    static getRegisteredProperties(safeObject) {
      const instanceProperties = [ safeObject.constructor ].concat(SafeObject.getAncestors(safeObject)).map(function (Constructor) {
        return Constructor.INSTANCE_PROPERTIES;
      }).reverse();
      instanceProperties.unshift({});
      return Object.assign(...instanceProperties);
    }

    static getUnregisteredPropertyNames(safeObject) {
      const registeredAttributeNames = SafeObject.getRegisteredPropertyNames(safeObject);
      registeredAttributeNames.push.apply(registeredAttributeNames, safeObject._getIgnoredSafeObjectPropertyNames());
      return Object.getOwnPropertyNames(safeObject).filter(function (propertyName)  {
        return registeredAttributeNames.indexOf(propertyName) === -1;
      });
    }

    static getRegisteredPropertyNames(safeObject) {
      return Object.getOwnPropertyNames(SafeObject.getRegisteredProperties(safeObject));
    }

    static setInstanceProperties(safeObject, state) {
      SafeObject.setProperties(safeObject, state, SafeObject.getRegisteredProperties(safeObject));
    }

    static setProperties(object, state, propertyDescriptors) {
      for (const propertyName in propertyDescriptors) {
        try {
          const propertyDescriptor = SafeObject.parsePropertyDescriptor(propertyDescriptors[propertyName]);
          SafeObject.setProperty(object, propertyName, propertyDescriptor, state);
        } catch (err) {
          warn('SafeObject#setProperties: ' + err.toString());
        }
      }
    }

    static setProperty(object, fieldName, propertyDescriptor, state) {
      if (!propertyDescriptor) {
        warn('Property descriptor isnt well formed for ' + String(fieldName) + '.');
        return;
      }
      Object.defineProperty(object, fieldName, propertyDescriptor.toObject());
    }

    static parsePropertyDescriptor(propertyDescriptor) {
      if (!propertyDescriptor || !(propertyDescriptor instanceof PropertyDescriptor)) {
        return new PropertyDescriptor(propertyDescriptor);
      }
      return propertyDescriptor;
    }

    constructor() {
      SafeObject.setInstanceProperties(this, SafeObject.SAFE_OBJECT_INITIALIZE);
      this._isDestroyed = false;
    }

    destroy() {
      SafeObject.setInstanceProperties(this, SafeObject.SAFE_OBJECT_DESTROY);
      this._isDestroyed = true;
    }

    _getIgnoredSafeObjectPropertyNames() {
      return [ '_isDestroyed' ];
    }

  }

  SafeObject.debugMode = false;
  SafeObject.VERSION = '1.2.0';
  SafeObject.SAFE_OBJECT_INITIALIZE = 1;
  SafeObject.SAFE_OBJECT_DESTROY = 2;

  SafeObject.INSTANCE_PROPERTIES = {
    _isSafeObject: new PropertyDescriptor(true, false, false, false)
  };

  SafeObject.PropertyDescriptor = PropertyDescriptor;

  SafeObject.registerConstructor(Object);
  SafeObject.registerConstructor(Array);
  SafeObject.registerConstructor(Date);
  SafeObject.registerConstructor(Map);
  SafeObject.registerConstructor(Set);

  if (typeof define === 'function' && define.amd) {
    define(function () {
      return SafeObject;
    });
  } else if (typeof module !== 'undefined' && module.exports) {
    module.exports = SafeObject;
  } else {
    this[exportName] = SafeObject;
  }
})('SafeObject');

<commit_msg>PropertyDescriptor misconception<commit_after>(function (exportName) {

  function warn() {
    if (typeof console === 'undefined' || !SafeObject.debugMode) return;
    if (console.warn) console.warn.apply(console, arguments);
    else if (console.log) console.log.apply(console, arguments);
  }

  const _registered_constructors = [];

  class PropertyDescriptor {
    constructor(value, enumerable, writable, configurable, valueIsFactory) {
      this.enumerable = typeof enumerable === 'undefined' ? true : enumerable;
      this.writable = typeof writable === 'undefined' ? true : writable;
      this.configurable = typeof configurable === 'undefined' ? true : configurable;
      const registeredConstructor = SafeObject.getRegisteredConstructor(value);
      if (registeredConstructor) {
        this.value = registeredConstructor.construct.bind(registeredConstructor);
        this.isFactory = true;
      } else {
        this.isFactory = typeof value === 'function' && typeof valueIsFactory === 'undefined' ? true : valueIsFactory || false;
        this.value = value;
      }
    }

    clone() {
      return new PropertyDescriptor(this.value, this.enumerable, this.writable, this.configurable, this.isFactory);
    }

    toObject() {
      return {
        value: this.isFactory ? this.value(this) : this.value,
        enumerable: this.enumerable,
        writable: this.writable,
        configurable: this.configurable
      };
    }
  }

  class RegisteredConstructor {
    constructor(ConstructorFunction) {
      this.ConstructorFunction = ConstructorFunction;
    }
    construct() {
      return new (this.ConstructorFunction)();
    }
  }

  class SafeObject {

    static debug(instance) {
      const buffer = [];
      buffer.push('----- SafeObject debug -----');
      buffer.push('Constructor: ' + String(instance.constructor.name));
      buffer.push('_isSafeObject: ' + String(!!instance._isSafeObject));
      if (instance._isSafeObject) {
        const ancestors = SafeObject.getAncestors(instance);
        buffer.push('Ancestors: ' + ancestors.map(function (d) {return d.name;}).join(' < '));
        const attributeNames = SafeObject.getRegisteredPropertyNames(instance);
        const registeredAttributeNames = instance._getIgnoredSafeObjectPropertyNames().concat(attributeNames);
        const unregisteredAttributeNames = Object.getOwnPropertyNames(instance).filter(function (d)  { return registeredAttributeNames.indexOf(d) === -1; });
        buffer.push('ignored properties: ' + instance._getIgnoredSafeObjectPropertyNames().join(', '));
        buffer.push('registered properties: ' + attributeNames.join(', '));
        buffer.push('unregistered properties: ' + unregisteredAttributeNames.join(', '));
      }
      return buffer.join('\n');
    }

    static include(instance, options = {}) {
      if (SafeObject.isSafeObject(instance)) return instance;
      if (!instance.constructor.INSTANCE_PROPERTIES) {
        instance.constructor.INSTANCE_PROPERTIES = {};
      }
      const instanceProperties = instance.constructor.INSTANCE_PROPERTIES;

      if (!('_isSafeObject' in instanceProperties)) {
        instanceProperties._isSafeObject = new PropertyDescriptor(true, false, false, false);
      }

      [
        { methodName: 'destroy', returnsMerge: 'super' },
        { methodName: '_getIgnoredSafeObjectPropertyNames', returnsMerge: 'concat' }
      ].forEach(function ({ methodName, returnsMerge }) {
        // check if property exists and is a method
        const hasProperty = methodName in instance;
        const isFunction = typeof instance[methodName] === 'function';
        const _superMethod = instance[methodName];
        if (options.force && hasProperty) {
          warn('Overriding ' + methodName + ' method');
        }
        // define the method only if it hasnt the property or 'force' is true
        if (hasProperty && options.force || !hasProperty) {
          if (!(methodName in instanceProperties)) {
            instanceProperties[methodName] = new PropertyDescriptor(
              isFunction ? overrideMethod : SafeObject.prototype[methodName],
              false, true, true, false
            );
          }
        }

        function overrideMethod() {
          const superOut = _superMethod.apply(this, arguments);
          const safeObjectOut = SafeObject.prototype[methodName].call(this);
          let out;
          switch (returnsMerge) {
            case 'super': out = superOut; break;
            case 'concat': out = (superOut || []).concat(safeObjectOut || []); break;
          }
          return out;
        }
      });

      SafeObject.setProperties(instance, SafeObject.SAFE_OBJECT_INITIALIZE, Object.assign(instanceProperties, SafeObject.INSTANCE_PROPERTIES));

      return instance;
    }

    static getRegisteredConstructor(ConstructorFunction) {
      return _registered_constructors.find((d) => { return d.ConstructorFunction === ConstructorFunction; });
    }

    static registerConstructor(ConstructorFunction) {
      _registered_constructors.push(new RegisteredConstructor(ConstructorFunction));
    }

    static unregisterConstructor(ConstructorFunction) {
      const index = _registered_constructors.findIndex((d) => { return d.ConstructorFunction === ConstructorFunction; });
      return _registered_constructors.splice(index, 1)[0];
    }

    static isSafeObject(object) {
      return object && object._isSafeObject === true;
    }

    static getAncestors(object) {
      let current = object.constructor;
      const out = [];
      while (current = Object.getPrototypeOf(current.prototype) ? Object.getPrototypeOf(current.prototype).constructor : null) {
        out.push(current || []);
      }
      return out;
    }

    static getRegisteredProperties(safeObject) {
      const instanceProperties = [ safeObject.constructor ].concat(SafeObject.getAncestors(safeObject)).map(function (Constructor) {
        return Constructor.INSTANCE_PROPERTIES;
      }).reverse();
      instanceProperties.unshift({});
      return Object.assign(...instanceProperties);
    }

    static getUnregisteredPropertyNames(safeObject) {
      const registeredAttributeNames = SafeObject.getRegisteredPropertyNames(safeObject);
      registeredAttributeNames.push.apply(registeredAttributeNames, safeObject._getIgnoredSafeObjectPropertyNames());
      return Object.getOwnPropertyNames(safeObject).filter(function (propertyName)  {
        return registeredAttributeNames.indexOf(propertyName) === -1;
      });
    }

    static getRegisteredPropertyNames(safeObject) {
      return Object.getOwnPropertyNames(SafeObject.getRegisteredProperties(safeObject));
    }

    static setInstanceProperties(safeObject, state) {
      SafeObject.setProperties(safeObject, state, SafeObject.getRegisteredProperties(safeObject));
    }

    static setProperties(object, state, propertyDescriptors) {
      for (const propertyName in propertyDescriptors) {
        try {
          const propertyDescriptor = SafeObject.parsePropertyDescriptor(propertyDescriptors[propertyName]);
          SafeObject.setProperty(object, propertyName, propertyDescriptor, state);
        } catch (err) {
          warn('SafeObject#setProperties: ' + err.toString());
        }
      }
    }

    static setProperty(object, fieldName, propertyDescriptor, state) {
      if (!propertyDescriptor) {
        warn('Property descriptor isnt well formed for ' + String(fieldName) + '.');
        return;
      }
      Object.defineProperty(object, fieldName, propertyDescriptor.toObject());
    }

    static parsePropertyDescriptor(propertyDescriptor) {
      if (!propertyDescriptor || !(propertyDescriptor instanceof PropertyDescriptor)) {
        return new PropertyDescriptor(propertyDescriptor);
      }
      return propertyDescriptor;
    }

    constructor() {
      SafeObject.setInstanceProperties(this, SafeObject.SAFE_OBJECT_INITIALIZE);
      this._isDestroyed = false;
    }

    destroy() {
      SafeObject.setInstanceProperties(this, SafeObject.SAFE_OBJECT_DESTROY);
      this._isDestroyed = true;
    }

    _getIgnoredSafeObjectPropertyNames() {
      return [ '_isDestroyed' ];
    }

  }

  SafeObject.debugMode = false;
  SafeObject.VERSION = '1.2.0';
  SafeObject.SAFE_OBJECT_INITIALIZE = 1;
  SafeObject.SAFE_OBJECT_DESTROY = 2;

  SafeObject.INSTANCE_PROPERTIES = {
    _isSafeObject: new PropertyDescriptor(true, false, false, false)
  };

  SafeObject.PropertyDescriptor = PropertyDescriptor;

  SafeObject.registerConstructor(Object);
  SafeObject.registerConstructor(Array);
  SafeObject.registerConstructor(Date);
  SafeObject.registerConstructor(Map);
  SafeObject.registerConstructor(Set);

  if (typeof define === 'function' && define.amd) {
    define(function () {
      return SafeObject;
    });
  } else if (typeof module !== 'undefined' && module.exports) {
    module.exports = SafeObject;
  } else {
    this[exportName] = SafeObject;
  }
})('SafeObject');

<|endoftext|>


<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'

/**
 * ScrollSync provider component
 *
 */

export default class ScrollSync extends Component {

  static propTypes = {
    children: PropTypes.element.isRequired,
    proportional: PropTypes.bool,
    vertical: PropTypes.bool,
    horizontal: PropTypes.bool
  };

  static defaultProps = {
    proportional: true,
    vertical: true,
    horizontal: true
  };

  static childContextTypes = {
    registerPane: PropTypes.func,
    unregisterPane: PropTypes.func
  }

  getChildContext() {
    return {
      registerPane: this.registerPane,
      unregisterPane: this.unregisterPane
    }
  }

  panes = {}

  registerPane = (node, group) => {
    if (!this.panes[group]) {
      this.panes[group] = []
    }

    if (!this.findPane(node, group)) {
      this.addEvents(node, group)
      this.panes[group].push(node)
    }
  }

  unregisterPane = (node, group) => {
    if (this.findPane(node, group)) {
      this.removeEvents(node)
      this.panes[group].splice(this.panes[group].indexOf(node), 1)
    }
  }

  addEvents = (node, group) => {
    /* For some reason element.addEventListener doesnt work with document.body */
    node.onscroll = this.handlePaneScroll.bind(this, node, group) // eslint-disable-line
  }

  removeEvents = (node) => {
    /* For some reason element.removeEventListener doesnt work with document.body */
    node.onscroll = null // eslint-disable-line
  }

  findPane = (node, group) => {
    if (!this.panes[group]) {
      return false
    }

    return this.panes[group].find(pane => pane === node)
  }

  handlePaneScroll = (node, group) => {
    window.requestAnimationFrame(() => {
      this.syncScrollPositions(node, group)
    })
  }

  syncScrollPositions = (scrolledPane, group) => {
    const {
      scrollTop,
      scrollHeight,
      clientHeight,
      scrollLeft,
      scrollWidth,
      clientWidth
    } = scrolledPane

    const scrollTopOffset = scrollHeight - clientHeight
    const scrollLeftOffset = scrollWidth - clientWidth

    const { proportional, vertical, horizontal } = this.props

    this.panes[group].forEach((pane) => {
      /* For all panes beside the currently scrolling one */
      if (scrolledPane !== pane) {
        /* Remove event listeners from the node that we'll manipulate */
        this.removeEvents(pane, group)
        /* Calculate the actual pane height */
        const paneHeight = pane.scrollHeight - clientHeight
        const paneWidth = pane.scrollWidth - clientWidth
        /* Adjust the scrollTop position of it accordingly */
        if (vertical && scrollTopOffset > 0) {
          pane.scrollTop = proportional ? (paneHeight * scrollTop) / scrollTopOffset : scrollTop // eslint-disable-line
        }
        if (horizontal && scrollLeftOffset > 0) {
          pane.scrollLeft = proportional ? (paneWidth * scrollLeft) / scrollLeftOffset : scrollLeft // eslint-disable-line
        }
        /* Re-attach event listeners after we're done scrolling */
        window.requestAnimationFrame(() => {
          this.addEvents(pane, group)
        })
      }
    })
  }

  render() {
    return React.Children.only(this.props.children)
  }
}
<commit_msg>feat: Sync newly added panes (#17)<commit_after>import React, { Component } from 'react'
import PropTypes from 'prop-types'

/**
 * ScrollSync provider component
 *
 */

export default class ScrollSync extends Component {

  static propTypes = {
    children: PropTypes.element.isRequired,
    proportional: PropTypes.bool,
    vertical: PropTypes.bool,
    horizontal: PropTypes.bool
  };

  static defaultProps = {
    proportional: true,
    vertical: true,
    horizontal: true
  };

  static childContextTypes = {
    registerPane: PropTypes.func,
    unregisterPane: PropTypes.func
  }

  getChildContext() {
    return {
      registerPane: this.registerPane,
      unregisterPane: this.unregisterPane
    }
  }

  panes = {}

  registerPane = (node, group) => {
    if (!this.panes[group]) {
      this.panes[group] = []
    }

    if (!this.findPane(node, group)) {
      if (this.panes[group].length > 0) {
        this.syncScrollPosition(this.panes[group][0], node)
      }
      this.addEvents(node, group)
      this.panes[group].push(node)
    }
  }

  unregisterPane = (node, group) => {
    if (this.findPane(node, group)) {
      this.removeEvents(node)
      this.panes[group].splice(this.panes[group].indexOf(node), 1)
    }
  }

  addEvents = (node, group) => {
    /* For some reason element.addEventListener doesnt work with document.body */
    node.onscroll = this.handlePaneScroll.bind(this, node, group) // eslint-disable-line
  }

  removeEvents = (node) => {
    /* For some reason element.removeEventListener doesnt work with document.body */
    node.onscroll = null // eslint-disable-line
  }

  findPane = (node, group) => {
    if (!this.panes[group]) {
      return false
    }

    return this.panes[group].find(pane => pane === node)
  }

  handlePaneScroll = (node, group) => {
    window.requestAnimationFrame(() => {
      this.syncScrollPositions(node, group)
    })
  }

  syncScrollPosition(scrolledPane, pane) {
    const {
      scrollTop,
      scrollHeight,
      clientHeight,
      scrollLeft,
      scrollWidth,
      clientWidth
    } = scrolledPane

    const scrollTopOffset = scrollHeight - clientHeight
    const scrollLeftOffset = scrollWidth - clientWidth

    const { proportional, vertical, horizontal } = this.props

    /* Calculate the actual pane height */
    const paneHeight = pane.scrollHeight - clientHeight
    const paneWidth = pane.scrollWidth - clientWidth
    /* Adjust the scrollTop position of it accordingly */
    if (vertical && scrollTopOffset > 0) {
      pane.scrollTop = proportional ? (paneHeight * scrollTop) / scrollTopOffset : scrollTop // eslint-disable-line
    }
    if (horizontal && scrollLeftOffset > 0) {
      pane.scrollLeft = proportional ? (paneWidth * scrollLeft) / scrollLeftOffset : scrollLeft // eslint-disable-line
    }
  }

  syncScrollPositions = (scrolledPane, group) => {
    this.panes[group].forEach((pane) => {
      /* For all panes beside the currently scrolling one */
      if (scrolledPane !== pane) {
        /* Remove event listeners from the node that we'll manipulate */
        this.removeEvents(pane, group)
        this.syncScrollPosition(scrolledPane, pane)
        /* Re-attach event listeners after we're done scrolling */
        window.requestAnimationFrame(() => {
          this.addEvents(pane, group)
        })
      }
    })
  }

  render() {
    return React.Children.only(this.props.children)
  }
}
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter;
var _ = require('underscore');
var path = require('path');
var fs = require('fs');
var Promise = require('bluebird');
var machine = require('./DockerMachine');
var virtualBox = require('./VirtualBox');
var setupUtil = require('./SetupUtil');
var util = require('./Util');
var assign = require('object-assign');
var metrics = require('./Metrics');
var bugsnag = require('bugsnag-js');
var rimraf = require('rimraf');

var _currentStep = null;
var _error = null;
var _cancelled = false;
var _retryPromise = null;
var _requiredSteps = [];

var _steps = [{
  name: 'download',
  title: 'Downloading VirtualBox',
  message: 'VirtualBox is being downloaded. Kitematic requires VirtualBox to run containers.',
  totalPercent: 35,
  percent: 0,
  run: function (progressCallback) {
    var packagejson = util.packagejson();
    return setupUtil.download(setupUtil.virtualBoxUrl(), path.join(util.supportDir(), packagejson['virtualbox-filename']), packagejson['virtualbox-checksum'], percent => {
      progressCallback(percent);
    });
  }
}, {
  name: 'install',
  title: 'Installing VirtualBox & Docker',
  message: 'VirtualBox & Docker are being installed or upgraded in the background. We may need you to type in your password to continue.',
  totalPercent: 5,
  percent: 0,
  seconds: 5,
  run: Promise.coroutine(function* (progressCallback) {
    var cmd = setupUtil.copyBinariesCmd() + ' && ' + setupUtil.fixBinariesCmd();
    if (!virtualBox.installed()) {
      yield virtualBox.killall();
      cmd += ' && ' + setupUtil.installVirtualBoxCmd();
    } else {
      if (!setupUtil.needsBinaryFix()) {
        return;
      }
    }
    try {
      progressCallback(50); // TODO: detect when the installation has started so we can simulate progress
      yield util.exec(setupUtil.macSudoCmd(cmd));
    } catch (err) {
      throw null;
    }
  })
}, {
  name: 'init',
  title: 'Starting Docker VM',
  message: 'To run Docker containers on your computer, Kitematic is starting a Linux virutal machine. This may take a minute...',
  totalPercent: 60,
  percent: 0,
  seconds: 53,
  run: Promise.coroutine(function* (progressCallback) {
    setupUtil.simulateProgress(this.seconds, progressCallback);
    yield virtualBox.vmdestroy('kitematic-vm');
    var exists = yield machine.exists();
    if (!exists || (yield machine.state()) === 'Error') {
      try {
        yield machine.rm();
        yield machine.create();
      } catch (err) {
        rimraf.sync(path.join(util.home(), '.docker', 'machine', 'machines', machine.name()));
        yield machine.create();
      }
      return;
    }

    var isoversion = machine.isoversion();
    var packagejson = util.packagejson();
    if (!isoversion || setupUtil.compareVersions(isoversion, packagejson['docker-version']) < 0) {
      yield machine.stop();
      yield machine.upgrade();
    }
    yield machine.start();
  })
}];

var SetupStore = assign(Object.create(EventEmitter.prototype), {
  PROGRESS_EVENT: 'setup_progress',
  STEP_EVENT: 'setup_step',
  ERROR_EVENT: 'setup_error',
  step: function () {
    return _currentStep;
  },
  steps: function () {
    return _.indexBy(_steps, 'name');
  },
  stepCount: function () {
    return _requiredSteps.length;
  },
  number: function () {
    return _.indexOf(_requiredSteps, _currentStep) + 1;
  },
  percent: function () {
    var sofar = 0;
    var totalPercent = _requiredSteps.reduce((prev, step) => prev + step.totalPercent, 0);
    _.each(_requiredSteps, step => {
      sofar += step.totalPercent * step.percent / 100;
    });
    return Math.min(Math.round(100 * sofar / totalPercent), 99);
  },
  error: function () {
    return _error;
  },
  setError: function (error) {
    _error = error;
    this.emit(this.ERROR_EVENT);
  },
  cancelled: function () {
    return _cancelled;
  },
  retry: function () {
    _error = null;
    _cancelled = false;
    if (_retryPromise) {
      _retryPromise.resolve();
    }
  },
  pause: function () {
    _retryPromise = Promise.defer();
    return _retryPromise.promise;
  },
  requiredSteps: Promise.coroutine(function* () {
    if (_requiredSteps.length) {
      return Promise.resolve(_requiredSteps);
    }
    var packagejson = util.packagejson();
    var isoversion = machine.isoversion();
    var required = {};
    var vboxfile = path.join(util.supportDir(), packagejson['virtualbox-filename']);
    var vboxNeedsInstall = !virtualBox.installed();
    required.download = vboxNeedsInstall && (!fs.existsSync(vboxfile) || setupUtil.checksum(vboxfile) !== packagejson['virtualbox-checksum']);
    required.install = vboxNeedsInstall || setupUtil.needsBinaryFix();
    required.init = required.install || !(yield machine.exists()) || (yield machine.state()) !== 'Running' || !isoversion || setupUtil.compareVersions(isoversion, packagejson['docker-version']) < 0;

    var exists = yield machine.exists();
    if (isoversion && setupUtil.compareVersions(isoversion, packagejson['docker-version']) < 0) {
      this.steps().init.seconds = 33;
    } else if (exists && (yield machine.state()) !== 'Error') {
      this.steps().init.seconds = 23;
    }

    _requiredSteps = _steps.filter(function (step) {
      return required[step.name];
    });
    return Promise.resolve(_requiredSteps);
  }),
  updateBinaries: function () {
    if (setupUtil.needsBinaryFix()) {
      return Promise.resolve();
    }
    if (setupUtil.shouldUpdateBinaries()) {
      return util.exec(setupUtil.copyBinariesCmd());
    }
    return Promise.resolve();
  },
  run: Promise.coroutine(function* () {
    metrics.track('Started Setup', {
      virtualbox: virtualBox.installed() ? yield virtualBox.version() : 'Not Installed'
    });
    yield this.updateBinaries();
    var steps = yield this.requiredSteps();
    for (let step of steps) {
      console.log(step.name);
      _currentStep = step;
      step.percent = 0;
      while (true) {
        try {
          this.emit(this.STEP_EVENT);
          yield step.run(percent => {
            if (_currentStep) {
              step.percent = percent;
              this.emit(this.PROGRESS_EVENT);
            }
          });
          metrics.track('Setup Completed Step', {
            name: step.name
          });
          step.percent = 100;
          break;
        } catch (err) {
          if (err) {
            console.log('Setup encountered an error.');
            console.log(err);
            console.log(err.stack);
            metrics.track('Setup Failed', {
              step: step.name
            });
            var virtualboxVersion = virtualBox.installed() ? yield virtualBox.version() : 'Not installed';
            bugsnag.notify('SetupError', 'Setup failed', {
              error: err,
              step: step.name,
              virtualbox: virtualboxVersion
            });
            _error = err;
            this.emit(this.ERROR_EVENT);
          } else {
            metrics.track('Setup Cancelled');
            _cancelled = true;
            this.emit(this.STEP_EVENT);
          }
          yield this.pause();
        }
      }
    }
    _currentStep = null;
    return yield machine.info();
  }),
  setup: Promise.coroutine(function * () {
    while (true) {
      var info = yield this.run();
      if (!info.url) {
        metrics.track('Setup Failed', {
          step: 'done',
          message: 'Machine URL not set'
        });
        var virtualboxVersion = virtualBox.installed() ? yield virtualBox.version() : 'Not installed';
        bugsnag.notify('SetupError', 'Machine url was not set', {
          machine: info,
          step: 'done',
          virtualbox: virtualboxVersion
        });
        SetupStore.setError('Could not reach the Docker Engine inside the VirtualBox VM');
        yield this.pause();
      } else {
        metrics.track('Setup Finished');
        return info;
      }
    }
  })
});

module.exports = SetupStore;
<commit_msg>Fixed typo.<commit_after>var EventEmitter = require('events').EventEmitter;
var _ = require('underscore');
var path = require('path');
var fs = require('fs');
var Promise = require('bluebird');
var machine = require('./DockerMachine');
var virtualBox = require('./VirtualBox');
var setupUtil = require('./SetupUtil');
var util = require('./Util');
var assign = require('object-assign');
var metrics = require('./Metrics');
var bugsnag = require('bugsnag-js');
var rimraf = require('rimraf');

var _currentStep = null;
var _error = null;
var _cancelled = false;
var _retryPromise = null;
var _requiredSteps = [];

var _steps = [{
  name: 'download',
  title: 'Downloading VirtualBox',
  message: 'VirtualBox is being downloaded. Kitematic requires VirtualBox to run containers.',
  totalPercent: 35,
  percent: 0,
  run: function (progressCallback) {
    var packagejson = util.packagejson();
    return setupUtil.download(setupUtil.virtualBoxUrl(), path.join(util.supportDir(), packagejson['virtualbox-filename']), packagejson['virtualbox-checksum'], percent => {
      progressCallback(percent);
    });
  }
}, {
  name: 'install',
  title: 'Installing VirtualBox & Docker',
  message: 'VirtualBox & Docker are being installed or upgraded in the background. We may need you to type in your password to continue.',
  totalPercent: 5,
  percent: 0,
  seconds: 5,
  run: Promise.coroutine(function* (progressCallback) {
    var cmd = setupUtil.copyBinariesCmd() + ' && ' + setupUtil.fixBinariesCmd();
    if (!virtualBox.installed()) {
      yield virtualBox.killall();
      cmd += ' && ' + setupUtil.installVirtualBoxCmd();
    } else {
      if (!setupUtil.needsBinaryFix()) {
        return;
      }
    }
    try {
      progressCallback(50); // TODO: detect when the installation has started so we can simulate progress
      yield util.exec(setupUtil.macSudoCmd(cmd));
    } catch (err) {
      throw null;
    }
  })
}, {
  name: 'init',
  title: 'Starting Docker VM',
  message: 'To run Docker containers on your computer, Kitematic is starting a Linux virtual machine. This may take a minute...',
  totalPercent: 60,
  percent: 0,
  seconds: 53,
  run: Promise.coroutine(function* (progressCallback) {
    setupUtil.simulateProgress(this.seconds, progressCallback);
    yield virtualBox.vmdestroy('kitematic-vm');
    var exists = yield machine.exists();
    if (!exists || (yield machine.state()) === 'Error') {
      try {
        yield machine.rm();
        yield machine.create();
      } catch (err) {
        rimraf.sync(path.join(util.home(), '.docker', 'machine', 'machines', machine.name()));
        yield machine.create();
      }
      return;
    }

    var isoversion = machine.isoversion();
    var packagejson = util.packagejson();
    if (!isoversion || setupUtil.compareVersions(isoversion, packagejson['docker-version']) < 0) {
      yield machine.stop();
      yield machine.upgrade();
    }
    yield machine.start();
  })
}];

var SetupStore = assign(Object.create(EventEmitter.prototype), {
  PROGRESS_EVENT: 'setup_progress',
  STEP_EVENT: 'setup_step',
  ERROR_EVENT: 'setup_error',
  step: function () {
    return _currentStep;
  },
  steps: function () {
    return _.indexBy(_steps, 'name');
  },
  stepCount: function () {
    return _requiredSteps.length;
  },
  number: function () {
    return _.indexOf(_requiredSteps, _currentStep) + 1;
  },
  percent: function () {
    var sofar = 0;
    var totalPercent = _requiredSteps.reduce((prev, step) => prev + step.totalPercent, 0);
    _.each(_requiredSteps, step => {
      sofar += step.totalPercent * step.percent / 100;
    });
    return Math.min(Math.round(100 * sofar / totalPercent), 99);
  },
  error: function () {
    return _error;
  },
  setError: function (error) {
    _error = error;
    this.emit(this.ERROR_EVENT);
  },
  cancelled: function () {
    return _cancelled;
  },
  retry: function () {
    _error = null;
    _cancelled = false;
    if (_retryPromise) {
      _retryPromise.resolve();
    }
  },
  pause: function () {
    _retryPromise = Promise.defer();
    return _retryPromise.promise;
  },
  requiredSteps: Promise.coroutine(function* () {
    if (_requiredSteps.length) {
      return Promise.resolve(_requiredSteps);
    }
    var packagejson = util.packagejson();
    var isoversion = machine.isoversion();
    var required = {};
    var vboxfile = path.join(util.supportDir(), packagejson['virtualbox-filename']);
    var vboxNeedsInstall = !virtualBox.installed();
    required.download = vboxNeedsInstall && (!fs.existsSync(vboxfile) || setupUtil.checksum(vboxfile) !== packagejson['virtualbox-checksum']);
    required.install = vboxNeedsInstall || setupUtil.needsBinaryFix();
    required.init = required.install || !(yield machine.exists()) || (yield machine.state()) !== 'Running' || !isoversion || setupUtil.compareVersions(isoversion, packagejson['docker-version']) < 0;

    var exists = yield machine.exists();
    if (isoversion && setupUtil.compareVersions(isoversion, packagejson['docker-version']) < 0) {
      this.steps().init.seconds = 33;
    } else if (exists && (yield machine.state()) !== 'Error') {
      this.steps().init.seconds = 23;
    }

    _requiredSteps = _steps.filter(function (step) {
      return required[step.name];
    });
    return Promise.resolve(_requiredSteps);
  }),
  updateBinaries: function () {
    if (setupUtil.needsBinaryFix()) {
      return Promise.resolve();
    }
    if (setupUtil.shouldUpdateBinaries()) {
      return util.exec(setupUtil.copyBinariesCmd());
    }
    return Promise.resolve();
  },
  run: Promise.coroutine(function* () {
    metrics.track('Started Setup', {
      virtualbox: virtualBox.installed() ? yield virtualBox.version() : 'Not Installed'
    });
    yield this.updateBinaries();
    var steps = yield this.requiredSteps();
    for (let step of steps) {
      console.log(step.name);
      _currentStep = step;
      step.percent = 0;
      while (true) {
        try {
          this.emit(this.STEP_EVENT);
          yield step.run(percent => {
            if (_currentStep) {
              step.percent = percent;
              this.emit(this.PROGRESS_EVENT);
            }
          });
          metrics.track('Setup Completed Step', {
            name: step.name
          });
          step.percent = 100;
          break;
        } catch (err) {
          if (err) {
            console.log('Setup encountered an error.');
            console.log(err);
            console.log(err.stack);
            metrics.track('Setup Failed', {
              step: step.name
            });
            var virtualboxVersion = virtualBox.installed() ? yield virtualBox.version() : 'Not installed';
            bugsnag.notify('SetupError', 'Setup failed', {
              error: err,
              step: step.name,
              virtualbox: virtualboxVersion
            });
            _error = err;
            this.emit(this.ERROR_EVENT);
          } else {
            metrics.track('Setup Cancelled');
            _cancelled = true;
            this.emit(this.STEP_EVENT);
          }
          yield this.pause();
        }
      }
    }
    _currentStep = null;
    return yield machine.info();
  }),
  setup: Promise.coroutine(function * () {
    while (true) {
      var info = yield this.run();
      if (!info.url) {
        metrics.track('Setup Failed', {
          step: 'done',
          message: 'Machine URL not set'
        });
        var virtualboxVersion = virtualBox.installed() ? yield virtualBox.version() : 'Not installed';
        bugsnag.notify('SetupError', 'Machine url was not set', {
          machine: info,
          step: 'done',
          virtualbox: virtualboxVersion
        });
        SetupStore.setError('Could not reach the Docker Engine inside the VirtualBox VM');
        yield this.pause();
      } else {
        metrics.track('Setup Finished');
        return info;
      }
    }
  })
});

module.exports = SetupStore;
<|endoftext|>


<commit_before>SpriteList = (function() {
  function constructor() {
    this.sprites = [];
  }

  constructor.prototype = {
    draw: function() {
      for (var i = 0; i < this.sprites.length; i++) {
        if (this.sprites[i]) {
          this.sprites[i].draw();
        }
      }
    },

    push: function(newSprite) {
      this.sprites.push(newSprite);
    },

    remove: function(sprite) {
      var index = this.sprites.indexOf(sprite);
      this.sprites.splice(index, 1);
    }
  };

  return constructor;
})();
<commit_msg>Implemented SpriteList.getLength().<commit_after>SpriteList = (function() {
  function constructor() {
    this.sprites = [];
  }

  constructor.prototype = {
    draw: function() {
      for (var i = 0; i < this.sprites.length; i++) {
        if (this.sprites[i]) {
          this.sprites[i].draw();
        }
      }
    },

    push: function(newSprite) {
      this.sprites.push(newSprite);
    },

    remove: function(sprite) {
      var index = this.sprites.indexOf(sprite);
      this.sprites.splice(index, 1);
    },

    getLength: function() {
      return this.sprites.length;
    }
  };

  return constructor;
})();
<|endoftext|>


<commit_before>'use strict';

var Thermostat = function() {
  this.temperature = 20;
  this.MIN_TEMPERATURE_LIMIT = 10;
};
Thermostat.prototype.getTemperature = function() { return this.temperature; };

Thermostat.prototype.isMinimumTemperature = function() {
  return this.temperature === this.MIN_TEMPERATURE_LIMIT;
};

Thermostat.prototype.up = function() {
  this.temperature += 1;
};
Thermostat.prototype.down = function() {
  if (this.isMinimumTemperature()) {
    return;
  }
  this.temperature -= 1;
};
<commit_msg>Thermostat: Implement maximum temperature of 25 degrees<commit_after>'use strict';

var Thermostat = function() {
  this.temperature = 20;
  this.MIN_TEMPERATURE_LIMIT = 10;
  this.MAX_TEMPERATURE_LIMIT = 25;
};
Thermostat.prototype.getTemperature = function() { return this.temperature; };

Thermostat.prototype.isMinimumTemperature = function() {
  return this.temperature === this.MIN_TEMPERATURE_LIMIT;
};

Thermostat.prototype.isMaximumTemperature = function() {
  return this.temperature === this.MAX_TEMPERATURE_LIMIT;
};

Thermostat.prototype.up = function() {
  if (this.isMaximumTemperature()) {
    return;
  }
  this.temperature += 1;
};
Thermostat.prototype.down = function() {
  if (this.isMinimumTemperature()) {
    return;
  }
  this.temperature -= 1;
};
<|endoftext|>


<commit_before>let path = require('path');
let objectValues = require('lodash').values;
let File = require('./File');

class Versioning {
    /**
     * Create a new Versioning instance.
     *
     * @param {Array}  manualFiles
     * @param {object} manifest
     * @param {string} publicPath
     */
    constructor(manualFiles = [], manifest, publicPath) {
        this.manualFiles = manualFiles.map(file => new File(file));
        this.manifest = manifest;
        this.publicPath = publicPath;
    }

    /**
     * Register a watcher for any files that aren't
     * included in Webpack's core bundle process.
     */
    watch() {
        if (! process.argv.includes('--watch')) return this;

        this.manualFiles.forEach(file => {
            file.watch(file => {
                // Delete the old versioned file.
                File.find(
                    path.join(this.publicPath, this.manifest.get(file))
                ).delete();

                // And then whip up a new one.
                file.version();

                this.prune();
            });
        });

        return this;
    }

    /**
     * Create all hashed files requested by the user,
     * when they called mix.version(['file']);
     */
    writeHashedFiles() {
        this.manualFiles.forEach(file => file.version());

        return this;
    }

    /**
     * The user may optionally add extra files to be
     * versioned. Here, we'll manually add those to
     * Mix's manifest file.
     */
    addManualFilesToManifest() {
        this.manualFiles.forEach(file => this.manifest.add(file));
    }

    /**
     * Replace all old hashed files with the new versions.
     */
    prune() {
        this.writeHashedFiles().addManualFilesToManifest();

        let cachedFiles = objectValues(this.manifest.cache);
        let currentFiles = objectValues(this.manifest.get());

        cachedFiles
            .filter(file => ! currentFiles.includes(file))
            .map(file => {
                return file.startsWith(this.publicPath)
                    ? file
                    : path.join(this.publicPath, file);
            })
            .forEach(file => this.manifest.remove(file));

        this.manifest.refresh();
        this.manifest.cache = currentFiles;

        return currentFiles;
    }
}

module.exports = Versioning;
<commit_msg>Fixed issue where zero based indexes will appear in manifest file<commit_after>let path = require('path');
let objectValues = require('lodash').values;
let File = require('./File');

class Versioning {
    /**
     * Create a new Versioning instance.
     *
     * @param {Array}  manualFiles
     * @param {object} manifest
     * @param {string} publicPath
     */
    constructor(manualFiles = [], manifest, publicPath) {
        this.manualFiles = manualFiles.map(file => new File(file));
        this.manifest = manifest;
        this.publicPath = publicPath;
    }

    /**
     * Register a watcher for any files that aren't
     * included in Webpack's core bundle process.
     */
    watch() {
        if (! process.argv.includes('--watch')) return this;

        this.manualFiles.forEach(file => {
            file.watch(file => {
                // Delete the old versioned file.
                File.find(
                    path.join(this.publicPath, this.manifest.get(file))
                ).delete();

                // And then whip up a new one.
                file.version();

                this.prune();
            });
        });

        return this;
    }

    /**
     * Create all hashed files requested by the user,
     * when they called mix.version(['file']);
     */
    writeHashedFiles() {
        this.manualFiles.forEach(file => file.version());

        return this;
    }

    /**
     * The user may optionally add extra files to be
     * versioned. Here, we'll manually add those to
     * Mix's manifest file.
     */
    addManualFilesToManifest() {
        this.manualFiles.forEach(file => this.manifest.add(file));
    }

    /**
     * Replace all old hashed files with the new versions.
     */
    prune() {
        this.writeHashedFiles().addManualFilesToManifest();

        let cachedFiles = objectValues(this.manifest.cache);
        let currentFiles = objectValues(this.manifest.get());

        cachedFiles
            .filter(file => ! currentFiles.includes(file))
            .map(file => {
                return file.startsWith(this.publicPath)
                    ? file
                    : path.join(this.publicPath, file);
            })
            .forEach(file => this.manifest.remove(file));

        this.manifest.refresh();
        this.manifest.cache = this.manifest.get();

        return currentFiles;
    }
}

module.exports = Versioning;
<|endoftext|>


<commit_before>/**
 * @file Tabs component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component, Fragment, createRef} from 'react';
import PropTypes from 'prop-types';

// Components
import {DragDropContext, Droppable} from 'react-beautiful-dnd';
import IconButton from '../IconButton';
import TabsButton from '../_TabButton';

// Statics
import Position from '../_statics/Position';
import Direction from '../_statics/Direction';

// Vendors
import classNames from 'classnames';
import Event from '../_vendors/Event';
import ScrollBar from '../_vendors/ScrollBar';

class Tabs extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.tabs = createRef();
        this.tabsEl = null;

        this.tabsScrollTimeout = null;

        this.state = {
            isTabsOverflow: false
        };

    }

    isTabsOverflow = () => {

        if (!this.tabsEl) {
            return false;
        }

        const scrollEl = this.tabsEl.querySelector('.tab-buttons-wrapper');

        if (!scrollEl) {
            return false;
        }

        return Math.floor(this.tabsEl.offsetWidth) < Math.floor(scrollEl.offsetWidth);

    };

    getScrollerStyle = () => {

        const horizontalScrollBarSize = ScrollBar.getSize(Direction.HORIZONTAL);

        if (!horizontalScrollBarSize || horizontalScrollBarSize <= 0) {
            return null;
        }

        return {
            height: `calc(100% + ${horizontalScrollBarSize}px)`,
            marginBottom: -horizontalScrollBarSize,
            paddingBottom: 0
        };

    };

    getInkBarStyle = () => {

        if (!this.tabsEl) {
            return null;
        }

        const tabs = this.tabsEl.querySelectorAll('.tab-buttons .tab-button');

        if (!tabs || tabs.length < 1) {
            return null;
        }

        const {activatedIndex} = this.props,
            activatedtab = tabs[activatedIndex];

        return activatedtab ? {
                width: activatedtab.offsetWidth,
                left: activatedtab.offsetLeft
            }
            :
            null;
    };

    handleTabsScroll = (direction, keepScrolling) => {

        if (!this.tabsEl) {
            return;
        }

        const {scrollStep, scrollInterval, keepScrollingWait} = this.props;

        this.tabsEl.scrollLeft += (direction === Position.LEFT ? -1 : 1) * scrollStep;

        this.clearTabsScrollTimeout();
        this.tabsScrollTimeout = setTimeout(() => {
            this.handleTabsScroll(direction, true);
        }, keepScrolling === true ? scrollInterval : keepScrollingWait);

    };

    tabsScrollLeft = e => {

        this.handleTabsScroll(Position.LEFT);

        const {onScrollLeftButtonMouseDown} = this.props;
        onScrollLeftButtonMouseDown && onScrollLeftButtonMouseDown(e);

    };

    tabsScrollRight = e => {

        this.handleTabsScroll(Position.RIGHT);

        const {onScrollRightButtonMouseDown} = this.props;
        onScrollRightButtonMouseDown && onScrollRightButtonMouseDown(e);

    };

    clearTabsScrollTimeout = () => {
        this.tabsScrollTimeout && clearTimeout(this.tabsScrollTimeout);
    };

    handleTabsOverflowChange = () => {
        const {isTabsOverflow, onTabsOverflowChange} = this.props;
        if (onTabsOverflowChange && isTabsOverflow !== this.isTabsOverflow()) {
            onTabsOverflowChange(!isTabsOverflow);
        }
    };

    componentDidMount() {

        this.tabsEl = this.tabs && this.tabs.current;

        Event.addEvent(window, 'resize', this.handleTabsOverflowChange);
        Event.addEvent(document, 'mouseup', this.clearTabsScrollTimeout);

        this.handleTabsOverflowChange();

    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        this.handleTabsOverflowChange();
    }

    componentWillUnmount() {
        Event.removeEvent(window, 'resize', this.handleTabsOverflowChange);
        Event.removeEvent(document, 'mouseup', this.clearTabsScrollTimeout);
    }

    render() {

        const {
                children, className, style, isTabFullWidth, isInkBarHidden,
                data, activatedIndex, isTabsOverflow, draggable, idProp,
                scrollLeftIconCls, scrollRightIconCls,
                onTabMouseDown, onTabMouseUp, onTabClick, onTabButtonDragStart, onTabButtonDragEnd
            } = this.props,

            scrollerStyle = this.getScrollerStyle(),
            inkBarStyle = this.getInkBarStyle();

        return (
            <DragDropContext onDragStart={onTabButtonDragStart}
                             onDragEnd={onTabButtonDragEnd}>

                        <Droppable droppableId="droppable"
                                   direction="horizontal">
                            {
                                dropProvided => (

                                            {
                                                data && data.map((item, index) => {

                                                    const {

                                                        // not passing down these props
                                                        tabContentRenderer, onActive,

                                                        ...restProps

                                                    } = item;

                                                    return (
                                                        <TabsButton {...restProps}
                                                                    key={idProp && item[idProp] || index}
                                                                    style={{width: isTabFullWidth ? `${100 / data.length}%` : 'auto'}}
                                                                    data={item}
                                                                    index={index}
                                                                    isTabFullWidth={isTabFullWidth}
                                                                    activated={activatedIndex === index}
                                                                    draggable={draggable}
                                                                    onMouseDown={onTabMouseDown}
                                                                    onMouseUp={onTabMouseUp}
                                                                    onClick={onTabClick}/>
                                                    );

                                                })
                                            }

                                            {dropProvided.placeholder}

                                )
                            }
                        </Droppable>

                        {
                            !isInkBarHidden && inkBarStyle ?
                                <div className="ink-bar"
                                     style={{
                                         bottom: scrollerStyle ? 0 : 20,
                                         width: inkBarStyle.width,
                                         transform: `translate(${inkBarStyle.left}px, 0)`
                                     }}>

                                :
                                null
                        }

                        {children}

                    {
                        isTabsOverflow ?
                            <Fragment>
                                <IconButton className="tab-button tab-scroll-left-button"
                                            iconCls={scrollLeftIconCls}
                                            onMouseDown={this.tabsScrollLeft}/>
                                <IconButton className="tab-button tab-scroll-right-button"
                                            iconCls={scrollRightIconCls}
                                            onMouseDown={this.tabsScrollRight}/>
                            </Fragment>
                            :
                            null
                    }

            </DragDropContext>
        );

    }
}

Tabs.propTypes = {

    children: PropTypes.any,

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Children passed into the TabsItem.
     */
    data: PropTypes.arrayOf(PropTypes.shape({

        /**
         * The text value of the tab.Type can be string or number.
         */
        value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

        /**
         * If true, the tab will be disabled.
         */
        disabled: PropTypes.bool,

        /**
         * If true,the tab will be have loading effect.
         */
        isLoading: PropTypes.bool,

        /**
         * If true,the element's ripple effect will be disabled.
         */
        disableTouchRipple: PropTypes.bool,

        /**
         * Use this property to display an icon.It will display on the left.
         */
        iconCls: PropTypes.string,

        /**
         * The position of the icon.
         */
        iconPosition: PropTypes.string,

        /**
         * The render of tab button.
         */
        renderer: PropTypes.any,

        /**
         * The render content in tab.
         */
        tabContentRenderer: PropTypes.any,

        /**
         * Callback function fired when click onActive tab.
         */
        onActive: PropTypes.func

    })).isRequired,

    /**
     * Activated tab index.
     */
    activatedIndex: PropTypes.number,

    /**
     * If true,the data is FullWidth.
     */
    isTabFullWidth: PropTypes.bool,

    isInkBarHidden: PropTypes.bool,
    isTabsOverflow: PropTypes.bool,
    draggable: PropTypes.bool,

    idProp: PropTypes.string,

    scrollLeftIconCls: PropTypes.string,
    scrollRightIconCls: PropTypes.string,
    scrollStep: PropTypes.number,
    scrollInterval: PropTypes.number,
    keepScrollingWait: PropTypes.number,

    onTabClick: PropTypes.func,
    onTabMouseDown: PropTypes.func,
    onTabMouseUp: PropTypes.func,
    onTabsOverflowChange: PropTypes.func,
    onTabButtonDragStart: PropTypes.func,
    onTabButtonDragEnd: PropTypes.func,
    onScrollLeftButtonMouseDown: PropTypes.func,
    onScrollRightButtonMouseDown: PropTypes.func

};

Tabs.defaultProps = {

    data: [],

    activatedIndex: 0,
    isTabFullWidth: true,
    isInkBarHidden: false,
    draggable: false,

    scrollLeftIconCls: 'fas fa-chevron-left',
    scrollRightIconCls: 'fas fa-chevron-right',
    scrollStep: 100,
    scrollInterval: 100,
    keepScrollingWait: 250

};

export default Tabs;
<commit_msg>update Tabs<commit_after>/**
 * @file Tabs component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component, Fragment, createRef} from 'react';
import PropTypes from 'prop-types';

// Components
import {DragDropContext, Droppable} from 'react-beautiful-dnd';
import IconButton from '../IconButton';
import TabsButton from '../_TabButton';

// Statics
import Position from '../_statics/Position';
import Direction from '../_statics/Direction';

// Vendors
import classNames from 'classnames';
import Event from '../_vendors/Event';
import ScrollBar from '../_vendors/ScrollBar';

class Tabs extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.tabs = createRef();
        this.tabsEl = null;
        this.scrollLeftButton = createRef();
        this.scrollRightButton = createRef();

        this.tabsScrollTimeout = null;

        this.state = {
            scrollLeft: 0
        };

    }

    isTabsOverflow = () => {

        if (!this.tabsEl) {
            return false;
        }

        const scrollEl = this.tabsEl.querySelector('.tab-buttons-wrapper');

        if (!scrollEl) {
            return false;
        }

        return Math.floor(this.tabsEl.offsetWidth) < Math.floor(scrollEl.offsetWidth);

    };

    isScrollLeftButtonDisabled = scrollLeft => {
        return scrollLeft <= 0;
    };

    isScrollRightButtonDisabled = scrollLeft => {

        if (!this.tabsEl) {
            return false;
        }

        return scrollLeft >= this.tabsEl.scrollWidth - this.tabsEl.offsetWidth;

    };

    getScrollerStyle = () => {

        const horizontalScrollBarSize = ScrollBar.getSize(Direction.HORIZONTAL);

        if (!horizontalScrollBarSize || horizontalScrollBarSize <= 0) {
            return null;
        }

        return {
            height: `calc(100% + ${horizontalScrollBarSize}px)`,
            marginBottom: -horizontalScrollBarSize,
            paddingBottom: 0
        };

    };

    getInkBarStyle = () => {

        if (!this.tabsEl) {
            return null;
        }

        const tabs = this.tabsEl.querySelectorAll('.tab-buttons .tab-button');

        if (!tabs || tabs.length < 1) {
            return null;
        }

        const {activatedIndex} = this.props,
            activatedtab = tabs[activatedIndex];

        return activatedtab ? {
                width: activatedtab.offsetWidth,
                left: activatedtab.offsetLeft
            }
            :
            null;
    };

    handleOnTabsScroll = e => {
        this.setState({
            scrollLeft: e.target.scrollLeft
        });
    };

    handleTabsScroll = (direction, keepScrolling) => {

        if (!this.tabsEl) {
            return;
        }

        const {scrollStep, scrollInterval, keepScrollingWait} = this.props;

        this.tabsEl.scrollLeft += (direction === Position.LEFT ? -1 : 1) * scrollStep;

        this.setState({
            scrollLeft: this.tabsEl.scrollLeft
        });

        this.clearTabsScrollTimeout();
        this.tabsScrollTimeout = setTimeout(() => {
            this.handleTabsScroll(direction, true);
        }, keepScrolling === true ? scrollInterval : keepScrollingWait);

    };

    tabsScrollLeft = e => {

        this.handleTabsScroll(Position.LEFT);

        const {onScrollLeftButtonMouseDown} = this.props;
        onScrollLeftButtonMouseDown && onScrollLeftButtonMouseDown(e);

    };

    tabsScrollRight = e => {

        this.handleTabsScroll(Position.RIGHT);

        const {onScrollRightButtonMouseDown} = this.props;
        onScrollRightButtonMouseDown && onScrollRightButtonMouseDown(e);

    };

    clearTabsScrollTimeout = () => {
        this.tabsScrollTimeout && clearTimeout(this.tabsScrollTimeout);
    };

    handleTabsOverflowChange = () => {

        const {isTabsOverflow, onTabsOverflowChange} = this.props,
            current = this.isTabsOverflow();

        if (current !== isTabsOverflow) {

            if (current && this.tabsEl) {
                this.setState({
                    scrollLeft: this.tabsEl.scrollLeft
                });
            }

            onTabsOverflowChange && onTabsOverflowChange(!isTabsOverflow);

        }

    };

    componentDidMount() {

        this.tabsEl = this.tabs && this.tabs.current;

        Event.addEvent(window, 'resize', this.handleTabsOverflowChange);
        Event.addEvent(document, 'mouseup', this.clearTabsScrollTimeout);

        this.handleTabsOverflowChange();

    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        this.handleTabsOverflowChange();
    }

    componentWillUnmount() {
        Event.removeEvent(window, 'resize', this.handleTabsOverflowChange);
        Event.removeEvent(document, 'mouseup', this.clearTabsScrollTimeout);
    }

    render() {

        const {
                children, className, style, isTabFullWidth, isInkBarHidden,
                data, activatedIndex, isTabsOverflow, draggable, idProp,
                scrollLeftIconCls, scrollRightIconCls,
                onTabMouseDown, onTabMouseUp, onTabClick, onTabButtonDragStart, onTabButtonDragEnd
            } = this.props,
            {scrollLeft} = this.state,

            scrollerStyle = this.getScrollerStyle(),
            inkBarStyle = this.getInkBarStyle();

        return (
            <DragDropContext onDragStart={onTabButtonDragStart}
                             onDragEnd={onTabButtonDragEnd}>

                        <Droppable droppableId="droppable"
                                   direction="horizontal">
                            {
                                dropProvided => (

                                            {
                                                data && data.map((item, index) => {

                                                    const {

                                                        // not passing down these props
                                                        tabContentRenderer, onActive,

                                                        ...restProps

                                                    } = item;

                                                    return (
                                                        <TabsButton {...restProps}
                                                                    key={idProp && item[idProp] || index}
                                                                    style={{width: isTabFullWidth ? `${100 / data.length}%` : 'auto'}}
                                                                    data={item}
                                                                    index={index}
                                                                    isTabFullWidth={isTabFullWidth}
                                                                    activated={activatedIndex === index}
                                                                    draggable={draggable}
                                                                    onMouseDown={onTabMouseDown}
                                                                    onMouseUp={onTabMouseUp}
                                                                    onClick={onTabClick}/>
                                                    );

                                                })
                                            }

                                            {dropProvided.placeholder}

                                )
                            }
                        </Droppable>

                        {
                            !isInkBarHidden && inkBarStyle ?
                                <div className="ink-bar"
                                     style={{
                                         bottom: scrollerStyle ? 0 : 20,
                                         width: inkBarStyle.width,
                                         transform: `translate(${inkBarStyle.left}px, 0)`
                                     }}>

                                :
                                null
                        }

                        {children}

                    {
                        isTabsOverflow ?
                            <Fragment>
                                <IconButton ref={this.scrollLeftButton}
                                            className="tab-button tab-scroll-left-button"
                                            iconCls={scrollLeftIconCls}
                                            disabled={this.isScrollLeftButtonDisabled(scrollLeft)}
                                            onMouseDown={this.tabsScrollLeft}/>
                                <IconButton ref={this.scrollRightButton}
                                            className="tab-button tab-scroll-right-button"
                                            iconCls={scrollRightIconCls}
                                            disabled={this.isScrollRightButtonDisabled(scrollLeft)}
                                            onMouseDown={this.tabsScrollRight}/>
                            </Fragment>
                            :
                            null
                    }

            </DragDropContext>
        );

    }
}

Tabs.propTypes = {

    children: PropTypes.any,

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Children passed into the TabsItem.
     */
    data: PropTypes.arrayOf(PropTypes.shape({

        /**
         * The text value of the tab.Type can be string or number.
         */
        value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

        /**
         * If true, the tab will be disabled.
         */
        disabled: PropTypes.bool,

        /**
         * If true,the tab will be have loading effect.
         */
        isLoading: PropTypes.bool,

        /**
         * If true,the element's ripple effect will be disabled.
         */
        disableTouchRipple: PropTypes.bool,

        /**
         * Use this property to display an icon.It will display on the left.
         */
        iconCls: PropTypes.string,

        /**
         * The position of the icon.
         */
        iconPosition: PropTypes.string,

        /**
         * The render of tab button.
         */
        renderer: PropTypes.any,

        /**
         * The render content in tab.
         */
        tabContentRenderer: PropTypes.any,

        /**
         * Callback function fired when click onActive tab.
         */
        onActive: PropTypes.func

    })).isRequired,

    /**
     * Activated tab index.
     */
    activatedIndex: PropTypes.number,

    /**
     * If true,the data is FullWidth.
     */
    isTabFullWidth: PropTypes.bool,

    isInkBarHidden: PropTypes.bool,
    isTabsOverflow: PropTypes.bool,
    draggable: PropTypes.bool,

    idProp: PropTypes.string,

    scrollLeftIconCls: PropTypes.string,
    scrollRightIconCls: PropTypes.string,
    scrollStep: PropTypes.number,
    scrollInterval: PropTypes.number,
    keepScrollingWait: PropTypes.number,

    onTabClick: PropTypes.func,
    onTabMouseDown: PropTypes.func,
    onTabMouseUp: PropTypes.func,
    onTabsOverflowChange: PropTypes.func,
    onTabButtonDragStart: PropTypes.func,
    onTabButtonDragEnd: PropTypes.func,
    onScrollLeftButtonMouseDown: PropTypes.func,
    onScrollRightButtonMouseDown: PropTypes.func

};

Tabs.defaultProps = {

    data: [],

    activatedIndex: 0,
    isTabFullWidth: true,
    isInkBarHidden: false,
    draggable: false,

    scrollLeftIconCls: 'fas fa-chevron-left',
    scrollRightIconCls: 'fas fa-chevron-right',
    scrollStep: 100,
    scrollInterval: 100,
    keepScrollingWait: 250

};

export default Tabs;
<|endoftext|>


<commit_before>/*
 * Handles making the request to the Riot API servers, with simple error handling for the response.
 * Checks rate limits as defined in the configuration. Tracks regions and their information.
 */

const Client = require("node-rest-client").Client,
	  cache = require("./cache").engine,
	  log = require("../util/log")("RiotAPI", "magenta"),
	  RateLimiter = require("limiter").RateLimiter;

let limiters = [],
	request_queue = [],
	request_counter = -1,
	config;

const regionData = {
	"na": {
		host: "na1.api.riotgames.com",
		id: "NA1"
	},
	"eune": {
		host: "eun1.api.riotgames.com",
		id: "EUN1"
	},
	"euw": {
		host: "euw1.api.riotgames.com",
		id: "EUW1"
	},
	"oce": {
		host: "oc1.api.riotgames.com",
		id: "OC1"
	},
	"br": {
		host: "br1.api.riotgames.com",
		id: "BR1"
	},
	"jp": {
		host: "jp1.api.riotgames.com",
		id: "JP1"
	},
	"kr": {
		host: "kr.api.riotgames.com",
		id: "KR"
	},
	"lan": {
		host: "la1.api.riotgames.com",
		id: "LA1"
	},
	"las": {
		host: "la2.api.riotgames.com",
		id: "LA2"
	},
	"tr": {
		host: "tr1.api.riotgames.com",
		id: "TR1"
	},
	"ru": {
		host: "ru.api.riotgames.com",
		id: "RU"
	},
	"pbe": {
		host: "pbe1.api.riotgames.com",
		id: "PBE1"
	}
};

module.exports.regions = regionData;

const client = new Client({
	requestConfig: {
		timeout: 3000,
		noDelay: true
	},
	responseConfig: {
		timeout: 15000
	}
});

module.exports.request = (callback, info) => {
	function retrieve(callback) {
		let args = {
			path: info.pathParameters || {},
			parameters: info.queryParameters || {}
		}, key;

		for(key in args.path)
			if(args.path[key] === undefined)
				delete args.path[key];

		for(key in args.parameters)
			if(args.parameters[key] === undefined)
				delete args.parameters[key];

		args.parameters.api_key = config.get("credentials.riot_api_key");

		let req = client[info.method || "get"](info.fullPath || "https://" + regionData[info.region].host + info.path, args, (data, response) => {
			log.info("API Request: " + info.path);
			if(response.statusCode !== 200) {
				const callbackReply = {
					type: "error",
					code: response.statusCode
				};

				switch(response.statusCode) {
					case 400:
						callbackReply.text = "Bad request.";
					break;
					case 403:
						callbackReply.text = "Authorization failure.";
						log.warn("Warning: Received an authentication error from Riot's API servers. Make sure your API key is correct.");
					break;
					case 404:
						callbackReply.text = "Resource not found.";
					break;
					case 429:
						return setTimeout(() => retrieve(callback), (response.headers["Retry-After"] * 1000));
					break;
					case 500:
						callbackReply.text = "The API encountered an internal server error.";
					break;
				}

				callback(callbackReply);
			} else
				callback(data);
		});

		req.on("requestTimeout", (req) => {
			callback({
				type: "error",
				text: "The request timed out before it could be executed. This implies an error with the machine - check you have available sockets."
			});
			req.abort();
		});

		req.on("responseTimeout", (res) => {
			callback({
				type: "error",
				text: "The request to the API server timed out. You can check the status of pvp.net servers at http://status.leagueoflegends.com/."
			});
		});

		req.on("error", (err) => {
			callback({
				type: "error",
				text: "Internal error before the request could be made: " + err
			});
		});
	};

	function check_limiter(request_counter, engine_callback) {
		for(let limiter of limiters)
			limiter.removeTokens(1, () => {
				if(--request_queue[request_counter] === 0) {
					retrieve((data) => {
						engine_callback(data);
					});
					delete request_queue[request_counter];
				}
			});
	}

	let add_to_limiter = (engine_callback) => {
		request_counter++;
		request_queue[request_counter] = limiters.length;

		check_limiter(request_counter, engine_callback);
	};

	if(info.cache && info.cache.enabled)
		cache.hitOr(callback, info.cache, add_to_limiter);
	else
		retrieve((data) => {
			callback(data);
		});
};

module.exports.init = appConfig => {
	config = appConfig;
	for(let condition of config.get("rate_limiting"))
		limiters.push(new RateLimiter(condition.requests, condition.reset * 1000));
};<commit_msg>Better path logging<commit_after>/*
 * Handles making the request to the Riot API servers, with simple error handling for the response.
 * Checks rate limits as defined in the configuration. Tracks regions and their information.
 */

const Client = require("node-rest-client").Client,
	  cache = require("./cache").engine,
	  colors = require("colors"),
	  log = require("../util/log")("RiotAPI", "magenta"),
	  RateLimiter = require("limiter").RateLimiter;

let limiters = [],
	request_queue = [],
	request_counter = -1,
	config;

const regionData = {
	"na": {
		host: "na1.api.riotgames.com",
		id: "NA1"
	},
	"eune": {
		host: "eun1.api.riotgames.com",
		id: "EUN1"
	},
	"euw": {
		host: "euw1.api.riotgames.com",
		id: "EUW1"
	},
	"oce": {
		host: "oc1.api.riotgames.com",
		id: "OC1"
	},
	"br": {
		host: "br1.api.riotgames.com",
		id: "BR1"
	},
	"jp": {
		host: "jp1.api.riotgames.com",
		id: "JP1"
	},
	"kr": {
		host: "kr.api.riotgames.com",
		id: "KR"
	},
	"lan": {
		host: "la1.api.riotgames.com",
		id: "LA1"
	},
	"las": {
		host: "la2.api.riotgames.com",
		id: "LA2"
	},
	"tr": {
		host: "tr1.api.riotgames.com",
		id: "TR1"
	},
	"ru": {
		host: "ru.api.riotgames.com",
		id: "RU"
	},
	"pbe": {
		host: "pbe1.api.riotgames.com",
		id: "PBE1"
	}
};

module.exports.regions = regionData;

const client = new Client({
	requestConfig: {
		timeout: 3000,
		noDelay: true
	},
	responseConfig: {
		timeout: 15000
	}
});

module.exports.request = (callback, info) => {
	function retrieve(callback) {
		let args = {
			path: info.pathParameters || {},
			parameters: info.queryParameters || {}
		}, key;

		for(key in args.path)
			if(args.path[key] === undefined)
				delete args.path[key];

		for(key in args.parameters)
			if(args.parameters[key] === undefined)
				delete args.parameters[key];

		args.parameters.api_key = config.get("credentials.riot_api_key");

		let req = client[info.method || "get"](info.fullPath || "https://" + regionData[info.region].host + info.path, args, (data, response) => {
			let path = function(str) {
				return eval(str.replace("${", "${this."));
			}.call(info.pathParameters, '`' + info.path + '`');

			log.info(`Request for ${path.cyan}`);

			if(response.statusCode !== 200) {
				const callbackReply = {
					type: "error",
					code: response.statusCode
				};

				switch(response.statusCode) {
					case 400:
						callbackReply.text = "Bad request.";
					break;
					case 403:
						callbackReply.text = "Authorization failure.";
						log.warn("Warning: Received an authentication error from Riot's API servers. Make sure your API key is correct.");
					break;
					case 404:
						callbackReply.text = "Resource not found.";
					break;
					case 429:
						return setTimeout(() => retrieve(callback), (response.headers["Retry-After"] * 1000));
					break;
					case 500:
						callbackReply.text = "The API encountered an internal server error.";
					break;
				}

				callback(callbackReply);
			} else
				callback(data);
		});

		req.on("requestTimeout", (req) => {
			callback({
				type: "error",
				text: "The request timed out before it could be executed. This implies an error with the machine - check you have available sockets."
			});
			req.abort();
		});

		req.on("responseTimeout", (res) => {
			callback({
				type: "error",
				text: "The request to the API server timed out. You can check the status of pvp.net servers at http://status.leagueoflegends.com/."
			});
		});

		req.on("error", (err) => {
			callback({
				type: "error",
				text: "Internal error before the request could be made: " + err
			});
		});
	};

	function check_limiter(request_counter, engine_callback) {
		for(let limiter of limiters)
			limiter.removeTokens(1, () => {
				if(--request_queue[request_counter] === 0) {
					retrieve((data) => {
						engine_callback(data);
					});
					delete request_queue[request_counter];
				}
			});
	}

	let add_to_limiter = (engine_callback) => {
		request_counter++;
		request_queue[request_counter] = limiters.length;

		check_limiter(request_counter, engine_callback);
	};

	if(info.cache && info.cache.enabled)
		cache.hitOr(callback, info.cache, add_to_limiter);
	else
		retrieve((data) => {
			callback(data);
		});
};

module.exports.init = appConfig => {
	config = appConfig;
	for(let condition of config.get("rate_limiting"))
		limiters.push(new RateLimiter(condition.requests, condition.reset * 1000));
};<|endoftext|>


<commit_before>import Node from "./node";
import {SourceNode} from "source-map";

export default class Script extends Node {
	get reactive() { return true; }

	compile(data) {
		this.start(data);
		this._normalize_indent();

		let line = this._line || 1;
		let column = this._column || 1;

		this.value.split(/\r?\n/g).forEach((l, i) => {
			this.push(new SourceNode(i + line, i === 0 ? column : 1, data.originalFilename, l + "\n"));
		});

		return this.end();
	}
}
<commit_msg>scripts with src attributes become regular script tags<commit_after>import {forEach} from "lodash";
import Node from "./node";
import {SourceNode} from "source-map";

export default class Script extends Node {
	get reactive() { return true; }

	compile(data) {
		this.start(data);

		let attrs = this.attributes.reduce((m,a) => {
			switch (a.type) {
				case "empty":
					m[a.name] = true;
					break;

				case "string":
					m[a.name] = a.value;
					break;
			}

			return m;
		}, {});

		if (attrs.src) {
			this.write(`(function(){`).indent();
			this.write(`var script = document.createElement("script");`);
			forEach(attrs, (v,n) => {
				this.write(`script[${JSON.stringify(n)}] = ${JSON.stringify(v)};`);
			});
			this.write(`document.head.appendChild(script);`);
			this.outdent().write(`}());`);
		} else {
			this._normalize_indent();
			let line = this._line || 1;
			let column = this._column || 1;

			this.value.split(/\r?\n/g).forEach((l, i) => {
				this.push(new SourceNode(i + line, i === 0 ? column : 1, data.originalFilename, l + "\n"));
			});
		}

		return this.end();
	}
}
<|endoftext|>


<commit_before>/* eslint-disable no-underscore-dangle */

import qs from 'query-string';

import { API_URL } from 'fm3/backendDefinitions';

import { setHomeLocation, startProgress, stopProgress } from 'fm3/actions/mainActions';
import { toastsAdd, toastsAddError } from 'fm3/actions/toastsActions';
import { authSetUser } from 'fm3/actions/authActions';

export default function initAuthHelper(store) {
  window.addEventListener('message', (e) => {
    if (e.origin !== location.origin || typeof e.data !== 'object' || !e.data.__freemap || !e.data.__freemap.oauthParams) {
      return;
    }

    const { oauth_token: token, oauth_verifier: verifier } = qs.parse(e.data.__freemap.oauthParams);

    const pid = Math.random();
    store.dispatch(startProgress(pid));
    fetch(`${API_URL}/auth/login2`, {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ token, verifier }),
    })
      .then((res) => {
        if (res.status !== 200) {
          throw new Error(`Server vrátil neočakávaný status: ${res.status}`);
        } else {
          return res.json();
        }
      })
      .then((data) => {
        localStorage.setItem('authToken', data.authToken);

        if (!store.getState().main.homeLocation) {
          store.dispatch(setHomeLocation({ lat: data.lat, lon: data.lon }));
        }

        store.dispatch(toastsAdd({
          collapseKey: 'login',
          message: 'Boli ste úspešne prihlásený.',
          style: 'info',
          timeout: 5000,
        }));
        store.dispatch(authSetUser(data));
      })
      .catch((err) => {
        store.dispatch(toastsAddError(`Nepodarilo sa prihlásiť: ${err.message}`));
      })
      .then(() => {
        store.dispatch(stopProgress(pid));
      });
  });
}
<commit_msg>added authToken validation<commit_after>/* eslint-disable no-underscore-dangle */

import qs from 'query-string';

import { API_URL } from 'fm3/backendDefinitions';

import { setHomeLocation, startProgress, stopProgress } from 'fm3/actions/mainActions';
import { toastsAdd, toastsAddError } from 'fm3/actions/toastsActions';
import { authSetUser } from 'fm3/actions/authActions';

export default function initAuthHelper(store) {
  const authToken = localStorage.getItem('authToken');

  if (authToken) {
    const pid = Math.random();
    store.dispatch(startProgress(pid));
    fetch(`${API_URL}/auth/validate`, {
      method: 'POST',
      headers: {
        Accept: 'applicaction/json',
        Authorization: `Bearer ${authToken}`,
      },
    })
      .then((res) => {
        if (res.status !== 200) {
          throw new Error(`Server vrátil neočakávaný status: ${res.status}`);
        } else {
          return res.json();
        }
      })
      .then((data) => {
        store.dispatch(authSetUser(data));
      })
      .catch((err) => {
        store.dispatch(toastsAddError(`Nepodarilo sa prihlásiť: ${err.message}`));
      })
      .then(() => {
        store.dispatch(stopProgress(pid));
      });
  }

  window.addEventListener('message', (e) => {
    if (e.origin !== location.origin || typeof e.data !== 'object' || !e.data.__freemap || !e.data.__freemap.oauthParams) {
      return;
    }

    const { oauth_token: token, oauth_verifier: verifier } = qs.parse(e.data.__freemap.oauthParams);

    const pid = Math.random();
    store.dispatch(startProgress(pid));
    fetch(`${API_URL}/auth/login2`, {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ token, verifier }),
    })
      .then((res) => {
        if (res.status !== 200) {
          throw new Error(`Server vrátil neočakávaný status: ${res.status}`);
        } else {
          return res.json();
        }
      })
      .then((data) => {
        localStorage.setItem('authToken', data.authToken);

        if (!store.getState().main.homeLocation) {
          store.dispatch(setHomeLocation({ lat: data.lat, lon: data.lon }));
        }

        store.dispatch(toastsAdd({
          collapseKey: 'login',
          message: 'Boli ste úspešne prihlásený.',
          style: 'info',
          timeout: 5000,
        }));
        store.dispatch(authSetUser(data));
      })
      .catch((err) => {
        store.dispatch(toastsAddError(`Nepodarilo sa prihlásiť: ${err.message}`));
      })
      .then(() => {
        store.dispatch(stopProgress(pid));
      });
  });
}
<|endoftext|>


<commit_before>// ugly chrome compatibility layer
if (typeof browser === 'undefined') {
  var browser = chrome;
}

// notify content script
function insertLoremIpsum(fillAllFields = false) {
  browser.tabs.query({active: true, currentWindow: true}, (tabs) => {
    if (fillAllFields === true) {
      browser.tabs.sendMessage(tabs[0].id, {status: 'insertLoremIpsum', fillAllFields: true});
    } else {
      browser.tabs.sendMessage(tabs[0].id, {status: 'insertLoremIpsum', fillAllFields: false});
    }
  });
}

// register hotkey
browser.commands.onCommand.addListener((command) => {
  if (command === 'insert-lorem-ipsum') {
    insertLoremIpsum();
  }
});

// create context menus
browser.contextMenus.create({
  id: 'contextmenuInsertLoremIpsumSingleField',
  title: browser.i18n.getMessage('contextmenuInsertLoremIpsumSingleField'),
  contexts: ['editable'],
  onclick: () => {
    insertLoremIpsum();
  }
});
browser.contextMenus.create({
  id: 'contextmenuInsertLoremIpsumAllFields',
  title: browser.i18n.getMessage('contextmenuInsertLoremIpsumAllFields'),
  contexts: ['editable'],
  onclick: () => {
    insertLoremIpsum(true);
  }
});
<commit_msg>improved annotation and reduced code<commit_after>// ugly chrome compatibility layer
if (typeof browser === 'undefined') {
  var browser = chrome;
}

/**
 * notify the content script to insert the lorem ipsum.
 * optionally notifiy if all fields of the form should be filled.
 *
 * @param fillAllFields
 */
function insertLoremIpsum(fillAllFields = false) {
  browser.tabs.query({active: true, currentWindow: true}, (tabs) => {
    browser.tabs.sendMessage(tabs[0].id, {status: 'insertLoremIpsum', fillAllFields});
  });
}

// register hotkey
browser.commands.onCommand.addListener((command) => {
  if (command === 'insert-lorem-ipsum') {
    insertLoremIpsum();
  }
});

// create context menus
browser.contextMenus.create({
  id: 'contextmenuInsertLoremIpsumSingleField',
  title: browser.i18n.getMessage('contextmenuInsertLoremIpsumSingleField'),
  contexts: ['editable'],
  onclick: () => {
    insertLoremIpsum();
  }
});
browser.contextMenus.create({
  id: 'contextmenuInsertLoremIpsumAllFields',
  title: browser.i18n.getMessage('contextmenuInsertLoremIpsumAllFields'),
  contexts: ['editable'],
  onclick: () => {
    insertLoremIpsum(true);
  }
});
<|endoftext|>