<commit_before>(function() {

  /* _FROM_SVG_START_ */
  function getColorStop(el) {
    var style = el.getAttribute('style'),
        offset = el.getAttribute('offset'),
        color, opacity;

    // convert percents to absolute values
    offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);

    if (style) {
      var keyValuePairs = style.split(/\s*;\s*/);

      if (keyValuePairs[keyValuePairs.length - 1] === '') {
        keyValuePairs.pop();
      }

      for (var i = keyValuePairs.length; i--; ) {

        var split = keyValuePairs[i].split(/\s*:\s*/),
            key = split[0].trim(),
            value = split[1].trim();

        if (key === 'stop-color') {
          color = value;
        }
        else if (key === 'stop-opacity') {
          opacity = value;
        }
      }
    }

    if (!color) {
      color = el.getAttribute('stop-color') || 'rgb(0,0,0)';
    }
    if (!opacity) {
      opacity = el.getAttribute('stop-opacity');
    }

    // convert rgba color to rgb color - alpha value has no affect in svg
    color = new fabric.Color(color).toRgb();

    return {
      offset: offset,
      color: color,
      opacity: isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity)
    };
  }

  function getLinearCoords(el) {
    return {
      x1: el.getAttribute('x1') || 0,
      y1: el.getAttribute('y1') || 0,
      x2: el.getAttribute('x2') || '100%',
      y2: el.getAttribute('y2') || 0
    };
  }

  function getRadialCoords(el) {
    return {
      x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',
      y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',
      r1: 0,
      x2: el.getAttribute('cx') || '50%',
      y2: el.getAttribute('cy') || '50%',
      r2: el.getAttribute('r') || '50%'
    };
  }
  /* _FROM_SVG_END_ */

  /**
   * Gradient class
   * @class fabric.Gradient
   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#gradients}
   * @see {@link fabric.Gradient#initialize} for constructor definition
   */
  fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {

    origX: 0,

    origY: 0,
    /**
     * Constructor
     * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops
     * @return {fabric.Gradient} thisArg
     */
    initialize: function(options) {
      options || (options = { });

      var coords = { };

      this.id = fabric.Object.__uid++;
      this.type = options.type || 'linear';

      coords = {
        x1: options.coords.x1 || 0,
        y1: options.coords.y1 || 0,
        x2: options.coords.x2 || 0,
        y2: options.coords.y2 || 0
      };

      if (this.type === 'radial') {
        coords.r1 = options.coords.r1 || 0;
        coords.r2 = options.coords.r2 || 0;
      }

      this.coords = coords;
      this.gradientUnits = options.gradientUnits || 'objectBoundingBox';
      this.colorStops = options.colorStops.slice();
      if (options.gradientTransform) {
        this.gradientTransform = options.gradientTransform;
      }
      this.origX = options.left;
      this.orgiY = options.top;
    },

    /**
     * Adds another colorStop
     * @param {Object} colorStop Object with offset and color
     * @return {fabric.Gradient} thisArg
     */
    addColorStop: function(colorStop) {
      for (var position in colorStop) {
        var color = new fabric.Color(colorStop[position]);
        this.colorStops.push({
          offset: position,
          color: color.toRgb(),
          opacity: color.getAlpha()
        });
      }
      return this;
    },

    /**
     * Returns object representation of a gradient
     * @return {Object}
     */
    toObject: function() {
      return {
        type: this.type,
        coords: this.coords,
        gradientUnits: this.gradientUnits,
        colorStops: this.colorStops
      };
    },

    /* _TO_SVG_START_ */
    /**
     * Returns SVG representation of an gradient
     * @param {Object} object Object to create a gradient for
     * @param {Boolean} normalize Whether coords should be normalized
     * @return {String} SVG representation of an gradient (linear/radial)
     */
    toSVG: function(object, normalize) {
      var coords = fabric.util.object.clone(this.coords),
          markup, commonMarkup;

      // colorStops must be sorted ascending
      this.colorStops.sort(function(a, b) {
        return a.offset - b.offset;
      });

      if (normalize && this.gradientUnits === 'userSpaceOnUse') {
        coords.x1 += object.width / 2;
        coords.y1 += object.height / 2;
        coords.x2 += object.width / 2;
        coords.y2 += object.height / 2;
      }
      else if (this.gradientUnits === 'objectBoundingBox') {
        _convertValuesToPercentUnits(object, coords);
      }
      commonMarkup = 'id="SVGID_' + this.id +
                     '" gradientUnits="' + this.gradientUnits + '"';
      if (this.gradientTransform) {
        commonMarkup += ' gradientTransform="matrix(' + this.gradientTransform.join(' ') + ')" ';
      }
      if (this.type === 'linear') {
        markup = [
          //jscs:disable validateIndentation
          '<linearGradient ',
            commonMarkup,
            ' x1="', coords.x1,
            '" y1="', coords.y1,
            '" x2="', coords.x2,
            '" y2="', coords.y2,
          '">\n'
          //jscs:enable validateIndentation
        ];
      }
      else if (this.type === 'radial') {
        markup = [
          //jscs:disable validateIndentation
          '<radialGradient ',
            commonMarkup,
            ' cx="', coords.x2,
            '" cy="', coords.y2,
            '" r="', coords.r2,
            '" fx="', coords.x1,
            '" fy="', coords.y1,
          '">\n'
          //jscs:enable validateIndentation
        ];
      }

      for (var i = 0; i < this.colorStops.length; i++) {
        markup.push(
          //jscs:disable validateIndentation
          '<stop ',
            'offset="', (this.colorStops[i].offset * 100) + '%',
            '" style="stop-color:', this.colorStops[i].color,
            (this.colorStops[i].opacity != null ? ';stop-opacity: ' + this.colorStops[i].opacity : ';'),
          '"/>\n'
          //jscs:enable validateIndentation
        );
      }

      markup.push((this.type === 'linear' ? '</linearGradient>\n' : '</radialGradient>\n'));

      return markup.join('');
    },
    /* _TO_SVG_END_ */

    /**
     * Returns an instance of CanvasGradient
     * @param {CanvasRenderingContext2D} ctx Context to render on
     * @return {CanvasGradient}
     */
    toLive: function(ctx) {
      var gradient;

      if (!this.type) {
        return;
      }

      if (this.type === 'linear') {
        gradient = ctx.createLinearGradient(
          this.coords.x1, this.coords.y1, this.coords.x2, this.coords.y2);
      }
      else if (this.type === 'radial') {
        gradient = ctx.createRadialGradient(
          this.coords.x1, this.coords.y1, this.coords.r1, this.coords.x2, this.coords.y2, this.coords.r2);
      }

      for (var i = 0, len = this.colorStops.length; i < len; i++) {
        var color = this.colorStops[i].color,
            opacity = this.colorStops[i].opacity,
            offset = this.colorStops[i].offset;

        if (typeof opacity !== 'undefined') {
          color = new fabric.Color(color).setAlpha(opacity).toRgba();
        }
        gradient.addColorStop(parseFloat(offset), color);
      }

      return gradient;
    }
  });

  fabric.util.object.extend(fabric.Gradient, {

    /* _FROM_SVG_START_ */
    /**
     * Returns {@link fabric.Gradient} instance from an SVG element
     * @static
     * @memberof fabric.Gradient
     * @param {SVGGradientElement} el SVG gradient element
     * @param {fabric.Object} instance
     * @return {fabric.Gradient} Gradient instance
     * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement
     * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement
     */
    fromElement: function(el, instance) {

      /**
       *  @example:
       *
       *  <linearGradient id="linearGrad1">
       *    <stop offset="0%" stop-color="white"/>
       *    <stop offset="100%" stop-color="black"/>
       *  </linearGradient>
       *
       *  OR
       *
       *  <linearGradient id="linearGrad2">
       *    <stop offset="0" style="stop-color:rgb(255,255,255)"/>
       *    <stop offset="1" style="stop-color:rgb(0,0,0)"/>
       *  </linearGradient>
       *
       *  OR
       *
       *  <radialGradient id="radialGrad1">
       *    <stop offset="0%" stop-color="white" stop-opacity="1" />
       *    <stop offset="50%" stop-color="black" stop-opacity="0.5" />
       *    <stop offset="100%" stop-color="white" stop-opacity="1" />
       *  </radialGradient>
       *
       *  OR
       *
       *  <radialGradient id="radialGrad2">
       *    <stop offset="0" stop-color="rgb(255,255,255)" />
       *    <stop offset="0.5" stop-color="rgb(0,0,0)" />
       *    <stop offset="1" stop-color="rgb(255,255,255)" />
       *  </radialGradient>
       *
       */

      var colorStopEls = el.getElementsByTagName('stop'),
          type = (el.nodeName === 'linearGradient' ? 'linear' : 'radial'),
          gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',
          gradientTransform = el.getAttribute('gradientTransform'),
          colorStops = [],
          coords = { };

      if (type === 'linear') {
        coords = getLinearCoords(el);
      }
      else if (type === 'radial') {
        coords = getRadialCoords(el);
      }

      for (var i = colorStopEls.length; i--; ) {
        colorStops.push(getColorStop(colorStopEls[i]));
      }

      _convertPercentUnitsToValues(instance, coords);

      var gradient = new fabric.Gradient({
        type: type,
        coords: coords,
        gradientUnits: gradientUnits,
        colorStops: colorStops
      });

      if (gradientTransform) {
        gradient.gradientTransform = fabric.parseTransformAttribute(gradientTransform);
      }

      return gradient;
    },
    /* _FROM_SVG_END_ */

    /**
     * Returns {@link fabric.Gradient} instance from its object representation
     * @static
     * @memberof fabric.Gradient
     * @param {Object} obj
     * @param {Object} [options] Options object
     */
    forObject: function(obj, options) {
      options || (options = { });
      _convertPercentUnitsToValues(obj, options);
      return new fabric.Gradient(options);
    }
  });

  /**
   * @private
   */
  function _convertPercentUnitsToValues(object, options) {
    for (var prop in options) {
      if (typeof options[prop] === 'string' && /^\d+%$/.test(options[prop])) {
        var percents = parseFloat(options[prop], 10);
        if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
          options[prop] = fabric.util.toFixed(object.width * percents / 100, 2)  + object.left;
        }
        else if (prop === 'y1' || prop === 'y2') {
          options[prop] = fabric.util.toFixed(object.height * percents / 100, 2) + object.top;
        }
      }
    }
  }

  /* _TO_SVG_START_ */
  /**
   * @private
   */
  function _convertValuesToPercentUnits(object, options) {
    for (var prop in options) {
      //convert to percent units
      if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
        options[prop] = fabric.util.toFixed((options[prop] - object.origX) / object.width * 100, 2) + '%';
      }
      else if (prop === 'y1' || prop === 'y2') {
        options[prop] = fabric.util.toFixed((options[prop] - object.origY) / object.height * 100, 2) + '%';
      }
    }
  }
  /* _TO_SVG_END_ */

})();
<commit_msg>Update gradient.class.js<commit_after>(function() {

  /* _FROM_SVG_START_ */
  function getColorStop(el) {
    var style = el.getAttribute('style'),
        offset = el.getAttribute('offset'),
        color, opacity;

    // convert percents to absolute values
    offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);

    if (style) {
      var keyValuePairs = style.split(/\s*;\s*/);

      if (keyValuePairs[keyValuePairs.length - 1] === '') {
        keyValuePairs.pop();
      }

      for (var i = keyValuePairs.length; i--; ) {

        var split = keyValuePairs[i].split(/\s*:\s*/),
            key = split[0].trim(),
            value = split[1].trim();

        if (key === 'stop-color') {
          color = value;
        }
        else if (key === 'stop-opacity') {
          opacity = value;
        }
      }
    }

    if (!color) {
      color = el.getAttribute('stop-color') || 'rgb(0,0,0)';
    }
    if (!opacity) {
      opacity = el.getAttribute('stop-opacity');
    }

    // convert rgba color to rgb color - alpha value has no affect in svg
    color = new fabric.Color(color).toRgb();

    return {
      offset: offset,
      color: color,
      opacity: isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity)
    };
  }

  function getLinearCoords(el) {
    return {
      x1: el.getAttribute('x1') || 0,
      y1: el.getAttribute('y1') || 0,
      x2: el.getAttribute('x2') || '100%',
      y2: el.getAttribute('y2') || 0
    };
  }

  function getRadialCoords(el) {
    return {
      x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',
      y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',
      r1: 0,
      x2: el.getAttribute('cx') || '50%',
      y2: el.getAttribute('cy') || '50%',
      r2: el.getAttribute('r') || '50%'
    };
  }
  /* _FROM_SVG_END_ */

  /**
   * Gradient class
   * @class fabric.Gradient
   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#gradients}
   * @see {@link fabric.Gradient#initialize} for constructor definition
   */
  fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {
    /*
     * Stores the original position of the gradient when we convert from % to fixed values,
     * On objectBoundingBox case. We could you object.left and top, but those are  subject
     * to change, and we need the original value when exporting back to SVG.
     */
    origX: 0,

    /*
     * Stores the original position of the gradient when we convert from % to fixed values,
     * On objectBoundingBox case. We could you object.left and top, but those are  subject
     * to change, and we need the original value when exporting back to SVG.
     */
    origY: 0,

    /**
     * Constructor
     * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops
     * @return {fabric.Gradient} thisArg
     */
    initialize: function(options) {
      options || (options = { });

      var coords = { };

      this.id = fabric.Object.__uid++;
      this.type = options.type || 'linear';

      coords = {
        x1: options.coords.x1 || 0,
        y1: options.coords.y1 || 0,
        x2: options.coords.x2 || 0,
        y2: options.coords.y2 || 0
      };

      if (this.type === 'radial') {
        coords.r1 = options.coords.r1 || 0;
        coords.r2 = options.coords.r2 || 0;
      }

      this.coords = coords;
      this.gradientUnits = options.gradientUnits || 'objectBoundingBox';
      this.colorStops = options.colorStops.slice();
      if (options.gradientTransform) {
        this.gradientTransform = options.gradientTransform;
      }
      this.origX = options.left;
      this.orgiY = options.top;
    },

    /**
     * Adds another colorStop
     * @param {Object} colorStop Object with offset and color
     * @return {fabric.Gradient} thisArg
     */
    addColorStop: function(colorStop) {
      for (var position in colorStop) {
        var color = new fabric.Color(colorStop[position]);
        this.colorStops.push({
          offset: position,
          color: color.toRgb(),
          opacity: color.getAlpha()
        });
      }
      return this;
    },

    /**
     * Returns object representation of a gradient
     * @return {Object}
     */
    toObject: function() {
      return {
        type: this.type,
        coords: this.coords,
        gradientUnits: this.gradientUnits,
        colorStops: this.colorStops
      };
    },

    /* _TO_SVG_START_ */
    /**
     * Returns SVG representation of an gradient
     * @param {Object} object Object to create a gradient for
     * @param {Boolean} normalize Whether coords should be normalized
     * @return {String} SVG representation of an gradient (linear/radial)
     */
    toSVG: function(object, normalize) {
      var coords = fabric.util.object.clone(this.coords),
          markup, commonAttributes;

      // colorStops must be sorted ascending
      this.colorStops.sort(function(a, b) {
        return a.offset - b.offset;
      });

      if (normalize && this.gradientUnits === 'userSpaceOnUse') {
        coords.x1 += object.width / 2;
        coords.y1 += object.height / 2;
        coords.x2 += object.width / 2;
        coords.y2 += object.height / 2;
      }
      else if (this.gradientUnits === 'objectBoundingBox') {
        _convertValuesToPercentUnits(object, coords);
      }
      commonAttributes = 'id="SVGID_' + this.id +
                     '" gradientUnits="' + this.gradientUnits + '"';
      if (this.gradientTransform) {
        commonAttributes += ' gradientTransform="matrix(' + this.gradientTransform.join(' ') + ')" ';
      }
      if (this.type === 'linear') {
        markup = [
          //jscs:disable validateIndentation
          '<linearGradient ',
            commonAttributes,
            ' x1="', coords.x1,
            '" y1="', coords.y1,
            '" x2="', coords.x2,
            '" y2="', coords.y2,
          '">\n'
          //jscs:enable validateIndentation
        ];
      }
      else if (this.type === 'radial') {
        markup = [
          //jscs:disable validateIndentation
          '<radialGradient ',
            commonAttributes,
            ' cx="', coords.x2,
            '" cy="', coords.y2,
            '" r="', coords.r2,
            '" fx="', coords.x1,
            '" fy="', coords.y1,
          '">\n'
          //jscs:enable validateIndentation
        ];
      }

      for (var i = 0; i < this.colorStops.length; i++) {
        markup.push(
          //jscs:disable validateIndentation
          '<stop ',
            'offset="', (this.colorStops[i].offset * 100) + '%',
            '" style="stop-color:', this.colorStops[i].color,
            (this.colorStops[i].opacity != null ? ';stop-opacity: ' + this.colorStops[i].opacity : ';'),
          '"/>\n'
          //jscs:enable validateIndentation
        );
      }

      markup.push((this.type === 'linear' ? '</linearGradient>\n' : '</radialGradient>\n'));

      return markup.join('');
    },
    /* _TO_SVG_END_ */

    /**
     * Returns an instance of CanvasGradient
     * @param {CanvasRenderingContext2D} ctx Context to render on
     * @return {CanvasGradient}
     */
    toLive: function(ctx) {
      var gradient;

      if (!this.type) {
        return;
      }

      if (this.type === 'linear') {
        gradient = ctx.createLinearGradient(
          this.coords.x1, this.coords.y1, this.coords.x2, this.coords.y2);
      }
      else if (this.type === 'radial') {
        gradient = ctx.createRadialGradient(
          this.coords.x1, this.coords.y1, this.coords.r1, this.coords.x2, this.coords.y2, this.coords.r2);
      }

      for (var i = 0, len = this.colorStops.length; i < len; i++) {
        var color = this.colorStops[i].color,
            opacity = this.colorStops[i].opacity,
            offset = this.colorStops[i].offset;

        if (typeof opacity !== 'undefined') {
          color = new fabric.Color(color).setAlpha(opacity).toRgba();
        }
        gradient.addColorStop(parseFloat(offset), color);
      }

      return gradient;
    }
  });

  fabric.util.object.extend(fabric.Gradient, {

    /* _FROM_SVG_START_ */
    /**
     * Returns {@link fabric.Gradient} instance from an SVG element
     * @static
     * @memberof fabric.Gradient
     * @param {SVGGradientElement} el SVG gradient element
     * @param {fabric.Object} instance
     * @return {fabric.Gradient} Gradient instance
     * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement
     * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement
     */
    fromElement: function(el, instance) {

      /**
       *  @example:
       *
       *  <linearGradient id="linearGrad1">
       *    <stop offset="0%" stop-color="white"/>
       *    <stop offset="100%" stop-color="black"/>
       *  </linearGradient>
       *
       *  OR
       *
       *  <linearGradient id="linearGrad2">
       *    <stop offset="0" style="stop-color:rgb(255,255,255)"/>
       *    <stop offset="1" style="stop-color:rgb(0,0,0)"/>
       *  </linearGradient>
       *
       *  OR
       *
       *  <radialGradient id="radialGrad1">
       *    <stop offset="0%" stop-color="white" stop-opacity="1" />
       *    <stop offset="50%" stop-color="black" stop-opacity="0.5" />
       *    <stop offset="100%" stop-color="white" stop-opacity="1" />
       *  </radialGradient>
       *
       *  OR
       *
       *  <radialGradient id="radialGrad2">
       *    <stop offset="0" stop-color="rgb(255,255,255)" />
       *    <stop offset="0.5" stop-color="rgb(0,0,0)" />
       *    <stop offset="1" stop-color="rgb(255,255,255)" />
       *  </radialGradient>
       *
       */

      var colorStopEls = el.getElementsByTagName('stop'),
          type = (el.nodeName === 'linearGradient' ? 'linear' : 'radial'),
          gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',
          gradientTransform = el.getAttribute('gradientTransform'),
          colorStops = [],
          coords = { };

      if (type === 'linear') {
        coords = getLinearCoords(el);
      }
      else if (type === 'radial') {
        coords = getRadialCoords(el);
      }

      for (var i = colorStopEls.length; i--; ) {
        colorStops.push(getColorStop(colorStopEls[i]));
      }

      _convertPercentUnitsToValues(instance, coords);

      var gradient = new fabric.Gradient({
        type: type,
        coords: coords,
        gradientUnits: gradientUnits,
        colorStops: colorStops
      });

      if (gradientTransform) {
        gradient.gradientTransform = fabric.parseTransformAttribute(gradientTransform);
      }

      return gradient;
    },
    /* _FROM_SVG_END_ */

    /**
     * Returns {@link fabric.Gradient} instance from its object representation
     * @static
     * @memberof fabric.Gradient
     * @param {Object} obj
     * @param {Object} [options] Options object
     */
    forObject: function(obj, options) {
      options || (options = { });
      _convertPercentUnitsToValues(obj, options);
      return new fabric.Gradient(options);
    }
  });

  /**
   * @private
   */
  function _convertPercentUnitsToValues(object, options) {
    for (var prop in options) {
      if (typeof options[prop] === 'string' && /^\d+%$/.test(options[prop])) {
        var percents = parseFloat(options[prop], 10);
        if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
          options[prop] = fabric.util.toFixed(object.width * percents / 100, 2)  + object.left;
        }
        else if (prop === 'y1' || prop === 'y2') {
          options[prop] = fabric.util.toFixed(object.height * percents / 100, 2) + object.top;
        }
      }
    }
  }

  /* _TO_SVG_START_ */
  /**
   * @private
   */
  function _convertValuesToPercentUnits(object, options) {
    for (var prop in options) {
      //convert to percent units
      if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
        options[prop] = fabric.util.toFixed((options[prop] - object.origX) / object.width * 100, 2) + '%';
      }
      else if (prop === 'y1' || prop === 'y2') {
        options[prop] = fabric.util.toFixed((options[prop] - object.origY) / object.height * 100, 2) + '%';
      }
    }
  }
  /* _TO_SVG_END_ */

})();
<|endoftext|>


