<commit_before>// Copyright 2014-2017, University of Colorado Boulder

/**
 * Demonstration of griddle components.
 * Demos are selected from a combo box, and are instantiated on demand.
 * Use the 'component' query parameter to set the initial selection of the combo box.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  const LabeledScrollingChartNode = require( 'GRIDDLE/LabeledScrollingChartNode' );
  const ScrollingChartNode = require( 'GRIDDLE/ScrollingChartNode' );
  const Text = require( 'SCENERY/nodes/Text' );
  var BarChartNode = require( 'GRIDDLE/BarChartNode' );
  var Color = require( 'SCENERY/util/Color' );
  var DemosScreenView = require( 'SUN/demo/DemosScreenView' );
  var Dimension2 = require( 'DOT/Dimension2' );
  var Emitter = require( 'AXON/Emitter' );
  var griddle = require( 'GRIDDLE/griddle' );
  var HBox = require( 'SCENERY/nodes/HBox' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Panel = require( 'SUN/Panel' );
  var PhetFont = require( 'SCENERY_PHET/PhetFont' );
  var Property = require( 'AXON/Property' );
  var Range = require( 'DOT/Range' );
  var sceneryPhetQueryParameters = require( 'SCENERY_PHET/sceneryPhetQueryParameters' );
  var Vector2 = require( 'DOT/Vector2' );
  var VSlider = require( 'SUN/VSlider' );
  var XYDataSeries = require( 'GRIDDLE/XYDataSeries' );
  var XYPlot = require( 'GRIDDLE/XYPlot' );

  // constants - this is a hack to enable components to animate from the animation loop
  var emitter = new Emitter();

  /**
   * @constructor
   */
  function GriddleDemoScreenView() {

    DemosScreenView.call( this, [

      /**
       * To add a demo, add an object literal here. Each object has these properties:
       *
       * {string} label - label in the combo box
       * {function(Bounds2): Node} createNode - creates the scene graph for the demo
       */
      { label: 'XYPlot', createNode: demoXYPlot },
      { label: 'BarChart', createNode: demoBarChart },
      { label: 'ScrollingChartNode', createNode: demoScrollingChartNode }
    ], {
      comboBoxItemFont: new PhetFont( 12 ),
      comboBoxItemYMargin: 3,
      selectedDemoLabel: sceneryPhetQueryParameters.component
    } );
  }

  // Creates a demo for the XYPlot
  var demoXYPlot = function( layoutBounds ) {

    var time = 0;
    var plot = new XYPlot( { backgroundFill: '#efecd9' } );
    var plotPanel = new Panel( plot, {
      fill: '#efecd9',
      xMargin: 10,
      yMargin: 10,
      x: 100,
      y: 100
    } );
    var series = new XYDataSeries( { color: Color.BLUE } );
    plot.addSeries( series, false );
    var forward = true;
    var count = 0;
    const listener = function( dt ) {
      series.addPoint( time, -Math.abs( -Math.sin( time / 100 + count ) * 400 * 0.8 ) );
      time = time + ( forward ? 1 : -1 );

      if ( time > 400 ) {
        forward = false;
        count++;
      }
      if ( time < 0 ) {
        forward = true;
        count++;
      }
    };
    emitter.addListener( listener );

    // Swap out the dispose function for one that also removes the Emitter listener
    var plotPanelDispose = plotPanel.dispose.bind( plotPanel );
    plotPanel.dispose = function() {
      emitter.removeListener( listener );
      plotPanelDispose();
    };
    return plotPanel;
  };

  // Creates a demo for the BarChartNode
  var demoBarChart = function( layoutBounds ) {
    var model = {
      aProperty: new Property( 0 ),
      bProperty: new Property( 0 ),
      cProperty: new Property( 0 )
    };
    var aEntry = {
      property: model.aProperty,
      color: 'red'
    };
    var bEntry = {
      property: model.bProperty,
      color: 'green'
    };
    var cEntry = {
      property: model.cProperty,
      color: 'blue'
    };

    var barChartNode = new BarChartNode( [
      { entries: [ aEntry ], label: new Node() },
      { entries: [ bEntry ], label: new Node() },
      { entries: [ cEntry ], label: new Node() },
      { entries: [ cEntry, bEntry, aEntry ], label: new Node() }
    ], new Property( new Range( -100, 200 ) ), {
      barOptions: {
        totalRange: new Range( -100, 200 )
      }
    } );
    const listener = function( dt ) {
      barChartNode.update();
    };
    emitter.addListener( listener );
    const sliderRange = new Range( -200, 300 );
    const sliderOptions = {
      trackSize: new Dimension2( 200, 5 )
    };
    const hBox = new HBox( {
      align: 'top',
      spacing: 60,
      center: new Vector2( 512, 309 ),
      children: [
        new Node( {
          children: [ barChartNode ]
        } ),
        new HBox( {
          spacing: 25,
          children: [
            new VSlider( model.aProperty, sliderRange, _.extend( {}, sliderOptions, { trackFillEnabled: aEntry.color } ) ),
            new VSlider( model.bProperty, sliderRange, _.extend( {}, sliderOptions, { trackFillEnabled: bEntry.color } ) ),
            new VSlider( model.cProperty, sliderRange, _.extend( {}, sliderOptions, { trackFillEnabled: cEntry.color } ) )
          ]
        } )
      ]
    } );

    // Swap out the dispose function for one that also removes the Emitter listener
    var hboxDispose = hBox.dispose.bind( hBox );
    hBox.dispose = function() {
      emitter.removeListener( listener );
      hboxDispose();
    };
    return hBox;
  };

  var demoScrollingChartNode = function( layoutBounds ) {

    var timeProperty = new Property( 0 );
    var series1 = {
      color: 'blue',
      data: [],
      emitter: emitter
    };
    var maxSeconds = 4;
    const listener = function( dt ) {
      timeProperty.value += dt;
      series1.data.push( new Vector2( timeProperty.value, Math.sin( timeProperty.value ) ) );
      while ( series1.data[ 0 ].x < timeProperty.value - maxSeconds ) {
        series1.data.shift();
      }
    };
    emitter.addListener( listener );
    const scrollingChartNode = new ScrollingChartNode( timeProperty, [ series1 ], {
      width: 200,
      height: 150
    } );
    const panel = new Panel( new LabeledScrollingChartNode(
      scrollingChartNode,
      new Text( 'Height (m)', { rotation: 3 * Math.PI / 2, fill: 'white' } ),
      new Text( '1 s', { fill: 'white' } ),
      'time (s)'
    ), {
      fill: 'gray',
      center: layoutBounds.center
    } );

    // Swap out the dispose function for one that also removes the Emitter listener
    var panelDispose = panel.dispose.bind( panel );
    panel.dispose = function() {
      emitter.removeListener( listener );
      panelDispose();
    };
    return panel;
  };

  griddle.register( 'GriddleDemoScreenView', GriddleDemoScreenView );

  return inherit( DemosScreenView, GriddleDemoScreenView, {
    step: function( dt ) {
      emitter.emit1( dt );
    }
  } );
} );<commit_msg>Moved GriddleDemoScreenView to ES6, see https://github.com/phetsims/griddle/issues/30<commit_after>// Copyright 2014-2017, University of Colorado Boulder

