<commit_before>(function () {

var
  global = this,
  previousFlotr = this.Flotr,
  Flotr;

Flotr = {
  _: _,
  bean: bean,
  version: "0.2.0-alpha",
  revision: ('$Revision: 192 $'.match(/(\d+)/) || [null,null])[1],
  author: ['Bas Wenneker', 'Fabien Ménager'],
  website: 'http://www.solutoire.com',
  isIphone: /iphone/i.test(navigator.userAgent),
  isIE: (navigator.appVersion.indexOf("MSIE") != -1 ? parseFloat(navigator.appVersion.split("MSIE")[1]) : false),

  /**
   * An object of the registered graph types. Use Flotr.addType(type, object)
   * to add your own type.
   */
  graphTypes: {},

  /**
   * The list of the registered plugins
   */
  plugins: {},

  /**
   * Can be used to add your own chart type.
   * @param {String} name - Type of chart, like 'pies', 'bars' etc.
   * @param {String} graphType - The object containing the basic drawing functions (draw, etc)
   */
  addType: function(name, graphType){
    Flotr.graphTypes[name] = graphType;
    Flotr.defaultOptions[name] = graphType.options || {};
    Flotr.defaultOptions.defaultType = Flotr.defaultOptions.defaultType || name;
  },

  /**
   * Can be used to add a plugin
   * @param {String} name - The name of the plugin
   * @param {String} plugin - The object containing the plugin's data (callbacks, options, function1, function2, ...)
   */
  addPlugin: function(name, plugin){
    Flotr.plugins[name] = plugin;
    Flotr.defaultOptions[name] = plugin.options || {};
  },

  /**
   * Draws the graph. This function is here for backwards compatibility with Flotr version 0.1.0alpha.
   * You could also draw graphs by directly calling Flotr.Graph(element, data, options).
   * @param {Element} el - element to insert the graph into
   * @param {Object} data - an array or object of dataseries
   * @param {Object} options - an object containing options
   * @param {Class} _GraphKlass_ - (optional) Class to pass the arguments to, defaults to Flotr.Graph
   * @return {Object} returns a new graph object and of course draws the graph.
   */
  draw: function(el, data, options, GraphKlass){
    GraphKlass = GraphKlass || Flotr.Graph;
    return new GraphKlass(el, data, options);
  },

  /**
   * Recursively merges two objects.
   * @param {Object} src - source object (likely the object with the least properties)
   * @param {Object} dest - destination object (optional, object with the most properties)
   * @return {Object} recursively merged Object
   * @TODO See if we can't remove this.
   */
  merge: function(src, dest){
    var i, v, result = dest || {};

    for (i in src) {
      v = src[i];
      if (v && typeof(v) === 'object') {
        if (v.constructor === Array) {
          result[i] = this._.clone(v);
        } else if (v.constructor !== RegExp && !this._.isElement(v)) {
          result[i] = Flotr.merge(v, (dest ? dest[i] : undefined));
        } else {
          result[i] = v;
        }
      } else {
        result[i] = v;
      }
    }

    return result;
  },

  /**
   * Recursively clones an object.
   * @param {Object} object - The object to clone
   * @return {Object} the clone
   * @TODO See if we can't remove this.
   */
  clone: function(object){
    return Flotr.merge(object, {});
  },

  /**
   * Function calculates the ticksize and returns it.
   * @param {Integer} noTicks - number of ticks
   * @param {Integer} min - lower bound integer value for the current axis
   * @param {Integer} max - upper bound integer value for the current axis
   * @param {Integer} decimals - number of decimals for the ticks
   * @return {Integer} returns the ticksize in pixels
   */
  getTickSize: function(noTicks, min, max, decimals){
    var delta = (max - min) / noTicks,
        magn = Flotr.getMagnitude(delta),
        tickSize = 10,
        norm = delta / magn; // Norm is between 1.0 and 10.0.

    if(norm < 1.5) tickSize = 1;
    else if(norm < 2.25) tickSize = 2;
    else if(norm < 3) tickSize = ((decimals === 0) ? 2 : 2.5);
    else if(norm < 7.5) tickSize = 5;

    return tickSize * magn;
  },

  /**
   * Default tick formatter.
   * @param {String, Integer} val - tick value integer
   * @param {Object} axisOpts - the axis' options
   * @return {String} formatted tick string
   */
  defaultTickFormatter: function(val, axisOpts){
    return val+'';
  },

  /**
   * Formats the mouse tracker values.
   * @param {Object} obj - Track value Object {x:..,y:..}
   * @return {String} Formatted track string
   */
  defaultTrackFormatter: function(obj){
    return '('+obj.x+', '+obj.y+')';
  },

  /**
   * Utility function to convert file size values in bytes to kB, MB, ...
   * @param value {Number} - The value to convert
   * @param precision {Number} - The number of digits after the comma (default: 2)
   * @param base {Number} - The base (default: 1000)
   */
  engineeringNotation: function(value, precision, base){
    var sizes =         ['Y','Z','E','P','T','G','M','k',''],
        fractionSizes = ['y','z','a','f','p','n','µ','m',''],
        total = sizes.length;

    base = base || 1000;
    precision = Math.pow(10, precision || 2);

    if (value === 0) return 0;

    if (value > 1) {
      while (total-- && (value >= base)) value /= base;
    }
    else {
      sizes = fractionSizes;
      total = sizes.length;
      while (total-- && (value < 1)) value *= base;
    }

    return (Math.round(value * precision) / precision) + sizes[total];
  },

  /**
   * Returns the magnitude of the input value.
   * @param {Integer, Float} x - integer or float value
   * @return {Integer, Float} returns the magnitude of the input value
   */
  getMagnitude: function(x){
    return Math.pow(10, Math.floor(Math.log(x) / Math.LN10));
  },
  toPixel: function(val){
    return Math.floor(val)+0.5;//((val-Math.round(val) < 0.4) ? (Math.floor(val)-0.5) : val);
  },
  toRad: function(angle){
    return -angle * (Math.PI/180);
  },
  floorInBase: function(n, base) {
    return base * Math.floor(n / base);
  },
  drawText: function(ctx, text, x, y, style) {
    if (!ctx.fillText) {
      ctx.drawText(text, x, y, style);
      return;
    }

    style = this._.extend({
      size: Flotr.defaultOptions.fontSize,
      color: '#000000',
      textAlign: 'left',
      textBaseline: 'bottom',
      weight: 1,
      angle: 0
    }, style);

    ctx.save();
    ctx.translate(x, y);
    ctx.rotate(style.angle);
    ctx.fillStyle = style.color;
    ctx.font = (style.weight > 1 ? "bold " : "") + (style.size*1.3) + "px sans-serif";
    ctx.textAlign = style.textAlign;
    ctx.textBaseline = style.textBaseline;
    ctx.fillText(text, 0, 0);
    ctx.restore();
  },
  getBestTextAlign: function(angle, style) {
    style = style || {textAlign: 'center', textBaseline: 'middle'};
    angle += Flotr.getTextAngleFromAlign(style);

    if (Math.abs(Math.cos(angle)) > 10e-3)
      style.textAlign    = (Math.cos(angle) > 0 ? 'right' : 'left');

    if (Math.abs(Math.sin(angle)) > 10e-3)
      style.textBaseline = (Math.sin(angle) > 0 ? 'top' : 'bottom');

    return style;
  },
  alignTable: {
    'right middle' : 0,
    'right top'    : Math.PI/4,
    'center top'   : Math.PI/2,
    'left top'     : 3*(Math.PI/4),
    'left middle'  : Math.PI,
    'left bottom'  : -3*(Math.PI/4),
    'center bottom': -Math.PI/2,
    'right bottom' : -Math.PI/4,
    'center middle': 0
  },
  getTextAngleFromAlign: function(style) {
    return Flotr.alignTable[style.textAlign+' '+style.textBaseline] || 0;
  },
  noConflict : function () {
    global.Flotr = previousFlotr;
    return this;
  }
};

global.Flotr = Flotr;

})();
<commit_msg>License.<commit_after>/**
 * Flotr2 (c) 2012 Carl Sutherland
 * MIT License
 * Special thanks to:
 * Flotr: http://code.google.com/p/flotr/ (fork)
 * Flot: https://github.com/flot/flot (original fork)
 */