<commit_before>import { isUndefined, defaults } from 'underscore';

module.exports = (() => {
  const defaultConfig = require('./config/config');
  const Editor = require('editor');
  const PluginManager = require('plugin_manager');
  const plugins = new PluginManager();
  const editors = [];

  return {

    // Will be replaced on build
    version: '<# VERSION #>',

    editors,

    plugins,

    /**
     * Initializes an editor based on passed options
     * @param {Object} config Configuration object
     * @param {string|HTMLElement} config.container Selector which indicates where render the editor
     * @param {Object|string} config.components='' HTML string or Component model in JSON format
     * @param {Object|string} config.style='' CSS string or CSS model in JSON format
     * @param {Boolean} [config.fromElement=false] If true, will fetch HTML and CSS from selected container
     * @param {Boolean} [config.copyPaste=true] Enable/Disable the possibility to copy(ctrl+c) & paste(ctrl+v) components
     * @param {Boolean} [config.undoManager=true] Enable/Disable undo manager
     * @param {Array} [config.plugins=[]] Array of plugins to execute on start
     * @return {grapesjs.Editor} GrapesJS editor instance
     * @example
     * var editor = grapesjs.init({
     *   container: '#myeditor',
     *   components: '
Hello world
',
     *   style: '.hello{color: red}',
     * })
     */
    init(config = {}) {
      const els = config.container;

      // Make a missing $ more verbose
      if (isUndefined($)) {
        throw 'jQuery not found';
      }

      if (!els) {
        throw new Error("'container' is required");
      }

      defaults(config, defaultConfig);
      config.el = els instanceof window.HTMLElement ? els : document.querySelector(els);
      const editor = new Editor(config).init();

      // Execute `onLoad` on modules once all plugins are initialized.
      // A plugin might have extended/added some custom type so this
      // is a good point to load stuff like components, css rules, etc.
      editor.getModel().loadOnStart();

      // Load plugins
      config.plugins.forEach(pluginId => {
        const plugin = plugins.get(pluginId);

        if (plugin) {
          plugin(editor, config.pluginsOpts[pluginId] || {});
        } else {
          console.warn(`Plugin ${pluginId} not found`);
        }
      });

      config.autorender && editor.render();

      editors.push(editor);
      return editor;
    },

  };

})();
<commit_msg>reverted to previous version<commit_after>import { isUndefined, defaults } from 'underscore';