/**
 * Demonstration of griddle components.
 * Demos are selected from a combo box, and are instantiated on demand.
 * Use the 'component' query parameter to set the initial selection of the combo box.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const LabeledScrollingChartNode = require( 'GRIDDLE/LabeledScrollingChartNode' );
  const ScrollingChartNode = require( 'GRIDDLE/ScrollingChartNode' );
  const Text = require( 'SCENERY/nodes/Text' );
  const BarChartNode = require( 'GRIDDLE/BarChartNode' );
  const Color = require( 'SCENERY/util/Color' );
  const DemosScreenView = require( 'SUN/demo/DemosScreenView' );
  const Dimension2 = require( 'DOT/Dimension2' );
  const Emitter = require( 'AXON/Emitter' );
  const griddle = require( 'GRIDDLE/griddle' );
  const HBox = require( 'SCENERY/nodes/HBox' );
  const Node = require( 'SCENERY/nodes/Node' );
  const Panel = require( 'SUN/Panel' );
  const PhetFont = require( 'SCENERY_PHET/PhetFont' );
  const Property = require( 'AXON/Property' );
  const Range = require( 'DOT/Range' );
  const sceneryPhetQueryParameters = require( 'SCENERY_PHET/sceneryPhetQueryParameters' );
  const Vector2 = require( 'DOT/Vector2' );
  const VSlider = require( 'SUN/VSlider' );
  const XYDataSeries = require( 'GRIDDLE/XYDataSeries' );
  const XYPlot = require( 'GRIDDLE/XYPlot' );

  // constants - this is a hack to enable components to animate from the animation loop
  const emitter = new Emitter();

  class GriddleDemoScreenView extends DemosScreenView {
    constructor() {

      super( [

        /**
         * To add a demo, add an object literal here. Each object has these properties:
         *
         * {string} label - label in the combo box
         * {function(Bounds2): Node} createNode - creates the scene graph for the demo
         */
        { label: 'XYPlot', createNode: demoXYPlot },
        { label: 'BarChart', createNode: demoBarChart },
        { label: 'LabeledScrollingChartNode', createNode: demoLabeledScrollingChartNode }
      ], {
        comboBoxItemFont: new PhetFont( 12 ),
        comboBoxItemYMargin: 3,
        selectedDemoLabel: sceneryPhetQueryParameters.component
      } );
    }

    /**
     * Move the model forward in time.
     * @param {number} dt - elapsed time in seconds
     * @public
     */
    step( dt ) {
      emitter.emit1( dt );
    }
  }

  // Creates a demo for the XYPlot
  const demoXYPlot = function( layoutBounds ) {

    let time = 0;
    const plot = new XYPlot( { backgroundFill: '#efecd9' } );
    const plotPanel = new Panel( plot, {
      fill: '#efecd9',
      xMargin: 10,
      yMargin: 10,
      x: 100,
      y: 100
    } );
    const series = new XYDataSeries( { color: Color.BLUE } );
    plot.addSeries( series, false );
    let forward = true;
    let count = 0;
    const listener = function( dt ) {
      series.addPoint( time, -Math.abs( -Math.sin( time / 100 + count ) * 400 * 0.8 ) );
      time = time + ( forward ? 1 : -1 );

      if ( time > 400 ) {
        forward = false;
        count++;
      }
      if ( time < 0 ) {
        forward = true;
        count++;
      }
    };
    emitter.addListener( listener );

    // Swap out the dispose function for one that also removes the Emitter listener
    const plotPanelDispose = plotPanel.dispose.bind( plotPanel );
    plotPanel.dispose = function() {
      emitter.removeListener( listener );
      plotPanelDispose();
    };
    return plotPanel;
  };

  // Creates a demo for the BarChartNode
  const demoBarChart = function( layoutBounds ) {
    const model = {
      aProperty: new Property( 0 ),
      bProperty: new Property( 0 ),
      cProperty: new Property( 0 )
    };
    const aEntry = {
      property: model.aProperty,
      color: 'red'
    };
    const bEntry = {
      property: model.bProperty,
      color: 'green'
    };
    const cEntry = {
      property: model.cProperty,
      color: 'blue'
    };

    const barChartNode = new BarChartNode( [
      { entries: [ aEntry ], label: new Node() },
      { entries: [ bEntry ], label: new Node() },
      { entries: [ cEntry ], label: new Node() },
      { entries: [ cEntry, bEntry, aEntry ], label: new Node() }
    ], new Property( new Range( -100, 200 ) ), {
      barOptions: {
        totalRange: new Range( -100, 200 )
      }
    } );
    const listener = function( dt ) {
      barChartNode.update();
    };
    emitter.addListener( listener );
    const sliderRange = new Range( -200, 300 );
    const sliderOptions = {
      trackSize: new Dimension2( 200, 5 )
    };
    const hBox = new HBox( {
      align: 'top',
      spacing: 60,
      center: new Vector2( 512, 309 ),
      children: [
        new Node( {
          children: [ barChartNode ]
        } ),
        new HBox( {
          spacing: 25,
          children: [
            new VSlider( model.aProperty, sliderRange, _.extend( {}, sliderOptions, { trackFillEnabled: aEntry.color } ) ),
            new VSlider( model.bProperty, sliderRange, _.extend( {}, sliderOptions, { trackFillEnabled: bEntry.color } ) ),
            new VSlider( model.cProperty, sliderRange, _.extend( {}, sliderOptions, { trackFillEnabled: cEntry.color } ) )
          ]
        } )
      ]
    } );

    // Swap out the dispose function for one that also removes the Emitter listener
    const hboxDispose = hBox.dispose.bind( hBox );
    hBox.dispose = function() {
      emitter.removeListener( listener );
      hboxDispose();
    };
    return hBox;
  };

  /**
   * Creates an example LabeledScrollingChartNode
   * @param layoutBounds
   */
  const demoLabeledScrollingChartNode = function( layoutBounds ) {
    const timeProperty = new Property( 0 );
    const series1 = {
      color: 'blue',
      data: [],
      emitter: emitter
    };
    const maxSeconds = 4;
    const listener = dt => {

      // Increment the model time
      timeProperty.value += dt;

      // Sample new data
      series1.data.push( new Vector2( timeProperty.value, Math.sin( timeProperty.value ) ) );

      // Data that does not fall within the displayed window should be removed.
      while ( series1.data[ 0 ].x < timeProperty.value - maxSeconds ) {
        series1.data.shift();
      }
    };
    emitter.addListener( listener );
    const scrollingChartNode = new ScrollingChartNode( timeProperty, [ series1 ], {
      width: 200,
      height: 150
    } );
    const panel = new Panel( new LabeledScrollingChartNode(
      scrollingChartNode,
      new Text( 'Height (m)', { rotation: 3 * Math.PI / 2, fill: 'white' } ),
      new Text( '1 s', { fill: 'white' } ),
      'time (s)'
    ), {
      fill: 'gray',
      center: layoutBounds.center
    } );

    // Swap out the dispose function for one that also removes the Emitter listener
    const panelDispose = panel.dispose.bind( panel );
    panel.dispose = () => {
      emitter.removeListener( listener );
      panelDispose();
    };
    return panel;
  };

  return griddle.register( 'GriddleDemoScreenView', GriddleDemoScreenView );
} );<|endoftext|>


<commit_before>// TODO: remove in v6.6.0 in favor of "js/foundation"
import { Foundation as Core } from '../foundation.core';
import * as CoreUtils from '../foundation.core.utils';
import { Box } from '../foundation.util.box'
import { onImagesLoaded } from '../foundation.util.imageLoader';
import { Keyboard } from '../foundation.util.keyboard';
import { MediaQuery } from '../foundation.util.mediaQuery';
import { Motion, Move } from '../foundation.util.motion';
import { Nest } from '../foundation.util.nest';
import { Timer } from '../foundation.util.timer';
import { Touch } from '../foundation.util.touch';
import { Triggers } from '../foundation.util.triggers';
import { Abide } from '../foundation.abide';
import { Accordion } from '../foundation.accordion';
import { AccordionMenu } from '../foundation.accordionMenu';
import { Drilldown } from '../foundation.drilldown';
import { Dropdown } from '../foundation.dropdown';
import { DropdownMenu } from '../foundation.dropdownMenu';
import { Equalizer } from '../foundation.equalizer';
import { Interchange } from '../foundation.interchange';
import { Magellan } from '../foundation.magellan';
import { OffCanvas } from '../foundation.offcanvas';
import { Orbit } from '../foundation.orbit';
import { ResponsiveMenu } from '../foundation.responsiveMenu';
import { ResponsiveToggle } from '../foundation.responsiveToggle';
import { Reveal } from '../foundation.reveal';
import { Slider } from '../foundation.slider';
import { SmoothScroll } from '../foundation.smoothScroll';
import { Sticky } from '../foundation.sticky';
import { Tabs } from '../foundation.tabs';
import { Toggler } from '../foundation.toggler';
import { Tooltip } from '../foundation.tooltip';
import { ResponsiveAccordionTabs } from '../foundation.responsiveAccordionTabs';

export {
  Core,
  CoreUtils,
  Box,
  onImagesLoaded,
  Keyboard,
  MediaQuery,
  Motion,
  Nest,
  Timer,
  Touch,
  Triggers,
  Abide,
  Accordion,
  AccordionMenu,
  Drilldown,
  Dropdown,
  DropdownMenu,
  Equalizer,
  Interchange,
  Magellan,
  OffCanvas,
  Orbit,
  ResponsiveMenu,
  ResponsiveToggle,
  Reveal,
  Slider,
  SmoothScroll,
  Sticky,
  Tabs,
  Toggler,
  Tooltip,
  ResponsiveAccordionTabs
}
<commit_msg>fix: add missing export of "Move" in "foundation-plugins" entry<commit_after>// TODO: remove in v6.6.0 in favor of "js/foundation"
import { Foundation as Core } from '../foundation.core';
import * as CoreUtils from '../foundation.core.utils';
import { Box } from '../foundation.util.box'
import { onImagesLoaded } from '../foundation.util.imageLoader';
import { Keyboard } from '../foundation.util.keyboard';
import { MediaQuery } from '../foundation.util.mediaQuery';
import { Motion, Move } from '../foundation.util.motion';
import { Nest } from '../foundation.util.nest';
import { Timer } from '../foundation.util.timer';
import { Touch } from '../foundation.util.touch';
import { Triggers } from '../foundation.util.triggers';
import { Abide } from '../foundation.abide';
import { Accordion } from '../foundation.accordion';
import { AccordionMenu } from '../foundation.accordionMenu';
import { Drilldown } from '../foundation.drilldown';
import { Dropdown } from '../foundation.dropdown';
import { DropdownMenu } from '../foundation.dropdownMenu';
import { Equalizer } from '../foundation.equalizer';
import { Interchange } from '../foundation.interchange';
import { Magellan } from '../foundation.magellan';
import { OffCanvas } from '../foundation.offcanvas';
import { Orbit } from '../foundation.orbit';
import { ResponsiveMenu } from '../foundation.responsiveMenu';
import { ResponsiveToggle } from '../foundation.responsiveToggle';
import { Reveal } from '../foundation.reveal';
import { Slider } from '../foundation.slider';
import { SmoothScroll } from '../foundation.smoothScroll';
import { Sticky } from '../foundation.sticky';
import { Tabs } from '../foundation.tabs';
import { Toggler } from '../foundation.toggler';
import { Tooltip } from '../foundation.tooltip';
import { ResponsiveAccordionTabs } from '../foundation.responsiveAccordionTabs';

export {
  Core,
  CoreUtils,
  Box,
  onImagesLoaded,
  Keyboard,
  MediaQuery,
  Motion,
  Move,
  Nest,
  Timer,
  Touch,
  Triggers,
  Abide,
  Accordion,
  AccordionMenu,
  Drilldown,
  Dropdown,
  DropdownMenu,
  Equalizer,
  Interchange,
  Magellan,
  OffCanvas,
  Orbit,
  ResponsiveMenu,
  ResponsiveToggle,
  Reveal,
  Slider,
  SmoothScroll,
  Sticky,
  Tabs,
  Toggler,
  Tooltip,
  ResponsiveAccordionTabs
}
<|endoftext|>