(function () {

var
  global = this,
  previousFlotr = this.Flotr,
  Flotr;

Flotr = {
  _: _,
  bean: bean,
  version: "0.2.0-alpha",
  revision: ('$Revision: 192 $'.match(/(\d+)/) || [null,null])[1],
  author: ['Bas Wenneker', 'Fabien Ménager'],
  website: 'http://www.solutoire.com',
  isIphone: /iphone/i.test(navigator.userAgent),
  isIE: (navigator.appVersion.indexOf("MSIE") != -1 ? parseFloat(navigator.appVersion.split("MSIE")[1]) : false),

  /**
   * An object of the registered graph types. Use Flotr.addType(type, object)
   * to add your own type.
   */
  graphTypes: {},

  /**
   * The list of the registered plugins
   */
  plugins: {},

  /**
   * Can be used to add your own chart type.
   * @param {String} name - Type of chart, like 'pies', 'bars' etc.
   * @param {String} graphType - The object containing the basic drawing functions (draw, etc)
   */
  addType: function(name, graphType){
    Flotr.graphTypes[name] = graphType;
    Flotr.defaultOptions[name] = graphType.options || {};
    Flotr.defaultOptions.defaultType = Flotr.defaultOptions.defaultType || name;
  },

  /**
   * Can be used to add a plugin
   * @param {String} name - The name of the plugin
   * @param {String} plugin - The object containing the plugin's data (callbacks, options, function1, function2, ...)
   */
  addPlugin: function(name, plugin){
    Flotr.plugins[name] = plugin;
    Flotr.defaultOptions[name] = plugin.options || {};
  },

  /**
   * Draws the graph. This function is here for backwards compatibility with Flotr version 0.1.0alpha.
   * You could also draw graphs by directly calling Flotr.Graph(element, data, options).
   * @param {Element} el - element to insert the graph into
   * @param {Object} data - an array or object of dataseries
   * @param {Object} options - an object containing options
   * @param {Class} _GraphKlass_ - (optional) Class to pass the arguments to, defaults to Flotr.Graph
   * @return {Object} returns a new graph object and of course draws the graph.
   */
  draw: function(el, data, options, GraphKlass){
    GraphKlass = GraphKlass || Flotr.Graph;
    return new GraphKlass(el, data, options);
  },

  /**
   * Recursively merges two objects.
   * @param {Object} src - source object (likely the object with the least properties)
   * @param {Object} dest - destination object (optional, object with the most properties)
   * @return {Object} recursively merged Object
   * @TODO See if we can't remove this.
   */
  merge: function(src, dest){
    var i, v, result = dest || {};

    for (i in src) {
      v = src[i];
      if (v && typeof(v) === 'object') {
        if (v.constructor === Array) {
          result[i] = this._.clone(v);
        } else if (v.constructor !== RegExp && !this._.isElement(v)) {
          result[i] = Flotr.merge(v, (dest ? dest[i] : undefined));
        } else {
          result[i] = v;
        }
      } else {
        result[i] = v;
      }
    }

    return result;
  },

  /**
   * Recursively clones an object.
   * @param {Object} object - The object to clone
   * @return {Object} the clone
   * @TODO See if we can't remove this.
   */
  clone: function(object){
    return Flotr.merge(object, {});
  },

  /**
   * Function calculates the ticksize and returns it.
   * @param {Integer} noTicks - number of ticks
   * @param {Integer} min - lower bound integer value for the current axis
   * @param {Integer} max - upper bound integer value for the current axis
   * @param {Integer} decimals - number of decimals for the ticks
   * @return {Integer} returns the ticksize in pixels
   */
  getTickSize: function(noTicks, min, max, decimals){
    var delta = (max - min) / noTicks,
        magn = Flotr.getMagnitude(delta),
        tickSize = 10,
        norm = delta / magn; // Norm is between 1.0 and 10.0.

    if(norm < 1.5) tickSize = 1;
    else if(norm < 2.25) tickSize = 2;
    else if(norm < 3) tickSize = ((decimals === 0) ? 2 : 2.5);
    else if(norm < 7.5) tickSize = 5;

    return tickSize * magn;
  },

  /**
   * Default tick formatter.
   * @param {String, Integer} val - tick value integer
   * @param {Object} axisOpts - the axis' options
   * @return {String} formatted tick string
   */
  defaultTickFormatter: function(val, axisOpts){
    return val+'';
  },

  /**
   * Formats the mouse tracker values.
   * @param {Object} obj - Track value Object {x:..,y:..}
   * @return {String} Formatted track string
   */
  defaultTrackFormatter: function(obj){
    return '('+obj.x+', '+obj.y+')';
  },

  /**
   * Utility function to convert file size values in bytes to kB, MB, ...
   * @param value {Number} - The value to convert
   * @param precision {Number} - The number of digits after the comma (default: 2)
   * @param base {Number} - The base (default: 1000)
   */
  engineeringNotation: function(value, precision, base){
    var sizes =         ['Y','Z','E','P','T','G','M','k',''],
        fractionSizes = ['y','z','a','f','p','n','µ','m',''],
        total = sizes.length;

    base = base || 1000;
    precision = Math.pow(10, precision || 2);

    if (value === 0) return 0;

    if (value > 1) {
      while (total-- && (value >= base)) value /= base;
    }
    else {
      sizes = fractionSizes;
      total = sizes.length;
      while (total-- && (value < 1)) value *= base;
    }

    return (Math.round(value * precision) / precision) + sizes[total];
  },

  /**
   * Returns the magnitude of the input value.
   * @param {Integer, Float} x - integer or float value
   * @return {Integer, Float} returns the magnitude of the input value
   */
  getMagnitude: function(x){
    return Math.pow(10, Math.floor(Math.log(x) / Math.LN10));
  },
  toPixel: function(val){
    return Math.floor(val)+0.5;//((val-Math.round(val) < 0.4) ? (Math.floor(val)-0.5) : val);
  },
  toRad: function(angle){
    return -angle * (Math.PI/180);
  },
  floorInBase: function(n, base) {
    return base * Math.floor(n / base);
  },
  drawText: function(ctx, text, x, y, style) {
    if (!ctx.fillText) {
      ctx.drawText(text, x, y, style);
      return;
    }

    style = this._.extend({
      size: Flotr.defaultOptions.fontSize,
      color: '#000000',
      textAlign: 'left',
      textBaseline: 'bottom',
      weight: 1,
      angle: 0
    }, style);

    ctx.save();
    ctx.translate(x, y);
    ctx.rotate(style.angle);
    ctx.fillStyle = style.color;
    ctx.font = (style.weight > 1 ? "bold " : "") + (style.size*1.3) + "px sans-serif";
    ctx.textAlign = style.textAlign;
    ctx.textBaseline = style.textBaseline;
    ctx.fillText(text, 0, 0);
    ctx.restore();
  },
  getBestTextAlign: function(angle, style) {
    style = style || {textAlign: 'center', textBaseline: 'middle'};
    angle += Flotr.getTextAngleFromAlign(style);

    if (Math.abs(Math.cos(angle)) > 10e-3)
      style.textAlign    = (Math.cos(angle) > 0 ? 'right' : 'left');

    if (Math.abs(Math.sin(angle)) > 10e-3)
      style.textBaseline = (Math.sin(angle) > 0 ? 'top' : 'bottom');

    return style;
  },
  alignTable: {
    'right middle' : 0,
    'right top'    : Math.PI/4,
    'center top'   : Math.PI/2,
    'left top'     : 3*(Math.PI/4),
    'left middle'  : Math.PI,
    'left bottom'  : -3*(Math.PI/4),
    'center bottom': -Math.PI/2,
    'right bottom' : -Math.PI/4,
    'center middle': 0
  },
  getTextAngleFromAlign: function(style) {
    return Flotr.alignTable[style.textAlign+' '+style.textBaseline] || 0;
  },
  noConflict : function () {
    global.Flotr = previousFlotr;
    return this;
  }
};

global.Flotr = Flotr;

})();
<|endoftext|>


<commit_before>import { Component } from 'cerebral-snabbdom';
import Example from './example';
import { Icon, Sidenav } from '../../lib';
const N = '\n';

export default Component(() => (

    <Example code="import { Sidenav } from 'snabbdom-material';"/>
    <Example code={`${
    N}<Sidenav isOpen={sidenavOpen} onClose={closeSidenavFunc}>${
    N}  <Sidenav.Title showCloseButton>Menu</Sidenav.Title>${
    N}  <Sidenav.Item showIcon icon={<Icon name="user"/>} onClick={itemSelected}>Option A</Sidenav.Item>${
    N}  <Sidenav.Item showIcon icon={<Icon name="dashboard"/>} onClick={itemSelected} selected>Option B</Sidenav.Item>${
    N}  <Sidenav.Separator/>${
    N}  <Sidenav.Item showIcon icon={<Icon name="cog"/>} onClick={itemSelected}>Settings</Sidenav.Item>${
    N}</Sidenav>
    `}/>

See the sidenav above.

It's also possible to have a mini sidenav that is always on display.

    <Example code={`${
    N}<Sidenav mini>${
    N}  <Sidenav.Item showIcon icon={<Icon name="user"/>} onClick={itemSelected}/>${
    N}  <Sidenav.Item showIcon icon={<Icon name="dashboard"/>} onClick={itemSelected} selected/>${
    N}  <Sidenav.Separator/>${
    N}  <Sidenav.Item showIcon icon={<Icon name="settings"/>} onClick={itemSelected}/>${
    N}</Sidenav>${
    N}
${
    N}  Page Content${
    N}

    `}/>

      <Sidenav mini style={{
        float: 'left',
        position: 'relative',
        top: '0',
        height: '200px'
      }}>
        <Sidenav.Item showIcon icon={<Icon name="user"/>}/>
        <Sidenav.Item showIcon icon={<Icon name="dashboard"/>} selected/>
        <Sidenav.Separator/>
        <Sidenav.Item showIcon icon={<Icon name="settings"/>}/>
      </Sidenav>

        Page Content

));
<commit_msg>Fixed missing icon on sidenav demo page<commit_after>import { Component } from 'cerebral-snabbdom';
import Example from './example';
import { Icon, Sidenav } from '../../lib';
const N = '\n';

export default Component(() => (

    <Example code="import { Sidenav } from 'snabbdom-material';"/>
    <Example code={`${
    N}<Sidenav isOpen={sidenavOpen} onClose={closeSidenavFunc}>${
    N}  <Sidenav.Title showCloseButton>Menu</Sidenav.Title>${
    N}  <Sidenav.Item showIcon icon={<Icon name="user"/>} onClick={itemSelected}>Option A</Sidenav.Item>${
    N}  <Sidenav.Item showIcon icon={<Icon name="dashboard"/>} onClick={itemSelected} selected>Option B</Sidenav.Item>${
    N}  <Sidenav.Separator/>${
    N}  <Sidenav.Item showIcon icon={<Icon name="cog"/>} onClick={itemSelected}>Settings</Sidenav.Item>${
    N}</Sidenav>
    `}/>

See the sidenav above.

It's also possible to have a mini sidenav that is always on display.

    <Example code={`${
    N}<Sidenav mini>${
    N}  <Sidenav.Item showIcon icon={<Icon name="user"/>} onClick={itemSelected}/>${
    N}  <Sidenav.Item showIcon icon={<Icon name="dashboard"/>} onClick={itemSelected} selected/>${
    N}  <Sidenav.Separator/>${
    N}  <Sidenav.Item showIcon icon={<Icon name="settings"/>} onClick={itemSelected}/>${
    N}</Sidenav>${
    N}
${
    N}  Page Content${
    N}

    `}/>

      <Sidenav mini style={{
        float: 'left',
        position: 'relative',
        top: '0',
        height: '200px'
      }}>
        <Sidenav.Item showIcon icon={<Icon name="person"/>}/>
        <Sidenav.Item showIcon icon={<Icon name="dashboard"/>} selected/>
        <Sidenav.Separator/>
        <Sidenav.Item showIcon icon={<Icon name="settings"/>}/>
      </Sidenav>

        Page Content

));
<|endoftext|>


<commit_before>// Copyright 2013-2020, University of Colorado Boulder

/**
 * A numeric range.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 * @author Andrew Adare
 * @author Chris Klusendorf (PhET Interactive Simulations)
 */

import IOType from '../../tandem/js/types/IOType.js';
import dot from './dot.js';

class Range {
  /**
   * @param {number} min - the minimum value of the range
   * @param {number} max - the maximum value of the range
   */
  constructor( min, max ) {

    assert && assert( min <= max, `max must be >= min. min: ${min}, max: ${max}` );

    // @private {number} - the minimum value of the range
    this._min = min;

    // @private {number} - the maximum value of the range
    this._max = max;
  }

  /**
   * Getter for min
   * @returns {number}
   * @public
   */
  getMin() {
    return this._min;
  }

  get min() {
    return this.getMin();
  }

  /**
   * Setter for min
   * @public
   * @param {number} min
   */
  setMin( min ) {
    assert && assert( min <= this._max, `min must be <= max: ${min}` );
    this._min = min;
  }

  set min( min ) {
    this.setMin( min );
  }

  /**
   * Getter for max
   * @returns {number}
   * @public
   */
  getMax() {
    return this._max;
  }

  get max() {
    return this.getMax();
  }

  /**
   * Setter for max
   * @public
   * @param {number} max
   */
  setMax( max ) {
    assert && assert( this._min <= max, `max must be >= to min: ${max}` );
    this._max = max;
  }