module.exports = (() => {
  const defaultConfig = require('./config/config');
  const Editor = require('editor');
  const PluginManager = require('plugin_manager');
  const plugins = new PluginManager();
  const editors = [];

  return {

    // Will be replaced on build
    version: '<# VERSION #>',

    editors,

    plugins,

    /**
     * Initializes an editor based on passed options
     * @param {Object} config Configuration object
     * @param {string|HTMLElement} config.container Selector which indicates where render the editor
     * @param {Object|string} config.components='' HTML string or Component model in JSON format
     * @param {Object|string} config.style='' CSS string or CSS model in JSON format
     * @param {Boolean} [config.fromElement=false] If true, will fetch HTML and CSS from selected container
     * @param {Boolean} [config.copyPaste=true] Enable/Disable the possibility to copy(ctrl+c) & paste(ctrl+v) components
     * @param {Boolean} [config.undoManager=true] Enable/Disable undo manager
     * @param {Array} [config.plugins=[]] Array of plugins to execute on start
     * @return {grapesjs.Editor} GrapesJS editor instance
     * @example
     * var editor = grapesjs.init({
     *   container: '#myeditor',
     *   components: '
Hello world
',
     *   style: '.hello{color: red}',
     * })
     */
    init(config = {}) {
      const els = config.container;

      // Make a missing $ more verbose
      if (isUndefined($)) {
        throw 'jQuery not found';
      }

      if (!els) {
        throw new Error("'container' is required");
      }

      defaults(config, defaultConfig);
      config.el = els instanceof window.HTMLElement ? els : document.querySelector(els);
      const editor = new Editor(config).init();

      // Load plugins
      config.plugins.forEach(pluginId => {
        const plugin = plugins.get(pluginId);

        if (plugin) {
          plugin(editor, config.pluginsOpts[pluginId] || {});
        } else {
          console.warn(`Plugin ${pluginId} not found`);
        }
      });

      // Execute `onLoad` on modules once all plugins are initialized.
      // A plugin might have extended/added some custom type so this
      // is a good point to load stuff like components, css rules, etc.
      editor.getModel().loadOnStart();

      config.autorender && editor.render();

      editors.push(editor);
      return editor;
    },

  };

})();
<|endoftext|>


<commit_before>angular.module("angular-growl").directive("growl", [
  function () {
    "use strict";

    return {
      restrict: 'A',
      templateUrl: 'templates/growl/growl.html',
      replace: false,
      scope: {
        reference: '@',
        inline: '=',
        limitMessages: '='
      },
      controller: ['$scope', '$interval', 'growl', 'growlMessages',
        function ($scope, $interval, growl, growlMessages) {
          $scope.referenceId = $scope.reference || 0;

          growlMessages.initDirective($scope.referenceId, $scope.limitMessages);
          $scope.growlMessages = growlMessages;
          $scope.inlineMessage = angular.isDefined($scope.inline) ? $scope.inline : growl.inlineMessages();

          $scope.$watch('limitMessages', function (limitMessages) {
            var directive = growlMessages.directives[$scope.referenceId];
            if (!angular.isUndefined(limitMessages) && !angular.isUndefined(directive)) {
              directive.limitMessages = limitMessages;
            }
          });

          //Cancels all promises within message upon deleting message or stop deleting.
          $scope.stopTimeoutClose = function (message) {
            if (!message.clickToClose) {
              angular.forEach(message.promises, function (promise) {
                $interval.cancel(promise);
              });
              if (message.close) {
                growlMessages.deleteMessage(message);
              } else {
                message.close = true;
              }
            }
          };

          $scope.alertClasses = function (message) {
            return {
              'alert-success': message.severity === "success",
              'alert-error': message.severity === "error", //bootstrap 2.3
              'alert-danger': message.severity === "error", //bootstrap 3
              'alert-info': message.severity === "info",
              'alert-warning': message.severity === "warning", //bootstrap 3, no effect in bs 2.3
              'icon': message.disableIcons === false,
              'alert-dismissable': !message.disableCloseButton
            };
          };

          $scope.showCountDown = function (message) {
            return !message.disableCountDown && message.ttl > 0;
          };

          $scope.wrapperClasses = function () {
            var classes = {};
            classes['growl-fixed'] = !$scope.inlineMessage;
            classes[growl.position()] = true;
            return classes;
          };

          $scope.computeTitle = function (message) {
            var ret = {
              'success': 'Success',
              'error': 'Error',
              'info': 'Information',
              'warn': 'Warning'
            };
            return ret[message.severity];
          };
        }
      ]
    };
  }
]);

angular.module("angular-growl").run(['$templateCache', function ($templateCache) {
  "use strict";
  if ($templateCache.get('templates/growl/growl.html') === undefined) {
    $templateCache.put("templates/growl/growl.html",
      '
' +
      '
' +
      '<button type="button" class="close" data-dismiss="alert" aria-hidden="true" ng-click="growlMessages.deleteMessage(message)" ng-show="!message.disableCloseButton">×</button>' +
      '<button type="button" class="close" aria-hidden="true" ng-show="showCountDown(message)">{{message.countdown}}</button>' +
      '

' +
      '

' +
      '
' +
      '
'
    );
  }
}]);
<commit_msg>Updating template to resolve Issue #98<commit_after>angular.module("angular-growl").directive("growl", [
  function () {
    "use strict";

    return {
      restrict: 'A',
      templateUrl: 'templates/growl/growl.html',
      replace: false,
      scope: {
        reference: '@',
        inline: '=',
        limitMessages: '='
      },
      controller: ['$scope', '$interval', 'growl', 'growlMessages',
        function ($scope, $interval, growl, growlMessages) {
          $scope.referenceId = $scope.reference || 0;

          growlMessages.initDirective($scope.referenceId, $scope.limitMessages);
          $scope.growlMessages = growlMessages;
          $scope.inlineMessage = angular.isDefined($scope.inline) ? $scope.inline : growl.inlineMessages();

          $scope.$watch('limitMessages', function (limitMessages) {
            var directive = growlMessages.directives[$scope.referenceId];
            if (!angular.isUndefined(limitMessages) && !angular.isUndefined(directive)) {
              directive.limitMessages = limitMessages;
            }
          });

          //Cancels all promises within message upon deleting message or stop deleting.
          $scope.stopTimeoutClose = function (message) {
            if (!message.clickToClose) {
              angular.forEach(message.promises, function (promise) {
                $interval.cancel(promise);
              });
              if (message.close) {
                growlMessages.deleteMessage(message);
              } else {
                message.close = true;
              }
            }
          };

          $scope.alertClasses = function (message) {
            return {
              'alert-success': message.severity === "success",
              'alert-error': message.severity === "error", //bootstrap 2.3
              'alert-danger': message.severity === "error", //bootstrap 3
              'alert-info': message.severity === "info",
              'alert-warning': message.severity === "warning", //bootstrap 3, no effect in bs 2.3
              'icon': message.disableIcons === false,
              'alert-dismissable': !message.disableCloseButton
            };
          };

          $scope.showCountDown = function (message) {
            return !message.disableCountDown && message.ttl > 0;
          };

          $scope.wrapperClasses = function () {
            var classes = {};
            classes['growl-fixed'] = !$scope.inlineMessage;
            classes[growl.position()] = true;
            return classes;
          };

          $scope.computeTitle = function (message) {
            var ret = {
              'success': 'Success',
              'error': 'Error',
              'info': 'Information',
              'warn': 'Warning'
            };
            return ret[message.severity];
          };
        }
      ]
    };
  }
]);

angular.module("angular-growl").run(['$templateCache', function ($templateCache) {
  "use strict";
  if ($templateCache.get('templates/growl/growl.html') === undefined) {
    $templateCache.put("templates/growl/growl.html",
      '
' +
      '
' +
      '<button type="button" class="close" data-dismiss="alert" aria-hidden="true" ng-click="growlMessages.deleteMessage(message)" ng-show="!message.disableCloseButton">×</button>' +
      '<button type="button" class="close" aria-hidden="true" ng-if="showCountDown(message)">{{message.countdown}}</button>' +
      '

' +
      '

' +
      '
' +
      '
'
    );
  }
}]);
<|endoftext|>