<commit_before>/**
 * Created by ksinger on 23.09.2015.
 *
 * Contains a list of actions to be used with the dispatcher and documentation for their expected payloads.
 */
import { tree2constants, deepFreeze, reduceAndMapTreeKeys } from './utils';
import './service/won';

export const actionTypes = tree2constants({

    /* actions received as responses or push notifications */
    received: {
        /* contains all user-bound data, e.g. ownedPosts,
         * drafts, messages,...
         * This action will likely be caused as a consequence of signing in.
         */
        userData : null
    },
    draft: {
        /*
         * A new draft was created (either through the view in this client or on another browser)
         */
        new: null,
        /*
         * A draft has changed. Pass along the draftURI and the respective data.
         */
        changed: {
            type: null,
            title: null,
            thumbnail: null,
        }
    },
    ownpost: {
        new: null,
    },
    moreWub: null
});

/**
 * actionCreators are functions that take the payload and output
 * an action object, thus prebinding the action-type.
 *
 * e.g.:
 *
 * ```javascript
 * function newDraft(draft) {
 *   return { type: 'draft.new', payload: draft }
 * }
 * ```
 */
export const actionCreators = tree2actionCreators(actionTypes);

function tree2actionCreators(obj) {
    return deepFreeze(reduceAndMapTreeKeys(
        (acc, k) => acc.concat(k), //construct paths, e.g. ['draft', 'new']
        (acc) => createActionCreator(won.lookup(actionTypes, acc)), //lookup constant at path
        [], obj
    ))
}
function createActionCreator(type) {
    return (payload) => ({type, payload});
}

//TODO for debug; deleteme
window.actionTypes = actionTypes;
window.actionCreators = actionCreators;
<commit_msg>Removed debug vars.<commit_after>/**
 * Created by ksinger on 23.09.2015.
 *
 * Contains a list of actions to be used with the dispatcher and documentation for their expected payloads.
 */
import { tree2constants, deepFreeze, reduceAndMapTreeKeys } from './utils';
import './service/won';

export const actionTypes = tree2constants({

    /* actions received as responses or push notifications */
    received: {
        /* contains all user-bound data, e.g. ownedPosts,
         * drafts, messages,...
         * This action will likely be caused as a consequence of signing in.
         */
        userData : null
    },
    draft: {
        /*
         * A new draft was created (either through the view in this client or on another browser)
         */
        new: null,
        /*
         * A draft has changed. Pass along the draftURI and the respective data.
         */
        changed: {
            type: null,
            title: null,
            thumbnail: null,
        }
    },
    ownpost: {
        new: null,
    },
    moreWub: null
});

/**
 * actionCreators are functions that take the payload and output
 * an action object, thus prebinding the action-type.
 *
 * e.g.:
 *
 * ```javascript
 * function newDraft(draft) {
 *   return { type: 'draft.new', payload: draft }
 * }
 * ```
 */
export const actionCreators = tree2actionCreators(actionTypes);

function tree2actionCreators(obj) {
    return deepFreeze(reduceAndMapTreeKeys(
        (acc, k) => acc.concat(k), //construct paths, e.g. ['draft', 'new']
        (acc) => createActionCreator(won.lookup(actionTypes, acc)), //lookup constant at path
        [], obj
    ))
}
function createActionCreator(type) {
    return (payload) => ({type, payload});
}
<|endoftext|>


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

function init() {
  if (arguments.length > 0) {
    for ( var key in arguments) {
      if (arguments.hasOwnProperty(key)) {
        var arg = arguments[key]
        if (util.isArray(arg)) {
          if (this._chain === false) this._commands.push(this.values(arg))
          else this.values(arg)
        } else this._commands.push(arg)
      }
    }

    if (this._chain === false) {
      this.pull()
    }
  }
}

function icebreaker() {
  if (!(this instanceof icebreaker)) {
    var i = Object.create(icebreaker.prototype);
    icebreaker.apply(i, [].slice.call(arguments));
    return i
  }

  this._commands = []

  /* jshint eqnull:true */
  if (this._chain == null) this._chain = false

  init.apply(this, [].slice.call(arguments))
}

icebreaker.prototype.add = function() {
  this._commands = this._commands.concat([].slice.call(arguments))
  return this
}

var mixin = icebreaker.mixin = function(obj, dest) {
  if (!dest) dest = icebreaker

  for ( var key in obj) {
    if (obj.hasOwnProperty(key)) {
      var value = obj[key]

      if (typeof value === 'function' && key !== 'prototype' &&
      key !== 'pull' && key !== 'keys' && typeof key === 'string') {
        (function(key, value) {
          dest[key] = function() {
            return value.apply(this, [].slice.call(arguments))
          }
          dest.prototype[key] = function() {
            var r = dest[key].apply(this, [].slice.call(arguments))
            return this._chain === true ? this.add(r) : r
          }
        })(key, value)
      }
      else if (typeof value === 'object' && key !== 'prototype') {
        console.log('key',key)
        dest[key] = value
        console.log(value)
        var w = function() {
          if (!(this instanceof w)) return new w()
          icebreaker.call(this)
        }

        util.inherits(w, icebreaker)

        icebreaker.mixin(value, w)

        dest.prototype[key] = function() {
          var s =  new w()
          s._commands = this._commands
          s._chain = this._chain
          return s
        }
      }
    }
  }
}

icebreaker.prototype.pull = function() {
  if(util.isArray(this._commands))
    for ( var key in this._commands) {
      if (this._commands[key] instanceof icebreaker) {
        this._commands[key].pull()
      }
    }

  var p = pull.apply(pull, this._commands)
  this._commands = []
  return p
}

mixin(pull)

mixin({
  fork : require('pull-fork'),
  pair : require('pull-pair'),
  source:function(s) {
    if (s instanceof stream.Duplex || s instanceof stream.Readable ||
    s instanceof stream.Transform)
      return toPullStream.source.apply(toPullStream, arguments)
      return this.Source.apply(this, arguments)
  },
  through:function() {
    return this.Through.apply(this, arguments)
  },
  sink:function(str) {
    if (str instanceof stream.Writable)
      return toPullStream.sink.apply(toPullStream, arguments)
    return this.Sink.apply(this, arguments)
  },
  chain:function() {
    if (!(this instanceof icebreaker)) {
      var i = Object.create(icebreaker.prototype);
      i._chain = true
      icebreaker.apply(i, [].slice.call(arguments));
      return i
    }

    this._chain = true
    init.apply(this, [].slice.call(arguments))
    return this
  }
})

module.exports=icebreaker<commit_msg>console.log removed<commit_after>var stream = require('stream')
var toPullStream = require('stream-to-pull-stream')
var pull = require('pull-stream')
var util = require('util')

function init() {
  if (arguments.length > 0) {
    for ( var key in arguments) {
      if (arguments.hasOwnProperty(key)) {
        var arg = arguments[key]
        if (util.isArray(arg)) {
          if (this._chain === false) this._commands.push(this.values(arg))
          else this.values(arg)
        } else this._commands.push(arg)
      }
    }

    if (this._chain === false) {
      this.pull()
    }
  }
}

function icebreaker() {
  if (!(this instanceof icebreaker)) {
    var i = Object.create(icebreaker.prototype);
    icebreaker.apply(i, [].slice.call(arguments));
    return i
  }

  this._commands = []

  /* jshint eqnull:true */
  if (this._chain == null) this._chain = false

  init.apply(this, [].slice.call(arguments))
}

icebreaker.prototype.add = function() {
  this._commands = this._commands.concat([].slice.call(arguments))
  return this
}

var mixin = icebreaker.mixin = function(obj, dest) {
  if (!dest) dest = icebreaker

  for ( var key in obj) {
    if (obj.hasOwnProperty(key)) {
      var value = obj[key]

      if (typeof value === 'function' && key !== 'prototype' &&
      key !== 'pull' && key !== 'keys' && typeof key === 'string') {
        (function(key, value) {
          dest[key] = function() {
            return value.apply(this, [].slice.call(arguments))
          }
          dest.prototype[key] = function() {
            var r = dest[key].apply(this, [].slice.call(arguments))
            return this._chain === true ? this.add(r) : r
          }
        })(key, value)
      }
      else if (typeof value === 'object' && key !== 'prototype') {
        dest[key] = value

        var w = function() {
          if (!(this instanceof w)) return new w()
          icebreaker.call(this)
        }

        util.inherits(w, icebreaker)

        icebreaker.mixin(value, w)

        dest.prototype[key] = function() {
          var s =  new w()
          s._commands = this._commands
          s._chain = this._chain
          return s
        }
      }
    }
  }
}

icebreaker.prototype.pull = function() {
  if(util.isArray(this._commands))
    for ( var key in this._commands) {
      if (this._commands[key] instanceof icebreaker) {
        this._commands[key].pull()
      }
    }

  var p = pull.apply(pull, this._commands)
  this._commands = []
  return p
}

mixin(pull)

mixin({
  fork : require('pull-fork'),
  pair : require('pull-pair'),
  source:function(s) {
    if (s instanceof stream.Duplex || s instanceof stream.Readable ||
    s instanceof stream.Transform)
      return toPullStream.source.apply(toPullStream, arguments)
      return this.Source.apply(this, arguments)
  },
  through:function() {
    return this.Through.apply(this, arguments)
  },
  sink:function(str) {
    if (str instanceof stream.Writable)
      return toPullStream.sink.apply(toPullStream, arguments)
    return this.Sink.apply(this, arguments)
  },
  chain:function() {
    if (!(this instanceof icebreaker)) {
      var i = Object.create(icebreaker.prototype);
      i._chain = true
      icebreaker.apply(i, [].slice.call(arguments));
      return i
    }

    this._chain = true
    init.apply(this, [].slice.call(arguments))
    return this
  }
})