  set max( max ) {
    this.setMax( max );
  }

  /**
   * Sets the minimum and maximum value of the range
   * @public
   * @param {number} min
   * @param {number} max
   */
  setMinMax( min, max ) {
    assert && assert( min <= max, `max must be >= to min. min: ${min}, max: ${max}` );
    this._min = min;
    this._max = max;
  }

  /**
   * Makes a copy of this range
   * @public
   * @returns {Range}
   */
  copy() {
    return new Range( this._min, this._max ); // eslint-disable-line no-html-constructors
  }

  /**
   * Gets the length of this range, that is the difference between the maximum and minimum value of this range
   * @public
   * @returns {number}
   */
  getLength() {
    return this._max - this._min;
  }

  /**
   * Gets the center of this range, that is the average value of the maximum and minimum value of this range
   * @public
   * @returns {number}
   */
  getCenter() {
    return ( this._max + this._min ) / 2;
  }

  /**
   * Determines if this range contains the value
   * @public
   * @param {number} value
   * @returns {boolean}
   */
  contains( value ) {
    return ( value >= this._min ) && ( value <= this._max );
  }

  /**
   * Does this range contain the specified range?
   * @public
   * @param {Range} range
   * @returns {boolean}
   */
  containsRange( range ) {
    return ( this._min <= range.min ) && ( this._max >= range.max );
  }

  /**
   * Determine if this range overlaps (intersects) with another range
   * @public
   * @param {Range} range
   * @returns {boolean}
   */
  intersects( range ) {
    return ( this._max >= range.min ) && ( range.max >= this._min );
  }

  /**
   * Do the two ranges overlap with one another?  Note that this assumes that
   * This is a open interval.
   * @public
   * @param {Range} range
   * @returns {boolean}
   */
  intersectsExclusive( range ) {
    return ( this._max > range.min ) && ( range.max > this._min );
  }

  /**
   * Converts the attributes of this range to a string
   * @public
   * @returns {string}
   */
  toString() {
    return `[Range (min:${this._min} max:${this._max})]`;
  }

  /**
   * Constrains a value to the range.
   * @public
   * @param {number} value
   * @returns {number}
   */
  constrainValue( value ) {
    return Math.min( Math.max( value, this._min ), this._max );
  }

  /**
   * Determines if this Range is equal to some object.
   * @public
   * @param {*} object
   * @returns {boolean}
   */
  equals( object ) {
    return ( this.constructor === object.constructor ) &&
           ( this._min === object.min ) &&
           ( this._max === object.max );
  }

  /**
   * Given a value, normalize it to this Range's length, returning a value between 0 and 1 for values contained in
   * the Range. If the value is not contained in Range, then the return value will not be between 0 and 1.
   * @public
   *
   * @param {number} value
   * @returns {number}
   */
  getNormalizedValue( value ) {
    assert && assert( typeof value === 'number' );
    assert && assert( this.getLength() !== 0, 'cannot get normalized value without a range length' );
    return ( value - this.min ) / this.getLength();
  }

  /**
   * In https://github.com/phetsims/dot/issues/57, defaultValue was moved to RangeWithValue.
   * This ES5 getter catches programming errors where defaultValue is still used with Range.
   */
  get defaultValue() {
    throw new Error( 'defaultValue is undefined, did you mean to use RangeWithValue?' );
  }
}

dot.register( 'Range', Range );

Range.RangeIO = new IOType( 'RangeIO', {
  valueType: Range,
  documentation: 'A range with "min" and a "max" members.',
  toStateObject: range => ( { min: range.min, max: range.max } ),
  fromStateObject: stateObject => new Range( stateObject.min, stateObject.max ) // eslint-disable-line no-html-constructors
} );

export default Range;<commit_msg>Use NumberIO for RangeIO toStateObject/fromStateObject, see https://github.com/phetsims/axon/issues/356<commit_after>// Copyright 2013-2020, University of Colorado Boulder

/**
 * A numeric range.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 * @author Andrew Adare
 * @author Chris Klusendorf (PhET Interactive Simulations)
 */

import IOType from '../../tandem/js/types/IOType.js';
import NumberIO from '../../tandem/js/types/NumberIO.js';
import dot from './dot.js';

class Range {
  /**
   * @param {number} min - the minimum value of the range
   * @param {number} max - the maximum value of the range
   */
  constructor( min, max ) {

    assert && assert( min <= max, `max must be >= min. min: ${min}, max: ${max}` );

    // @private {number} - the minimum value of the range
    this._min = min;

    // @private {number} - the maximum value of the range
    this._max = max;
  }

  /**
   * Getter for min
   * @returns {number}
   * @public
   */
  getMin() {
    return this._min;
  }

  get min() {
    return this.getMin();
  }

  /**
   * Setter for min
   * @public
   * @param {number} min
   */
  setMin( min ) {
    assert && assert( min <= this._max, `min must be <= max: ${min}` );
    this._min = min;
  }

  set min( min ) {
    this.setMin( min );
  }

  /**
   * Getter for max
   * @returns {number}
   * @public
   */
  getMax() {
    return this._max;
  }

  get max() {
    return this.getMax();
  }

  /**
   * Setter for max
   * @public
   * @param {number} max
   */
  setMax( max ) {
    assert && assert( this._min <= max, `max must be >= to min: ${max}` );
    this._max = max;
  }

  set max( max ) {
    this.setMax( max );
  }

  /**
   * Sets the minimum and maximum value of the range
   * @public
   * @param {number} min
   * @param {number} max
   */
  setMinMax( min, max ) {
    assert && assert( min <= max, `max must be >= to min. min: ${min}, max: ${max}` );
    this._min = min;
    this._max = max;
  }

  /**
   * Makes a copy of this range
   * @public
   * @returns {Range}
   */
  copy() {
    return new Range( this._min, this._max ); // eslint-disable-line no-html-constructors
  }

  /**
   * Gets the length of this range, that is the difference between the maximum and minimum value of this range
   * @public
   * @returns {number}
   */
  getLength() {
    return this._max - this._min;
  }

  /**
   * Gets the center of this range, that is the average value of the maximum and minimum value of this range
   * @public
   * @returns {number}
   */
  getCenter() {
    return ( this._max + this._min ) / 2;
  }

  /**
   * Determines if this range contains the value
   * @public
   * @param {number} value
   * @returns {boolean}
   */
  contains( value ) {
    return ( value >= this._min ) && ( value <= this._max );
  }

  /**
   * Does this range contain the specified range?
   * @public
   * @param {Range} range
   * @returns {boolean}
   */
  containsRange( range ) {
    return ( this._min <= range.min ) && ( this._max >= range.max );
  }

  /**
   * Determine if this range overlaps (intersects) with another range
   * @public
   * @param {Range} range
   * @returns {boolean}
   */
  intersects( range ) {
    return ( this._max >= range.min ) && ( range.max >= this._min );
  }

  /**
   * Do the two ranges overlap with one another?  Note that this assumes that
   * This is a open interval.
   * @public
   * @param {Range} range
   * @returns {boolean}
   */
  intersectsExclusive( range ) {
    return ( this._max > range.min ) && ( range.max > this._min );
  }

  /**
   * Converts the attributes of this range to a string
   * @public
   * @returns {string}
   */
  toString() {
    return `[Range (min:${this._min} max:${this._max})]`;
  }

  /**
   * Constrains a value to the range.
   * @public
   * @param {number} value
   * @returns {number}
   */
  constrainValue( value ) {
    return Math.min( Math.max( value, this._min ), this._max );
  }

  /**
   * Determines if this Range is equal to some object.
   * @public
   * @param {*} object
   * @returns {boolean}
   */
  equals( object ) {
    return ( this.constructor === object.constructor ) &&
           ( this._min === object.min ) &&
           ( this._max === object.max );
  }

  /**
   * Given a value, normalize it to this Range's length, returning a value between 0 and 1 for values contained in
   * the Range. If the value is not contained in Range, then the return value will not be between 0 and 1.
   * @public
   *
   * @param {number} value
   * @returns {number}
   */
  getNormalizedValue( value ) {
    assert && assert( typeof value === 'number' );
    assert && assert( this.getLength() !== 0, 'cannot get normalized value without a range length' );
    return ( value - this.min ) / this.getLength();
  }

  /**
   * In https://github.com/phetsims/dot/issues/57, defaultValue was moved to RangeWithValue.
   * This ES5 getter catches programming errors where defaultValue is still used with Range.
   */
  get defaultValue() {
    throw new Error( 'defaultValue is undefined, did you mean to use RangeWithValue?' );
  }
}

dot.register( 'Range', Range );

Range.RangeIO = new IOType( 'RangeIO', {
  valueType: Range,
  documentation: 'A range with "min" and a "max" members.',
  toStateObject: range => ( {
    min: NumberIO.toStateObject( range.min ),
    max: NumberIO.toStateObject( range.max )
  } ),

  // eslint-disable-next-line no-html-constructors
  fromStateObject: stateObject => new Range(
    NumberIO.fromStateObject( stateObject.min ),
    NumberIO.fromStateObject( stateObject.max )
  )
} );

export default Range;<|endoftext|>


<commit_before>var Shelf = React.createClass({

	getInitialState: function() {
		return {data: {'read': [], 'currently-reading': []}};
	},

	loadBooks: function() {
        $.get(this.props.url, function(result) {
            this.setState({data: JSON.parse(result)});
        }.bind(this));
	},

	componentDidMount: function() {
		this.loadBooks();
	},

    render: function() {
        var cr_shelf = this.state.data['currently-reading'].map(function(book, index) {
            return (
                <Book data={book} key={index} />
            );
        });

        var read_shelf = [];
        var read_books = this.state.data['read'];
        for (var i = 0; i < Math.min(read_books.length, max_disp); i++) {
            read_shelf.push(<Book data={read_books[i]} key={i} />);
        }

        if (this.state.data['currently-reading'].length || this.state.data['read'].length) {
            return (

 currently reading

                            {cr_shelf}

 read

                            {read_shelf}

                         more

            );
        }
        else
            return (

            );
    }
});

var Book = React.createClass({
    render: function() {
        var book = this.props.data;
        return (

        );
    }
})

var url = "https://dl.dropboxusercontent.com/u/96903373/book_data.json";
var max_disp = 12;