<commit_before>var GuiControl = function (guiInput, context)
{
	this._input = guiInput;
	this._context = context;
};

GuiControl.extend(
{

});

GuiControl.prototype.extend(
{

	drawControls: function (wnd, deltaTime)
	{
		var controlsCount = this._calculateControlSizes(wnd);
		this._interactControls(wnd, deltaTime);

		var retries = 3;

		while (this.recalculate && retries >= 0)
		{
			this._calculateControlSizes(wnd);
			retries--;
		}

		if(retries <= 0)
		{
			console.log("controls desync, bailing..");
			return;
		}

		this._drawControls(wnd, deltaTime);
	},

	_beginControl: function (wnd)
	{
		var rect = wnd.layout.beginControl(wnd);
		if(rect == null)
		{
			this.recalculate = true;
			return null;
		}

		if(Gui.debugLayout)
		{
			this.debugLayoutLastRect = rect;
		}

		var relativeMousePosition = vec2.create();
		vec2.subtract(relativeMousePosition, this._input.getCursorPosition(), rect.position);

		var hovered = PointRectTest(this._input.getCursorPosition(), rect.position, rect.size) && Gui._activeWindow == wnd;
		var clicked = hovered && this._input._mouseDown;

		if(wnd._resizing || wnd._dragging)
		{
			hovered = false;
			clicked = false;
		}

		if (clicked)
		{
			Gui._activeControlPosition = rect.position;
			Gui._activeControlSize = rect.size;
			this._input._mouseDown = false;
		}

		var state = "normal";

		if (hovered)
		{
			state = "hovered";
		}

		if (clicked)
		{
			state = "clicked";
		}

		var active =
			Gui._activeControlPosition[0] == rect.position[0] &&
			Gui._activeControlPosition[1] == rect.position[1] &&
			Gui._activeControlSize[0] == rect.size[0] &&
			Gui._activeControlSize[1] == rect.size[1];

		return {

			rect: rect,
			hovered: hovered,
			clicked: clicked,
			active: active,
			state: state,
			relativeMousePosition: relativeMousePosition,
			mousePosition: this._input.getCursorPosition(),
			caret: this._input.getCaret(),

		};
	},

	_endControl: function (wnd)
	{

	},

	_calculateControlSizes: function (wnd)
	{
		var controlsCount = 0;
		wnd.layout.beginPrepareLayout();

		wnd.drawSelf(
		{

			beginHorizontalGroup: function ()
			{
				wnd.layout.beginHorizontalGroup();
			}.bind(this),

			endHorizontalGroup: function ()
			{
				wnd.layout.endHorizontalGroup(wnd);
			}.bind(this),

			horizontalSeparator: function ()
			{
				wnd.layout.prepareControl(GuiRenderer.calculateHorizontalSeparatorSize(this._context, wnd));
				controlsCount++;
			}.bind(this),

			label: function (message)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateLabelSize(this._context, wnd, message));
				controlsCount++;
			}.bind(this),

			button: function (label)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateButtonSize(this._context, wnd, label));
				controlsCount++;
				return false;
			}.bind(this),

			inputbox: function (input, maxLength)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateInputBoxSize(this._context, wnd, maxLength));
				controlsCount++;
				return input;
			}.bind(this),

			textbox: function (input, rows, cols, readonly)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateTextBoxSize(this._context, wnd, rows, cols));
				controlsCount++;
				return input;
			}.bind(this),

			image: function (resourceName, width, height)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateImageSize(this._context, wnd, ResourceLoader.getContent(resourceName), width, height));
				controlsCount++;
			}.bind(this),

			checkbox: function (checked)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateCheckBoxSize(this._context, wnd));
				controlsCount++;
				return checked;
			}.bind(this),

			listbox: function (items, width, height, selectedIndex)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateListBoxSize(this._context, wnd, width, height));
				controlsCount++;
				return selectedIndex;
			}.bind(this),

		});

		wnd.layout.endPrepareLayout();
		return controlsCount;
	},

	_interactControls: function (wnd, deltaTime)
	{
		wnd.layout.beginLayout(wnd);

		this.controlList = [];
		this.recalculate = false;

		wnd.drawSelf(
		{

			beginHorizontalGroup: function ()
			{
				wnd.layout.beginHorizontalGroup();
			}.bind(this),

			endHorizontalGroup: function ()
			{
				wnd.layout.endHorizontalGroup(wnd);
			}.bind(this),

			horizontalSeparator: function ()
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return;
				}

				this.controlList.push(['horizontalSeparator', control]);
				this._endControl(wnd);
			}.bind(this),

			label: function (message)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return;
				}

				control.message = message;

				this.controlList.push(['label', control]);
				this._endControl(wnd);
			}.bind(this),

			button: function (label)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return false;
				}

				this.controlList.push(['button', control]);
				this._endControl(wnd);

				control.label = label;

				if (control.clicked)
				{
					return true;
				}

				return false;
			}.bind(this),

			inputbox: function (input, maxLength)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return input;
				}

				control.input = input;
				control.maxLength = maxLength;
				this.controlList.push(['inputbox', control]);

				if (control.clicked)
				{
					var caretIndex = 0;

					this._input.setKeyBuffer(input);
					caretIndex = GuiRenderer.calculateInputBoxCaretIndex(this._context, wnd, input, control);

					if(caretIndex > input.length + 1)
					{
						caretIndex = input.length + 1;
					}

					this._input.setCaretIndex(caretIndex);
					control.caret[0] = caretIndex;
				}

				this._endControl(wnd);

				if (control.active)
				{
					var newInput = this._input.getKeyBuffer();

					if(newInput.length > maxLength)
					{
						newInput = newInput.slice(0, maxLength);
					}

					return newInput;
				}

				return input;
			}.bind(this),

			textbox: function (input, rows, cols, readonly)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return input;
				}

				control.input = input;
				control.rows = rows;
				control.cols = cols;
				control.readonly = readonly;
				this.controlList.push(['textbox', control]);

				if (control.clicked)
				{
					this._input.setKeyBuffer(input);
					control.caret = GuiRenderer.calculateTextBoxCaretIndex(this._context, wnd, input, rows, cols, control);
					this._input.setCaret(control.caret);
				}

				this._endControl(wnd);

				if(control.active)
				{
					var newInput = this._input.getKeyBuffer();
					return newInput;
				}

				return input;
			}.bind(this),

			image: function (resourceName, width, height)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return;
				}

				control.resourceName = resourceName;
				control.width = width;
				control.height = height;

				this.controlList.push(['image', control]);
				this._endControl(wnd);
			}.bind(this),

			checkbox: function (checked)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return checked;
				}

				control.checked = checked;
				this.controlList.push(['checkbox', control]);
				this._endControl(wnd);

				if (control.clicked)
				{
					return !checked;
				}

				return checked;
			}.bind(this),

			listbox: function (items, width, height, selectedIndex)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return selectedIndex;
				}

				control.items = items;
				control.width = width;
				control.height = height;
				control.selectedIndex = selectedIndex;
				this.controlList.push(['listbox', control]);
				var hoveredItem = null;

				if(control.hovered)
				{
					hoveredItem = Math.floor((control.relativeMousePosition[1] - 8.0) / wnd.layout.fontSize);

					if(control.clicked)
					{
						selectedIndex = hoveredItem;

						if(selectedIndex >= items.length)
						{
							selectedIndex = null;
						}
					}

					if(hoveredItem >= items.length)
					{
						hoveredItem = null;
					}
				}

				this._endControl(wnd);

				return selectedIndex;
			}.bind(this),

		});

		wnd.layout.endLayout(wnd);
	},

	_drawControls: function (wnd, deltaTime)
	{
		//	console.log(this.controlList[i]);

		for(var i = 0; i < this.controlList.length; i++)
		{
			var type = this.controlList[i][0];
			var control = this.controlList[i][1];
			var rect = control.rect;

			this._context.save();
			this._context.beginPath();
			this._context.rect(rect.position[0], rect.position[1], rect.size[0], rect.size[1]);
			this._context.clip();

			if(type == 'horizontalSeparator')
			{
				GuiRenderer.drawHorizontalSeparator(this._context, wnd, control.rect);
			}
			else if(type == 'label')
			{
				GuiRenderer.drawLabel(this._context, wnd, control.message, "white", control);
			}
			else if(type == 'button')
			{
				GuiRenderer.drawButton(this._context, wnd, control.label, control);
			}
			else if(type == 'inputbox')
			{
				GuiRenderer.drawInputBox(this._context, wnd, control.input, control);
			}
			else if(type == 'textbox')
			{
				GuiRenderer.drawTextBox(this._context, wnd, control.input, control.rows, control.cols, control);
			}
			else if(type == 'image')
			{
				GuiRenderer.drawImage(this._context, wnd, control.image, control);
			}
			else if(type == 'checkbox')
			{
				GuiRenderer.drawCheckBox(this._context, wnd, control.checked, control);
			}
			else if(type == 'listbox')
			{
				GuiRenderer.drawListBox(this._context, wnd, control.items, control.selectedIndex, control.hoveredItem, control);
			}

			this._context.restore();

			if(this.debugLayout)
			{
				var rect = this.debugLayoutLastRect;
				this._context.strokeStyle = 'green';
				this._context.strokeRect(rect.position[0], rect.position[1], rect.size[0], rect.size[1]);
			}
		}
	},

	/*

		wnd.drawSelf(
		{

			beginHorizontalGroup: function ()
			{
				wnd.layout.beginHorizontalGroup();
			}.bind(this),

			endHorizontalGroup: function ()
			{
				wnd.layout.endHorizontalGroup(wnd);
			}.bind(this),

			horizontalSeparator: function ()
			{
				var control = this._beginControl(wnd);
				GuiRenderer.drawHorizontalSeparator(this._context, wnd, control.rect);
				this._endControl(wnd);
			}.bind(this),

			label: function (message)
			{
				var control = this._beginControl(wnd);

				this._endControl(wnd);
			}.bind(this),

			button: function (label)
			{
				var control = this._beginControl(wnd);

				this._endControl(wnd);

				if (control.clicked)
				{
					return true;
				}

				return false;
			}.bind(this),

			inputbox: function (input, maxLength)
			{
				var control = this._beginControl(wnd);

				if (control.clicked)
				{
					var caretIndex = 0;

					this._input.setKeyBuffer(input);
					caretIndex = GuiRenderer.calculateInputBoxCaretIndex(this._context, wnd, input, control);

					if(caretIndex > input.length + 1)
					{
						caretIndex = input.length + 1;
					}

					this._input.setCaretIndex(caretIndex);
					control.caret[0] = caretIndex;
				}

				this._endControl(wnd);

				if (control.active)
				{
					var newInput = this._input.getKeyBuffer();

					if(newInput.length > maxLength)
					{
						newInput = newInput.slice(0, maxLength);
					}

					return newInput;
				}

				return input;
			}.bind(this),

			textbox: function (input, rows, cols, readonly)
			{
				var control = this._beginControl(wnd);

				if (control.clicked)
				{
					this._input.setKeyBuffer(input);
					control.caret = GuiRenderer.calculateTextBoxCaretIndex(this._context, wnd, input, rows, cols, control);
					this._input.setCaret(control.caret);
				}

				this._endControl(wnd);

				if(control.active)
				{
					var newInput = this._input.getKeyBuffer();
					return newInput;
				}

				return input;
			}.bind(this),

			image: function (resourceName, width, height)
			{
				var control = this._beginControl(wnd);
				var image = ResourceLoader.getContent(resourceName);

				this._endControl(wnd);
			}.bind(this),

			checkbox: function (checked)
			{
				var control = this._beginControl(wnd);
				this._endControl(wnd);

				if (control.clicked)
				{
					return !checked;
				}

				return checked;
			}.bind(this),

			listbox: function (items, width, height, selectedIndex)
			{
				var control = this._beginControl(wnd);
				var hoveredItem = null;

				if(control.hovered)
				{
					hoveredItem = Math.floor(control.relativeMousePosition[1] / ptsToPixels(wnd.layout.fontSize));

					if(control.clicked)
					{
						selectedIndex = hoveredItem;

						if(selectedIndex < 0 || selectedIndex >= items.length)
						{
							selectedIndex = null;
						}
					}

					if(hoveredItem < 0 || 	hoveredItem >= items.length)
					{
						hoveredItem = null;
					}
				}

				this._endControl(wnd);

				return selectedIndex;
			}.bind(this),

		});

		wnd.layout.endLayout(wnd);
	},*/

});<commit_msg>fixed listbox hover<commit_after>var GuiControl = function (guiInput, context)
{
	this._input = guiInput;
	this._context = context;
};