module.exports=icebreaker
<|endoftext|>


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

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

// Components
import ListItem from '../_ListItem';
import Tip from '../Tip';

// Statics
import Theme from '../Theme';
import SelectMode from '../_statics/SelectMode';
import LIST_SEPARATOR from '../_statics/ListSeparator';

// Vendors
import isArray from 'lodash/isArray';
import classNames from 'classnames';
import Util from '../_vendors/Util';
import Calculation from '../_vendors/Calculation';
import ComponentUtil from '../_vendors/ComponentUtil';

class List extends Component {

    static SelectMode = SelectMode;
    static LIST_SEPARATOR = LIST_SEPARATOR;
    static Theme = Theme;

    static getDerivedStateFromProps(props, state) {
        return {
            prevProps: props,
            value: Calculation.getInitValue({
                value: ComponentUtil.getDerivedState(props, state, 'value'),
                selectMode: props.selectMode
            })
        };
    }

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.list = createRef();
        this.listEl = null;

        this.state = {
            value: Calculation.getInitValue(props)
        };

    }

    /**
     * public
     */
    adjustScroll = () => {

        const {data} = this.props,
            {value} = this.state,
            index = data.indexOf(value);

        if (index < 0) {
            return;
        }

        const listHeight = this.listEl.clientHeight,
            listScrollTop = this.listEl.scrollTop,
            itemEl = this.listEl.childNodes[index],
            itemHeight = itemEl.clientHeight,
            itemTop = itemEl.offsetTop;

        if (itemTop < listScrollTop) {
            this.listEl.scrollTop = itemTop;
        } else if (itemTop + itemHeight > listScrollTop + listHeight) {
            this.listEl.scrollTop = itemTop + itemHeight - listHeight;
        }

    };

    handleListItemSelect = (item, index) => {

        const {selectMode} = this.props,
            {value} = this.state,
            state = {};

        if (selectMode === SelectMode.MULTI_SELECT) {

            let result = value ? value.slice() : value;
            if (!result || !isArray(result)) {
                result = [];
            }

            result.push(item);

            state.value = result;

        } else if (selectMode === SelectMode.SINGLE_SELECT) {
            state.value = item;
        }

        this.setState(state, () => {
            const {onItemSelect, onChange} = this.props;
            onItemSelect && onItemSelect(item, index);
            onChange && onChange(state.value, index);
        });

    };

    handleListItemDeselect = (item, index) => {

        const {selectMode} = this.props;

        if (selectMode !== SelectMode.MULTI_SELECT) {
            return;
        }

        const {valueField, displayField} = this.props,
            {value: stateValue} = this.state;
        let value = stateValue ? stateValue.slice() : stateValue;

        if (!value || !isArray(value)) {
            value = [];
        } else {
            value = value.filter(valueItem => {
                return Util.getValueByValueField(valueItem, valueField, displayField)
                    != Util.getValueByValueField(item, valueField, displayField);
            });
        }

        this.setState({
            value
        }, () => {
            const {onItemDeselect, onChange} = this.props;
            onItemDeselect && onItemDeselect(item, index);
            onChange && onChange(value, index);
        });

    };

    isListDisabled = listDisabled => {
        const {data} = this.props,
            {value} = this.state;
        return (typeof listDisabled === 'function' ? listDisabled(value, data) : listDisabled);
    };

    isItemDisabled = (listItemDisabled, item, itemDisabled) => {
        const {data} = this.props,
            {value} = this.state;
        return (
                listItemDisabled != undefined
                && (typeof listItemDisabled === 'function' ? listItemDisabled(item, value, data) : listItemDisabled)
            )
            || (
                itemDisabled != undefined
                && (typeof itemDisabled === 'function' ? itemDisabled(item, value, data) : itemDisabled)
            );
    };

    componentDidMount() {
        this.listEl = this.list && this.list.current;
    }

    renderListItem = (item, index) => {

        if (!item) {
            return;
        }

        const {

                theme, activatedTheme, itemHeight, valueField, displayField, descriptionField, disabled,
                itemDisabled, isLoading, renderer, autoSelect, disableTouchRipple, selectTheme, selectMode, parentEl,
                indeterminateCallback, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                onItemClick

            } = this.props,
            {value} = this.state;

        return typeof item === 'object' ?
            <ListItem key={index}
                      {...item}
                      index={index}
                      parentEl={parentEl}
                      style={{height: itemHeight}}
                      theme={item.theme || theme}
                      activatedTheme={item.activatedTheme || activatedTheme}
                      selectTheme={item.selectTheme || selectTheme}
                      radioUncheckedIconCls={item.radioUncheckedIconCls || radioUncheckedIconCls}
                      radioCheckedIconCls={item.radioCheckedIconCls || radioCheckedIconCls}
                      checkboxUncheckedIconCls={item.checkboxUncheckedIconCls || checkboxUncheckedIconCls}
                      checkboxCheckedIconCls={item.checkboxCheckedIconCls || checkboxCheckedIconCls}
                      checkboxIndeterminateIconCls={item.checkboxIndeterminateIconCls || checkboxIndeterminateIconCls}
                      data={item}
                      checked={Calculation.isItemChecked(item, value, this.props)}
                      value={Util.getValueByValueField(item, valueField, displayField)}
                      text={Util.getTextByDisplayField(item, displayField, valueField)}
                      desc={item[descriptionField] || null}
                      disabled={this.isListDisabled(disabled) || this.isItemDisabled(itemDisabled, item, item.disabled)}
                      isLoading={isLoading || item.isLoading}
                      selectMode={selectMode}
                      renderer={renderer}
                      autoSelect={autoSelect}
                      disableTouchRipple={item.disableTouchRipple || disableTouchRipple}
                      indeterminateCallback={indeterminateCallback}
                      onClick={e => {
                          onItemClick && onItemClick(item, index, e);
                          item.onClick && item.onClick(e);
                      }}
                      onSelect={() => this.handleListItemSelect(item, index)}
                      onDeselect={() => this.handleListItemDeselect(item, index)}/>
            :
            <ListItem key={index}
                      index={index}
                      parentEl={parentEl}
                      style={{height: itemHeight}}
                      theme={theme}
                      activatedTheme={activatedTheme}
                      selectTheme={selectTheme}
                      radioUncheckedIconCls={radioUncheckedIconCls}
                      radioCheckedIconCls={radioCheckedIconCls}
                      checkboxUncheckedIconCls={checkboxUncheckedIconCls}
                      checkboxCheckedIconCls={checkboxCheckedIconCls}
                      checkboxIndeterminateIconCls={checkboxIndeterminateIconCls}
                      data={item}
                      checked={Calculation.isItemChecked(item, value, this.props)}
                      value={item}
                      text={item}
                      disabled={this.isListDisabled(disabled) || this.isItemDisabled(itemDisabled, item)}
                      isLoading={isLoading}
                      selectMode={selectMode}
                      renderer={renderer}
                      autoSelect={autoSelect}
                      disableTouchRipple={disableTouchRipple}
                      indeterminateCallback={indeterminateCallback}
                      onClick={e => onItemClick && onItemClick(item, index, e)}
                      onSelect={() => this.handleListItemSelect(item, index)}
                      onDeselect={() => this.handleListItemDeselect(item, index)}/>;

    };

    render() {

        const {

            children, className, style, data, disabled,

            // not passing down these props
            activatedTheme, selectTheme, selectMode, value, idField, valueField, displayField, descriptionField,
            itemDisabled, disableTouchRipple, autoSelect, isLoading, itemHeight, parentEl,
            radioUncheckedIconCls, radioCheckedIconCls,
            checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,
            indeterminateCallback, renderer, onItemClick, onItemSelect, onItemDeselect,

            ...restProps

        } = this.props;

        return (

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

                        :
                        this.renderListItem(item, index)
                    )
                }

                {children}

        );

    }
}

List.propTypes = {

    children: PropTypes.any,

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

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

    /**
     * The theme of the list item.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The theme of the list item activated.
     */
    activatedTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The theme of the list item select radio or checkbox.
     */
    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The mode of listItem.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * Children passed into the ListItem.
     */
    data: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({

        /**
         * The CSS class name of the list button.
         */
        className: PropTypes.string,

        /**
         * Override the styles of the list button.
         */
        style: PropTypes.object,

        /**
         * The theme of the list button.
         */
        theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

        /**
         * The theme of the list button activated.
         */
        activatedTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),

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

        /**
         * The list item's display text. Type can be string, number or bool.
         */
        text: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

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

        /**
         * The title value of the list button.
         */
        title: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

        /**
         * If true, the list item will be disabled.
         */
        disabled: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

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

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

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

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

        /**
         * The class name of tip.
         */
        tipClassName: PropTypes.string,

        /**
         * The message of tip.
         */
        tip: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

        /**
         * The position of tip.
         */
        tipPosition: PropTypes.oneOf(Util.enumerateValue(Tip.Position)),

        /**
         * If true, the item will have center displayed ripple effect.
         */
        rippleDisplayCenter: PropTypes.bool,

        /**
         * You can create a complicated renderer callback instead of value and desc prop.
         */
        itemRenderer: PropTypes.func,

        /**
         * Callback function fired when a list item touch-tapped.
         */
        onClick: PropTypes.func

    }), PropTypes.string, PropTypes.number, PropTypes.symbol])),

    value: PropTypes.any,

    /**
     * The id field name in data. (default: "id")
     */
    idField: PropTypes.string,

    /**
     * The value field name in data. (default: "value")
     */
    valueField: PropTypes.string,

    /**
     * The display field name in data. (default: "text")
     */
    displayField: PropTypes.string,

    /**
     * The description field name in data. (default: "desc")
     */
    descriptionField: PropTypes.string,

    /**
     * If true, the list will be disabled.
     */
    disabled: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

    /**
     * List item disabled callback.
     */
    itemDisabled: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

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

    /**
     * If true, the list will be at loading status.
     */
    isLoading: PropTypes.bool,

    /**
     * Whether select when item clicked.
     */
    autoSelect: PropTypes.bool,
    itemHeight: PropTypes.number,
    parentEl: PropTypes.object,
    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    /**
     * You can create a complicated renderer callback instead of value and desc prop.
     */
    renderer: PropTypes.func,

    /**
     * Callback function fired when the list-item touch tap.
     */
    onItemClick: PropTypes.func,

    /**
     * Callback function fired when the list-item select.
     */
    onItemSelect: PropTypes.func,

    /**
     * Callback function fired when the list-item deselect.
     */
    onItemDeselect: PropTypes.func,

    /**
     * Callback function fired when the list changed.
     */
    onChange: PropTypes.func,

    indeterminateCallback: PropTypes.func

};