React.render(
    <Shelf url={url} />,
    document.getElementById('content')
);
<commit_msg>consistency<commit_after>var Shelf = React.createClass({

	getInitialState: function() {
		return {data: {'read': [], 'currently-reading': []}};
	},

	loadBooks: function() {
        $.get(this.props.url, function(result) {
            this.setState({data: JSON.parse(result)});
        }.bind(this));
	},

	componentDidMount: function() {
		this.loadBooks();
	},

    render: function() {
        var cr_shelf = [];
        var reading_books = this.state.data['currently-reading'];
        for (var i = 0; i < Math.min(reading_books.length, max_disp); i++) {
            cr_shelf.push(<Book data={reading_books[i]} key={i} />);
        }

        var read_shelf = [];
        var read_books = this.state.data['read'];
        for (var i = 0; i < Math.min(read_books.length, max_disp); i++) {
            read_shelf.push(<Book data={read_books[i]} key={i} />);
        }

        if (this.state.data['currently-reading'].length || this.state.data['read'].length) {
            return (

 currently reading

                            {cr_shelf}

 read

                            {read_shelf}

                         more

            );
        }
        else
            return (

            );
    }
});

var Book = React.createClass({
    render: function() {
        var book = this.props.data;
        return (

        );
    }
})

var url = "https://dl.dropboxusercontent.com/u/96903373/book_data.json";
var max_disp = 12;

React.render(
    <Shelf url={url} />,
    document.getElementById('content')
);
<|endoftext|>


<commit_before>//Translated from stone.rb using babyruby2js
'use strict';

var main = require('./main');
var Grid = require('./Grid');
var Group = require('./Group');

var EMPTY = main.EMPTY, DIR0 = main.DIR0, DIR3 = main.DIR3;

/** @class A "stone" stores everything we want to keep track of regarding an intersection on the board.
 *  By extension, an empty intersection is also a stone, with a color attribute equals to EMPTY.
 *  This class is also the entry point for moves in general, so it has methods to play or undo,
 *  and verify if a planned move is authorized.
 *  public read-only attribute: goban, group, color, i, j, neighbors
 */
function Stone(goban, i, j, color) {
    this.goban = goban;
    this.i = i;
    this.j = j;
    this.color = color;
    this.group = null;
    this.neighbors = []; // direct neighbors (top, right, bottom, left)
    this.allNeighbors = []; // including diagonals - top, top-right, right, bottom-right, etc.
}
module.exports = Stone;

Stone.XY_AROUND = [[0, 1], [1, 0], [0, -1], [-1, 0]]; // top, right, bottom, left
Stone.XY_DIAGONAL = [[1, 1], [1, -1], [-1, -1], [-1, 1]]; // top-right, bottom-right, bottom-left, top-left

Stone.prototype.clear = function () {
    this.color = EMPTY;
    this.group = null;
};

// Computes each stone's neighbors (called for each stone after init)
// NB: Stones next to side have only 3 neighbors, and the corner stones have 2
Stone.prototype.findNeighbors = function () {
    var coords = Stone.XY_AROUND, diags = Stone.XY_DIAGONAL, stone;
    // NB: order in which we push neighbors should be irrelevant but is not at this point.
    // 2 places:
    // - TestGroup looks at group merging numbers etc. (no worry here)
    // - TestPotentialTerritory#testBigEmptySpace has a group that is seen dead or not depending on order.
    // The latter one should be fixed one day.
    for (var i = DIR3; i >= DIR0; i--) {
        stone = this.goban.stoneAt(this.i + coords[i][0], this.j + coords[i][1]);
        if (stone !== main.BORDER) this.neighbors.push(stone);
    }
    for (i = DIR0; i <= DIR3; i++) {
        stone = this.goban.stoneAt(this.i + coords[i][0], this.j + coords[i][1]);
        this.allNeighbors.push(stone);
        stone = this.goban.stoneAt(this.i + diags[i][0], this.j + diags[i][1]);
        this.allNeighbors.push(stone);
    }
};

Stone.prototype.toString = function () {
    if (this.color === EMPTY) {
        return 'empty:' + this.asMove();
    } else {
        return 'stone' + Grid.colorToChar(this.color) + ':' + this.asMove();
    }
};

// Returns "c3" for a stone in 3,3
Stone.prototype.asMove = function () {
    return Grid.xy2move(this.i, this.j);
};

Stone.prototype.debugDump = function () {
    return this.toString(); // we could add more info
};

// Returns a string with the list of empty points, sorted (debug only)
Stone.prototype.emptiesDump = function () {
    return this.empties().map(function (s) {
        return s.asMove();
    }).sort().join(',');
};

Stone.prototype.isEmpty = function () {
    return this.color === EMPTY;
};

Stone.validMove = function (goban, i, j, color) {
    // Remark: no log here because of the noise created with web server mode
    if (!goban.validMove(i, j)) { // also checks if empty
        return false;
    }
    var stone = goban.stoneAt(i, j);
    if (stone.moveIsSuicide(color)) {
        return false;
    }
    if (stone.moveIsKo(color)) {
        return false;
    }
    return true;
};

// Is a move a suicide?
// not a suicide if 1 free life around
// or if one enemy group will be killed
// or if the result of the merge of ally groups will have more than 0 life
Stone.prototype.moveIsSuicide = function (color) {
    for (var i = this.neighbors.length - 1; i >= 0; i--) {
        var s = this.neighbors[i];
        if (s.color === EMPTY) {
            return false;
        } else if (s.color !== color) {
            if (s.group.lives === 1) return false; // we kill 1 group
        } else {
            if (s.group.lives > 1) return false; // our neighbor group will still have lives left
        }
    }
    // $log.debug("move #{@i}, #{@j}, color:#{color} would be a suicide") if $debug
    return true;
};

// Is a move a ko?
// if the move would kill with stone i,j a single stone A (and nothing else!)
// and the previous move killed with stone A a single stone B in same position i,j
// then it is a ko
Stone.prototype.moveIsKo = function (color) {
    // 1) Must kill a single group
    // NB: we don't need to iterate on unique groups because on condition #2 below
    var groupA = null;
    //TODO: check here if we always have the unique allies ready anyway
    for (var n = this.neighbors.length - 1; n >= 0; n--) {
        var enemy = this.neighbors[n].group;
        if (!enemy || enemy.color !== 1 - color) continue;
        if (enemy.lives !== 1) continue;
        if (groupA) return false;
        groupA = enemy;
    }
    if (!groupA) return false;

    // 2) This killed group must be a single stone A
    if (groupA.stones.length !== 1) {
        return false;
    }
    var stoneA = groupA.stones[0];
    // 3) Stone A was played just now
    if (this.goban.previousStone() !== stoneA) {
        return false;
    }
    // 4) Stone B was killed by A in same position we are looking at
    var groupB = this.goban.killedGroups[this.goban.killedGroups.length-1];
    if (groupB.killedBy !== stoneA) {
        return false;
    }
    if (groupB.stones.length !== 1) {
        return false;
    }
    var stoneB = groupB.stones[0];
    if (stoneB.i !== this.i || stoneB.j !== this.j) {
        return false;
    }
    //if (main.debug) main.log.debug('ko in ' + this.toString() + ', color:' + color + ' cannot be played now');
    return true;
};

Stone.prototype.die = function () {
    this.color = EMPTY;
    this.group = null;
};

Stone.prototype.resuscitateIn = function (group) {
    this.group = group;
    this.color = group.color;
};

Stone.playAt = function (goban, i, j, color) {
    var stone = goban.putDown(i, j);
    stone._putDown(color);
    return stone;
};

// Called to undo a single stone (the main undo feature relies on this)
Stone.undo = function (goban) {
    var stone = goban.takeBack();
    if (!stone) return;
    if (main.debug) main.log.debug('Stone.undo ' + stone);
    stone._takeBack();
};

// Called for each new stone played
Stone.prototype._putDown = function (color) {
    this.color = color;
    if (main.debug) main.log.debug('put_down: ' + this.toString());

    var allies = this.uniqueAllies(color); // note we would not need unique if group#merge ignores dupes
    if (allies.length === 0) {
        this.group = this.goban.newGroup(this, this.numEmpties());
    } else {
        this.group = allies[0];
        this.group.connectStone(this);
    }
    // kill before merging to get the right live-count in merged subgroups
    var enemies = this.uniqueAllies(1 - color);
    for (var e = enemies.length - 1; e >= 0; e--) {
        enemies[e].attackedBy(this);
    }
    for (var a = 1; a < allies.length; a++) {
        this.group.merge(allies[a], this);
    }
};

Stone.prototype._takeBack = function () {
    if (main.debugGroup) main.log.debug('_takeBack: ' + this.toString() + ' from group ' + this.group);

    this.group.unmergeFrom(this);
    this.group.disconnectStone(this);
    var enemies = this.uniqueAllies(1 - this.color);
    for (var e = enemies.length - 1; e >= 0; e--) {
        enemies[e].notAttackedAnymore(this);
    }
    var logGroup;
    if (main.debugGroup) logGroup = this.group;

    this.group = null;
    this.color = EMPTY;
    Group.resuscitateFrom(this, this.goban);
    if (main.debugGroup) main.log.debug('_takeBack: end; main group: ' + logGroup.debugDump());
};

Stone.prototype.setGroupOnMerge = function (newGroup) {
    this.group = newGroup;
};

Stone.prototype.uniqueAllies = function (color) {
    var allies = [];
    var neighbors = this.neighbors;
    for (var i = neighbors.length - 1; i >= 0; i--) {
        var s = neighbors[i];
        if (s.color === color && allies.indexOf(s.group) < 0) {
            allies.push(s.group);
        }
    }
    return allies;
};

Stone.prototype.uniqueEnemies = function (allyColor) {
    return this.uniqueAllies(1 - allyColor);
};

// Returns the empty points around this stone
Stone.prototype.empties = function () {
    var empties = [], neighbors = this.neighbors;
    for (var i = neighbors.length - 1; i >= 0; i--) {
        var s = neighbors[i];
        if (s.color === EMPTY) empties.push(s);
    }
    return empties;
};

// Number of empty points around this stone
Stone.prototype.numEmpties = function () {
    var count = 0, neighbors = this.neighbors;
    for (var i = neighbors.length - 1; i >= 0; i--) {
        if (neighbors[i].color === EMPTY) count++;
    }
    return count;
};

/** Returns the count of ally stones around.
 *  If an array is passed, the stones are pushed on it. */
Stone.prototype.allyStones = function (color, array) {
    var count = 0, neighbors = this.neighbors;
    for (var i = neighbors.length - 1; i >= 0; i--) {
        if (neighbors[i].color === color) {
            if (array) array.push(neighbors[i]);
            count++;
        }
    }
    return count;
};

Stone.prototype.isNextTo = function (group) {
    var neighbors = this.neighbors;
    for (var i = neighbors.length - 1; i >= 0; i--) {
        if (neighbors[i].group === group) return true;
    }
    return false;
};
<commit_msg>Clearer debug log for stones<commit_after>//Translated from stone.rb using babyruby2js
'use strict';

var main = require('./main');
var Grid = require('./Grid');
var Group = require('./Group');

var EMPTY = main.EMPTY, DIR0 = main.DIR0, DIR3 = main.DIR3;