GuiControl.extend(
{

});

GuiControl.prototype.extend(
{

	drawControls: function (wnd, deltaTime)
	{
		var controlsCount = this._calculateControlSizes(wnd);
		this._interactControls(wnd, deltaTime);

		var retries = 3;

		while (this.recalculate && retries >= 0)
		{
			this._calculateControlSizes(wnd);
			retries--;
		}

		if(retries <= 0)
		{
			console.log("controls desync, bailing..");
			return;
		}

		this._drawControls(wnd, deltaTime);
	},

	_beginControl: function (wnd)
	{
		var rect = wnd.layout.beginControl(wnd);
		if(rect == null)
		{
			this.recalculate = true;
			return null;
		}

		if(Gui.debugLayout)
		{
			this.debugLayoutLastRect = rect;
		}

		var relativeMousePosition = vec2.create();
		vec2.subtract(relativeMousePosition, this._input.getCursorPosition(), rect.position);

		var hovered = PointRectTest(this._input.getCursorPosition(), rect.position, rect.size) && Gui._activeWindow == wnd;
		var clicked = hovered && this._input._mouseDown;

		if(wnd._resizing || wnd._dragging)
		{
			hovered = false;
			clicked = false;
		}

		if (clicked)
		{
			Gui._activeControlPosition = rect.position;
			Gui._activeControlSize = rect.size;
			this._input._mouseDown = false;
		}

		var state = "normal";

		if (hovered)
		{
			state = "hovered";
		}

		if (clicked)
		{
			state = "clicked";
		}

		var active =
			Gui._activeControlPosition[0] == rect.position[0] &&
			Gui._activeControlPosition[1] == rect.position[1] &&
			Gui._activeControlSize[0] == rect.size[0] &&
			Gui._activeControlSize[1] == rect.size[1];

		return {

			rect: rect,
			hovered: hovered,
			clicked: clicked,
			active: active,
			state: state,
			relativeMousePosition: relativeMousePosition,
			mousePosition: this._input.getCursorPosition(),
			caret: this._input.getCaret(),

		};
	},

	_endControl: function (wnd)
	{

	},

	_calculateControlSizes: function (wnd)
	{
		var controlsCount = 0;
		wnd.layout.beginPrepareLayout();

		wnd.drawSelf(
		{

			beginHorizontalGroup: function ()
			{
				wnd.layout.beginHorizontalGroup();
			}.bind(this),

			endHorizontalGroup: function ()
			{
				wnd.layout.endHorizontalGroup(wnd);
			}.bind(this),

			horizontalSeparator: function ()
			{
				wnd.layout.prepareControl(GuiRenderer.calculateHorizontalSeparatorSize(this._context, wnd));
				controlsCount++;
			}.bind(this),

			label: function (message)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateLabelSize(this._context, wnd, message));
				controlsCount++;
			}.bind(this),

			button: function (label)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateButtonSize(this._context, wnd, label));
				controlsCount++;
				return false;
			}.bind(this),

			inputbox: function (input, maxLength)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateInputBoxSize(this._context, wnd, maxLength));
				controlsCount++;
				return input;
			}.bind(this),

			textbox: function (input, rows, cols, readonly)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateTextBoxSize(this._context, wnd, rows, cols));
				controlsCount++;
				return input;
			}.bind(this),

			image: function (resourceName, width, height)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateImageSize(this._context, wnd, ResourceLoader.getContent(resourceName), width, height));
				controlsCount++;
			}.bind(this),

			checkbox: function (checked)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateCheckBoxSize(this._context, wnd));
				controlsCount++;
				return checked;
			}.bind(this),

			listbox: function (items, width, height, selectedIndex)
			{
				wnd.layout.prepareControl(GuiRenderer.calculateListBoxSize(this._context, wnd, width, height));
				controlsCount++;
				return selectedIndex;
			}.bind(this),

		});

		wnd.layout.endPrepareLayout();
		return controlsCount;
	},

	_interactControls: function (wnd, deltaTime)
	{
		wnd.layout.beginLayout(wnd);

		this.controlList = [];
		this.recalculate = false;

		wnd.drawSelf(
		{

			beginHorizontalGroup: function ()
			{
				wnd.layout.beginHorizontalGroup();
			}.bind(this),

			endHorizontalGroup: function ()
			{
				wnd.layout.endHorizontalGroup(wnd);
			}.bind(this),

			horizontalSeparator: function ()
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return;
				}

				this.controlList.push(['horizontalSeparator', control]);
				this._endControl(wnd);
			}.bind(this),

			label: function (message)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return;
				}

				control.message = message;

				this.controlList.push(['label', control]);
				this._endControl(wnd);
			}.bind(this),

			button: function (label)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return false;
				}

				this.controlList.push(['button', control]);
				this._endControl(wnd);

				control.label = label;

				if (control.clicked)
				{
					return true;
				}

				return false;
			}.bind(this),

			inputbox: function (input, maxLength)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return input;
				}

				control.input = input;
				control.maxLength = maxLength;
				this.controlList.push(['inputbox', control]);

				if (control.clicked)
				{
					var caretIndex = 0;

					this._input.setKeyBuffer(input);
					caretIndex = GuiRenderer.calculateInputBoxCaretIndex(this._context, wnd, input, control);

					if(caretIndex > input.length + 1)
					{
						caretIndex = input.length + 1;
					}

					this._input.setCaretIndex(caretIndex);
					control.caret[0] = caretIndex;
				}

				this._endControl(wnd);

				if (control.active)
				{
					var newInput = this._input.getKeyBuffer();

					if(newInput.length > maxLength)
					{
						newInput = newInput.slice(0, maxLength);
					}

					return newInput;
				}

				return input;
			}.bind(this),

			textbox: function (input, rows, cols, readonly)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return input;
				}

				control.input = input;
				control.rows = rows;
				control.cols = cols;
				control.readonly = readonly;
				this.controlList.push(['textbox', control]);

				if (control.clicked)
				{
					this._input.setKeyBuffer(input);
					control.caret = GuiRenderer.calculateTextBoxCaretIndex(this._context, wnd, input, rows, cols, control);
					this._input.setCaret(control.caret);
				}

				this._endControl(wnd);

				if(control.active)
				{
					var newInput = this._input.getKeyBuffer();
					return newInput;
				}

				return input;
			}.bind(this),

			image: function (resourceName, width, height)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return;
				}

				control.resourceName = resourceName;
				control.width = width;
				control.height = height;

				this.controlList.push(['image', control]);
				this._endControl(wnd);
			}.bind(this),

			checkbox: function (checked)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return checked;
				}

				control.checked = checked;
				this.controlList.push(['checkbox', control]);
				this._endControl(wnd);

				if (control.clicked)
				{
					return !checked;
				}

				return checked;
			}.bind(this),

			listbox: function (items, width, height, selectedIndex)
			{
				var control = this._beginControl(wnd);
				if(control == null)
				{
					return selectedIndex;
				}

				control.items = items;
				control.width = width;
				control.height = height;
				control.selectedIndex = selectedIndex;
				var hoveredItem = null;

				if(control.hovered)
				{
					hoveredItem = Math.floor(control.relativeMousePosition[1] / ptsToPixels(wnd.layout.fontSize));

					if(control.clicked)
					{
						selectedIndex = hoveredItem;

						if(selectedIndex >= items.length)
						{
							selectedIndex = null;
						}
					}

					if(hoveredItem >= items.length)
					{
						hoveredItem = null;
					}

					control.hoveredItem = hoveredItem;
				}

				this.controlList.push(['listbox', control]);

				this._endControl(wnd);

				return selectedIndex;
			}.bind(this),

		});

		wnd.layout.endLayout(wnd);
	},

	_drawControls: function (wnd, deltaTime)
	{
		//	console.log(this.controlList[i]);

		for(var i = 0; i < this.controlList.length; i++)
		{
			var type = this.controlList[i][0];
			var control = this.controlList[i][1];
			var rect = control.rect;

			this._context.save();
			this._context.beginPath();
			this._context.rect(rect.position[0], rect.position[1], rect.size[0], rect.size[1]);
			this._context.clip();

			if(type == 'horizontalSeparator')
			{
				GuiRenderer.drawHorizontalSeparator(this._context, wnd, control.rect);
			}
			else if(type == 'label')
			{
				GuiRenderer.drawLabel(this._context, wnd, control.message, "white", control);
			}
			else if(type == 'button')
			{
				GuiRenderer.drawButton(this._context, wnd, control.label, control);
			}
			else if(type == 'inputbox')
			{
				GuiRenderer.drawInputBox(this._context, wnd, control.input, control);
			}
			else if(type == 'textbox')
			{
				GuiRenderer.drawTextBox(this._context, wnd, control.input, control.rows, control.cols, control);
			}
			else if(type == 'image')
			{
				GuiRenderer.drawImage(this._context, wnd, control.image, control);
			}
			else if(type == 'checkbox')
			{
				GuiRenderer.drawCheckBox(this._context, wnd, control.checked, control);
			}
			else if(type == 'listbox')
			{
				GuiRenderer.drawListBox(this._context, wnd, control.items, control.selectedIndex, control.hoveredItem, control);
			}

			this._context.restore();

			if(this.debugLayout)
			{
				var rect = this.debugLayoutLastRect;
				this._context.strokeStyle = 'green';
				this._context.strokeRect(rect.position[0], rect.position[1], rect.size[0], rect.size[1]);
			}
		}
	},

});<|endoftext|>