List.defaultProps = {

    theme: Theme.DEFAULT,
    activatedTheme: Theme.DEFAULT,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    idField: 'id',
    valueField: 'value',
    displayField: 'text',
    descriptionField: 'desc',
    disabled: false,
    itemDisabled: false,
    disableTouchRipple: false,
    autoSelect: true,

    checkboxUncheckedIconCls: 'far fa-square',
    checkboxCheckedIconCls: 'fas fa-check-square',
    checkboxIndeterminateIconCls: 'fas fa-minus-square'

};

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

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

// Components
import ListItem from '../_ListItem';
import Tip from '../Tip';

// Statics
import Theme from '../Theme';
import SelectMode from '../_statics/SelectMode';
import LIST_SEPARATOR from '../_statics/ListSeparator';

// Vendors
import isArray from 'lodash/isArray';
import classNames from 'classnames';
import Util from '../_vendors/Util';
import Calculation from '../_vendors/Calculation';
import ComponentUtil from '../_vendors/ComponentUtil';

class List extends Component {

    static SelectMode = SelectMode;
    static LIST_SEPARATOR = LIST_SEPARATOR;
    static Theme = Theme;

    static getDerivedStateFromProps(props, state) {
        return {
            prevProps: props,
            value: Calculation.getInitValue({
                value: ComponentUtil.getDerivedState(props, state, 'value'),
                selectMode: props.selectMode
            })
        };
    }

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.list = createRef();
        this.listEl = null;

        this.state = {
            value: Calculation.getInitValue(props)
        };

    }

    componentDidMount() {
        this.listEl = this.list?.current;
    }

    /**
     * public
     */
    adjustScroll = () => {

        const {data} = this.props,
            {value} = this.state,
            index = data.indexOf(value);

        if (index < 0) {
            return;
        }

        const listHeight = this.listEl.clientHeight,
            listScrollTop = this.listEl.scrollTop,
            itemEl = this.listEl.childNodes[index],
            itemHeight = itemEl.clientHeight,
            itemTop = itemEl.offsetTop;

        if (itemTop < listScrollTop) {
            this.listEl.scrollTop = itemTop;
        } else if (itemTop + itemHeight > listScrollTop + listHeight) {
            this.listEl.scrollTop = itemTop + itemHeight - listHeight;
        }

    };

    handleListItemSelect = (item, index) => {

        const {selectMode} = this.props,
            {value} = this.state,
            state = {};

        if (selectMode === SelectMode.MULTI_SELECT) {

            let result = value ? value.slice() : value;
            if (!result || !isArray(result)) {
                result = [];
            }

            result.push(item);

            state.value = result;

        } else if (selectMode === SelectMode.SINGLE_SELECT) {
            state.value = item;
        }

        this.setState(state, () => {
            this.props.onItemSelect?.(item, index);
            this.props.onChange?.(state.value, index);
        });

    };

    handleListItemDeselect = (item, index) => {

        const {selectMode} = this.props;

        if (selectMode !== SelectMode.MULTI_SELECT) {
            return;
        }

        const {valueField, displayField} = this.props,
            {value: stateValue} = this.state;
        let value = stateValue ? stateValue.slice() : stateValue;

        if (!value || !isArray(value)) {
            value = [];
        } else {
            value = value.filter(valueItem =>
                Util.getValueByValueField(valueItem, valueField, displayField)
                != Util.getValueByValueField(item, valueField, displayField)
            );
        }

        this.setState({
            value
        }, () => {
            this.props.onItemDeselect?.(item, index);
            this.props.onChange?.(value, index);
        });

    };

    isListDisabled = listDisabled => {
        const {data} = this.props,
            {value} = this.state;
        return (typeof listDisabled === 'function' ? listDisabled(value, data) : listDisabled);
    };

    isItemDisabled = (listItemDisabled, item, itemDisabled) => {

        const {data} = this.props,
            {value} = this.state;

        return (
            listItemDisabled != undefined
            && (typeof listItemDisabled === 'function' ? listItemDisabled(item, value, data) : listItemDisabled)
        ) || (
            itemDisabled != undefined
            && (typeof itemDisabled === 'function' ? itemDisabled(item, value, data) : itemDisabled)
        );

    };

    renderListItem = (item, index) => {

        if (!item) {
            return;
        }

        const {

                theme, activatedTheme, itemHeight, valueField, displayField, descriptionField, disabled,
                itemDisabled, isLoading, renderer, autoSelect, disableTouchRipple, selectTheme, selectMode, parentEl,
                indeterminateCallback, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                onItemClick

            } = this.props,
            {value} = this.state;

        return typeof item === 'object' ?
            <ListItem key={index}
                      {...item}
                      index={index}
                      parentEl={parentEl}
                      style={{height: itemHeight}}
                      theme={item.theme || theme}
                      activatedTheme={item.activatedTheme || activatedTheme}
                      selectTheme={item.selectTheme || selectTheme}
                      radioUncheckedIconCls={item.radioUncheckedIconCls || radioUncheckedIconCls}
                      radioCheckedIconCls={item.radioCheckedIconCls || radioCheckedIconCls}
                      checkboxUncheckedIconCls={item.checkboxUncheckedIconCls || checkboxUncheckedIconCls}
                      checkboxCheckedIconCls={item.checkboxCheckedIconCls || checkboxCheckedIconCls}
                      checkboxIndeterminateIconCls={item.checkboxIndeterminateIconCls || checkboxIndeterminateIconCls}
                      data={item}
                      checked={Calculation.isItemChecked(item, value, this.props)}
                      value={Util.getValueByValueField(item, valueField, displayField)}
                      text={Util.getTextByDisplayField(item, displayField, valueField)}
                      desc={item[descriptionField] || null}
                      disabled={this.isListDisabled(disabled) || this.isItemDisabled(itemDisabled, item, item.disabled)}
                      isLoading={isLoading || item.isLoading}
                      selectMode={selectMode}
                      renderer={renderer}
                      autoSelect={autoSelect}
                      disableTouchRipple={item.disableTouchRipple || disableTouchRipple}
                      indeterminateCallback={indeterminateCallback}
                      onClick={e => {
                          onItemClick && onItemClick(item, index, e);
                          item.onClick && item.onClick(e);
                      }}
                      onSelect={() => this.handleListItemSelect(item, index)}
                      onDeselect={() => this.handleListItemDeselect(item, index)}/>
            :
            <ListItem key={index}
                      index={index}
                      parentEl={parentEl}
                      style={{height: itemHeight}}
                      theme={theme}
                      activatedTheme={activatedTheme}
                      selectTheme={selectTheme}
                      radioUncheckedIconCls={radioUncheckedIconCls}
                      radioCheckedIconCls={radioCheckedIconCls}
                      checkboxUncheckedIconCls={checkboxUncheckedIconCls}
                      checkboxCheckedIconCls={checkboxCheckedIconCls}
                      checkboxIndeterminateIconCls={checkboxIndeterminateIconCls}
                      data={item}
                      checked={Calculation.isItemChecked(item, value, this.props)}
                      value={item}
                      text={item}
                      disabled={this.isListDisabled(disabled) || this.isItemDisabled(itemDisabled, item)}
                      isLoading={isLoading}
                      selectMode={selectMode}
                      renderer={renderer}
                      autoSelect={autoSelect}
                      disableTouchRipple={disableTouchRipple}
                      indeterminateCallback={indeterminateCallback}
                      onClick={e => onItemClick && onItemClick(item, index, e)}
                      onSelect={() => this.handleListItemSelect(item, index)}
                      onDeselect={() => this.handleListItemDeselect(item, index)}/>;

    };

    render() {

        const {

            children, className, style, data, disabled,

            // not passing down these props
            activatedTheme, selectTheme, selectMode, value, idField, valueField, displayField, descriptionField,
            itemDisabled, disableTouchRipple, autoSelect, isLoading, itemHeight, parentEl,
            radioUncheckedIconCls, radioCheckedIconCls,
            checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,
            indeterminateCallback, renderer, onItemClick, onItemSelect, onItemDeselect,

            ...restProps

        } = this.props;

        return (

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

                        :
                        this.renderListItem(item, index)
                    )
                }

                {children}

        );

    }
}