/** @class A "stone" stores everything we want to keep track of regarding an intersection on the board.
 *  By extension, an empty intersection is also a stone, with a color attribute equals to EMPTY.
 *  This class is also the entry point for moves in general, so it has methods to play or undo,
 *  and verify if a planned move is authorized.
 *  public read-only attribute: goban, group, color, i, j, neighbors
 */
function Stone(goban, i, j, color) {
    this.goban = goban;
    this.i = i;
    this.j = j;
    this.color = color;
    this.group = null;
    this.neighbors = []; // direct neighbors (top, right, bottom, left)
    this.allNeighbors = []; // including diagonals - top, top-right, right, bottom-right, etc.
}
module.exports = Stone;

Stone.XY_AROUND = [[0, 1], [1, 0], [0, -1], [-1, 0]]; // top, right, bottom, left
Stone.XY_DIAGONAL = [[1, 1], [1, -1], [-1, -1], [-1, 1]]; // top-right, bottom-right, bottom-left, top-left

Stone.prototype.clear = function () {
    this.color = EMPTY;
    this.group = null;
};

// Computes each stone's neighbors (called for each stone after init)
// NB: Stones next to side have only 3 neighbors, and the corner stones have 2
Stone.prototype.findNeighbors = function () {
    var coords = Stone.XY_AROUND, diags = Stone.XY_DIAGONAL, stone;
    // NB: order in which we push neighbors should be irrelevant but is not at this point.
    // 2 places:
    // - TestGroup looks at group merging numbers etc. (no worry here)
    // - TestPotentialTerritory#testBigEmptySpace has a group that is seen dead or not depending on order.
    // The latter one should be fixed one day.
    for (var i = DIR3; i >= DIR0; i--) {
        stone = this.goban.stoneAt(this.i + coords[i][0], this.j + coords[i][1]);
        if (stone !== main.BORDER) this.neighbors.push(stone);
    }
    for (i = DIR0; i <= DIR3; i++) {
        stone = this.goban.stoneAt(this.i + coords[i][0], this.j + coords[i][1]);
        this.allNeighbors.push(stone);
        stone = this.goban.stoneAt(this.i + diags[i][0], this.j + diags[i][1]);
        this.allNeighbors.push(stone);
    }
};

Stone.prototype.toString = function () {
    if (this.color === EMPTY) {
        return this.asMove();
    } else {
        return (this.color ? 'W' : 'B') + '-' + this.asMove();
    }
};

// Returns "c3" for a stone in 3,3
Stone.prototype.asMove = function () {
    return Grid.xy2move(this.i, this.j);
};

Stone.prototype.debugDump = function () {
    return this.toString(); // we could add more info
};

// Returns a string with the list of empty points, sorted (debug only)
Stone.prototype.emptiesDump = function () {
    return this.empties().map(function (s) {
        return s.asMove();
    }).sort().join(',');
};

Stone.prototype.isEmpty = function () {
    return this.color === EMPTY;
};

Stone.validMove = function (goban, i, j, color) {
    // Remark: no log here because of the noise created with web server mode
    if (!goban.validMove(i, j)) { // also checks if empty
        return false;
    }
    var stone = goban.stoneAt(i, j);
    if (stone.moveIsSuicide(color)) {
        return false;
    }
    if (stone.moveIsKo(color)) {
        return false;
    }
    return true;
};

// Is a move a suicide?
// not a suicide if 1 free life around
// or if one enemy group will be killed
// or if the result of the merge of ally groups will have more than 0 life
Stone.prototype.moveIsSuicide = function (color) {
    for (var i = this.neighbors.length - 1; i >= 0; i--) {
        var s = this.neighbors[i];
        if (s.color === EMPTY) {
            return false;
        } else if (s.color !== color) {
            if (s.group.lives === 1) return false; // we kill 1 group
        } else {
            if (s.group.lives > 1) return false; // our neighbor group will still have lives left
        }
    }
    // $log.debug("move #{@i}, #{@j}, color:#{color} would be a suicide") if $debug
    return true;
};

// Is a move a ko?
// if the move would kill with stone i,j a single stone A (and nothing else!)
// and the previous move killed with stone A a single stone B in same position i,j
// then it is a ko
Stone.prototype.moveIsKo = function (color) {
    // 1) Must kill a single group
    // NB: we don't need to iterate on unique groups because on condition #2 below
    var groupA = null;
    //TODO: check here if we always have the unique allies ready anyway
    for (var n = this.neighbors.length - 1; n >= 0; n--) {
        var enemy = this.neighbors[n].group;
        if (!enemy || enemy.color !== 1 - color) continue;
        if (enemy.lives !== 1) continue;
        if (groupA) return false;
        groupA = enemy;
    }
    if (!groupA) return false;

    // 2) This killed group must be a single stone A
    if (groupA.stones.length !== 1) {
        return false;
    }
    var stoneA = groupA.stones[0];
    // 3) Stone A was played just now
    if (this.goban.previousStone() !== stoneA) {
        return false;
    }
    // 4) Stone B was killed by A in same position we are looking at
    var groupB = this.goban.killedGroups[this.goban.killedGroups.length-1];
    if (groupB.killedBy !== stoneA) {
        return false;
    }
    if (groupB.stones.length !== 1) {
        return false;
    }
    var stoneB = groupB.stones[0];
    if (stoneB.i !== this.i || stoneB.j !== this.j) {
        return false;
    }
    //if (main.debug) main.log.debug('ko in ' + this.toString() + ', color:' + color + ' cannot be played now');
    return true;
};

Stone.prototype.die = function () {
    this.color = EMPTY;
    this.group = null;
};

Stone.prototype.resuscitateIn = function (group) {
    this.group = group;
    this.color = group.color;
};

Stone.playAt = function (goban, i, j, color) {
    var stone = goban.putDown(i, j);
    stone._putDown(color);
    return stone;
};

// Called to undo a single stone (the main undo feature relies on this)
Stone.undo = function (goban) {
    var stone = goban.takeBack();
    if (!stone) return;
    if (main.debug) main.log.debug('Stone.undo ' + stone);
    stone._takeBack();
};

// Called for each new stone played
Stone.prototype._putDown = function (color) {
    this.color = color;
    if (main.debug) main.log.debug('put_down: ' + this.toString());

    var allies = this.uniqueAllies(color); // note we would not need unique if group#merge ignores dupes
    if (allies.length === 0) {
        this.group = this.goban.newGroup(this, this.numEmpties());
    } else {
        this.group = allies[0];
        this.group.connectStone(this);
    }
    // kill before merging to get the right live-count in merged subgroups
    var enemies = this.uniqueAllies(1 - color);
    for (var e = enemies.length - 1; e >= 0; e--) {
        enemies[e].attackedBy(this);
    }
    for (var a = 1; a < allies.length; a++) {
        this.group.merge(allies[a], this);
    }
};

Stone.prototype._takeBack = function () {
    if (main.debugGroup) main.log.debug('_takeBack: ' + this.toString() + ' from group ' + this.group);

    this.group.unmergeFrom(this);
    this.group.disconnectStone(this);
    var enemies = this.uniqueAllies(1 - this.color);
    for (var e = enemies.length - 1; e >= 0; e--) {
        enemies[e].notAttackedAnymore(this);
    }
    var logGroup;
    if (main.debugGroup) logGroup = this.group;

    this.group = null;
    this.color = EMPTY;
    Group.resuscitateFrom(this, this.goban);
    if (main.debugGroup) main.log.debug('_takeBack: end; main group: ' + logGroup.debugDump());
};

Stone.prototype.setGroupOnMerge = function (newGroup) {
    this.group = newGroup;
};

Stone.prototype.uniqueAllies = function (color) {
    var allies = [];
    var neighbors = this.neighbors;
    for (var i = neighbors.length - 1; i >= 0; i--) {
        var s = neighbors[i];
        if (s.color === color && allies.indexOf(s.group) < 0) {
            allies.push(s.group);
        }
    }
    return allies;
};

Stone.prototype.uniqueEnemies = function (allyColor) {
    return this.uniqueAllies(1 - allyColor);
};

// Returns the empty points around this stone
Stone.prototype.empties = function () {
    var empties = [], neighbors = this.neighbors;
    for (var i = neighbors.length - 1; i >= 0; i--) {
        var s = neighbors[i];
        if (s.color === EMPTY) empties.push(s);
    }
    return empties;
};

// Number of empty points around this stone
Stone.prototype.numEmpties = function () {
    var count = 0, neighbors = this.neighbors;
    for (var i = neighbors.length - 1; i >= 0; i--) {
        if (neighbors[i].color === EMPTY) count++;
    }
    return count;
};

/** Returns the count of ally stones around.
 *  If an array is passed, the stones are pushed on it. */
Stone.prototype.allyStones = function (color, array) {
    var count = 0, neighbors = this.neighbors;
    for (var i = neighbors.length - 1; i >= 0; i--) {
        if (neighbors[i].color === color) {
            if (array) array.push(neighbors[i]);
            count++;
        }
    }
    return count;
};

Stone.prototype.isNextTo = function (group) {
    var neighbors = this.neighbors;
    for (var i = neighbors.length - 1; i >= 0; i--) {
        if (neighbors[i].group === group) return true;
    }
    return false;
};
<|endoftext|>


<commit_before>var Botkit = require('botkit')
var mongoUri = process.env.MONGODB_URI || 'mongodb://localhost/botkit-demo'
var db = require('../../config/db')({
  mongoUri: mongoUri
});
var request = require('request')

var controller = Botkit.facebookbot({
  debug: true,
  access_token: process.env.FACEBOOK_PAGE_TOKEN,
  verify_token: process.env.FACEBOOK_VERIFY_TOKEN,
  storage: db
});

var bot = controller.spawn({});

// subscribe to page events
request.post('https://graph.facebook.com/me/subscribed_apps?access_token=' + process.env.FACEBOOK_PAGE_TOKEN,
  function(err, res, body) {
    if (err) {
      controller.log('Could not subscribe to page messages');
    } else {
      controller.log('Successfully subscribed to Facebook events:', body);
      console.log('Botkit activated');

      // start ticking to send conversation messages
      controller.startTicking();
    }
  }
);

console.log('botkit');

// this is triggered when a user clicks the send-to-messenger plugin
controller.on('facebook_optin', function(bot, message) {
  bot.reply(message, 'Hey there. I\'m Podo. Nice to meet you.');
});

// user said hello
controller.hears(['hello'], 'message_received', function(bot, message) {
  bot.replyWithTyping(message, 'Hey there, how\'s your day?');
});

// // user says anything else
// controller.hears('(.*)', 'message_received', function(bot, message) {
//   bot.replyWithTyping(message, 'you said ' + message.match[1]);
// });