<commit_before>'use strict';

import knex from 'knex';
import config from '../../config/config.json';
import Bookshelf from 'bookshelf';

const knexConfig = knex(config.bookshelf.postgresql);
let bookshelf = new Bookshelf(knexConfig);

bookshelf.models = {};

// Register models
import User from './model/User';
User.register(bookshelf);
import Thing from './model/Thing'
Thing.register(bookshelf);

// TODO: Migrations functions to automatically update DB
// var db = import from'./db/schema').tables;

export default bookshelf;
<commit_msg>Update init.js<commit_after>'use strict';

import knex from 'knex';
import config from '../../config/config.json';
import Bookshelf from 'bookshelf';

const knexConfig = knex(config.bookshelf.postgresql);
let bookshelf = new Bookshelf(knexConfig);

bookshelf.models = {};

// Register models
import User from './model/User';
User.register(bookshelf);
import Thing from './model/Thing';
Thing.register(bookshelf);

// TODO: Migrations functions to automatically update DB
// var db = import from'./db/schema').tables;

export default bookshelf;
<|endoftext|>


<commit_before>exports.BattleMovedex = {
    stealthrock: {
      		inherit: true,
      		effect: {
          	// this is a side condition
          	onStart: function(side) {
              		this.add('-sidestart',side,'move: Stealth Rock');
         	},
          	onSwitchIn: function(pokemon) {
              		var typeMod = this.getEffectiveness('Rock', pokemon);
              		var factor = 8;
              		if (typeMod == 1) factor = 4;
              		if (typeMod >= 2) factor = 4;
              		if (typeMod == -1) factor = 16;
              		if (typeMod <= -2) factor = 32;
                  	//below are the original Stealth Rock factors and such
  				   	  //if (typeMod == 1) factor = 4;
				          //if (typeMod >= 2) factor = 2;
				          //if (typeMod == -1) factor = 16;
				          //if (typeMod <= -2) factor = 32;
              		var damage = this.damage(pokemon.maxhp/factor);
          		}
      		}
  	},
  	"lockon": {
		num: 199,
		accuracy: true,
		basePower: 0,
		category: "Status",
		desc: "The user locks on to its target, boosting its Special Attack and accuracy by one stage.",
		shortDesc: "Boosts SpA and accuracy.",
		id: "lockon",
		name: "Lock-On",
		pp: 20,
		priority: 0,
		isSnatchable: true,
		boosts: {
			spa: 1,
			accuracy: 1
		},
		secondary: false,
		target: "self",
		type: "Normal"
	},
	"howl": {
		num: 336,
		accuracy: true,
		basePower: 0,
		category: "Status",
		desc: "Raises the user's Attack by 2 stages.",
		shortDesc: "Boosts the user's Atk by 2.",
		id: "howl",
		isViable: true,
		name: "Howl",
		pp: 20,
		priority: 0,
		isSnatchable: true,
		boosts: {
			atk: 2
		},
		secondary: false,
		target: "self",
		type: "Normal"
	},
	"lunardance": {
		num: 461,
		accuracy: true,
		basePower: 0,
		category: "Status",
		desc: "The user surrounds itself in lunar energy, boosting its Special Attack and Speed.",
		shortDesc: "Boosts SpA and Speed by one stage.",
		id: "lunardance",
		isViable: true,
		name: "Lunar Dance",
		pp: 20,
		priority: 0,
		isSnatchable: true,
		boosts: {
			spa: 1,
			spe: 1
		},
		secondary: false,
		target: "self",
		type: "Psychic"
	},
	"meditate": {
		num: 96,
		accuracy: true,
		basePower: 0,
		category: "Status",
		desc: "Raises the user's Attack and Special Defense by 1 stage.",
		shortDesc: "Boosts the user's Attack and Special Defense by 1.",
		id: "meditate",
		isViable: true,
		name: "Meditate",
		pp: 20,
		priority: 0,
		isSnatchable: true,
		boosts: {
			atk: 1,
			spd: 1
		},
		secondary: false,
		target: "self",
		type: "Psychic"
	},
	//DEBUG NOTE: The following four moves do NOT summon weather if they hit a Substitute instead of the actual pokemon, I will fix this later, since it the big picture it is not a priority.
	"heatwave": {
		num: 257,
		accuracy: 100,
		basePower: 80,
		category: "Special",
		desc: "Deals damage to one adjacent target and will activate Sunny Day if it hits.",
		shortDesc: "Activates sun if it hits.",
		id: "heatwave",
		isViable: true,
		name: "Heat Wave",
		pp: 10,
		priority: 0,
		onHit: function(source) {
			this.setWeather('sunnyday');
			this.weatherData.duration = 5;
		},
		secondary: false,
		target: "normal",
		type: "Fire"
	},
	"icywind": {
		num: 196,
		accuracy: 100,
		basePower: 80,
		category: "Special",
		desc: "Deals damage to one adjacent target and will activate Hail if it hits.",
		shortDesc: "Activates hail if it hits.",
		id: "icywind",
		name: "Icy Wind",
		pp: 10,
		priority: 0,
		onHit: function(source) {
			this.setWeather('hail');
			this.weatherData.duration = 5;
		},
		secondary: false,
		target: "normal",
		type: "Ice"
	},
	"sandattack": {
		num: 28,
		accuracy: 100,
		basePower: 80,
		category: "Physical",
		desc: "Deals damage to one adjacent target and will activate Sandstorm if it hits.",
		shortDesc: "Activates sand if it hits.",
		id: "sandattack",
		name: "Sand-Attack",
		pp: 10,
		priority: 0,
		onHit: function(source) {
			this.setWeather('sandstorm');
			this.weatherData.duration = 5;
		},
		secondary: false,
		target: "normal",
		type: "Ground"
	},
	"soak": {
		num: 487,
		accuracy: 100,
		basePower: 80,
		category: "Special",
		desc: "Deals damage to one adjacent target and will activate Rain Dance if it hits.",
		shortDesc: "Activates rain if it hits.",
		id: "soak",
		name: "Soak",
		pp: 10,
		priority: 0,
		onHit: function(source) {
			this.setWeather('raindance');
			this.weatherData.duration = 5;
		},
		secondary: false,
		target: "normal",
		type: "Water"
	},
	magmastorm: {
		inherit: true,
		basePower: 100,
		accuracy: 100
	},
	"spikecannon": {
		num: 131,
		accuracy: 100,
		basePower: 20,
		category: "Physical",
		desc: "Deals damage to one adjacent target and scatters Spikes on the opposing side if it hits.",
		shortDesc: "Scatters Spikes on the opposing side of the field if it successfully hits.",
		id: "spikecannon",
		name: "Spike Cannon",
		pp: 15,
		priority: 0,
		sideCondition: 'spikes',
		secondary: false,
		target: "normal",
		type: "Ground"
	},
	"payday": {
		num: 6,
		accuracy: 100,
		basePower: 20,
		category: "Physical",
		desc: "Always crits and deals damage in two seperate hits to one adjacent target.",
		shortDesc: "Damages twice with a 100% crit rate.",
		id: "payday",
		name: "Pay Day",
		pp: 20,
		priority: 0,
		willCrit: true,
		multihit: 2,
		onHit: function() {
			this.add('-fieldactivate', 'move: Pay Day');
		},
		secondary: false,
		target: "normal",
		type: "Normal"
	},
	"roaroftime": {
		num: 459,
		accuracy: 90,
		basePower: 120,
		category: "Special",
		desc: "Deals damage to one adjacent target. If this move is successful, the user must recharge on the following turn and cannot make a move.",
		shortDesc: "User cannot move next turn.",
		id: "roaroftime",
		name: "Roar of Time",
		pp: 5,
		priority: 0,
		secondary: {
			chance: 50,
			onHit: function(target, source) {
				var result = this.random(5);
				if (result===0) {
					target.trySetStatus('brn', source);
				} else if (result===1) {
					target.trySetStatus('par', source);
				} else if (result===2) {
					target.trySetStatus('tox', source);
				} else if (result===3) {
					target.addVolatile('confusion', source);
				} else {
					target.trySetStatus('frz', source);
				}
			}
		},
		target: "normal",
		type: "Dragon"
	},
	"cometpunch": {
		num: 4,
		accuracy: 100,
		basePower: 75,
		category: "Physical",
		desc: "Deals damage to one adjacent target and hits two to five times. Has a 1/3 chance to hit two or three times, and a 1/6 chance to hit four or five times. If one of the hits breaks the target's Substitute, it will take damage for the remaining hits. If the user has the Ability Skill Link, this move will always hit five times. Makes contact. Damage is boosted to 1.2x by the Ability Iron Fist.",
		shortDesc: "Hits 2-5 times in one turn.",
		id: "cometpunch",
		name: "Comet Punch",
		pp: 15,
		priority: 0,
		isContact: true,
		isPunchAttack: true,
		secondary: false,
		target: "normal",
		type: "Psychic"
	},
	"gust": {
		num: 16,
		accuracy: 100,
		basePower: 20,
		category: "Special",
		desc: "Deals damage to one adjacent or non-adjacent target. Power doubles against Pokemon using Bounce, Fly, or Sky Drop.",
		shortDesc: "Power doubles during Fly, Bounce, and Sky Drop.",
		id: "gust",
		name: "Gust",
		pp: 35,
		priority: 0,
		self: {
			onHit: function(pokemon) {
				var sideConditions = {spikes:1, toxicspikes:1, stealthrock:1};
				for (var i in sideConditions) {
					if (pokemon.hp && pokemon.side.removeSideCondition(i)) {
						this.add('-sideend', pokemon.side, this.getEffect(i).name, '[from] move: Gust', '[of] '+pokemon);
					}
				}
			}
		},
		secondary: false,
		target: "normal",
		type: "Flying"
	}
};
<commit_msg>Finish move changes<commit_after>exports.BattleMovedex = {
    stealthrock: {
      		inherit: true,
      		effect: {
          	// this is a side condition
          	onStart: function(side) {
              		this.add('-sidestart',side,'move: Stealth Rock');
         	},
          	onSwitchIn: function(pokemon) {
              		var typeMod = this.getEffectiveness('Rock', pokemon);
              		var factor = 8;
              		if (typeMod == 1) factor = 4;
              		if (typeMod >= 2) factor = 4;
              		if (typeMod == -1) factor = 16;
              		if (typeMod <= -2) factor = 32;
                  	//below are the original Stealth Rock factors and such
  				   	  //if (typeMod == 1) factor = 4;
				          //if (typeMod >= 2) factor = 2;
				          //if (typeMod == -1) factor = 16;
				          //if (typeMod <= -2) factor = 32;
              		var damage = this.damage(pokemon.maxhp/factor);
          		}
      		}
  	},
  	"lockon": {
		num: 199,
		accuracy: true,
		basePower: 0,
		category: "Status",
		desc: "The user locks on to its target, boosting its Special Attack and accuracy by one stage.",
		shortDesc: "Boosts SpA and accuracy.",
		id: "lockon",
		name: "Lock-On",
		pp: 20,
		priority: 0,
		isSnatchable: true,
		boosts: {
			spa: 1,
			accuracy: 1
		},
		secondary: false,
		target: "self",
		type: "Normal"
	},
	"howl": {
		num: 336,
		accuracy: true,
		basePower: 0,
		category: "Status",
		desc: "Raises the user's Attack by 2 stages.",
		shortDesc: "Boosts the user's Atk by 2.",
		id: "howl",
		isViable: true,
		name: "Howl",
		pp: 20,
		priority: 0,
		isSnatchable: true,
		boosts: {
			atk: 2
		},
		secondary: false,
		target: "self",
		type: "Normal"
	},
	"lunardance": {
		num: 461,
		accuracy: true,
		basePower: 0,
		category: "Status",
		desc: "The user surrounds itself in lunar energy, boosting its Special Attack and Speed.",
		shortDesc: "Boosts SpA and Speed by one stage.",
		id: "lunardance",
		isViable: true,
		name: "Lunar Dance",
		pp: 20,
		priority: 0,
		isSnatchable: true,
		boosts: {
			spa: 1,
			spe: 1
		},
		secondary: false,
		target: "self",
		type: "Psychic"
	},
	"meditate": {
		num: 96,
		accuracy: true,
		basePower: 0,
		category: "Status",
		desc: "Raises the user's Attack and Special Defense by 1 stage.",
		shortDesc: "Boosts the user's Attack and Special Defense by 1.",
		id: "meditate",
		isViable: true,
		name: "Meditate",
		pp: 20,
		priority: 0,
		isSnatchable: true,
		boosts: {
			atk: 1,
			spd: 1
		},
		secondary: false,
		target: "self",
		type: "Psychic"
	},
	//DEBUG NOTE: The following four moves do NOT summon weather if they hit a Substitute instead of the actual pokemon, I will fix this later, since it the big picture it is not a priority.
	"heatwave": {
		num: 257,
		accuracy: 100,
		basePower: 80,
		category: "Special",
		desc: "Deals damage to one adjacent target and will activate Sunny Day if it hits.",
		shortDesc: "Activates sun if it hits.",
		id: "heatwave",
		isViable: true,
		name: "Heat Wave",
		pp: 10,
		priority: 0,
		onHit: function(source) {
			this.setWeather('sunnyday');
			this.weatherData.duration = 5;
		},
		secondary: false,
		target: "normal",
		type: "Fire"
	},
	"icywind": {
		num: 196,
		accuracy: 100,
		basePower: 80,
		category: "Special",
		desc: "Deals damage to one adjacent target and will activate Hail if it hits.",
		shortDesc: "Activates hail if it hits.",
		id: "icywind",
		name: "Icy Wind",
		pp: 10,
		priority: 0,
		onHit: function(source) {
			this.setWeather('hail');
			this.weatherData.duration = 5;
		},
		secondary: false,
		target: "normal",
		type: "Ice"
	},
	"sandattack": {
		num: 28,
		accuracy: 100,
		basePower: 80,
		category: "Physical",
		desc: "Deals damage to one adjacent target and will activate Sandstorm if it hits.",
		shortDesc: "Activates sand if it hits.",
		id: "sandattack",
		name: "Sand-Attack",
		pp: 10,
		priority: 0,
		onHit: function(source) {
			this.setWeather('sandstorm');
			this.weatherData.duration = 5;
		},
		secondary: false,
		target: "normal",
		type: "Ground"
	},
	"soak": {
		num: 487,
		accuracy: 100,
		basePower: 80,
		category: "Special",
		desc: "Deals damage to one adjacent target and will activate Rain Dance if it hits.",
		shortDesc: "Activates rain if it hits.",
		id: "soak",
		name: "Soak",
		pp: 10,
		priority: 0,
		onHit: function(source) {
			this.setWeather('raindance');
			this.weatherData.duration = 5;
		},
		secondary: false,
		target: "normal",
		type: "Water"
	},
	magmastorm: {
		inherit: true,
		basePower: 100,
		accuracy: 100
	},
	"spikecannon": {
		num: 131,
		accuracy: 100,
		basePower: 20,
		category: "Physical",
		desc: "Deals damage to one adjacent target and scatters Spikes on the opposing side if it hits.",
		shortDesc: "Scatters Spikes on the opposing side of the field if it successfully hits.",
		id: "spikecannon",
		name: "Spike Cannon",
		pp: 10,
		priority: 0,
		sideCondition: 'spikes',
		secondary: false,
		target: "normal",
		type: "Ground"
	},
	"payday": {
		num: 6,
		accuracy: 100,
		basePower: 20,
		category: "Physical",
		desc: "Always crits and deals damage in two seperate hits to one adjacent target.",
		shortDesc: "Damages twice with a 100% crit rate.",
		id: "payday",
		name: "Pay Day",
		pp: 20,
		priority: 0,
		willCrit: true,
		multihit: 2,
		onHit: function() {
			this.add('-fieldactivate', 'move: Pay Day');
		},
		secondary: false,
		target: "normal",
		type: "Normal"
	},
	"roaroftime": {
		num: 459,
		accuracy: 90,
		basePower: 120,
		category: "Special",
		desc: "",
		shortDesc: "",
		id: "roaroftime",
		name: "Roar of Time",
		pp: 5,
		priority: 0,
		secondary: {
			chance: 50,
			onHit: function(target, source) {
				var result = this.random(5);
				if (result===0) {
					target.trySetStatus('brn', source);
				} else if (result===1) {
					target.trySetStatus('par', source);
				} else if (result===2) {
					target.trySetStatus('tox', source);
				} else if (result===3) {
					target.addVolatile('confusion', source);
				} else {
					target.trySetStatus('frz', source);
				}
			}
		},
		target: "normal",
		type: "Dragon"
	},
	"cometpunch": {
		num: 4,
		accuracy: 100,
		basePower: 75,
		category: "Physical",
		desc: "",
		shortDesc: "",
		id: "cometpunch",
		name: "Comet Punch",
		pp: 15,
		priority: 0,
		isContact: true,
		isPunchAttack: true,
		secondary: false,
		target: "normal",
		type: "Psychic"
	},
	"gust": {
		num: 16,
		accuracy: 100,
		basePower: 20,
		category: "Special",
		desc: "",
		shortDesc: "",
		id: "gust",
		name: "Gust",
		pp: 30,
		priority: 0,
		self: {
			onHit: function(pokemon) {
				var sideConditions = {spikes:1, toxicspikes:1, stealthrock:1};
				for (var i in sideConditions) {
					if (pokemon.hp && pokemon.side.removeSideCondition(i)) {
						this.add('-sideend', pokemon.side, this.getEffect(i).name, '[from] move: Gust', '[of] '+pokemon);
					}
				}
			}
		},
		secondary: false,
		target: "normal",
		type: "Flying"
	},
	sacredsword: {
		inherit: true,
		secondary: {
			chance: 10,
			self: {
				boosts: {
					atk: 1
				}
			}
		}
	},
	"aeroblast": {
		num: 177,
		accuracy: 95,
		basePower: 100,
		category: "Special",
		defensiveCategory: "Physical",
		desc: "",
		shortDesc: "",
		id: "aeroblast",
		isViable: true,
		name: "Aeroblast",
		pp: 5,
		priority: 0,
		secondary: {
			chance: 10,
			boosts: {
				atk: -1
			}
		},
		target: "any",
		type: "Flying"
	},
	"rocksmash": {
		num: 249,
		accuracy: 100,
		basePower: 40,
		category: "Physical",
		desc: "",
		shortDesc: "",
		id: "rocksmash",
		name: "Rock Smash",
		pp: 15,
		priority: 0,
		isContact: true,
		willCrit: true,
		secondary: false,
		target: "normal",
		type: "Fighting"
	},
	"peck": {
		num: 64,
		accuracy: 100,
		basePower: 40,
		category: "Physical",
		desc: "",
		shortDesc: "Always lands a critical hit.",
		id: "peck",
		name: "Peck",
		pp: 15,
		priority: 0,
		isContact: true,
		willCrit: true,
		secondary: false,
		target: "any",
		type: "Flying"
	},
	rocktomb: {
		inherit: true,
		accuracy: 95,
		basePower: 60
	},
	shadowclaw: {
		inherit: true,
		basePower: 80
	},
	"needlearm": {
		num: 302,
		accuracy: 100,
		basePower: 40,
		category: "Physical",
		desc: "",
		shortDesc: "",
		id: "needlearm",
		name: "Needle Arm",
		pp: 10,
		priority: 4,
		isContact: true,
		onTryHit: function(target, pokemon) {
			if (pokemon.activeTurns > 1) {
				this.debug('It\'s not your first turn out.');
				return false;
			}
		},
		secondary: {
			chance: 100,
			volatileStatus: 'flinch'
		},
		target: "normal",
		type: "Grass"
	},
	"psychocut": {
		num: 427,
		accuracy: 100,
		basePower: 50,
		category: "Physical",
		desc: "",
		shortDesc: "Always lands a critical hit.",
		id: "psychocut",
		isViable: true,
		name: "Psycho Cut",
		pp: 10,
		priority: 0,
		willCrit: true,
		secondary: false,
		target: "normal",
		type: "Psychic"
	},
	"glaciate": {
		num: 549,
		accuracy: 95,
		basePower: 100,
		category: "Special",
		desc: "Deals damage to all adjacent foes with a 100% chance to lower their Speed by 2 stages each.",
		shortDesc: "100% chance to lower the foe(s) Speed by 2.",
		id: "glaciate",
		name: "Glaciate",
		pp: 10,
		priority: 0,
		secondary: {
			chance: 100,
			boosts: {
				spe: -2
			}
		},
		target: "allAdjacentFoes",
		type: "Ice"
	},
	twister: {
		inherit: true,
		basePower: 80,
		type: "Flying"
	},
	razorshell: {
		inherit: true,
		basePower: 100,
		accuracy: 85
	},
	"skyattack": {
		num: 143,
		accuracy: 90,
		basePower: 100,
		category: "Physical",
		desc: "",
		shortDesc: "",
		id: "skyattack",
		name: "Sky Attack",
		pp: 10,
		priority: 0,
		secondary: {
			chance: 20,
			boosts: {
				def: -1
			}
		},
		target: "any",
		type: "Flying"
	},
	relicsong: {
		inherit: true,
		secondary: {
			chance: 20,
			self: {
				boosts: {
					atk: 1,
					spa: 1
				}
			}
		}
	},
	"electroweb": {
		num: 527,
		accuracy: 85,
		basePower: 70,
		category: "Special",
		desc: "",
		shortDesc: "",
		id: "electroweb",
		name: "Electroweb",
		pp: 10,
		priority: 0,
		secondary: {
			chance: 100,
			status: 'par'
		},
		target: "normal",
		type: "Electric"
	},
	"naturepower": {
                inherit: true,
                basePower: 80,
                accuracy: 100,
                priority: 0,
                category: "Physical",
                target: "normal",
                type: "Ground",
                onHit: false,
                onModifyMove: function(move, source, target) {
                        if (source.hasType('Grass')) {
                            move.basePower = 120;
                            }
		}
        },
        leechseed: {
        	inherit: true,
        	accuracy: 100
        },
        shellsmash: {
                inherit: true,
                boosts: {
                        atk: 2,
                        spa: 2,
                        spe: 2,
                        def: -1,
                        spd: -1
                },
                onModifyMove: function(move, user) {
                        if (user.ability === 'shellarmor') {
                                move.boosts = {
                                        spa: 1,
                                        atk: 1,
                                        spe: 1,
                                };
                        }
                }
        },
        "triattack": {
		num: 161,
		accuracy: 100,
		basePower: 30,
		category: "Special",
		desc: "",
		shortDesc: "",
		id: "triattack",
		isViable: true,
		name: "Tri Attack",
		pp: 10,
		priority: 0,
		multihit: 3,
		secondary: {
			chance: 25,
			onHit: function(target, source) {
				var result = this.random(3);
				if (result===0) {
					target.trySetStatus('brn', source);
				} else if (result===1) {
					target.trySetStatus('par', source);
				} else {
					target.trySetStatus('frz', source);
				}
			}
		},
		target: "normal",
		type: "Normal"
	},
	"razorwind": {
		num: 13,
		accuracy: 100,
		basePower: 30,
		category: "Special",
		desc: "",
		shortDesc: "",
		id: "razorwind",
		name: "Razor Wind",
		pp: 10,
		priority: 0,
		multihit: 2,
		critRatio: 2,
		secondary: false,
		target: "allAdjacentFoes",
		type: "Normal"
	},
	heartstamp: {
		inherit: true,
		basePower: 80
	}
};
<|endoftext|>