List.propTypes = {

    children: PropTypes.any,

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

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

    /**
     * The theme of the list item.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The theme of the list item activated.
     */
    activatedTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The theme of the list item select radio or checkbox.
     */
    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The mode of listItem.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * Children passed into the ListItem.
     */
    data: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({

        /**
         * The CSS class name of the list button.
         */
        className: PropTypes.string,

        /**
         * Override the styles of the list button.
         */
        style: PropTypes.object,

        /**
         * The theme of the list button.
         */
        theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

        /**
         * The theme of the list button activated.
         */
        activatedTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),

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

        /**
         * The list item's display text. Type can be string, number or bool.
         */
        text: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

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

        /**
         * The title value of the list button.
         */
        title: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

        /**
         * If true, the list item will be disabled.
         */
        disabled: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

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

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

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

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

        /**
         * The class name of tip.
         */
        tipClassName: PropTypes.string,

        /**
         * The message of tip.
         */
        tip: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

        /**
         * The position of tip.
         */
        tipPosition: PropTypes.oneOf(Util.enumerateValue(Tip.Position)),

        /**
         * If true, the item will have center displayed ripple effect.
         */
        rippleDisplayCenter: PropTypes.bool,

        /**
         * You can create a complicated renderer callback instead of value and desc prop.
         */
        itemRenderer: PropTypes.func,

        /**
         * Callback function fired when a list item touch-tapped.
         */
        onClick: PropTypes.func

    }), PropTypes.string, PropTypes.number, PropTypes.symbol])),

    value: PropTypes.any,

    /**
     * The id field name in data. (default: "id")
     */
    idField: PropTypes.string,

    /**
     * The value field name in data. (default: "value")
     */
    valueField: PropTypes.string,

    /**
     * The display field name in data. (default: "text")
     */
    displayField: PropTypes.string,

    /**
     * The description field name in data. (default: "desc")
     */
    descriptionField: PropTypes.string,

    /**
     * If true, the list will be disabled.
     */
    disabled: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

    /**
     * List item disabled callback.
     */
    itemDisabled: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

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

    /**
     * If true, the list will be at loading status.
     */
    isLoading: PropTypes.bool,

    /**
     * Whether select when item clicked.
     */
    autoSelect: PropTypes.bool,
    itemHeight: PropTypes.number,
    parentEl: PropTypes.object,
    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    /**
     * You can create a complicated renderer callback instead of value and desc prop.
     */
    renderer: PropTypes.func,

    /**
     * Callback function fired when the list-item touch tap.
     */
    onItemClick: PropTypes.func,

    /**
     * Callback function fired when the list-item select.
     */
    onItemSelect: PropTypes.func,

    /**
     * Callback function fired when the list-item deselect.
     */
    onItemDeselect: PropTypes.func,

    /**
     * Callback function fired when the list changed.
     */
    onChange: PropTypes.func,

    indeterminateCallback: PropTypes.func

};

List.defaultProps = {

    theme: Theme.DEFAULT,
    activatedTheme: Theme.DEFAULT,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    idField: 'id',
    valueField: 'value',
    displayField: 'text',
    descriptionField: 'desc',
    disabled: false,
    itemDisabled: false,
    disableTouchRipple: false,
    autoSelect: true,

    checkboxUncheckedIconCls: 'far fa-square',
    checkboxCheckedIconCls: 'fas fa-check-square',
    checkboxIndeterminateIconCls: 'fas fa-minus-square'

};

export default List;
<|endoftext|>


<commit_before>Meteor.startup(function () {
	var SerialPort = serialport.SerialPort;
	var arduino = new SerialPort("/dev/ttyACM0", {
		baudrate: 9600
	});
	arduino.open(function(err) {
		if (err) {
			console.log("Failed to open: " + err);
		} else {
			console.log("Serial port open");
			Meteor.methods({
				writeData: function(velocity, y) {
					var byte = 196 * (velocity === 0 ? 0 : 1) + y * 32 + (velocity < 0 ? 0 : 1) * 16 + Math.abs(velocity);
					var byteChar = String.fromCharCode(byte);
					console.log(byteChar);
					arduino.write(byteChar);
				}
			});
		}
	});
});
<commit_msg>Added UTF-8 byte encoding<commit_after>Meteor.startup(function () {
	var SerialPort = serialport.SerialPort;
	var arduino = new SerialPort("/dev/ttyACM0", {
		baudrate: 9600
	});
	arduino.open(function(err) {
		if (err) {
			console.log("Failed to open: " + err);
		} else {
			console.log("Serial port open");
			Meteor.methods({
				writeData: function(velocity, y) {
					var byte = [196 * (velocity === 0 ? 0 : 1) + y * 32 + (velocity < 0 ? 0 : 1) * 16 + Math.abs(velocity)];
					var buff = new Buffer(byte);
					console.log(buff.toString('utf8'));
					arduino.write(buff.toString('utf8'));
				}
			});
		}
	});
});
<|endoftext|>