// check user submission
controller.hears(['check', 'submissions'], 'message_received', function(bot, message) {
  // start a conversation to handle this response.
  bot.createConversation(message, function(err, convo) {

    convo.say('Okay I will check your form submissions.');
    convo.ask('May I know the form ID?',function(response, convo) {

      convo.setVar('formID', response.text);
      convo.say('Cool, I\'ll be back in sec.');

      setTimeout(function() {
        bot.replyWithTyping(message, 'Here\'s the submissions of your form.');
        convo.say('Form ID: {{formID}} and Submission as of 10/12/2016');

        convo.ask('Anything else?', [
          {
            pattern: bot.utterances.no,
            callback: function(response,convo) {
              convo.say('OK see you next time!');
              convo.next();
            }
          },
          {
            pattern: bot.utterances.yes,
            callback: function(response,convo) {
              convo.say('Great! ask away...');
              // do something else...
              convo.next();
            }
          },
          {
            default: true,
            callback: function(response,convo) {
              // just repeat the question
              convo.say('OK I think that\'s a NO, see yah!');
              convo.next();
            }
          }
        ]);
      }, 3000);
    });

    convo.activate();
  });
});

// this function processes the POST request to the webhook
var handler = function(obj) {
  controller.debug('GOT A MESSAGE HOOK from facebook');
  var message;

  // if we receive a message
  if (obj.entry) {
    for (var e = 0; e < obj.entry.length; e++) {
      for (var m = 0; m < obj.entry[e].messaging.length; m++) {
        var facebook_message = obj.entry[e].messaging[m];

        console.log(facebook_message);

        // normal message
        if (facebook_message.message) {
          message = {
            text: facebook_message.message.text,
            user: facebook_message.sender.id,
            channel: facebook_message.sender.id,
            timestamp: facebook_message.timestamp,
            seq: facebook_message.message.seq,
            mid: facebook_message.message.mid,
            attachments: facebook_message.message.attachments
          };

          // save if user comes from m.me adress or Facebook search
          createUserIfNew(facebook_message.sender.id, facebook_message.timestamp);

          // notify bot we receive a message
          controller.receiveMessage(bot, message);
        }
        // clicks on a postback action in an attachment
        else if (facebook_message.postback) {
          // trigger BOTH a facebook_postback event
          // and a normal message received event.
          // this allows developers to receive postbacks as part of a conversation.
          message = {
            payload: facebook_message.postback.payload,
            user: facebook_message.sender.id,
            channel: facebook_message.sender.id,
            timestamp: facebook_message.timestamp
          };

          controller.trigger('facebook_postback', [bot, message]);

          message = {
            text: facebook_message.postback.payload,
            user: facebook_message.sender.id,
            channel: facebook_message.sender.id,
            timestamp: facebook_message.timestamp
          };

          controller.receiveMessage(bot, message);
        }
        // When a user clicks on "Send to Messenger"
        else if (facebook_message.optin) {
          message = {
            optin: facebook_message.optin,
            user: facebook_message.sender.id,
            channel: facebook_message.sender.id,
            timestamp: facebook_message.timestamp
          };

          // save if user comes from "Send to Messenger"
          createUserIfNew(facebook_message.sender.id, facebook_message.timestamp);

          // user just clicked the send message
          controller.trigger('facebook_optin', [bot, message]);
        }
        // message delivered callback
        else if (facebook_message.delivery) {
          message = {
            optin: facebook_message.delivery,
            user: facebook_message.sender.id,
            channel: facebook_message.sender.id,
            timestamp: facebook_message.timestamp
          };

          // message has been delivered
          controller.trigger('message_delivered', [bot, message]);
        } else {
          // we dont understand the following fb hook
          controller.log('Got an unexpected message from Facebook: ', facebook_message);
        }
      }
    }
  }
}

var createUserIfNew = function(id, ts) {
  controller.storage.users.get(id, function(err, user) {
    if (err) {
      console.log(err);
    } else if (!user) {
      controller.storage.users.save({
        id: id,
        created_at: ts
      });
    }
  });
};

exports.handler = handler;
<commit_msg>use replyWithTyping for presenting forms<commit_after>var Botkit = require('botkit')
var mongoUri = process.env.MONGODB_URI || 'mongodb://localhost/botkit-demo'
var db = require('../../config/db')({
  mongoUri: mongoUri
});
var request = require('request')

var controller = Botkit.facebookbot({
  debug: true,
  access_token: process.env.FACEBOOK_PAGE_TOKEN,
  verify_token: process.env.FACEBOOK_VERIFY_TOKEN,
  storage: db
});

var bot = controller.spawn({});

// subscribe to page events
request.post('https://graph.facebook.com/me/subscribed_apps?access_token=' + process.env.FACEBOOK_PAGE_TOKEN,
  function(err, res, body) {
    if (err) {
      controller.log('Could not subscribe to page messages');
    } else {
      controller.log('Successfully subscribed to Facebook events:', body);
      console.log('Botkit activated');

      // start ticking to send conversation messages
      controller.startTicking();
    }
  }
);

console.log('botkit');

// this is triggered when a user clicks the send-to-messenger plugin
controller.on('facebook_optin', function(bot, message) {
  bot.reply(message, 'Hey there. I\'m Podo. Nice to meet you.');
});

// user said hello
controller.hears(['hello'], 'message_received', function(bot, message) {
  bot.replyWithTyping(message, 'Hey there, how\'s your day?');
});

// // user says anything else
// controller.hears('(.*)', 'message_received', function(bot, message) {
//   bot.replyWithTyping(message, 'you said ' + message.match[1]);
// });

// check user submission
controller.hears(['check', 'submissions'], 'message_received', function(bot, message) {
  // start a conversation to handle this response.
  bot.createConversation(message, function(err, convo) {

    convo.say('Okay I will check your form submissions.');
    convo.ask('May I know the form ID?',function(response, convo) {

      convo.setVar('formID', response.text);
      convo.say('Cool, I\'ll be back in sec.');

      setTimeout(function() {
        convo.replyWithTyping(message, 'Here\'s the submissions of your form.');
        convo.say('Form ID: {{formID}} and Submission as of 10/12/2016');

        convo.ask('Anything else?', [
          {
            pattern: bot.utterances.no,
            callback: function(response,convo) {
              convo.say('OK see you next time!');
              convo.next();
            }
          },
          {
            pattern: bot.utterances.yes,
            callback: function(response,convo) {
              convo.say('Great! ask away...');
              // do something else...
              convo.next();
            }
          },
          {
            default: true,
            callback: function(response,convo) {
              // just repeat the question
              convo.say('OK I think that\'s a NO, see yah!');
              convo.next();
            }
          }
        ]);
      }, 3000);
    });

    convo.activate();
  });
});

// this function processes the POST request to the webhook
var handler = function(obj) {
  controller.debug('GOT A MESSAGE HOOK from facebook');
  var message;

  // if we receive a message
  if (obj.entry) {
    for (var e = 0; e < obj.entry.length; e++) {
      for (var m = 0; m < obj.entry[e].messaging.length; m++) {
        var facebook_message = obj.entry[e].messaging[m];

        console.log(facebook_message);

        // normal message
        if (facebook_message.message) {
          message = {
            text: facebook_message.message.text,
            user: facebook_message.sender.id,
            channel: facebook_message.sender.id,
            timestamp: facebook_message.timestamp,
            seq: facebook_message.message.seq,
            mid: facebook_message.message.mid,
            attachments: facebook_message.message.attachments
          };

          // save if user comes from m.me adress or Facebook search
          createUserIfNew(facebook_message.sender.id, facebook_message.timestamp);

          // notify bot we receive a message
          controller.receiveMessage(bot, message);
        }
        // clicks on a postback action in an attachment
        else if (facebook_message.postback) {
          // trigger BOTH a facebook_postback event
          // and a normal message received event.
          // this allows developers to receive postbacks as part of a conversation.
          message = {
            payload: facebook_message.postback.payload,
            user: facebook_message.sender.id,
            channel: facebook_message.sender.id,
            timestamp: facebook_message.timestamp
          };

          controller.trigger('facebook_postback', [bot, message]);

          message = {
            text: facebook_message.postback.payload,
            user: facebook_message.sender.id,
            channel: facebook_message.sender.id,
            timestamp: facebook_message.timestamp
          };

          controller.receiveMessage(bot, message);
        }
        // When a user clicks on "Send to Messenger"
        else if (facebook_message.optin) {
          message = {
            optin: facebook_message.optin,
            user: facebook_message.sender.id,
            channel: facebook_message.sender.id,
            timestamp: facebook_message.timestamp
          };

          // save if user comes from "Send to Messenger"
          createUserIfNew(facebook_message.sender.id, facebook_message.timestamp);

          // user just clicked the send message
          controller.trigger('facebook_optin', [bot, message]);
        }
        // message delivered callback
        else if (facebook_message.delivery) {
          message = {
            optin: facebook_message.delivery,
            user: facebook_message.sender.id,
            channel: facebook_message.sender.id,
            timestamp: facebook_message.timestamp
          };

          // message has been delivered
          controller.trigger('message_delivered', [bot, message]);
        } else {
          // we dont understand the following fb hook
          controller.log('Got an unexpected message from Facebook: ', facebook_message);
        }
      }
    }
  }
}

var createUserIfNew = function(id, ts) {
  controller.storage.users.get(id, function(err, user) {
    if (err) {
      console.log(err);
    } else if (!user) {
      controller.storage.users.save({
        id: id,
        created_at: ts
      });
    }
  });
};

exports.handler = handler;
<|endoftext|>


<commit_before>'use strict';

function bests_init(newprefix, bests, defaultvalue){
    bests_default = defaultvalue || 0;
    bests_prefix = newprefix;

    for(var best in bests){
        bests_bests[best] = parseFloat(window.localStorage.getItem(bests_prefix + best))
          || bests[best];
    }
}

function bests_reset(){
    if(!window.confirm('Reset best?')){
        return;
    }

    for(var best in bests_bests){
        bests_bests[best] = bests_default;
        bests_update(bests_bests[best]);
    }
}

function bests_update(key, value){
    if(value > bests_bests[key]){
        bests_bests[key] = value;
    }

    if(bests_bests[key] !== bests_default){
        window.localStorage.setItem(
          bests_prefix + key,
          bests_bests[key]
        );

    }else{
        window.localStorage.removeItem(bests_prefix + key);
    }
}

var bests_bests = {};
var bests_default = 0;
var bests_prefix = '';
<commit_msg>improved bests_init() variable clarity<commit_after>'use strict';

function bests_init(newprefix, bests, default_default){
    bests_default = default_default || 0;
    bests_prefix = newprefix;

    for(var best in bests){
        bests_bests[best] = parseFloat(window.localStorage.getItem(bests_prefix + best))
          || bests[best];
    }
}

function bests_reset(){
    if(!window.confirm('Reset best?')){
        return;
    }

    for(var best in bests_bests){
        bests_bests[best] = bests_default;
        bests_update(bests_bests[best]);
    }
}