<commit_before>`use strict`

// this file configures knex and bookshelf
const environment = process.env.NODE_ENV || 'development';
const config = require('../knexfile.js')[environment];
const knex = require('knex')(config);
const bookshelf = require('bookshelf')(knex);
const cascadeDelete = require('bookshelf-cascade-delete');

// registry plugin resolves circular dependencies
bookshelf.plugin('registry');
// cascade delete automatically deletes related entries from join tables
bookshelf.plugin(cascadeDelete);

module.exports = {knex, bookshelf}
<commit_msg>added comments<commit_after>`use strict`

// this file configures knex and bookshelf
const environment = process.env.NODE_ENV || 'development';
const config = require('../knexfile.js')[environment];
const knex = require('knex')(config);
const bookshelf = require('bookshelf')(knex);
const cascadeDelete = require('bookshelf-cascade-delete');

// registry plugin resolves circular dependencies
bookshelf.plugin('registry');
// cascade delete automatically deletes related entries from join tables. (not currently deleting anything so this isn't really needed)
bookshelf.plugin(cascadeDelete);

module.exports = {knex, bookshelf}
<|endoftext|>


<commit_before>export default {
  debate: 'Fact-checking',
  history: 'History',
  approve: 'Confirm',
  refute: 'Refute',
  comments: 'Comments',
  community: 'Community',
  flagForm: {
    title: 'Why do you want to flag this comment ?',
    xAvailable: '{{count}} available',
    xAvailable_plural: '{{count}} available'
  },
  comment: {
    writeComment: 'Write a comment...',
    addSource: 'Add a source to turn this comment into a fact',
    post: 'Post Comment',
    post_reply: 'Post reply',
    deleteThread: 'Delete comment',
    deleteThread_plural: 'Delete thread',
    replies_hide: 'Hide replies',
    replies_show: 'Show replies ({{count}})',
    loadMore_replies: 'Load more replies ({{count}})',
    loadMore_comments: 'Load more comments ({{count}})',
    replyingTo: 'Replying to',
    approve: 'Approve',
    approve_reply: 'Approve this comment',
    refute: 'Refute',
    refute_reply: 'Refute this comment',
    revealForm: 'Add a source or comment'
  },
  video: {
    added: 'Added',
    edit: 'Edit Video',
    shiftStatements: 'Shift all statements (in seconds)'
  },
  speaker: {
    one: 'Speaker',
    remove: 'Remove speaker',
    confirmRemove: 'All statements made by {{speaker.full_name}} on this video will become orphans',
    add: 'Add Speaker',
    create: 'Create speaker "{{name}}"',
    search: 'Type a name to search',
    fullName: 'Full name',
    title: 'Title',
    titlePlaceholder: 'Politician, doctor, journalist...',
    titleFormat: '{{title}}',
    titleFormat_FR: 'French {{title}}'
  },
  statement: {
    remove: 'Remove statement',
    confirmRemove: 'Do you really want to remove this statement ?',
    textPlaceholder: 'Type a raw transcript of what the speaker says',
    noSpeakerTextPlaceholder: 'Describe what you see or select a speaker',
    text: 'Text',
    add: 'Add a Statement',
    abortAdd: 'Close Statement Form',
    autoscroll_enable: 'Enable Autoscroll',
    autoscroll_disable: 'Disable Autoscroll',
    reverseTimeLock_lock: 'Unlock time marker',
    reverseTimeLock_unlock: 'Lock time marker'
  },
  loading: {
    statements: 'Loading Statements',
    video: 'Loading Video'
  },
  tips: {
    firstStatement: 'You can <1>add a first statement</1> by clicking on the <3></3> icon next to the speaker\'s name',
    firstSpeaker: 'Start by adding a speaker using left column',
    noContentUnauthenticated: 'This video hasn\'t been verified yet. Login / Signup to contribute!'
  },
  presence: {
    viewer: '{{count}} viewer',
    viewer_plural: '{{count}} viewers',
    user: '{{count}} fact-checker',
    user_plural: '{{count}} fact-checkers'
  }
}
<commit_msg>Update videoDebate.js<commit_after>export default {
  debate: 'Fact-checking',
  history: 'History',
  approve: 'Confirm',
  refute: 'Refute',
  comments: 'Comments',
  community: 'Community',
  flagForm: {
    title: 'Why do you want to flag this comment?',
    xAvailable: '{{count}} available',
    xAvailable_plural: '{{count}} available'
  },
  comment: {
    writeComment: 'Write a comment...',
    addSource: 'Add a source to turn this comment into a fact',
    post: 'Post Comment',
    post_reply: 'Post reply',
    deleteThread: 'Delete comment',
    deleteThread_plural: 'Delete thread',
    replies_hide: 'Hide replies',
    replies_show: 'Show replies ({{count}})',
    loadMore_replies: 'Load more replies ({{count}})',
    loadMore_comments: 'Load more comments ({{count}})',
    replyingTo: 'Replying to',
    approve: 'Approve',
    approve_reply: 'Approve this comment',
    refute: 'Refute',
    refute_reply: 'Refute this comment',
    revealForm: 'Add a source or comment'
  },
  video: {
    added: 'Added',
    edit: 'Edit Video',
    shiftStatements: 'Shift all statements (in seconds)'
  },
  speaker: {
    one: 'Speaker',
    remove: 'Remove speaker',
    confirmRemove: 'All statements made by {{speaker.full_name}} on this video will become orphans',
    add: 'Add Speaker',
    create: 'Create speaker "{{name}}"',
    search: 'Type a name to search',
    fullName: 'Full name',
    title: 'Title',
    titlePlaceholder: 'Politician, doctor, journalist...',
    titleFormat: '{{title}}',
    titleFormat_FR: 'French {{title}}'
  },
  statement: {
    remove: 'Remove statement',
    confirmRemove: 'Do you really want to remove this statement?',
    textPlaceholder: 'Type a raw transcript of what the speaker says',
    noSpeakerTextPlaceholder: 'Describe what you see or select a speaker',
    text: 'Text',
    add: 'Add a Statement',
    abortAdd: 'Close Statement Form',
    autoscroll_enable: 'Enable Autoscroll',
    autoscroll_disable: 'Disable Autoscroll',
    reverseTimeLock_lock: 'Unlock time marker',
    reverseTimeLock_unlock: 'Lock time marker'
  },
  loading: {
    statements: 'Loading Statements',
    video: 'Loading Video'
  },
  tips: {
    firstStatement: 'You can <1>add a first statement</1> by clicking on the <3></3> icon next to the speaker\'s name',
    firstSpeaker: 'Start by adding a speaker using left column',
    noContentUnauthenticated: 'This video hasn\'t been verified yet. Login / Sign up to contribute!'
  },
  presence: {
    viewer: '{{count}} viewer',
    viewer_plural: '{{count}} viewers',
    user: '{{count}} fact-checker',
    user_plural: '{{count}} fact-checkers'
  }
}
<|endoftext|>


<commit_before>var pull = require('pull-stream')

function rate (s) {
  var recent = []
  var stream = pull.through(function (d) {
    stream.ts = Date.now()
    recent.push({size: d.length, ts: stream.ts})
    if(recent.length > 5)
      recent.shift()

  })

  stream.rate = function () {
    var ts = Date.now()
    if(recent.length > 1) {
      var rate = (recent.reduce(function (size, item) {
        return size + item.size
      }, 0)/1000000) / ((ts - recent[0].ts)/1000)

      return rate
    }
  }

  return stream
}

module.exports = rate
<commit_msg>stream.ts starts at stream creation time.<commit_after>var pull = require('pull-stream')

function rate (s) {
  var recent = []
  var stream = pull.through(function (d) {
    stream.ts = Date.now()
    recent.push({size: d.length, ts: stream.ts})
    if(recent.length > 5)
      recent.shift()

  })

  stream.ts = Date.now()

  stream.rate = function () {
    var ts = Date.now()
    if(recent.length > 1) {
      var rate = (recent.reduce(function (size, item) {
        return size + item.size
      }, 0)/1000000) / ((ts - recent[0].ts)/1000)

      return rate
    }
  }

  return stream
}

module.exports = rate
<|endoftext|>