<commit_before>define('app/views/machine_add', ['app/views/controlled'],
    /**
     *  Machine Add View
     *
     *  @returns Class
     */
    function (ControlledComponent) {
        return App.MachineAddComponent = ControlledComponent.extend({

            layoutName: 'machine_add',
            controllerName: 'machineAddController',

            changeProviderFlag: false,
            dockerNeedScript: false,
            hasAdvancedScript: false,
            hasLibvirtDiskNew: true,

            hasLibvirt: function() {
                var provider = Mist.machineAddController.newMachineProvider;
                return provider ? (provider.provider && provider.provider == 'libvirt' ? true : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasDocker: function() {
                var provider = Mist.machineAddController.newMachineProvider;
                return provider ? (provider.provider && provider.provider == 'docker' ? true : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasOpenstack: function() {
                var provider = Mist.machineAddController.newMachineProvider;
                return provider ? (provider.provider && provider.provider == 'openstack' ? true : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasAzure: function() {
                var provider = Mist.machineAddController.newMachineProvider;
                return provider ? (provider.provider && provider.provider == 'azure' ? true : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasKey: function() {
                var provider = Mist.machineAddController.newMachineProvider,
                invalids = ['docker', 'libvirt'];
                return provider ? (provider.provider ? (((invalids.indexOf(provider.provider) != -1 ? false : true) || (provider.provider == 'docker' && this.get('dockerNeedScript'))) ? true : false) : false) : false;
            }.property('hasDocker', 'dockerNeedScript', 'Mist.machineAddController.newMachineProvider'),

            hasCloudInit: Ember.computed('Mist.machineAddController.newMachineProvider', function() {
                var provider = Mist.machineAddController.newMachineProvider,
                valids = ['openstack', 'azure', 'digitalocean'];
                return provider ? (provider.provider ? ((valids.indexOf(provider.provider) != -1 || provider.provider.indexOf('ec2') > -1) ? true : false) : false) : false;
            }),

            hasScript: Ember.computed('hasKey', 'dockerNeedScript', function() {
                return this.get('hasKey') == true || this.get('dockerNeedScript');
            }),

            hasLocation: function() {
                var provider = Mist.machineAddController.newMachineProvider,
                valids = ['docker', 'indonesiancloud', 'vcloud', 'libvirt'];
                return provider ? (provider.provider ? ((valids.indexOf(provider.provider) != -1 || provider.locations.model.length == 1) ? false : true) : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasNetworks: function() {
                var provider = Mist.machineAddController.newMachineProvider,
                valids = ['openstack', 'hpcloud', 'vcloud', 'libvirt'];
                return provider ? (provider.provider ? ((valids.indexOf(provider.provider) != -1 && provider.networks.model.length) ? true : false) : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasMonitoring: Ember.computed('hasLibvirt', function() {
                return Mist.email && !this.get('hasLibvirt') ? true : false;
            }),

            /**
             *  Properties
             */

            price: function () {

                var image = Mist.machineAddController.newMachineImage;
                var size = Mist.machineAddController.newMachineSize;
                var provider = Mist.machineAddController.newMachineProvider;
                var location = Mist.machineAddController.newMachineLocation;

                if (!image || !image.id || !size || !size.id || !provider || !provider.id) return 0;

                try { //might fail with TypeError if no size for this image
                    if (provider.provider.indexOf('ec2') > -1) {
                        if (image.name.indexOf('SUSE Linux Enterprise') > -1)
                            return size.price.sles;
                        if (image.name.indexOf('Red Hat') > -1)
                            return size.price.rhel;
                        return size.price.linux;
                    }
                    if (provider.provider.indexOf('rackspace') > -1) {
                        if (image.name.indexOf('Red Hat') > -1)
                            return size.price.rhel;
                        if (image.name.indexOf('Vyatta') > -1)
                            return size.price.vyatta;
                        return size.price.linux;
                    }
                    if (provider.provider.indexOf('gce') > -1) {
                        if (location.name.indexOf('europe-') > -1)
                            return size.price.eu;
                        if (location.name.indexOf('us-') > -1)
                            return size.price.us;
                        if (location.name.indexOf('asia-') > -1)
                            return size.price.as;
                        return size.price.eu;
                    }
                    return size.price;

                } catch (error) {
                    return 0;
                }
            }.property('Mist.machineAddController.newMachineProvider',
                       'Mist.machineAddController.newMachineImage',
                       'Mist.machineAddController.newMachineSize',
                       'Mist.machineAddController.newMachineLocation'),

            /**
             *
             *  Initialization
             *
             */

             load: function () {
                Ember.run.next(function(){
                    $( "#create-machine" ).collapsible({
                        expand: function(event, ui) {
                            Mist.machineAddController.open(null);

                            var id = $(this).attr('id'),
                            overlay = id ? $('#' + id+'-overlay') : false;
                            if (overlay) {
                                overlay.removeClass('ui-screen-hidden').addClass('in');
                            }
                            $(this).children().next().hide();
                            $(this).children().next().slideDown(250);
                        }
                    });
                });

                // Add event listeners
                Mist.scriptsController.on('onChange', this, 'renderFields');
                Mist.keysController.on('onKeyListChange', this, 'renderFields');
                Mist.backendsController.on('onImagesChange', this, 'renderFields');

             }.on('didInsertElement'),

             unload: function () {
                Ember.run.next(function(){
                    $( "#create-machine" ).collapsible({
                        collapse: function(event, ui) {
                            $(this).children().next().slideUp(250);
                            var id = $(this).attr('id'),
                            overlay = id ? $('#' + id+'-overlay') : false;
                            if (overlay) {
                                overlay.removeClass('in').addClass('ui-screen-hidden');
                            }
                        }
                    });
                });

                // Remove event listeners
                Mist.scriptsController.off('onChange', this, 'renderFields');
                Mist.keysController.off('onKeyListChange', this, 'renderFields');
                Mist.backendsController.off('onImagesChange', this, 'renderFields');

             }.on('willDestroyElement'),

            /**
             *
             *  Methods
             *
             */

             clear: function () {
                 this.$('select').val('basic').slider('refresh');
                 this.$('.ui-collapsible').removeClass('selected');
                 this.setProperties({
                    changeProviderFlag: false,
                    dockerNeedScript: false,
                    hasAdvancedScript: false
                });
                $('#create-machine-floating-ip .ui-checkbox > .ui-btn')
                    .removeClass('ui-checkbox-off')
                    .addClass('ui-checkbox-on');
             },

             checkImageSelected: function(image) {
                if (image) {
                    this.triggerAction({
                        action:'selectProvider',
                        target: this,
                        actionContext: image.backend
                    });

                    this.triggerAction({
                        action:'selectImage',
                        target: this,
                        actionContext: image
                    });
                }
             },

             fieldIsReady: function (field) {
                $('#create-machine')
                    .find('.ui-collapsible')
                    .collapsible()
                    .collapsible('collapse');
                $('#create-machine-' + field).addClass('selected');
             },

             renderFields: function () {
                Ember.run.next(function () {

                    // Render collapsibles
                    if ($('.ui-collapsible').collapsible) {
                        $('.ui-collapsible').collapsible().enhanceWithin();
                    }

                    // Render listviews
                    if ($('.ui-listview').listview) {
                        $('.ui-listview').listview().listview('refresh');
                    }

                    // Render checkboxes
                    if ($('.ember-checkbox').checkboxradio) {
                        $('.ember-checkbox').checkboxradio().checkboxradio('refresh');
                    }
                });
             },

            /**
             *
             *  Actions
             *
             */

            actions: {

                clickOverlay: function() {
                    $('#create-machine').collapsible('collapse');
                },

                switchToggled: function () {
                    var value = this.$('#script select').val();
                    Mist.machineAddController.set('newMachineScript', '');
                    Mist.machineAddController.set('newMachineScriptParams', '');
                    Mist.machineAddController.set('hasScript', value == 'advanced');
                    this.set('hasAdvancedScript', value == 'advanced');
                    this.renderFields();
                },

                switchLibvirtDiskType: function () {
                    var value = this.$('#create-machine-libvirt-disk-type select').val();
                    Mist.machineAddController.set('newMachineLibvirtImagePath', '');
                    Mist.machineAddController.set('newMachineLibvirtExistingDiskPath', '');
                    this.set('hasLibvirtDiskNew', value != 1);
                    this.renderFields();
                },

                createLibvirtImage: function () {
                    var that = this;
                    Mist.machineImageCreateController.open(function(newImagePath) {
                        if (newImagePath) {
                            var imageFaker = Ember.Object.create({
                                id: newImagePath,
                                name: newImagePath
                            });

                            Mist.machineAddController.setProperties({
                                'newMachineImage': imageFaker,
                                'newMachineLibvirtImagePath': newImagePath
                            });

                            that.fieldIsReady('image');
                        }
                    });
                },

                selectProvider: function (backend) {

                    if (this.fieldIsReady) {
                        this.fieldIsReady('provider');
                    }

                    backend.networks.model.forEach(function (network, index) {
                        network.set('selected', false);
                    });
                    Mist.machineAddController.set('newMachineLocation', {'name' : 'Select Location'})
                                             .set('newMachineImage', {'name' : 'Select Image'})
                                             .set('newMachineSize', {'name' : 'Select Size'})
                                             .set('newMachineProvider', backend);

                    // Check we are not on single image page
                    if(! Mist.machineAddController.get('selectedImage')) this.set('changeProviderFlag', true);
                },

                selectImage: function (image) {

                    if (this.fieldIsReady) {
                        this.fieldIsReady('image');
                    }

                    Mist.machineAddController.set('newMachineLocation', {'name' : 'Select Location'})
                                             .set('newMachineSize', {'name' : 'Select Size'})
                                             .set('newMachineImage', image);

                    this.set('dockerNeedScript', image.get('isMist'));
                },

                selectSize: function (size) {
                    this.fieldIsReady('size');

                    Mist.machineAddController.set('newMachineLocation', {'name' : 'Select Location'})
                                             .set('newMachineSize', size);
                },

                selectLocation: function (location) {
                    this.fieldIsReady('location');

                    Mist.machineAddController.set('newMachineLocation', location);
                },

                selectKey: function (key) {
                    this._selectKey(key)
                },

                selectScript: function (script) {
                    Mist.machineAddController.set('newMachineScript', script);
                    $('#create-machine-script-select').collapsible().collapsible('collapse');
                },

                toggleNetworkSelection: function (network) {
                    network.set('selected', !network.selected);
                },

                createKeyClicked: function () {
                    var that = this;
                    Mist.keyAddController.open(function (success, key) {
                        that._selectKey(key);
                    });
                },

                backClicked: function () {
                    Mist.machineAddController.close();
                },

                launchClicked: function () {
                    Mist.machineAddController.add();
                }
            },

            _selectKey: function (key) {
                this.fieldIsReady('key');

                Mist.machineAddController.set('newMachineKey', key);
            },

            /**
             *
             *  Observers
             *
             */

             bindingsObserver: function () {
                Ember.run.once(this, 'renderFields');
             }.observes('Mist.machineAddController.newMachineSize',
                        'Mist.machineAddController.newMachineImage',
                        'Mist.machineAddController.newMachineProvider',
                        'Mist.machineAddController.newMachineLocation'),

             providerObserver: function() {
                 Ember.run.once(this, function(){
                    if (this.changeProviderFlag) Mist.machineAddController._resetProvider();
                 });
             }.observes('Mist.machineAddController.newMachineProvider'),

             networksObserver: function() {
                 Ember.run.once(this, function () {
                    if (this.get('hasOpenstack')) {
                        if (Mist.machineAddController.newMachineProvider.networks.model.filterBy('selected', true).length) {
                            $('#create-machine-floating-ip').slideDown();
                        } else {
                            $('#create-machine-floating-ip').slideUp();
                        }
                    }
                 });
             }.observes('hasOpenstack', 'Mist.machineAddController.newMachineProvider.networks.model.@each.selected')
        });
    }
);
<commit_msg>fix render blink<commit_after>define('app/views/machine_add', ['app/views/controlled'],
    /**
     *  Machine Add View
     *
     *  @returns Class
     */
    function (ControlledComponent) {
        return App.MachineAddComponent = ControlledComponent.extend({

            layoutName: 'machine_add',
            controllerName: 'machineAddController',

            changeProviderFlag: false,
            dockerNeedScript: false,
            hasAdvancedScript: false,
            hasLibvirtDiskNew: true,

            hasLibvirt: function() {
                var provider = Mist.machineAddController.newMachineProvider;
                return provider ? (provider.provider && provider.provider == 'libvirt' ? true : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasDocker: function() {
                var provider = Mist.machineAddController.newMachineProvider;
                return provider ? (provider.provider && provider.provider == 'docker' ? true : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasOpenstack: function() {
                var provider = Mist.machineAddController.newMachineProvider;
                return provider ? (provider.provider && provider.provider == 'openstack' ? true : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasAzure: function() {
                var provider = Mist.machineAddController.newMachineProvider;
                return provider ? (provider.provider && provider.provider == 'azure' ? true : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasKey: function() {
                var provider = Mist.machineAddController.newMachineProvider,
                invalids = ['docker', 'libvirt'];
                return provider ? (provider.provider ? (((invalids.indexOf(provider.provider) != -1 ? false : true) || (provider.provider == 'docker' && this.get('dockerNeedScript'))) ? true : false) : false) : false;
            }.property('hasDocker', 'dockerNeedScript', 'Mist.machineAddController.newMachineProvider'),

            hasCloudInit: Ember.computed('Mist.machineAddController.newMachineProvider', function() {
                var provider = Mist.machineAddController.newMachineProvider,
                valids = ['openstack', 'azure', 'digitalocean'];
                return provider ? (provider.provider ? ((valids.indexOf(provider.provider) != -1 || provider.provider.indexOf('ec2') > -1) ? true : false) : false) : false;
            }),

            hasScript: Ember.computed('hasKey', 'dockerNeedScript', function() {
                return this.get('hasKey') == true || this.get('dockerNeedScript');
            }),

            hasLocation: function() {
                var provider = Mist.machineAddController.newMachineProvider,
                valids = ['docker', 'indonesiancloud', 'vcloud', 'libvirt'];
                return provider ? (provider.provider ? ((valids.indexOf(provider.provider) != -1 || provider.locations.model.length == 1) ? false : true) : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasNetworks: function() {
                var provider = Mist.machineAddController.newMachineProvider,
                valids = ['openstack', 'hpcloud', 'vcloud', 'libvirt'];
                return provider ? (provider.provider ? ((valids.indexOf(provider.provider) != -1 && provider.networks.model.length) ? true : false) : false) : false;
            }.property('Mist.machineAddController.newMachineProvider'),

            hasMonitoring: Ember.computed('hasLibvirt', function() {
                return Mist.email && !this.get('hasLibvirt') ? true : false;
            }),

            /**
             *  Properties
             */

            price: function () {

                var image = Mist.machineAddController.newMachineImage;
                var size = Mist.machineAddController.newMachineSize;
                var provider = Mist.machineAddController.newMachineProvider;
                var location = Mist.machineAddController.newMachineLocation;

                if (!image || !image.id || !size || !size.id || !provider || !provider.id) return 0;

                try { //might fail with TypeError if no size for this image
                    if (provider.provider.indexOf('ec2') > -1) {
                        if (image.name.indexOf('SUSE Linux Enterprise') > -1)
                            return size.price.sles;
                        if (image.name.indexOf('Red Hat') > -1)
                            return size.price.rhel;
                        return size.price.linux;
                    }
                    if (provider.provider.indexOf('rackspace') > -1) {
                        if (image.name.indexOf('Red Hat') > -1)
                            return size.price.rhel;
                        if (image.name.indexOf('Vyatta') > -1)
                            return size.price.vyatta;
                        return size.price.linux;
                    }
                    if (provider.provider.indexOf('gce') > -1) {
                        if (location.name.indexOf('europe-') > -1)
                            return size.price.eu;
                        if (location.name.indexOf('us-') > -1)
                            return size.price.us;
                        if (location.name.indexOf('asia-') > -1)
                            return size.price.as;
                        return size.price.eu;
                    }
                    return size.price;

                } catch (error) {
                    return 0;
                }
            }.property('Mist.machineAddController.newMachineProvider',
                       'Mist.machineAddController.newMachineImage',
                       'Mist.machineAddController.newMachineSize',
                       'Mist.machineAddController.newMachineLocation'),

            /**
             *
             *  Initialization
             *
             */

             load: function () {
                Ember.run.next(function(){
                    $( "#create-machine" ).collapsible({
                        expand: function(event, ui) {
                            Mist.machineAddController.open(null);

                            var id = $(this).attr('id'),
                            overlay = id ? $('#' + id+'-overlay') : false;
                            if (overlay) {
                                overlay.removeClass('ui-screen-hidden').addClass('in');
                            }
                            $(this).children().next().hide();
                            $(this).children().next().slideDown(250);
                        }
                    });
                });

                // Add event listeners
                Mist.scriptsController.on('onChange', this, 'renderFields');
                Mist.keysController.on('onKeyListChange', this, 'renderFields');
                Mist.backendsController.on('onImagesChange', this, 'renderFields');

             }.on('didInsertElement'),

             unload: function () {
                Ember.run.next(function(){
                    $( "#create-machine" ).collapsible({
                        collapse: function(event, ui) {
                            $(this).children().next().slideUp(250);
                            var id = $(this).attr('id'),
                            overlay = id ? $('#' + id+'-overlay') : false;
                            if (overlay) {
                                overlay.removeClass('in').addClass('ui-screen-hidden');
                            }
                        }
                    });
                });

                // Remove event listeners
                Mist.scriptsController.off('onChange', this, 'renderFields');
                Mist.keysController.off('onKeyListChange', this, 'renderFields');
                Mist.backendsController.off('onImagesChange', this, 'renderFields');

             }.on('willDestroyElement'),

            /**
             *
             *  Methods
             *
             */

             clear: function () {
                 this.$('select').val('basic').slider('refresh');
                 this.$('.ui-collapsible').removeClass('selected');
                 this.setProperties({
                    changeProviderFlag: false,
                    dockerNeedScript: false,
                    hasAdvancedScript: false
                });
                $('#create-machine-floating-ip .ui-checkbox > .ui-btn')
                    .removeClass('ui-checkbox-off')
                    .addClass('ui-checkbox-on');
             },

             checkImageSelected: function(image) {
                if (image) {
                    this.triggerAction({
                        action:'selectProvider',
                        target: this,
                        actionContext: image.backend
                    });

                    this.triggerAction({
                        action:'selectImage',
                        target: this,
                        actionContext: image
                    });
                }
             },

             fieldIsReady: function (field) {
                $('#create-machine')
                    .find('.ui-collapsible')
                    .collapsible()
                    .collapsible('collapse');
                $('#create-machine-' + field).addClass('selected');
             },

             renderFields: function () {
                Ember.run.schedule('afterRender', this, function () {

                    // Render collapsibles
                    if ($('.ui-collapsible').collapsible) {
                        $('.ui-collapsible').collapsible().enhanceWithin();
                    }

                    // Render listviews
                    if ($('.ui-listview').listview) {
                        $('.ui-listview').listview().listview('refresh');
                    }

                    // Render checkboxes
                    if ($('.ember-checkbox').checkboxradio) {
                        $('.ember-checkbox').checkboxradio().checkboxradio('refresh');
                    }
                });
             },

            /**
             *
             *  Actions
             *
             */

            actions: {

                clickOverlay: function() {
                    $('#create-machine').collapsible('collapse');
                },

                switchToggled: function () {
                    var value = this.$('#script select').val();
                    Mist.machineAddController.set('newMachineScript', '');
                    Mist.machineAddController.set('newMachineScriptParams', '');
                    Mist.machineAddController.set('hasScript', value == 'advanced');
                    this.set('hasAdvancedScript', value == 'advanced');
                    this.renderFields();
                },

                switchLibvirtDiskType: function () {
                    var value = this.$('#create-machine-libvirt-disk-type select').val();
                    Mist.machineAddController.set('newMachineLibvirtImagePath', '');
                    Mist.machineAddController.set('newMachineLibvirtExistingDiskPath', '');
                    this.set('hasLibvirtDiskNew', value != 1);
                    this.renderFields();
                },

                createLibvirtImage: function () {
                    var that = this;
                    Mist.machineImageCreateController.open(function(newImagePath) {
                        if (newImagePath) {
                            var imageFaker = Ember.Object.create({
                                id: newImagePath,
                                name: newImagePath
                            });

                            Mist.machineAddController.setProperties({
                                'newMachineImage': imageFaker,
                                'newMachineLibvirtImagePath': newImagePath
                            });

                            that.fieldIsReady('image');
                        }
                    });
                },

                selectProvider: function (backend) {

                    if (this.fieldIsReady) {
                        this.fieldIsReady('provider');
                    }

                    backend.networks.model.forEach(function (network, index) {
                        network.set('selected', false);
                    });
                    Mist.machineAddController.set('newMachineLocation', {'name' : 'Select Location'})
                                             .set('newMachineImage', {'name' : 'Select Image'})
                                             .set('newMachineSize', {'name' : 'Select Size'})
                                             .set('newMachineProvider', backend);

                    // Check we are not on single image page
                    if(! Mist.machineAddController.get('selectedImage')) this.set('changeProviderFlag', true);
                },

                selectImage: function (image) {

                    if (this.fieldIsReady) {
                        this.fieldIsReady('image');
                    }

                    Mist.machineAddController.set('newMachineLocation', {'name' : 'Select Location'})
                                             .set('newMachineSize', {'name' : 'Select Size'})
                                             .set('newMachineImage', image);

                    this.set('dockerNeedScript', image.get('isMist'));
                },

                selectSize: function (size) {
                    this.fieldIsReady('size');

                    Mist.machineAddController.set('newMachineLocation', {'name' : 'Select Location'})
                                             .set('newMachineSize', size);
                },

                selectLocation: function (location) {
                    this.fieldIsReady('location');

                    Mist.machineAddController.set('newMachineLocation', location);
                },

                selectKey: function (key) {
                    this._selectKey(key)
                },

                selectScript: function (script) {
                    Mist.machineAddController.set('newMachineScript', script);
                    $('#create-machine-script-select').collapsible().collapsible('collapse');
                },

                toggleNetworkSelection: function (network) {
                    network.set('selected', !network.selected);
                },

                createKeyClicked: function () {
                    var that = this;
                    Mist.keyAddController.open(function (success, key) {
                        that._selectKey(key);
                    });
                },

                backClicked: function () {
                    Mist.machineAddController.close();
                },

                launchClicked: function () {
                    Mist.machineAddController.add();
                }
            },

            _selectKey: function (key) {
                this.fieldIsReady('key');

                Mist.machineAddController.set('newMachineKey', key);
            },

            /**
             *
             *  Observers
             *
             */

             bindingsObserver: function () {
                Ember.run.once(this, 'renderFields');
             }.observes('Mist.machineAddController.newMachineSize',
                        'Mist.machineAddController.newMachineImage',
                        'Mist.machineAddController.newMachineProvider',
                        'Mist.machineAddController.newMachineLocation'),

             providerObserver: function() {
                 Ember.run.once(this, function(){
                    if (this.changeProviderFlag) Mist.machineAddController._resetProvider();
                 });
             }.observes('Mist.machineAddController.newMachineProvider'),

             networksObserver: function() {
                 Ember.run.once(this, function () {
                    if (this.get('hasOpenstack')) {
                        if (Mist.machineAddController.newMachineProvider.networks.model.filterBy('selected', true).length) {
                            $('#create-machine-floating-ip').slideDown();
                        } else {
                            $('#create-machine-floating-ip').slideUp();
                        }
                    }
                 });
             }.observes('hasOpenstack', 'Mist.machineAddController.newMachineProvider.networks.model.@each.selected')
        });
    }
);
<|endoftext|>