function bests_update(key, value){
    if(value > bests_bests[key]){
        bests_bests[key] = value;
    }

    if(bests_bests[key] !== bests_default){
        window.localStorage.setItem(
          bests_prefix + key,
          bests_bests[key]
        );

    }else{
        window.localStorage.removeItem(bests_prefix + key);
    }
}

var bests_bests = {};
var bests_default = 0;
var bests_prefix = '';
<|endoftext|>


<commit_before>"use strict"

var pool = require("typedarray-pool")
var inline = require("inlinify")
var uniq = require("uniq")
var iota = require("iota-array")

function wrap(proc, num_opts) {
  var opts = iota(num_opts).map(function(i) { return "opt" + i })
  var args = [ "proc", "pool", "array" ]
  var body = [
    "var size = array.size",
    "var visited = pool.mallocUint8(size)",
    "var result = proc(array.data, array.shape, array.stride, array.offset, visited, size" + (num_opts > 0 ? ","+opts.join(",")  : "") + ")",
    "pool.freeUint8(visited)",
    "return result"
  ].join("\n")
  var func = Function.apply(undefined, [].concat(args).concat(opts).concat([body]))
  return func.bind(undefined, proc, pool)
}

function generateMesher(order, pre, post, skip, merge, append, num_options, options) {
  var code = []
  var d = order.length
  var i, j, k
  var can_inline = true
  var pre_macro, post_macro, skip_macro, merge_macro, append_macro

  //Type coerce offset to int
  code.push("offset = offset|0")

  //Build arguments for append macro
  var append_args = new Array(2*d+1+num_options)
  for(i=0; i<d; ++i) {
    append_args[i] = "i"+i
  }
  for(i=0; i<d; ++i) {
    append_args[i+d] = "j"+i
  }
  append_args[2*d] = "val"

  var opt_args = new Array(num_options)
  for(i=0; i<num_options; ++i) {
    opt_args[i] = "opt"+i
    append_args[2*d+1+i] = "opt"+i
  }

  try {
    if(options.force_no_inline) {
      throw new Error("Forced non-inline")
    }
    //Compile all the macros
    pre_macro     = inline(pre, "pre_", opt_args)
    post_macro    = inline(post, "post_", opt_args)
    skip_macro    = inline(skip, "skip_", ["val"].concat(opt_args))
    merge_macro   = inline(merge, "merge_", ["val", "oval"].concat(opt_args))
    append_macro  = inline(append, "append_", append_args)

  } catch(e) {
    console.warn("WARNING!  Could not inline methods, performance will be lowered: ", e)

    var opt_str = num_opts > 0 ? "," + opt_args.join(",") : ""

    pre_macro = {
      this_variables: ["this_"],
      variables: [],
      return_variable: "return_pre_",
      body: "this_ = {}; return_pre_=pre_func.call(this_"+opt_str+")"
    };
    post_macro = {
      this_variables: ["this_"],
      variables: [],
      return_variable: "return_post_",
      body: "return_post_=post_func.call(this_"+opt_str+")"
    };
    skip_macro = {
      this_variables: ["this_"],
      variables: [],
      return_variable: "return_skip_",
      body: "return_skip_=skip_func.call(this_,val"+opt_str+")"
    };
    merge_macro = {
      this_variables: ["this_"],
      variables: [],
      return_variable: "return_merge_",
      body: "return_merge_=merge_func.call(this_,val,oval"+opt_str+")"
    };
    append_macro = {
      this_variables: ["this_"],
      variables: [],
      return_variable: "return_append_",
      body: "return_append_=append_func.call(this_," + append_args.join(",") + ")"
    };
    can_inline = false
  }

  //Combine this variables, add to result
  var combined_vars = [ pre_macro.return_variable,
                        post_macro.return_variable,
                        skip_macro.return_variable,
                        merge_macro.return_variable,
                        append_macro.return_variable ]
                        .concat(pre_macro.this_variables)
                        .concat(post_macro.this_variables)
                        .concat(skip_macro.this_variables)
                        .concat(merge_macro.this_variables)
                        .concat(append_macro.this_variables)
                        .concat(pre_macro.variables)
                        .concat(post_macro.variables)
                        .concat(skip_macro.variables)
                        .concat(merge_macro.variables)
                        .concat(append_macro.variables)
  code.push("var " + uniq(combined_vars).join(","))

  code.push("var d")

  //Unpack stride and shape arrays into variables
  for(var i=0; i<d; ++i) {
    code.push("var stride"+i+"=stride["+order[i]+"]|0")
    code.push("var shape"+i+"=shape["+order[i]+"]|0")
    if(i > 0) {
      code.push("var astep"+i+"=(stride"+i+"-stride"+(i-1)+"*shape"+(i-1)+")|0")
    } else {
      code.push("var astep"+i+"=stride"+i+"|0")
    }
    if(i > 0) {
      code.push("var vstep"+i+"=(vstep"+(i-1)+"*shape"+(i-1)+")|0")
    } else {
      code.push("var vstep"+i+"=1")
    }
    code.push("var ustep"+i+"=vstep"+i)
    code.push("var bstep"+i+"=astep"+i)
    code.push("var i"+i)
    code.push("var j"+i)
    code.push("var k"+i)
  }

  //Initialize pointers
  code.push("var a_ptr=0")
  code.push("var b_ptr=0")
  code.push("var u_ptr=0")
  code.push("var v_ptr=0")
  code.push("var val")
  code.push("var oval")

  //Paste in premacro
  code.push(pre_macro.body)

  //Zero out visited map
  code.push("for(v_ptr=0,i=0;i<count;++i) {")
    code.push("visited[i]=0")
  code.push("}")

  //Begin traversal
  code.push("v_ptr=0")
  for(i=d-1; i>=0; --i) {
    code.push("for(i"+i+"=0;i"+i+"<shape"+i+";++i"+i+"){")
  }
  code.push("if(!visited[v_ptr]){")
    code.push("val = data[a_ptr]")
    code.push(skip_macro.body)
    code.push("if(!" + skip_macro.return_variable + "){")

      //Save val to oval
      code.push("oval = val")

      //Generate merging code
      for(i=0; i<d; ++i) {
        code.push("u_ptr=v_ptr+vstep"+i)
        code.push("b_ptr=a_ptr+stride"+i)
        code.push("j"+i+"_loop: for(j"+i+"=1+i"+i+";j"+i+"<shape"+i+";++j"+i+"){")
        for(j=i-1; j>=0; --j) {
          code.push("for(k"+j+"=i"+j+";k"+j+"<j"+j+";++k"+j+"){")
        }

          //Check if we can merge this voxel
          code.push("if(visited[u_ptr]) { break j"+i+"_loop; }")
          code.push("val=data[b_ptr]")
          code.push(skip_macro.body)
          code.push("if("+skip_macro.return_variable+") { break j"+i+"_loop; }")
          code.push(merge_macro.body)
          code.push("if(!"+merge_macro.return_variable+") { break j"+i+"_loop; }")

          //Close off loop bodies
          code.push("++u_ptr")
          code.push("b_ptr+=stride0")
        code.push("}")

        for(j=1; j<=i; ++j) {
          code.push("u_ptr+=ustep"+j)
          code.push("b_ptr+=bstep"+j)
          code.push("}")
        }
        if(i < d-1) {
          code.push("d=j"+i+"-i"+i)
          code.push("ustep"+(i+1)+"=(vstep"+(i+1)+"-vstep"+i+"*d)|0")
          code.push("bstep"+(i+1)+"=(stride"+(i+1)+"-stride"+i+"*d)|0")
        }
      }

      //Mark off visited table
      code.push("u_ptr=v_ptr")
      for(i=d-1; i>=0; --i) {
        code.push("for(k"+i+"=i"+i+";k"+i+"<j"+i+";++k"+i+"){")
      }
      code.push("visited[u_ptr++]=1")
      code.push("}")
      for(i=1; i<d; ++i) {
        code.push("u_ptr+=ustep"+i)
        code.push("}")
      }

      //Append chunk to mesh
      code.push("val = oval")
      code.push(append_macro.body)

    code.push("}")
  code.push("}")
  code.push("++v_ptr")
  for(var i=0; i<d; ++i) {
    code.push("a_ptr+=astep"+i)
    code.push("}")
  }

  //Run post macro
  code.push(post_macro.body)
  code.push("return " + post_macro.return_variable)

  if(options.debug) {
    console.log("GENERATING MESHER:")
    console.log(code.join("\n"))
  }

  //Compile procedure
  var args = ["data", "shape", "stride", "offset", "visited", "count" ].concat(opt_args)
  args.push(code.join("\n"))
  var proc
  if(can_inline) {
    proc = Function.apply(undefined, args)
  } else {
    tmp_proc = Function.apply(undefined, ["pre_func", "post_func", "skip_func", "merge_func", "append_func"].concat(args))
    proc = tmp_proc.bind(undefined, pre, post, skip, merge, append)
  }

  return wrap(proc, num_options)
}

//Default stuff
function DEFAULT_PRE()        { }
function DEFAULT_POST()       { }
function DEFAULT_SKIP()       { return false; }
function DEFAULT_MERGE(a, b)  { return a === b; }
function DEFAULT_APPEND()     { }
function compileMesher(options) {
  options = options || {}
  if(!options.order) {
    throw new Error("Missing order field")
  }
  return generateMesher(
    options.order,
    options.pre         || DEFAULT_PRE,
    options.post        || DEFAULT_POST,
    options.skip        || DEFAULT_SKIP,
    options.merge       || DEFAULT_MERGE,
    options.append      || DEFAULT_APPEND,
    options.num_options|0,
    options
  )
}
module.exports = compileMesher
<commit_msg>adding local stuff<commit_after>"use strict"

var pool = require("typedarray-pool")
var inline = require("inlinify")
var uniq = require("uniq")
var iota = require("iota-array")

function wrap(proc, num_opts) {
  var opts = iota(num_opts).map(function(i) { return "opt" + i })
  var args = [ "proc", "pool", "array" ]
  var body = [
    "var size = array.size",
    "var visited = pool.mallocUint8(size)",
    "var result = proc(array.data, array.shape, array.stride, array.offset, visited, size" + (num_opts > 0 ? ","+opts.join(",")  : "") + ")",
    "pool.freeUint8(visited)",
    "return result"
  ].join("\n")

  console.log("WRAPPER:\n\n", args, opts, body)

  var func = Function.apply(undefined, [].concat(args).concat(opts).concat([body]))
  return func.bind(undefined, proc, pool)
}

function generateMesher(order, pre, post, skip, merge, append, num_options, options) {
  var code = []
  var d = order.length
  var i, j, k
  var can_inline = true
  var pre_macro, post_macro, skip_macro, merge_macro, append_macro

  //Type coerce offset to int
  code.push("offset = offset|0")

  //Build arguments for append macro
  var append_args = new Array(2*d+1+num_options)
  for(i=0; i<d; ++i) {
    append_args[i] = "i"+i
  }
  for(i=0; i<d; ++i) {
    append_args[i+d] = "j"+i
  }
  append_args[2*d] = "val"

  var opt_args = new Array(num_options)
  for(i=0; i<num_options; ++i) {
    opt_args[i] = "opt"+i
    append_args[2*d+1+i] = "opt"+i
  }

  try {
    if(options.force_no_inline) {
      throw new Error("Forced non-inline")
    }
    //Compile all the macros
    pre_macro     = inline(pre, "pre_", opt_args)
    post_macro    = inline(post, "post_", opt_args)
    skip_macro    = inline(skip, "skip_", ["val"].concat(opt_args))
    merge_macro   = inline(merge, "merge_", ["val", "oval"].concat(opt_args))
    append_macro  = inline(append, "append_", append_args)

  } catch(e) {
    console.warn("WARNING!  Could not inline methods, performance will be lowered: ", e)

    var opt_str = num_opts > 0 ? "," + opt_args.join(",") : ""

    pre_macro = {
      this_variables: ["this_"],
      variables: [],
      return_variable: "return_pre_",
      body: "this_ = {}; return_pre_=pre_func.call(this_"+opt_str+")"
    };
    post_macro = {
      this_variables: ["this_"],
      variables: [],
      return_variable: "return_post_",
      body: "return_post_=post_func.call(this_"+opt_str+")"
    };
    skip_macro = {
      this_variables: ["this_"],
      variables: [],
      return_variable: "return_skip_",
      body: "return_skip_=skip_func.call(this_,val"+opt_str+")"
    };
    merge_macro = {
      this_variables: ["this_"],
      variables: [],
      return_variable: "return_merge_",
      body: "return_merge_=merge_func.call(this_,val,oval"+opt_str+")"
    };
    append_macro = {
      this_variables: ["this_"],
      variables: [],
      return_variable: "return_append_",
      body: "return_append_=append_func.call(this_," + append_args.join(",") + ")"
    };
    can_inline = false
  }

  //Combine this variables, add to result
  var combined_vars = [ pre_macro.return_variable,
                        post_macro.return_variable,
                        skip_macro.return_variable,
                        merge_macro.return_variable,
                        append_macro.return_variable ]
                        .concat(pre_macro.this_variables)
                        .concat(post_macro.this_variables)
                        .concat(skip_macro.this_variables)
                        .concat(merge_macro.this_variables)
                        .concat(append_macro.this_variables)
                        .concat(pre_macro.variables)
                        .concat(post_macro.variables)
                        .concat(skip_macro.variables)
                        .concat(merge_macro.variables)
                        .concat(append_macro.variables)
  code.push("var " + uniq(combined_vars).join(","))

  code.push("var d")

  //Unpack stride and shape arrays into variables
  for(var i=0; i<d; ++i) {
    code.push("var stride"+i+"=stride["+order[i]+"]|0")
    code.push("var shape"+i+"=shape["+order[i]+"]|0")
    if(i > 0) {
      code.push("var astep"+i+"=(stride"+i+"-stride"+(i-1)+"*shape"+(i-1)+")|0")
    } else {
      code.push("var astep"+i+"=stride"+i+"|0")
    }
    if(i > 0) {
      code.push("var vstep"+i+"=(vstep"+(i-1)+"*shape"+(i-1)+")|0")
    } else {
      code.push("var vstep"+i+"=1")
    }
    code.push("var ustep"+i+"=vstep"+i)
    code.push("var bstep"+i+"=astep"+i)
    code.push("var i"+i)
    code.push("var j"+i)
    code.push("var k"+i)
  }

  //Initialize pointers
  code.push("var a_ptr=0")
  code.push("var b_ptr=0")
  code.push("var u_ptr=0")
  code.push("var v_ptr=0")
  code.push("var val")
  code.push("var oval")

  //Paste in premacro
  code.push(pre_macro.body)

  //Zero out visited map

  code.push("for(v_ptr=0,i=0;i<count;++i) {")
    code.push("visited[i]=0")
  code.push("}")

  //Begin traversal
  code.push("v_ptr=0")
  for(i=d-1; i>=0; --i) {
    code.push("for(i"+i+"=0;i"+i+"<shape"+i+";++i"+i+"){")
  }
  code.push("if(!visited[v_ptr]){")
    code.push("val = data[a_ptr]")
    code.push(skip_macro.body)
    code.push("if(!" + skip_macro.return_variable + "){")

      //Save val to oval
      code.push("oval = val")

      //Generate merging code
      for(i=0; i<d; ++i) {
        code.push("u_ptr=v_ptr+vstep"+i)
        code.push("b_ptr=a_ptr+stride"+i)
        code.push("j"+i+"_loop: for(j"+i+"=1+i"+i+";j"+i+"<shape"+i+";++j"+i+"){")
        for(j=i-1; j>=0; --j) {
          code.push("for(k"+j+"=i"+j+";k"+j+"<j"+j+";++k"+j+"){")
        }

          //Check if we can merge this voxel
          code.push("if(visited[u_ptr]) { break j"+i+"_loop; }")
          code.push("val=data[b_ptr]")
          code.push(skip_macro.body)
          code.push("if("+skip_macro.return_variable+") { break j"+i+"_loop; }")
          code.push(merge_macro.body)
          code.push("if(!"+merge_macro.return_variable+") { break j"+i+"_loop; }")

          //Close off loop bodies
          code.push("++u_ptr")
          code.push("b_ptr+=stride0")
        code.push("}")

        for(j=1; j<=i; ++j) {
          code.push("u_ptr+=ustep"+j)
          code.push("b_ptr+=bstep"+j)
          code.push("}")
        }
        if(i < d-1) {
          code.push("d=j"+i+"-i"+i)
          code.push("ustep"+(i+1)+"=(vstep"+(i+1)+"-vstep"+i+"*d)|0")
          code.push("bstep"+(i+1)+"=(stride"+(i+1)+"-stride"+i+"*d)|0")
        }
      }

      //Mark off visited table
      code.push("u_ptr=v_ptr")
      for(i=d-1; i>=0; --i) {
        code.push("for(k"+i+"=i"+i+";k"+i+"<j"+i+";++k"+i+"){")
      }
      code.push("visited[u_ptr++]=1")
      code.push("}")
      for(i=1; i<d; ++i) {
        code.push("u_ptr+=ustep"+i)
        code.push("}")
      }

      //Append chunk to mesh
      code.push("val = oval")
      code.push(append_macro.body)

    code.push("}")
  code.push("}")
  code.push("++v_ptr")
  for(var i=0; i<d; ++i) {
    code.push("a_ptr+=astep"+i)
    code.push("}")
  }

  //Run post macro
  code.push(post_macro.body)
  code.push("return " + post_macro.return_variable)

  if(options.debug) {
    console.log("GENERATING MESHER:")
    console.log(code.join("\n"))
  }

  //Compile procedure
  var args = ["data", "shape", "stride", "offset", "visited", "count" ].concat(opt_args)
  args.push(code.join("\n"))
  var proc
  if(can_inline) {
    proc = Function.apply(undefined, args)
  } else {
    tmp_proc = Function.apply(undefined, ["pre_func", "post_func", "skip_func", "merge_func", "append_func"].concat(args))
    proc = tmp_proc.bind(undefined, pre, post, skip, merge, append)
  }

  console.log(args)

  return wrap(proc, num_options)
}

//Default stuff
function DEFAULT_PRE()        { }
function DEFAULT_POST()       { }
function DEFAULT_SKIP()       { return false; }
function DEFAULT_MERGE(a, b)  { return a === b; }
function DEFAULT_APPEND()     { }
function compileMesher(options) {
  options = options || {}
  if(!options.order) {
    throw new Error("Missing order field")
  }
  return generateMesher(
    options.order,
    options.pre         || DEFAULT_PRE,
    options.post        || DEFAULT_POST,
    options.skip        || DEFAULT_SKIP,
    options.merge       || DEFAULT_MERGE,
    options.append      || DEFAULT_APPEND,
    options.num_options|0,
    options
  )
}
module.exports = compileMesher
<|endoftext|>


<commit_before>import Ember from 'ember';
export default Ember.Controller.extend({

 actions: {
      stepThree() {
          alert('Thanks');
          this.transitionToRoute('step3');
              },

      popup() {
          this.toggleProperty('enabled');
              },
      print() {
          this.set('name', this.get('print'));
          this.toggleProperty('enabled');
              },
      close() {
          this.toggleProperty('enabled');
             },
            }
});
<commit_msg>Region page.<commit_after>    import Ember from 'ember';

    const {
        Controller,
        inject: {service},
    } = Ember;

export default Ember.Controller.extend({
  regioninfos: service(),
  storage: service(),
  sessionStorage: service(),

  hostInfos:   [ Ember.Object.create({
    regionName: '',
    compute: '',
    storage: '',
    }) ],

  storeData(data, storage) {
    return storage.setItem('megdc.hostinfos', JSON.stringify(data));
  },
 actions: {
      stepThree() {
          alert('Thanks');
          this.transitionToRoute('step3');
              },

      popup() {
          this.toggleProperty('enabled');
              },
      print() {
          this.set('name', this.get('print'));
          this.toggleProperty('enabled');
              },
      close() {
        //  this.toggleProperty('enabled');
        alert(this.get('print'));
             },

             addhost() {
              // alert("1");
                 this.get('hostInfos').pushObject(Ember.Object.create({
                       regionName: '',
                       compute: '',
                       storage: '',
                 }));
            },

            regionData() {

              return this.get('ajax').request('/region/content', {
                method: 'POST',
                param:{
                        regionName:this.get('print'),
                        cost:
                           {
                             compute: this.get('compute'),
                             storage: this.get('storage'),
                           }

                     }
              });
            },

            }
});
<|endoftext|>


<commit_before>module.exports = function(router, config) {

  router.all(config.routes.step, function(req,res, next){

    var requestedPage = req.params.step,
    postData = req.body || {};

    switch(requestedPage) {

      // kills the current session
      case 'kill_session':
        req.session.destroy();
        return res.redirect('start');
      break;
      // redirects the correct payment choice screen
      case 'change_payment':
        if(postData['change_choice'] == 'increase') {
          return res.redirect('increase_value');
        } else {
          return res.redirect('reduce_value');
        }
      break;
    }

    next();

  });

  return router;
}
<commit_msg>fixed kill session<commit_after>module.exports = function(router, config) {

  router.all(config.routes.step, function(req,res, next){

    var requestedPage = req.params.step,
    postData = req.body || {};

    switch(requestedPage) {

      // kills the current session
      case 'kill_session':
        req.session.destroy();
        return res.redirect('configure');
      break;
      // redirects the correct payment choice screen
      case 'change_payment':
        if(postData['change_choice'] == 'increase') {
          return res.redirect('increase_value');
        } else {
          return res.redirect('reduce_value');
        }
      break;
    }

    next();

  });

  return router;
}
<|endoftext|>