<commit_before>/* @flow weak */
"use strict";
var _ = {
  assign: require("lodash.assign")
};

var MemoryStore = module.exports = function MemoryStore() {
};

// resources represents out in-memory data store
var resources = { };

/**
  Handlers readiness status. This should be set to `true` once all handlers are ready to process requests.
 */
MemoryStore.prototype.ready = false;

/**
  initialise gets invoked once for each resource that uses this hander.
  In this instance, we're allocating an array in our in-memory data store.
 */
MemoryStore.prototype.initialise = function(resourceConfig) {
  resources[resourceConfig.resource] = resourceConfig.examples || [ ];
  this.ready = true;
};

/**
  Search for a list of resources, given a resource type.
 */
MemoryStore.prototype.search = function(request, callback) {
  var self = this;

  var results = [].concat(resources[request.params.type]);
  self._sortList(request, results);
  var resultCount = results.length;
  if (request.params.page) {
    results = results.slice(request.params.page.offset, request.params.page.offset + request.params.page.limit);
  }
  return callback(null, this._clone(results), resultCount);
};

/**
  Find a specific resource, given a resource type and and id.
 */
MemoryStore.prototype.find = function(request, callback) {
  // Pull the requested resource from the in-memory store
  var theResource = resources[request.params.type].filter(function(anyResource) {
    return anyResource.id === request.params.id;
  }).pop();

  // If the resource doesn't exist, error
  if (!theResource) {
    return callback({
      status: "404",
      code: "ENOTFOUND",
      title: "Requested resource does not exist",
      detail: "There is no " + request.params.type + " with id " + request.params.id
    });
  }

  // Return the requested resource
  return callback(null, this._clone(theResource));
};

/**
  Create (store) a new resource given a resource type and an object.
 */
MemoryStore.prototype.create = function(request, newResource, callback) {
  // Check to see if the ID already exists
  var matches = resources[request.params.type].filter(function(resource) {
    return resource.id === newResource.id;
  }).length;
  if (matches > 0) {
    return callback({
      status: "403",
      code: "EFORBIDDEN",
      title: "Requested resource already exists",
      detail: "The requested resource already exists of type " + request.params.type + " with id " + request.params.id
    });
  }
  // Push the newResource into our in-memory store.
  resources[request.params.type].push(newResource);
  // Return the newly created resource
  return callback(null, this._clone(newResource));
};

/**
  Delete a resource, given a resource type and and id.
 */
MemoryStore.prototype.delete = function(request, callback) {
  // Find the requested resource
  this.find(request, function(err, theResource) {
    if (err) return callback(err);

    // Remove the resource from the in-memory store.
    resources[request.params.type].some(function(resource, index) {
      var match = resource.id === theResource.id;
      if (match) {
        resources[request.params.type].splice(index, 1);
      }
      return match;
    });

    // Return with no error
    return callback();
  });
};

/**
  Update a resource, given a resource type and id, along with a partialResource.
  partialResource contains a subset of changes that need to be merged over the original.
 */
MemoryStore.prototype.update = function(request, partialResource, callback) {
  var self = this;
  // Find the requested resource
  self.find(request, function(err, theResource) {
    if (err) return callback(err);

    // Merge the partialResource over the original
    theResource = _.assign(theResource, partialResource);

    // Push the newly updated resource back into the in-memory store
    resources[request.params.type].some(function(resource, index) {
      var match = resource.id === theResource.id;
      if (match) {
        resources[request.params.type][index] = theResource;
      }
      return match;
    });

    // Return the newly updated resource
    return callback(null, self._clone(theResource));
  });
};

/**
  Internal helper function to sort data
 */
MemoryStore.prototype._sortList = function(request, list) {
  var attribute = request.params.sort;
  if (!attribute) return;

  var ascending = 1;
  attribute = ("" + attribute);
  if (attribute[0] === "-") {
    ascending = -1;
    attribute = attribute.substring(1, attribute.length);
  }

  list.sort(function(a, b) {
    if (typeof a[attribute] === "string") {
      return a[attribute].localeCompare(b[attribute]) * ascending;
    } else if (typeof a[attribute] === "number") {
      return (a[attribute] - b[attribute]) * ascending;
    } else {
      return 0;
    }
  });
};

MemoryStore.prototype._clone = function(obj) {
  return JSON.parse(JSON.stringify(obj));
};
<commit_msg>Clone all objects passing in-to and out-of the in memory store<commit_after>/* @flow weak */
"use strict";
var _ = {
  assign: require("lodash.assign")
};

var MemoryStore = module.exports = function MemoryStore() {
};

// resources represents out in-memory data store
var resources = { };

/**
  Handlers readiness status. This should be set to `true` once all handlers are ready to process requests.
 */
MemoryStore.prototype.ready = false;

/**
  initialise gets invoked once for each resource that uses this hander.
  In this instance, we're allocating an array in our in-memory data store.
 */
MemoryStore.prototype.initialise = function(resourceConfig) {
  resources[resourceConfig.resource] = resourceConfig.examples || [ ];
  this.ready = true;
};

/**
  Search for a list of resources, given a resource type.
 */
MemoryStore.prototype.search = function(request, callback) {
  var self = this;

  var results = [].concat(resources[request.params.type]);
  self._sortList(request, results);
  var resultCount = results.length;
  if (request.params.page) {
    results = results.slice(request.params.page.offset, request.params.page.offset + request.params.page.limit);
  }
  return callback(null, MemoryStore._clone(results), resultCount);
};

/**
  Find a specific resource, given a resource type and and id.
 */
MemoryStore.prototype.find = function(request, callback) {
  // Pull the requested resource from the in-memory store
  var theResource = resources[request.params.type].filter(function(anyResource) {
    return anyResource.id === request.params.id;
  }).pop();

  // If the resource doesn't exist, error
  if (!theResource) {
    return callback({
      status: "404",
      code: "ENOTFOUND",
      title: "Requested resource does not exist",
      detail: "There is no " + request.params.type + " with id " + request.params.id
    });
  }

  // Return the requested resource
  return callback(null, MemoryStore._clone(theResource));
};

/**
  Create (store) a new resource given a resource type and an object.
 */
MemoryStore.prototype.create = function(request, newResource, callback) {
  // Check to see if the ID already exists
  var index = MemoryStore._indexOf(resources[request.params.type], newResource);
  if (index !== -1) {
    return callback({
      status: "403",
      code: "EFORBIDDEN",
      title: "Requested resource already exists",
      detail: "The requested resource already exists of type " + request.params.type + " with id " + request.params.id
    });
  }
  // Push the newResource into our in-memory store.
  resources[request.params.type].push(newResource);
  // Return the newly created resource
  return callback(null, MemoryStore._clone(newResource));
};

/**
  Delete a resource, given a resource type and and id.
 */
MemoryStore.prototype.delete = function(request, callback) {
  // Find the requested resource
  this.find(request, function(err, theResource) {
    if (err) return callback(err);

    // Remove the resource from the in-memory store.
    var index = MemoryStore._indexOf(resources[request.params.type], theResource);
    resources[request.params.type].splice(index, 1);

    // Return with no error
    return callback();
  });
};

/**
  Update a resource, given a resource type and id, along with a partialResource.
  partialResource contains a subset of changes that need to be merged over the original.
 */
MemoryStore.prototype.update = function(request, partialResource, callback) {
  var self = this;
  // Find the requested resource
  self.find(request, function(err, theResource) {
    if (err) return callback(err);

    // Merge the partialResource over the original
    theResource = _.assign(theResource, partialResource);

    // Push the newly updated resource back into the in-memory store
    var index = MemoryStore._indexOf(resources[request.params.type], theResource);
    resources[request.params.type][index] = theResource;

    // Return the newly updated resource
    return callback(null, MemoryStore._clone(theResource));
  });
};

/**
  Internal helper function to sort data
 */
MemoryStore.prototype._sortList = function(request, list) {
  var attribute = request.params.sort;
  if (!attribute) return;

  var ascending = 1;
  attribute = ("" + attribute);
  if (attribute[0] === "-") {
    ascending = -1;
    attribute = attribute.substring(1, attribute.length);
  }

  list.sort(function(a, b) {
    if (typeof a[attribute] === "string") {
      return a[attribute].localeCompare(b[attribute]) * ascending;
    } else if (typeof a[attribute] === "number") {
      return (a[attribute] - b[attribute]) * ascending;
    } else {
      return 0;
    }
  });
};

MemoryStore._clone = function(obj) {
  return JSON.parse(JSON.stringify(obj));
};

MemoryStore._indexOf = function(list, obj) {
  for (var i in list) {
    if (list[i].id === obj.id) return i;
  }
  return -1;
};
<|endoftext|>


<commit_before>var graphAPI = (function(){

  var trace1 = {
    x: [0.000000e+0,1.000000e-4,3.514000e-2,7.152000e-2,1.091700e-1,1.371370e+0,5.918310e+0,8.440610e+0,1.102264e+1,1.379108e+1,1.657924e+1,1.918366e+1,2.217395e+1,2.560725e+1,2.954921e+1,3.407519e+1,3.790451e+1,4.215191e+1,4.686301e+1,
        5.588529e+1,6.660830e+1,7.935261e+1,9.449926e+1,1.125011e+2,1.338963e+2,1.593245e+2,1.895461e+2,2.254644e+2,3.188895e+2,3.791894e+2,4.508559e+2,5.360318e+2,6.372635e+2,7.575776e+2,9.005711e+2],
    y: [4.903500e-20,4.903500e-20,5.501140e-20,5.747600e-20,5.896700e-20,6.938560e-20,6.025320e-20,5.209010e-20,4.444340e-20,3.734320e-20,3.184430e-20,2.766530e-20,2.383470e-20,
        1.998990e-20,1.667870e-20,1.385490e-20,1.190580e-20,1.024370e-20,8.806780e-21,6.702370e-21,5.073960e-21,3.808260e-21,2.878530e-21,2.204960e-21,1.622750e-21,1.224330e-21,9.142570e-22,6.756040e-22,4.949030e-22,3.701550e-22,
        2.748810e-22,2.023320e-22,1.477860e-22,1.101690e-22,8.165410e-23,5.983320e-23],
    type: 'scatter'
  };

  var trace2 = {
    x: [0.000000e+0,1.000000e-3,2.000000e-3,3.000000e-3,5.000000e-3,7.000000e-3,8.500000e-3,1.000000e-2,1.500000e-2,2.000000e-2,3.000000e-2,4.000000e-2,5.000000e-2,7.000000e-2,1.000000e-1,1.200000e-1,1.500000e-1,1.700000e-1,2.000000e-1,2.500000e-1,3.000000e-1,
        3.500000e-1,4.000000e-1,5.000000e-1,7.000000e-1,1.000000e+0,1.200000e+0,1.300000e+0,1.500000e+0,1.700000e+0,1.900000e+0,2.100000e+0,2.200000e+0,2.500000e+0,2.800000e+0,3.000000e+0,3.300000e+0,3.600000e+0,4.000000e+0,4.500000e+0,5.000000e+0,6.000000e+0,7.000000e+0,8.000000e+0,1.000000e+1,1.200000e+1,1.500000e+1,1.700000e+1,2.000000e+1,2.500000e+1,3.000000e+1,5.000000e+1,7.500000e+1,1.000000e+2,1.500000e+2,2.000000e+2,3.000000e+2,5.000000e+2,7.500000e+2,1.000000e+3],
    y: [4.960000e-20,4.980000e-20,5.020000e-20,5.070000e-20,5.120000e-20,5.150000e-20,5.180000e-20,5.210000e-20,5.280000e-20,5.350000e-20,5.460000e-20,5.540000e-20,
        5.620000e-20,5.740000e-20,5.860000e-20,5.940000e-20,6.040000e-20,6.080000e-20,6.160000e-20,6.270000e-20,6.350000e-20,6.420000e-20,6.490000e-20,6.590000e-20,6.730000e-20,6.850000e-20,
        6.910000e-20,6.920000e-20,6.960000e-20,6.970000e-20,6.980000e-20,6.980000e-20,6.980000e-20,6.960000e-20,6.920000e-20,6.890000e-20,6.820000e-20,6.730000e-20,6.600000e-20,6.490000e-20,
        6.310000e-20,6.000000e-20,5.680000e-20,5.350000e-20,4.720000e-20,4.200000e-20,3.500000e-20,3.150000e-20,2.640000e-20,2.050000e-20,1.740000e-20,1.100000e-20,8.800000e-21,
        7.500000e-21,6.050000e-21,5.200000e-21,4.100000e-21,3.000000e-21,2.350000e-21,1.700000e-21],
    type: 'scatter'
  };

  var data = [trace1, trace2];

  var layout = {
    autosize: true, //?
    width: 1000,
    height: 800,
    xaxis: {
      range: [],
      type: 'log',
      dtick: "D1", // En mode log, affiche les 10+ small digits.
      tickcolor: "#333",
      gridcolor: "#999",
      // tickfont:{
      //   color: "#fff" // Pour cacher.
      // },
      exponentformat: 'e',
      showexponent: 'All',
      // autorange: true,
    },
    yaxis: {
      range: [],
      type: 'log',
      dtick: "D1",
      exponentformat: 'e',
      showexponent: 'All',
      tickcolor: "#333",
      gridcolor: "#999",
      // autorange: true,
    }
  };

  Plotly.newPlot('graph', data, layout);

  return {
    addData: function(toadd){
      data.push(toadd);
    },
    refresh: function(){

    },
    updateLayout: function( update ){

    }
  }

})();<commit_msg>tests sur le layout<commit_after>var graphAPI = (function(){

  var trace1 = {
    x: [0.000000e+0,1.000000e-4,3.514000e-2,7.152000e-2,1.091700e-1,1.371370e+0,5.918310e+0,8.440610e+0,1.102264e+1,1.379108e+1,1.657924e+1,1.918366e+1,2.217395e+1,2.560725e+1,2.954921e+1,3.407519e+1,3.790451e+1,4.215191e+1,4.686301e+1,
        5.588529e+1,6.660830e+1,7.935261e+1,9.449926e+1,1.125011e+2,1.338963e+2,1.593245e+2,1.895461e+2,2.254644e+2,3.188895e+2,3.791894e+2,4.508559e+2,5.360318e+2,6.372635e+2,7.575776e+2,9.005711e+2],
    y: [4.903500e-20,4.903500e-20,5.501140e-20,5.747600e-20,5.896700e-20,6.938560e-20,6.025320e-20,5.209010e-20,4.444340e-20,3.734320e-20,3.184430e-20,2.766530e-20,2.383470e-20,
        1.998990e-20,1.667870e-20,1.385490e-20,1.190580e-20,1.024370e-20,8.806780e-21,6.702370e-21,5.073960e-21,3.808260e-21,2.878530e-21,2.204960e-21,1.622750e-21,1.224330e-21,9.142570e-22,6.756040e-22,4.949030e-22,3.701550e-22,
        2.748810e-22,2.023320e-22,1.477860e-22,1.101690e-22,8.165410e-23,5.983320e-23],
    type: 'scatter'
  };

  var trace2 = {
    x: [0.000000e+0,1.000000e-3,2.000000e-3,3.000000e-3,5.000000e-3,7.000000e-3,8.500000e-3,1.000000e-2,1.500000e-2,2.000000e-2,3.000000e-2,4.000000e-2,5.000000e-2,7.000000e-2,1.000000e-1,1.200000e-1,1.500000e-1,1.700000e-1,2.000000e-1,2.500000e-1,3.000000e-1,
        3.500000e-1,4.000000e-1,5.000000e-1,7.000000e-1,1.000000e+0,1.200000e+0,1.300000e+0,1.500000e+0,1.700000e+0,1.900000e+0,2.100000e+0,2.200000e+0,2.500000e+0,2.800000e+0,3.000000e+0,3.300000e+0,3.600000e+0,4.000000e+0,4.500000e+0,5.000000e+0,6.000000e+0,7.000000e+0,8.000000e+0,1.000000e+1,1.200000e+1,1.500000e+1,1.700000e+1,2.000000e+1,2.500000e+1,3.000000e+1,5.000000e+1,7.500000e+1,1.000000e+2,1.500000e+2,2.000000e+2,3.000000e+2,5.000000e+2,7.500000e+2,1.000000e+3],
    y: [4.960000e-20,4.980000e-20,5.020000e-20,5.070000e-20,5.120000e-20,5.150000e-20,5.180000e-20,5.210000e-20,5.280000e-20,5.350000e-20,5.460000e-20,5.540000e-20,
        5.620000e-20,5.740000e-20,5.860000e-20,5.940000e-20,6.040000e-20,6.080000e-20,6.160000e-20,6.270000e-20,6.350000e-20,6.420000e-20,6.490000e-20,6.590000e-20,6.730000e-20,6.850000e-20,
        6.910000e-20,6.920000e-20,6.960000e-20,6.970000e-20,6.980000e-20,6.980000e-20,6.980000e-20,6.960000e-20,6.920000e-20,6.890000e-20,6.820000e-20,6.730000e-20,6.600000e-20,6.490000e-20,
        6.310000e-20,6.000000e-20,5.680000e-20,5.350000e-20,4.720000e-20,4.200000e-20,3.500000e-20,3.150000e-20,2.640000e-20,2.050000e-20,1.740000e-20,1.100000e-20,8.800000e-21,
        7.500000e-21,6.050000e-21,5.200000e-21,4.100000e-21,3.000000e-21,2.350000e-21,1.700000e-21],
    type: 'scatter'
  };

  var data = [trace1, trace2];

  var layout = {
    autosize: true, //?
    width: 1000,
    height: 800,
    showgrid: false,
    xaxis: {
      title:"",
      range: [],
      type: 'log',
      dtick: "D1", // En mode log, affiche les 10+ small digits.
      tickcolor: "#333",
      gridcolor: "#999",
      // tickfont:{
      //   color: "#fff" // Pour cacher.
      // },
      exponentformat: 'e',
      showexponent: 'All',
      // autorange: true,
    },
    yaxis: {
      title:"",
      range: [],
      type: 'log',
      dtick: "D1",
      exponentformat: 'e',
      showexponent: 'All',
      tickcolor: "#333",
      gridcolor: "#999",
      // autorange: true,
    }
  };

  Plotly.newPlot('graph', data, layout);

  return {
    addData: function(toadd){
      data.push(toadd);
    },
    refresh: function(){

    },
    updateLayout: function( update ){

    }
  }

})();<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import uniqueId from 'lodash/uniqueId';

import formField from '../FormField';
import css from './Select.css';
import formStyles from '../sharedStyles/form.css';
import sharedInputStylesHelper from '../sharedStyles/sharedInputStylesHelper';
import omitProps from '../../util/omitProps';
import parseMeta from '../FormField/parseMeta';
import Icon from '../Icon';
import Label from '../Label';

class Select extends Component {
  static propTypes = {
    'aria-label': PropTypes.string,
    'aria-labelledby': PropTypes.string,
    'autoFocus': PropTypes.bool,
    'children': PropTypes.node,
    'dataOptions': PropTypes.arrayOf(PropTypes.object),
    'dirty': PropTypes.bool,
    'disabled': PropTypes.bool,
    'error': PropTypes.node,
    'fullWidth': PropTypes.bool,
    'id': PropTypes.string,
    'inputRef': PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
    'label': PropTypes.node,
    'loading': PropTypes.bool,
    'marginBottom0': PropTypes.bool,
    'name': PropTypes.string,
    'placeholder': PropTypes.string,
    'readOnly': PropTypes.bool,
    'required': PropTypes.bool,
    'selectClass': PropTypes.string,
    'valid': PropTypes.bool,
    'validationEnabled': PropTypes.bool,
    'validStylesEnabled': PropTypes.bool,
    'value': PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
    'warning': PropTypes.node,
    'multiple': PropTypes.bool,
  };

  static defaultProps = {
    'autoFocus': false,
    'validationEnabled': true,
    'validStylesEnabled': false,
    'multiple': false,
  };

  constructor(props) {
    super(props);
    this.id = this.props.id || uniqueId('select-');
  }

  getRootClass() {
    return classNames(
      css.select,
      formStyles.inputGroup,
      { [`${css.fullWidth}`]: this.props.fullWidth },
    );
  }

  getSelectClass() {
    return classNames(
      css.selectControl,
      // placeholder styling
      {
        [`${css.placeholder}`]: this.props.placeholder && !this.props.value
      }, // end placeholder
      sharedInputStylesHelper(this.props),
      this.props.selectClass,
    );
  }

  getAriaLabelledBy() {
    const label = this.props.label && `${this.id}-label`;
    const readOnly = this.props.readOnly && `${this.id}-read-only-message`;

    const finalString = [label, this.props['aria-labelledby'], readOnly].filter(Boolean).join(' ');

    return finalString ?? undefined;
  }

  render() {
    /* eslint-disable no-unused-vars */
    const {
      autoFocus,
      dataOptions,
      dirty,
      children,
      error,
      fullWidth,
      label,
      loading,
      marginBottom0,
      name,
      placeholder,
      readOnly,
      required,
      valid,
      validationEnabled,
      validStylesEnabled,
      warning,
      inputRef,
      multiple,
      ...selectCustom
    } = this.props;
    /* eslint-enable no-unused-vars */

    const options = [];

    if (this.props.placeholder) {
      options.push(
        <option value="" key="x" disabled>{placeholder}</option>
      );
    }

    if (dataOptions) {
      dataOptions.forEach((option, i) => {
        options.push(
          <option
            value={option.value}
            key={option.id || `option-${i}`}
            disabled={option.disabled || (readOnly && option.value !== this.props.value)}
          >
            {option.label}
          </option>
        );
      });
    }

    const component = (
      <select
        autoFocus={autoFocus}
        className={this.getSelectClass()}
        name={name}
        {...omitProps(selectCustom, ['selectClass', 'aria-labelledby', 'aria-label'])}
        aria-labelledby={this.getAriaLabelledBy()}
        aria-invalid={!!this.props.error}
        aria-required={required}
        id={this.id}
        required={required}
        ref={inputRef}
      >
        {options}
        {
          React.Children.map(children, (child) => {
            if (child.type === 'option') {
              return React.cloneElement(child, {
                // Disable option if it's disabled
                // or <Select> is read-only and option is different from current value
                disabled: child.props.disabled || (readOnly && child.props.value !== this.props.value),
              });
            }

            return child;
          })
        }
      </select>
    );

    const errorElem = error ?

{error}
 : null;

    const warningElem = warning ?

{warning}
 : null;

    return (

        {(label || this.props['aria-label']) ? (
          <Label
            htmlFor={this.id}
            id={`${this.id}-label`}
            readOnly={readOnly}
            required={required}
            className={this.props['aria-label'] && 'sr-only'}
          >
            {this.props['aria-label'] || label}
          )
          : ''}

          {component}
          {!multiple && <Icon icon="triangle-down" iconRootClass={css.selectIcon} />}

          {warningElem}
          {errorElem}

    );
  }
}

export default formField(
  Select,
  ({ meta }) => ({
    dirty: meta.dirty,
    error: (meta.touched && meta.error ? meta.error : ''),
    valid: meta.valid,
    warning: (meta.touched ? parseMeta(meta, 'warning') : ''),
  })
);
<commit_msg>STCOM-925 restore Select `multiple` prop support (#1715)<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import uniqueId from 'lodash/uniqueId';

import formField from '../FormField';
import css from './Select.css';
import formStyles from '../sharedStyles/form.css';
import sharedInputStylesHelper from '../sharedStyles/sharedInputStylesHelper';
import omitProps from '../../util/omitProps';
import parseMeta from '../FormField/parseMeta';
import Icon from '../Icon';
import Label from '../Label';

class Select extends Component {
  static propTypes = {
    'aria-label': PropTypes.string,
    'aria-labelledby': PropTypes.string,
    'autoFocus': PropTypes.bool,
    'children': PropTypes.node,
    'dataOptions': PropTypes.arrayOf(PropTypes.object),
    'dirty': PropTypes.bool,
    'disabled': PropTypes.bool,
    'error': PropTypes.node,
    'fullWidth': PropTypes.bool,
    'id': PropTypes.string,
    'inputRef': PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
    'label': PropTypes.node,
    'loading': PropTypes.bool,
    'marginBottom0': PropTypes.bool,
    'name': PropTypes.string,
    'placeholder': PropTypes.string,
    'readOnly': PropTypes.bool,
    'required': PropTypes.bool,
    'selectClass': PropTypes.string,
    'valid': PropTypes.bool,
    'validationEnabled': PropTypes.bool,
    'validStylesEnabled': PropTypes.bool,
    'value': PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
    'warning': PropTypes.node,
    'multiple': PropTypes.bool,
  };

  static defaultProps = {
    'autoFocus': false,
    'validationEnabled': true,
    'validStylesEnabled': false,
    'multiple': false,
  };

  constructor(props) {
    super(props);
    this.id = this.props.id || uniqueId('select-');
  }

  getRootClass() {
    return classNames(
      css.select,
      formStyles.inputGroup,
      { [`${css.fullWidth}`]: this.props.fullWidth },
    );
  }

  getSelectClass() {
    return classNames(
      css.selectControl,
      // placeholder styling
      {
        [`${css.placeholder}`]: this.props.placeholder && !this.props.value
      }, // end placeholder
      sharedInputStylesHelper(this.props),
      this.props.selectClass,
    );
  }

  getAriaLabelledBy() {
    const label = this.props.label && `${this.id}-label`;
    const readOnly = this.props.readOnly && `${this.id}-read-only-message`;

    const finalString = [label, this.props['aria-labelledby'], readOnly].filter(Boolean).join(' ');

    return finalString ?? undefined;
  }

  render() {
    /* eslint-disable no-unused-vars */
    const {
      autoFocus,
      dataOptions,
      dirty,
      children,
      error,
      fullWidth,
      label,
      loading,
      marginBottom0,
      name,
      placeholder,
      readOnly,
      required,
      valid,
      validationEnabled,
      validStylesEnabled,
      warning,
      inputRef,
      multiple,
      ...selectCustom
    } = this.props;
    /* eslint-enable no-unused-vars */

    const options = [];

    if (this.props.placeholder) {
      options.push(
        <option value="" key="x" disabled>{placeholder}</option>
      );
    }

    if (dataOptions) {
      dataOptions.forEach((option, i) => {
        options.push(
          <option
            value={option.value}
            key={option.id || `option-${i}`}
            disabled={option.disabled || (readOnly && option.value !== this.props.value)}
          >
            {option.label}
          </option>
        );
      });
    }

    const component = (
      <select
        autoFocus={autoFocus}
        className={this.getSelectClass()}
        name={name}
        {...omitProps(selectCustom, ['selectClass', 'aria-labelledby', 'aria-label'])}
        aria-labelledby={this.getAriaLabelledBy()}
        aria-invalid={!!this.props.error}
        aria-required={required}
        id={this.id}
        required={required}
        ref={inputRef}
        multiple={multiple}
      >
        {options}
        {
          React.Children.map(children, (child) => {
            if (child.type === 'option') {
              return React.cloneElement(child, {
                // Disable option if it's disabled
                // or <Select> is read-only and option is different from current value
                disabled: child.props.disabled || (readOnly && child.props.value !== this.props.value),
              });
            }

            return child;
          })
        }
      </select>
    );

    const errorElem = error ?

{error}
 : null;

    const warningElem = warning ?

{warning}
 : null;

    return (

        {(label || this.props['aria-label']) ? (
          <Label
            htmlFor={this.id}
            id={`${this.id}-label`}
            readOnly={readOnly}
            required={required}
            className={this.props['aria-label'] && 'sr-only'}
          >
            {this.props['aria-label'] || label}
          )
          : ''}

          {component}
          {!multiple && <Icon icon="triangle-down" iconRootClass={css.selectIcon} />}

          {warningElem}
          {errorElem}

    );
  }
}

export default formField(
  Select,
  ({ meta }) => ({
    dirty: meta.dirty,
    error: (meta.touched && meta.error ? meta.error : ''),
    valid: meta.valid,
    warning: (meta.touched ? parseMeta(meta, 'warning') : ''),
  })
);
<|endoftext|>


<commit_before>var _ = require('underscore')
var Peer = require('../ipfs-peer')

module.exports = DHTRouting

// DHTRouting interfaces between IPFS Routing module
// and an underlying DHT implementation

function DHTRouting(localPeer, dht) {
  this.peer = localPeer
  this.dht = dht

  // the blocks to periodically announce as providing
  // Note: should probably query live storage.
  this.provide = {}
}

// findPeer looks for a particular peer with given id
// callback returns a Peer
// callback errors: same as DHT.findNode
DHTRouting.prototype.findPeer = function findPeer(id, cb) {
  this.dht.findNode(id, function(err, nodeId, addr) {
    if (err) return cb(err)

    if (nodeId != id) {
      var msg = 'Expected: ' + hex(id) + ' Got: ' + hex(nodeId)
      return cb(new Error('dht returned incorrect id. ' + msg))
    }

    var peer = Peer(id)
    peer.addresses.push(addr)
    return cb(null, peer)
  })
}

// findValuePeers retrieves a number of peers serving this value.
// callback returns [Peer, ...]
// callback errors: same as DHT.getSloppyValues
DHTRouting.prototype.findValuePeers = function findValuePeers(key, num, cb) {
  this.dht.getSloppyValues(key, num, function(err, values) {
    if (err) return cb(err)

    values = _.map(values, decodeValue)
    values = _.map(values, Peer)
    cb(null, values)
  })
}

// provideValue tells the DHT that this node can serve
// a particular value. The DHT implementation should:
// - verify is_multihash(key, value)
// callback returns null
// callback errors: same as DHT.setSloppyValue
DHTRouting.prototype.provideValue = function provideValue(key, value, cb) {
  // ignore value. value our own node key.
  value = {id: this.peer.id, addresses: this.peer.addresses}
  value = encodeValue(value)
  this.provide[key] = value
  this.dht.setSloppyValue(key, value, cb)
}

// utilities

function hex(buf) {
  return buf.toString('hex')
}

// function keyConcat(key, other) {
//   key = new Buffer(key.toString() + other.toString())
//   return multihashing.digest(buf, 'sha1')
// }

// use json as encoding for now.
// later, protobuf with multiaddr
function encodeValue(val) {
  return JSON.stringify(val)
}

function decodeValue(val) {
  return JSON.parse(val)
}
<commit_msg>moved provide to dht<commit_after>var _ = require('underscore')
var Peer = require('../ipfs-peer')

module.exports = DHTRouting

// DHTRouting interfaces between IPFS Routing module
// and an underlying DHT implementation

function DHTRouting(localPeer, dht) {
  this.peer = localPeer
  this.dht = dht
}

// findPeer looks for a particular peer with given id
// callback returns a Peer
// callback errors: same as DHT.findNode
DHTRouting.prototype.findPeer = function findPeer(id, cb) {
  this.dht.findNode(id, function(err, nodeId, addr) {
    if (err) return cb(err)

    if (nodeId != id) {
      var msg = 'Expected: ' + hex(id) + ' Got: ' + hex(nodeId)
      return cb(new Error('dht returned incorrect id. ' + msg))
    }

    var peer = Peer(id)
    peer.addresses.push(addr)
    return cb(null, peer)
  })
}

// findValuePeers retrieves a number of peers serving this value.
// callback returns [Peer, ...]
// callback errors: same as DHT.getSloppyValues
DHTRouting.prototype.findValuePeers = function findValuePeers(key, num, cb) {
  this.dht.getSloppyValues(key, num, function(err, values) {
    if (err) return cb(err)

    values = _.map(values, decodeValue)
    values = _.map(values, Peer)
    cb(null, values)
  })
}

// provideValue tells the DHT that this node can serve
// a particular value. The DHT implementation should:
// - verify is_multihash(key, value)
// callback returns null
// callback errors: same as DHT.setSloppyValue
DHTRouting.prototype.provideValue = function provideValue(key, value, cb) {
  // ignore value. value our own node key.
  value = {id: this.peer.id, addresses: this.peer.addresses}
  value = encodeValue(value)
  this.provide[key] = value
  this.dht.setSloppyValue(key, value, cb)
}

// utilities

function hex(buf) {
  return buf.toString('hex')
}

// function keyConcat(key, other) {
//   key = new Buffer(key.toString() + other.toString())
//   return multihashing.digest(buf, 'sha1')
// }

// use json as encoding for now.
// later, protobuf with multiaddr
function encodeValue(val) {
  return JSON.stringify(val)
}

function decodeValue(val) {
  return JSON.parse(val)
}
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2014 microServiceBus.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

/* jshint node: true */
/* jshint esversion: 6 */
/* jshint strict:false */
'use strict';
require('colors');
var EventEmitter = require('events').EventEmitter;
function SignalRClient(uri) {
    var self = this;
    let url = new URL(uri);
    if (url.hostname === "localhost") {
        process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
    }
    const signalR = require("@microsoft/signalr");
    const connection = new signalR.HubConnectionBuilder()
        .withUrl(`${uri}/nodeHub`)
        .withAutomaticReconnect() // .withAutomaticReconnect([0, 2000, 10000, 30000]) yields the default behavior
        //.configureLogging(signalR.LogLevel.Debug)
        .configureLogging(new Logger())
        .build();
    connection.keepAliveIntervalInMilliseconds = 1000 * 60 * 3; // Three minutes
    connection.serverTimeoutInMilliseconds = 1000 * 60 * 6; // Six minutes

    this.start = function () {
        return new Promise(function (resolve, reject) {
            init();
            connection.start()
                .then(() => {
                    self.emit('connected', {});
                    resolve();
                })
                .catch((e) => {
                    // 404 should be handled by falling back to  legacy client
                    // and should not trigger onerror
                    if (e.statusCode === 302) {
                        reject("NOTV2");
                    }
                    else {
                        self.emit('onerror', e);
                        reject(e);
                    }

                });
        });
    }
    this.invoke = function (methodName) {
        switch (arguments.length) {
            case 1:
                return connection.invoke(arguments[0]);
            case 2:
                return connection.invoke(arguments[0], arguments[1]);
            case 3:
                return connection.invoke(arguments[0], arguments[1], arguments[2]);
            case 4:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3]);
            case 5:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
            case 6:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
            case 7:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
            case 8:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]);
            case 9:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8]);
            case 9:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9]);
            default:
                throw "unsupported length of parameters";
        }
    }
    this.isConnected = function () {
        return connection.connection.state === "Connected";
    }
    function init() {
        // Wire up signalR events
        /* istanbul ignore next */
        connection.onclose(() => {
            self.emit('disconnected');
        });
        connection.onreconnecting(() => {
            self.emit('reconnecting', 0);
        });
        connection.onreconnected(() => {
            self.emit('reconnected', {});
        });

        // Wire up signalR events
        /* istanbul ignore next */
        connection.on('errorMessage', (message, errorCode) => {
            self.emit('errorMessage', message, errorCode);
        });
        connection.on('ping', (message) => {
            self.emit('ping', message);
        });
        connection.on('getEndpoints', (message) => {
            self.emit('getEndpoints', message);
        });
        connection.on('updateItinerary', (updatedItinerary) => {
            self.emit('updateItinerary', updatedItinerary);
        });
        connection.on('changeState', (state) => {
            self.emit('changeState', state);
        });
        connection.on('changeDebug', (debug) => {
            self.emit('changeDebug', debug);
        });
        connection.on('changeTracking', (enableTracking) => {
            self.emit('changeTracking', enableTracking);
        });
        connection.on('sendMessage', (message, destination) => {
            self.emit('sendMessage', message, destination);
        });
        connection.on('signInMessage', (response) => {
            self.emit('signInMessage', response);
        });
        connection.on('nodeCreated', (nodeData) => {
            self.emit('nodeCreated', nodeData);
        });
        connection.on('heartBeat', (id) => {
            self.emit('heartBeat', id);
        });
        connection.on('forceUpdate', () => {
            self.emit('forceUpdate');
        });
        connection.on('restart', () => {
            self.emit('restart');
        });
        connection.on('reboot', () => {
            self.emit('reboot');
        });
        connection.on('shutdown', () => {
            self.emit('shutdown');
        });
        connection.on('refreshSnap', (snap, mode, connId) => {
            self.emit('refreshSnap', snap, mode, connId);
        });
        connection.on('reset', (id) => {
            self.emit('reset', id);
        });
        connection.on('resetKeepEnvironment', (id) => {
            self.emit('resetKeepEnvironment', id);
        });
        connection.on('updateFlowState', (itineraryId, environment, enabled) => {
            self.emit('updateFlowState', itineraryId, environment, enabled);
        });
        connection.on('enableDebug', (connId) => {
            self.emit('enableDebug', connId);
        });
        connection.on('stopDebug', (connId) => {
            self.emit('stopDebug', connId);
        });
        connection.on('reportState', (id) => {
            self.emit('reportState', id);
        });
        connection.on('uploadSyslogs', (connectionId, fileName, account, accountKey) => {
            self.emit('uploadSyslogs', connectionId, fileName, account, accountKey);
        });
        connection.on('resendHistory', (req) => {
            self.emit('resendHistory', req);
        });
        connection.on('requestHistory', (req) => {
            self.emit('requestHistory', req);
        });
        connection.on('transferToPrivate', (req) => {
            self.emit('transferToPrivate', req);
        });
        connection.on('updatedToken', (token) => {
            self.emit('updatedToken', token);
        });
        connection.on('updateFirmware', (force, connid) => {
            self.emit('updateFirmware', force, connid);
        });
        connection.on('grantAccess', () => {
            self.emit('grantAccess');
        });
        connection.on('runTest', (testDescription) => {
            self.emit('runTest', testDescription);
        });
        connection.on('pingNodeTest', (connid) => {
            self.emit('pingNodeTest', connid);
        });
        connection.on('updatePolicies', (policies) => {
            self.emit('updatePolicies', policies);
        });
        connection.on('setBootPartition', (partition, connid) => {
            self.emit('setBootPartition', partition, connid);
        });
        connection.on('executeScript', (patchScript, connid) => {
            self.emit('executeScript', patchScript, connid);
        });
        connection.on('updateVulnerabilities', (connid) => {
            self.emit('updateVulnerabilities', connid);
        });
    }
    function getArgValues(params) {
        var res = [];

        if (params.length && params.length > 1) {
            for (var i = 1; i < params.length; i++) {
                var p = params[i];
                if (typeof p === "function" || typeof p === "undefined") {
                    p = null;
                }
                res[i - 1] = p;
            }
        }
        return res;
    }
    function Logger() {
        this.log = function (logLevel, message) {
            switch (logLevel) {
                case signalR.LogLevel.Critical:
                    self.emit('onerror', "Critical ".red + message.grey);
                case signalR.LogLevel.Error:
                    self.emit('onerror', "Error ".red + message.grey);
                case signalR.LogLevel.Warning:
                    self.emit('onerror', "Warning ".yellow + message.grey);
                // case signalR.LogLevel.Information:
                //     self.emit('onerror', "Information ".yellow + message.grey);
                // case signalR.LogLevel.Debug:
                //     self.emit('onerror', "Debug ".yellow + message.grey);
                // case signalR.LogLevel.Trace:
                //     self.emit('onerror', "Trace ".yellow + message.grey);
                default:
                    break;
            }
        }
    }
}
module.exports = SignalRClient;
SignalRClient.prototype.__proto__ = EventEmitter.prototype;<commit_msg>Fixed isConnected<commit_after>/*
The MIT License (MIT)

Copyright (c) 2014 microServiceBus.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

/* jshint node: true */
/* jshint esversion: 6 */
/* jshint strict:false */
'use strict';
require('colors');
var EventEmitter = require('events').EventEmitter;
function SignalRClient(uri) {
    var self = this;
    let url = new URL(uri);
    if (url.hostname === "localhost") {
        process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
    }
    const signalR = require("@microsoft/signalr");
    const connection = new signalR.HubConnectionBuilder()
        .withUrl(`${uri}/nodeHub`)
        .withAutomaticReconnect() // .withAutomaticReconnect([0, 2000, 10000, 30000]) yields the default behavior
        //.configureLogging(signalR.LogLevel.Debug)
        .configureLogging(new Logger())
        .build();
    connection.keepAliveIntervalInMilliseconds = 1000 * 60 * 3; // Three minutes
    connection.serverTimeoutInMilliseconds = 1000 * 60 * 6; // Six minutes

    this.start = function () {
        return new Promise(function (resolve, reject) {
            init();
            connection.start()
                .then(() => {
                    self.emit('connected', {});
                    resolve();
                })
                .catch((e) => {
                    // 404 should be handled by falling back to  legacy client
                    // and should not trigger onerror
                    if (e.statusCode === 302) {
                        reject("NOTV2");
                    }
                    else {
                        self.emit('onerror', e);
                        reject(e);
                    }

                });
        });
    }
    this.invoke = function (methodName) {
        switch (arguments.length) {
            case 1:
                return connection.invoke(arguments[0]);
            case 2:
                return connection.invoke(arguments[0], arguments[1]);
            case 3:
                return connection.invoke(arguments[0], arguments[1], arguments[2]);
            case 4:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3]);
            case 5:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
            case 6:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
            case 7:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
            case 8:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]);
            case 9:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8]);
            case 9:
                return connection.invoke(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9]);
            default:
                throw "unsupported length of parameters";
        }
    }
    this.isConnected = function () {
        return connection.connection.connectionState === "Connected";
    }
    function init() {
        // Wire up signalR events
        /* istanbul ignore next */
        connection.onclose(() => {
            self.emit('disconnected');
        });
        connection.onreconnecting(() => {
            self.emit('reconnecting', 0);
        });
        connection.onreconnected(() => {
            self.emit('reconnected', {});
        });

        // Wire up signalR events
        /* istanbul ignore next */
        connection.on('errorMessage', (message, errorCode) => {
            self.emit('errorMessage', message, errorCode);
        });
        connection.on('ping', (message) => {
            self.emit('ping', message);
        });
        connection.on('getEndpoints', (message) => {
            self.emit('getEndpoints', message);
        });
        connection.on('updateItinerary', (updatedItinerary) => {
            self.emit('updateItinerary', updatedItinerary);
        });
        connection.on('changeState', (state) => {
            self.emit('changeState', state);
        });
        connection.on('changeDebug', (debug) => {
            self.emit('changeDebug', debug);
        });
        connection.on('changeTracking', (enableTracking) => {
            self.emit('changeTracking', enableTracking);
        });
        connection.on('sendMessage', (message, destination) => {
            self.emit('sendMessage', message, destination);
        });
        connection.on('signInMessage', (response) => {
            self.emit('signInMessage', response);
        });
        connection.on('nodeCreated', (nodeData) => {
            self.emit('nodeCreated', nodeData);
        });
        connection.on('heartBeat', (id) => {
            self.emit('heartBeat', id);
        });
        connection.on('forceUpdate', () => {
            self.emit('forceUpdate');
        });
        connection.on('restart', () => {
            self.emit('restart');
        });
        connection.on('reboot', () => {
            self.emit('reboot');
        });
        connection.on('shutdown', () => {
            self.emit('shutdown');
        });
        connection.on('refreshSnap', (snap, mode, connId) => {
            self.emit('refreshSnap', snap, mode, connId);
        });
        connection.on('reset', (id) => {
            self.emit('reset', id);
        });
        connection.on('resetKeepEnvironment', (id) => {
            self.emit('resetKeepEnvironment', id);
        });
        connection.on('updateFlowState', (itineraryId, environment, enabled) => {
            self.emit('updateFlowState', itineraryId, environment, enabled);
        });
        connection.on('enableDebug', (connId) => {
            self.emit('enableDebug', connId);
        });
        connection.on('stopDebug', (connId) => {
            self.emit('stopDebug', connId);
        });
        connection.on('reportState', (id) => {
            self.emit('reportState', id);
        });
        connection.on('uploadSyslogs', (connectionId, fileName, account, accountKey) => {
            self.emit('uploadSyslogs', connectionId, fileName, account, accountKey);
        });
        connection.on('resendHistory', (req) => {
            self.emit('resendHistory', req);
        });
        connection.on('requestHistory', (req) => {
            self.emit('requestHistory', req);
        });
        connection.on('transferToPrivate', (req) => {
            self.emit('transferToPrivate', req);
        });
        connection.on('updatedToken', (token) => {
            self.emit('updatedToken', token);
        });
        connection.on('updateFirmware', (force, connid) => {
            self.emit('updateFirmware', force, connid);
        });
        connection.on('grantAccess', () => {
            self.emit('grantAccess');
        });
        connection.on('runTest', (testDescription) => {
            self.emit('runTest', testDescription);
        });
        connection.on('pingNodeTest', (connid) => {
            self.emit('pingNodeTest', connid);
        });
        connection.on('updatePolicies', (policies) => {
            self.emit('updatePolicies', policies);
        });
        connection.on('setBootPartition', (partition, connid) => {
            self.emit('setBootPartition', partition, connid);
        });
        connection.on('executeScript', (patchScript, connid) => {
            self.emit('executeScript', patchScript, connid);
        });
        connection.on('updateVulnerabilities', (connid) => {
            self.emit('updateVulnerabilities', connid);
        });
    }
    function getArgValues(params) {
        var res = [];

        if (params.length && params.length > 1) {
            for (var i = 1; i < params.length; i++) {
                var p = params[i];
                if (typeof p === "function" || typeof p === "undefined") {
                    p = null;
                }
                res[i - 1] = p;
            }
        }
        return res;
    }
    function Logger() {
        this.log = function (logLevel, message) {
            switch (logLevel) {
                case signalR.LogLevel.Critical:
                    self.emit('onerror', "Critical ".red + message.grey);
                case signalR.LogLevel.Error:
                    self.emit('onerror', "Error ".red + message.grey);
                case signalR.LogLevel.Warning:
                    self.emit('onerror', "Warning ".yellow + message.grey);
                // case signalR.LogLevel.Information:
                //     self.emit('onerror', "Information ".yellow + message.grey);
                // case signalR.LogLevel.Debug:
                //     self.emit('onerror', "Debug ".yellow + message.grey);
                // case signalR.LogLevel.Trace:
                //     self.emit('onerror', "Trace ".yellow + message.grey);
                default:
                    break;
            }
        }
    }
}
module.exports = SignalRClient;
SignalRClient.prototype.__proto__ = EventEmitter.prototype;<|endoftext|>


<commit_before>var request = require('request');

/**
 * Does nothing. Takes no params, returns nothing. It's a no-op!
 */
function noop() {}

/**
 * Returns an interface to the Slack API in the context of the given bot
 *
 * @param {Object} bot The botkit bot object
 * @param {Object} config A config containing auth credentials.
 * @returns {Object} A callback-based Slack API interface.
 */
module.exports = function(bot, config) {
    var slack_api = {
        api_url: 'https://slack.com/api/'
    };

    // Slack API methods: https://api.slack.com/methods
    var slackApiMethods = [
        'auth.test',
        'oauth.access',
        'channels.archive',
        'channels.create',
        'channels.history',
        'channels.info',
        'channels.invite',
        'channels.join',
        'channels.kick',
        'channels.leave',
        'channels.list',
        'channels.mark',
        'channels.rename',
        'channels.setPurpose',
        'channels.setTopic',
        'channels.unarchive',
        'chat.delete',
        'chat.postMessage',
        'chat.update',
        'dnd.endDnd',
        'dnd.endSnooze',
        'dnd.info',
        'dnd.setSnooze',
        'dnd.teamInfo',
        'emoji.list',
        'files.delete',
        'files.info',
        'files.list',
        'files.upload',
        'groups.archive',
        'groups.close',
        'groups.create',
        'groups.createChild',
        'groups.history',
        'groups.info',
        'groups.invite',
        'groups.kick',
        'groups.leave',
        'groups.list',
        'groups.mark',
        'groups.open',
        'groups.rename',
        'groups.setPurpose',
        'groups.setTopic',
        'groups.unarchive',
        'im.close',
        'im.history',
        'im.list',
        'im.mark',
        'im.open',
        'mpim.close',
        'mpim.history',
        'mpim.list',
        'mpim.mark',
        'mpim.open',
        'pins.add',
        'pins.list',
        'pins.remove',
        'reactions.add',
        'reactions.get',
        'reactions.list',
        'reactions.remove',
        'rtm.start',
        'search.all',
        'search.files',
        'search.messages',
        'stars.add',
        'stars.list',
        'stars.remove',
        'team.accessLogs',
        'team.info',
        'users.getPresence',
        'users.info',
        'users.list',
        'users.setActive'
    ];

    /**
     * Calls Slack using a Token for authentication/authorization
     *
     * @param {string} command The Slack API command to call
     * @param {Object} data The data to pass to the API call
     * @param {function} cb A NodeJS-style callback
     */
    slack_api.callAPI = function(command, data, cb) {
        if (!data.token) {
            data.token = config.token;
        }

        bot.debug(command, data);
        postForm(slack_api.api_url + command, data, cb);
    };

    /**
     * Calls Slack using OAuth for authentication/authorization
     *
     * @param {string} command The Slack API command to call
     * @param {Object} data The data to pass to the API call
     * @param {function} cb A NodeJS-style callback
     */
    slack_api.callAPIWithoutToken = function(command, data, cb) {
        if (!data.client_id) {
            data.client_id = bot.config.clientId;
        }
        if (!data.client_secret) {
            data.client_secret = bot.config.clientSecret;
        }
        if (!data.redirect_uri) {
            data.redirect_uri = bot.config.redirectUri;
        }

        // DON'T log options: that could expose the client secret!
        postForm(slack_api.api_url + command, data, cb);
    };

    // generate all API methods
    slackApiMethods.forEach(function(slackMethod) {
        // most slack api methods are only two parts, of the form group.method, e.g. auth.test
        // some have three parts: group.subgroup.method, e.g, users.profile.get
        // this method loops through all groups in a method, ensures they exist,
        // then adds the method to the terminal group

        var groups = slackMethod.split('.');
        var method = groups.pop();
        var currentGroup = slack_api;

        groups.forEach(function(nextGroupName) {
            if (!currentGroup[nextGroupName]) {
                currentGroup[nextGroupName] = {};
            }
            currentGroup = currentGroup[nextGroupName];
        });

        currentGroup[method] = function(options, cb) {
            slack_api.callAPI(slackMethod, options, cb);
        };

    });

    // overwrite default behavior
    slack_api.chat.postMessage = function(options, cb) {
        sanitizeOptions(options);
        slack_api.callAPI('chat.postMessage', options, cb);
    };

    slack_api.chat.update = function(options, cb) {
        sanitizeOptions(options);
        slack_api.callAPI('chat.update', options, cb);
    };

    function sanitizeOptions(options) {
        if (options.attachments && typeof(options.attachments) != 'string') {
            try {
                options.attachments = JSON.stringify(options.attachments);
            } catch (err) {
                delete options.attachments;
                bot.log.error('Could not parse attachments', err);
            }
        }
    }

    return slack_api;

    /**
     * Makes a POST request as a form to the given url with the options as data
     *
     * @param {string} url The URL to POST to
     * @param {Object} formData The data to POST as a form
     * @param {function=} cb An optional NodeJS style callback when the POST completes or errors out.
     */
    function postForm(url, formData, cb) {
        cb = cb || noop;

        bot.log('** API CALL: ' + url);
        request.post(url, function(error, response, body) {
            bot.debug('Got response', error, body);
            if (!error && response.statusCode == 200) {
                var json;
                try {
                    json = JSON.parse(body);
                } catch (parseError) {
                    return cb(parseError);
                }

                if (json.ok) {
                    return cb(null, json);
                }
                return cb(json.error, json);
            }
            return cb(error || new Error('Invalid response'));
        }).form(formData);
    }
};
<commit_msg>Fix bot.api.files.upload and add support for both multi-part and non-multi-part file uploads<commit_after>var request = require('request');

/**
 * Does nothing. Takes no params, returns nothing. It's a no-op!
 */
function noop() {}

/**
 * Returns an interface to the Slack API in the context of the given bot
 *
 * @param {Object} bot The botkit bot object
 * @param {Object} config A config containing auth credentials.
 * @returns {Object} A callback-based Slack API interface.
 */
module.exports = function(bot, config) {
    var slack_api = {
        api_url: 'https://slack.com/api/'
    };

    // Slack API methods: https://api.slack.com/methods
    var slackApiMethods = [
        'auth.test',
        'oauth.access',
        'channels.archive',
        'channels.create',
        'channels.history',
        'channels.info',
        'channels.invite',
        'channels.join',
        'channels.kick',
        'channels.leave',
        'channels.list',
        'channels.mark',
        'channels.rename',
        'channels.setPurpose',
        'channels.setTopic',
        'channels.unarchive',
        'chat.delete',
        'chat.postMessage',
        'chat.update',
        'dnd.endDnd',
        'dnd.endSnooze',
        'dnd.info',
        'dnd.setSnooze',
        'dnd.teamInfo',
        'emoji.list',
        'files.delete',
        'files.info',
        'files.list',
        'files.upload',
        'groups.archive',
        'groups.close',
        'groups.create',
        'groups.createChild',
        'groups.history',
        'groups.info',
        'groups.invite',
        'groups.kick',
        'groups.leave',
        'groups.list',
        'groups.mark',
        'groups.open',
        'groups.rename',
        'groups.setPurpose',
        'groups.setTopic',
        'groups.unarchive',
        'im.close',
        'im.history',
        'im.list',
        'im.mark',
        'im.open',
        'mpim.close',
        'mpim.history',
        'mpim.list',
        'mpim.mark',
        'mpim.open',
        'pins.add',
        'pins.list',
        'pins.remove',
        'reactions.add',
        'reactions.get',
        'reactions.list',
        'reactions.remove',
        'rtm.start',
        'search.all',
        'search.files',
        'search.messages',
        'stars.add',
        'stars.list',
        'stars.remove',
        'team.accessLogs',
        'team.info',
        'users.getPresence',
        'users.info',
        'users.list',
        'users.setActive'
    ];

    /**
     * Calls Slack using a Token for authentication/authorization
     *
     * @param {string} command The Slack API command to call
     * @param {Object} data The data to pass to the API call
     * @param {function} cb A NodeJS-style callback
     */
    slack_api.callAPI = function(command, data, cb, multipart) {
        if (!data.token) {
            data.token = config.token;
        }

        bot.debug(command, data);
        postForm(slack_api.api_url + command, data, cb, multipart);
    };

    /**
     * Calls Slack using OAuth for authentication/authorization
     *
     * @param {string} command The Slack API command to call
     * @param {Object} data The data to pass to the API call
     * @param {function} cb A NodeJS-style callback
     */
    slack_api.callAPIWithoutToken = function(command, data, cb) {
        if (!data.client_id) {
            data.client_id = bot.config.clientId;
        }
        if (!data.client_secret) {
            data.client_secret = bot.config.clientSecret;
        }
        if (!data.redirect_uri) {
            data.redirect_uri = bot.config.redirectUri;
        }

        // DON'T log options: that could expose the client secret!
        postForm(slack_api.api_url + command, data, cb);
    };

    // generate all API methods
    slackApiMethods.forEach(function(slackMethod) {
        // most slack api methods are only two parts, of the form group.method, e.g. auth.test
        // some have three parts: group.subgroup.method, e.g, users.profile.get
        // this method loops through all groups in a method, ensures they exist,
        // then adds the method to the terminal group

        var groups = slackMethod.split('.');
        var method = groups.pop();
        var currentGroup = slack_api;

        groups.forEach(function(nextGroupName) {
            if (!currentGroup[nextGroupName]) {
                currentGroup[nextGroupName] = {};
            }
            currentGroup = currentGroup[nextGroupName];
        });

        currentGroup[method] = function(options, cb) {
            slack_api.callAPI(slackMethod, options, cb);
        };

    });

    // overwrite default behavior
    slack_api.chat.postMessage = function(options, cb) {
        sanitizeOptions(options);
        slack_api.callAPI('chat.postMessage', options, cb);
    };

    slack_api.chat.update = function(options, cb) {
        sanitizeOptions(options);
        slack_api.callAPI('chat.update', options, cb);
    };

    // specify that files get uploaded using multipart
    slack_api.files.upload = function(options, cb) {
        if (options.file) {
            slack_api.callAPI('files.upload', options, cb, true);
        } else {
            slack_api.callAPI('files.upload', options, cb, false);
        }
    };

    function sanitizeOptions(options) {
        if (options.attachments && typeof(options.attachments) != 'string') {
            try {
                options.attachments = JSON.stringify(options.attachments);
            } catch (err) {
                delete options.attachments;
                bot.log.error('Could not parse attachments', err);
            }
        }
    }

    return slack_api;

    /**
     * Makes a POST request as a form to the given url with the options as data
     *
     * @param {string} url The URL to POST to
     * @param {Object} formData The data to POST as a form
     * @param {function=} cb An optional NodeJS style callback when the POST completes or errors out.
     */
    function postForm(url, formData, cb, multipart) {
        cb = cb || noop;

        bot.log('** API CALL: ' + url);
        var params = {
            url: url
        };

        if (multipart === true) {
            params.formData = formData;
        } else {
            params.form = formData;
        }

        request.post(params, function(error, response, body) {
            bot.debug('Got response', error, body);
            if (!error && response.statusCode == 200) {
                var json;
                try {
                    json = JSON.parse(body);
                } catch (parseError) {
                    return cb(parseError);
                }

                if (json.ok) {
                    return cb(null, json);
                }
                return cb(json.error, json);
            }
            return cb(error || new Error('Invalid response'));
        });
    }
};
<|endoftext|>


<commit_before>(function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['backbone'], function(Backbone) {
            return factory(Backbone);
        });
    } else if (typeof exports !== 'undefined') {
        var Backbone = require('backbone');
        module.exports = factory(Backbone);
    } else {
        factory(root.Backbone);
    }
}(this, function(Backbone) {

    var ArrMethods = {
        where: function(attrs) {
            var nodes = [];
            _.each(this, function(model) {
                nodes = nodes.concat(model.where(attrs));
            });
            return wrapArray(_.uniq(nodes));
        }
    };
    var wrapArray = function(array) { return _.extend(array, ArrMethods); };

    var TreeModel = Backbone.TreeModel = Backbone.Model.extend({
        constructor: function tree(node) {
            Backbone.Model.prototype.constructor.apply(this, arguments);
            this._nodes = new this.collectionConstructor([], {
                model : this.constructor,
            });
            this._nodes.parent = this;
            if(node && node[this.nodesAttribute]) this.add(node[this.nodesAttribute]);
            this.once('sync', function(model, node) {
                if (node[this.nodesAttribute]) this.add(node[this.nodesAttribute]);
            });
        },

        collectionConstructor : null,

        nodesAttribute: 'nodes',

        /**
         * returns JSON object representing tree, account for branch changes
         */
        toJSON: function() {
            var jsonObj = _.clone(_.omit(this.attributes, this.nodesAttribute));
            var children = this._nodes.toJSON();
            if(children.length) jsonObj[this.nodesAttribute] = children;
            return jsonObj;
        },

        /**
         * returns descendant matching :id
         */
        find: function(id) { return this.findWhere({id: id}); },

        /**
         * return first matched descendant
         */
        findWhere: function(attrs) { return this.where(attrs, true); },

        /**
         * return first matched descendant
         */
        walk: function(callback) {
            if (callback(this) === false) return this;
            var lastNode;
            this._nodes.every(function(node) {
                lastNode = node.walk(callback);
                return !lastNode;
            });
            return lastNode;
        },

        /**
         * return all matched descendants
         */
        where: function(attrs, first, excludeCurrentNode) {
            var nodes = [], matchedNode;

            // manual (non-collection method) check on the current node
            if(!excludeCurrentNode && _.where([this.toJSON()], attrs)[0]) nodes.push(this);

            if(first) {
                // return if first/current node is a match
                if(nodes[0]) return nodes[0];

                // return first matched node in children collection
                matchedNode = this._nodes.where(attrs, true);
                if(_.isArray(matchedNode)) matchedNode = matchedNode[0];
                if(matchedNode instanceof Backbone.Model) return matchedNode;

                // recursive call on children nodes
                for(var i=0, len=this._nodes.length; i<len; i++) {
                    matchedNode = this._nodes.at(i).where(attrs, true, true);
                    if(matchedNode) return matchedNode;
                }
            } else {
                // add all matched children
                nodes = nodes.concat(this._nodes.where(attrs));

                // recursive call on children nodes
                this._nodes.each(function(node) {
                    nodes = nodes.concat(node.where(attrs, false, true));
                });

                // return all matched nodes
                return wrapArray(nodes);
            }
        },

        /**
         * returns true if current node is root node
         */
        isRoot: function() { return this.parent() === null; },

        /**
         * returns the root for any node
         */
        root: function() { return this.parent() && this.parent().root() || this; },

        /**
         * checks if current node contains argument node
         */
        contains: function(node) {
            if(!node || !(node.isRoot && node.parent) || node.isRoot()) return false;
            var parent = node.parent();
            return (parent === this) || this.contains(parent);
        },

        /**
         * returns the parent node
         */
        parent: function() { return this.collection && this.collection.parent || null; },

        /**
         * returns the children Backbone Collection if children nodes exist
         */
        nodes: function() { return this._nodes.length && this._nodes || null; },

        /**
         * returns index of node relative to collection
         */
        index: function() {
            if(this.isRoot()) return null;
            return this.collection.indexOf(this);
        },

        /**
         * returns the node to the right
         */
        next: function() {
            if(this.isRoot()) return null;
            var currentIndex = this.index();
            if(currentIndex < this.collection.length-1) {
                return this.collection.at(currentIndex+1);
            } else {
                return null;
            }
        },

        /**
         * returns the node to the left
         */
        prev: function() {
            if(this.isRoot()) return null;
            var currentIndex = this.index();
            if(currentIndex > 0) {
                return this.collection.at(currentIndex-1);
            } else {
                return null;
            }
        },

        /**
         * removes current node if no attributes arguments is passed,
         * otherswise remove matched nodes or first matched node
         */
        remove: function(attrs, first) {
            if(!attrs) {
                if(this.isRoot()) return false; // can't remove root node
                this.collection.remove(this);
                return true;
            } else {
                if(first) {
                    this.where(attrs, true).remove();
                } else {
                    _.each(this.where(attrs), function(node) {
                        if(node.collection) node.remove();
                    });
                }
                return this;
            }
        },

        /**
         * removes all children nodes
         */
        empty: function() {
            this._nodes.reset();
            return this;
        },

        /**
         * add child/children nodes to Backbone Collection
         */
        add: function(node) {
            if(node instanceof Backbone.Model && node.collection) node.collection.remove(node);
            this._nodes.add.apply(this._nodes, arguments);
            return this;
        },

        /**
         * inserts a node before the current node
         */
        insertBefore: function(node) {
            if(!this.isRoot()) {
                if(node instanceof Backbone.Model && node.collection) node.collection.remove(node);
                this.parent().add(node, {at: this.index()});
            }
            return this;
        },

        /**
         * inserts a node after the current node
         */
        insertAfter: function(node) {
            if(!this.isRoot()) {
                if(node instanceof Backbone.Model && node.collection) node.collection.remove(node);
                this.parent().add(node, {at: this.index()+1});
            }
            return this;
        },

        /**
         * shorthand for getting/inserting nodes before
         */
        before: function(nodes) {
            if(nodes) return this.insertBefore(nodes);
            return this.prev();
        },

        /**
         * shorthand for getting/inserting nodes before
         */
        after: function(nodes) {
            if(nodes) return this.insertAfter(nodes);
            return this.next();
        }
    });

    var TreeCollection = Backbone.TreeCollection = Backbone.Collection.extend({
        model: TreeModel,
        where: function(attrs, opts) {
            if(opts && opts.deep) {
                var nodes = [];
                this.each(function(model) {
                    nodes = nodes.concat(model.where(attrs));
                });
                return wrapArray(nodes);
            } else {
                return Backbone.Collection.prototype.where.apply(this, arguments);
            }
        }
    });

    Backbone.TreeModel.prototype.collectionConstructor = TreeCollection

    return Backbone.TreeModel;

}));
<commit_msg>Add #walk to collection<commit_after>(function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['backbone'], function(Backbone) {
            return factory(Backbone);
        });
    } else if (typeof exports !== 'undefined') {
        var Backbone = require('backbone');
        module.exports = factory(Backbone);
    } else {
        factory(root.Backbone);
    }
}(this, function(Backbone) {

    var ArrMethods = {
        where: function(attrs) {
            var nodes = [];
            _.each(this, function(model) {
                nodes = nodes.concat(model.where(attrs));
            });
            return wrapArray(_.uniq(nodes));
        }
    };
    var wrapArray = function(array) { return _.extend(array, ArrMethods); };

    var TreeModel = Backbone.TreeModel = Backbone.Model.extend({
        constructor: function tree(node) {
            Backbone.Model.prototype.constructor.apply(this, arguments);
            this._nodes = new this.collectionConstructor([], {
                model : this.constructor,
            });
            this._nodes.parent = this;
            if(node && node[this.nodesAttribute]) this.add(node[this.nodesAttribute]);
            this.once('sync', function(model, node) {
                if (node[this.nodesAttribute]) this.add(node[this.nodesAttribute]);
            });
        },

        collectionConstructor : null,

        nodesAttribute: 'nodes',

        /**
         * returns JSON object representing tree, account for branch changes
         */
        toJSON: function() {
            var jsonObj = _.clone(_.omit(this.attributes, this.nodesAttribute));
            var children = this._nodes.toJSON();
            if(children.length) jsonObj[this.nodesAttribute] = children;
            return jsonObj;
        },

        /**
         * returns descendant matching :id
         */
        find: function(id) { return this.findWhere({id: id}); },

        /**
         * return first matched descendant
         */
        findWhere: function(attrs) { return this.where(attrs, true); },

        /**
         * return first matched descendant
         */
        walk: function(callback) {
            if (callback(this) === false) return this;
            var lastNode;
            this._nodes.every(function(node) {
                lastNode = node.walk(callback);
                return !lastNode;
            });
            return lastNode;
        },

        /**
         * return all matched descendants
         */
        where: function(attrs, first, excludeCurrentNode) {
            var nodes = [], matchedNode;

            // manual (non-collection method) check on the current node
            if(!excludeCurrentNode && _.where([this.toJSON()], attrs)[0]) nodes.push(this);

            if(first) {
                // return if first/current node is a match
                if(nodes[0]) return nodes[0];

                // return first matched node in children collection
                matchedNode = this._nodes.where(attrs, true);
                if(_.isArray(matchedNode)) matchedNode = matchedNode[0];
                if(matchedNode instanceof Backbone.Model) return matchedNode;

                // recursive call on children nodes
                for(var i=0, len=this._nodes.length; i<len; i++) {
                    matchedNode = this._nodes.at(i).where(attrs, true, true);
                    if(matchedNode) return matchedNode;
                }
            } else {
                // add all matched children
                nodes = nodes.concat(this._nodes.where(attrs));

                // recursive call on children nodes
                this._nodes.each(function(node) {
                    nodes = nodes.concat(node.where(attrs, false, true));
                });

                // return all matched nodes
                return wrapArray(nodes);
            }
        },

        /**
         * returns true if current node is root node
         */
        isRoot: function() { return this.parent() === null; },

        /**
         * returns the root for any node
         */
        root: function() { return this.parent() && this.parent().root() || this; },

        /**
         * checks if current node contains argument node
         */
        contains: function(node) {
            if(!node || !(node.isRoot && node.parent) || node.isRoot()) return false;
            var parent = node.parent();
            return (parent === this) || this.contains(parent);
        },

        /**
         * returns the parent node
         */
        parent: function() { return this.collection && this.collection.parent || null; },

        /**
         * returns the children Backbone Collection if children nodes exist
         */
        nodes: function() { return this._nodes.length && this._nodes || null; },

        /**
         * returns index of node relative to collection
         */
        index: function() {
            if(this.isRoot()) return null;
            return this.collection.indexOf(this);
        },

        /**
         * returns the node to the right
         */
        next: function() {
            if(this.isRoot()) return null;
            var currentIndex = this.index();
            if(currentIndex < this.collection.length-1) {
                return this.collection.at(currentIndex+1);
            } else {
                return null;
            }
        },

        /**
         * returns the node to the left
         */
        prev: function() {
            if(this.isRoot()) return null;
            var currentIndex = this.index();
            if(currentIndex > 0) {
                return this.collection.at(currentIndex-1);
            } else {
                return null;
            }
        },

        /**
         * removes current node if no attributes arguments is passed,
         * otherswise remove matched nodes or first matched node
         */
        remove: function(attrs, first) {
            if(!attrs) {
                if(this.isRoot()) return false; // can't remove root node
                this.collection.remove(this);
                return true;
            } else {
                if(first) {
                    this.where(attrs, true).remove();
                } else {
                    _.each(this.where(attrs), function(node) {
                        if(node.collection) node.remove();
                    });
                }
                return this;
            }
        },

        /**
         * removes all children nodes
         */
        empty: function() {
            this._nodes.reset();
            return this;
        },

        /**
         * add child/children nodes to Backbone Collection
         */
        add: function(node) {
            if(node instanceof Backbone.Model && node.collection) node.collection.remove(node);
            this._nodes.add.apply(this._nodes, arguments);
            return this;
        },

        /**
         * inserts a node before the current node
         */
        insertBefore: function(node) {
            if(!this.isRoot()) {
                if(node instanceof Backbone.Model && node.collection) node.collection.remove(node);
                this.parent().add(node, {at: this.index()});
            }
            return this;
        },

        /**
         * inserts a node after the current node
         */
        insertAfter: function(node) {
            if(!this.isRoot()) {
                if(node instanceof Backbone.Model && node.collection) node.collection.remove(node);
                this.parent().add(node, {at: this.index()+1});
            }
            return this;
        },

        /**
         * shorthand for getting/inserting nodes before
         */
        before: function(nodes) {
            if(nodes) return this.insertBefore(nodes);
            return this.prev();
        },

        /**
         * shorthand for getting/inserting nodes before
         */
        after: function(nodes) {
            if(nodes) return this.insertAfter(nodes);
            return this.next();
        }
    });

    var TreeCollection = Backbone.TreeCollection = Backbone.Collection.extend({
        model: TreeModel,
        where: function(attrs, opts) {
            if(opts && opts.deep) {
                var nodes = [];
                this.each(function(model) {
                    nodes = nodes.concat(model.where(attrs));
                });
                return wrapArray(nodes);
            } else {
                return Backbone.Collection.prototype.where.apply(this, arguments);
            }
        },
        walk: function(callback) {
            var lastNode;
            this.every(function(node) {
                lastNode = node.walk(callback);
                return !lastNode;
            });
            return lastNode;
        }
    });

    Backbone.TreeModel.prototype.collectionConstructor = TreeCollection

    return Backbone.TreeModel;

}));
<|endoftext|>


<commit_before>var Board = require("../lib/board.js"),
    events = require("events"),
    util = require("util"),
    __ = require("../lib/fn.js");

function calculate( method, y, x ) {
  return Math[ method ]( y, x ) * 180 / Math.PI;
}

function acceleration( axis, vRange, sensitivity ) {
  var voltage;

  // convert raw reading to voltage
  // (read * vRange / 1024) - (vRange / 2)
  voltage = ( axis * vRange / 1024 ) - ( vRange / 2 );

  // 800mV sensitivity
  return voltage / sensitivity;
}

/**
 * Accelerometer
 * @constructor
 *
 * five.Accelerometer([ x, y[, z] ]);
 *
 * five.Accelerometer({
 *   pins: [ x, y[, z] ]
 *   freq: ms
 *  });
 *
 *
 * @param {Object} opts [description]
 *
 */
function Accelerometer( opts ) {

  if ( !(this instanceof Accelerometer) ) {
    return new Accelerometer( opts );
  }

  var pinAxis, last, err, axes, changed, loPass;

  // axis keys
  axes = ["x", "y", "z"];
  // "last" values initialized as zeros for the smoother
  last = {
    x: 0,
    y: 0,
    z: 0
  };
  // Array of changed values
  changed = [];
  err = null;

  // Initialize a Device instance on a Board
  Board.Device.call(
    this, opts = Board.options( opts )
  );

  this.mode = this.firmata.MODES.ANALOG;
  this.pins = opts.pins;

  // Accelerometer instance properties
  this.voltage = opts.voltage || 3.3;

  this.sensitivity = opts.sensitivity || 0.8;

  this.freq = opts.freq || 500;

  // unconditioned response
  this.raw = {};

  // Objects for possible output

  // conditioned response, no smoother
  this.accel = {};
  // conditioned response, smoothed

  this.smooth = {};

  // smoother

  // Blending property for the smoother. Smaller is less filtering

  this.alpha = opts.alpha || 0.2;

  // make an actual API sometime
  loPass = function() {
    var alpha = this.alpha;

    axes.forEach( function( axis, index ) {
      // Simple blending with n - 1th result. last is initialized at 0 for
      // the very first run only.
      this.smooth[axis] = (last[axis] * alpha) + (1 - alpha) * this.accel[axis];
      // update change for the axischange event
      changed[index] = last[axis] - this.smooth[axis];
      // might as well set the last value here
      last[axis] = this.smooth[axis];
    }, this);
    return this.smooth;
  }.bind(this);

  this.smoother = opts.smoother || loPass;

  // Pin to Axis mapping
  pinAxis = {};

  // Setup read listeners for each pin, update instance
  // properties as they are received. Special values are
  // calculated during the throttled event emit phase
  this.pins.forEach(function( pin, index ) {

    pinAxis[ pin ] = axes.slice( index, index + 1 )[0];

    // Set the pin to input mode to ANALOG
    this.firmata.pinMode( pin, this.mode );

    this.firmata.analogRead( pin, function( data ) {
      var paxis = pinAxis[ pin ];
      // unconditioned on voltage/sensitivity
      this.raw[ paxis ] = data;
      // the output we're interested in most of the time
      this.accel[ paxis ] = acceleration( data, this.voltage, this.sensitivity );
    }.bind(this));

  }, this );

  // Throttle event emitter
  setInterval(function() {
    var data = {
      smooth: this.smoother(),
      rough: this.accel
    };

    // Check each axis for change above some threshold
    // threshold is not set properly now
    if ( changed.some(function(element) {
          return Math.abs(element) > 5;
        }) ) {
      this.emit( "axischange", err, {
        now: this.smooth,
        previous: last
      });
    }

    this.emit( "acceleration", err, data );

  }.bind(this), this.freq );

  /**
   * raw x, y, z data
   * @property raw
   * @type Object
   */

  /**
   * smooth x, y, z data
   * @property smooth
   * @type Object
   */

   /**
    * acceleration calculated x, y, z data
    * @property axis
    * @type Object
    */

  Object.defineProperties( this, {
    /**
     * [read-only] Calculated pitch value
     * @property pitch
     * @type Number
     */
    pitch: {
      get: function() {
        return Math.abs( Math.atan2( this.accel.x, Math.sqrt( Math.pow(this.accel.y, 2) + Math.pow(this.accel.z, 2) ) ) );
      }
    },
    /**
     * [read-only] Calculated roll value
     * @property roll
     * @type Number
     */
    roll: {
      get: function() {
        return Math.abs( Math.atan2( this.accel.y, Math.sqrt( Math.pow(this.accel.x, 2) + Math.pow(this.accel.z, 2) ) ) );
      }
    }
  });
}

util.inherits( Accelerometer, events.EventEmitter );

Object.defineProperty( Accelerometer, "G", {
  /**
   * [read-only] One g is the acceleration due to gravity at the Earth's surface and is the standard gravity (symbol: gn), defined as 9.80665 metres per second squared, or equivalently 9.80665 newtons of force per kilogram of mass.
   *
   * meters/s ^ 2
   *
   * @property G
   * @type Number
   */
  value: 9.81
});

/**
 * Fires once every N ms, equal to value of `freq`. Defaults to 500ms
 *
 * @event
 * @name acceleration
 * @memberOf Accelerometer
 */

/**
 * Fires only when X, Y or Z has changed
 *
 * @event
 * @name axischange
 * @memberOf Accelerometer
 */

module.exports = Accelerometer;

// References
//
// http://www.instructables.com/id/Accelerometer-Gyro-Tutorial/
//
// Images
//
// http://www.robotshop.com/gorobotics/wp-content/uploads/2012/05/euler-angles1.jpg
// http://www.instructables.com/image/F7NMMPEG4PBOJPY/The-Accelerometer.jpg
<commit_msg>Update axis change threshold<commit_after>var Board = require("../lib/board.js"),
    events = require("events"),
    util = require("util"),
    __ = require("../lib/fn.js");

function calculate( method, y, x ) {
  return Math[ method ]( y, x ) * 180 / Math.PI;
}

// Filter for change events

function axisChange(change, threshold) {
  // TODO set actual threshold
  return change.some(function(element) {
      return Math.abs(element) > threshold;
    });
}

function acceleration( axis, vRange, sensitivity ) {
  var voltage;

  // convert raw reading to voltage
  // (read * vRange / 1024) - (vRange / 2)
  voltage = ( axis * vRange / 1024 ) - ( vRange / 2 );

  // 800mV sensitivity
  return voltage / sensitivity;
}

/**
 * Accelerometer
 * @constructor
 *
 * five.Accelerometer([ x, y[, z] ]);
 *
 * five.Accelerometer({
 *   pins: [ x, y[, z] ]
 *   freq: ms
 *  });
 *
 *
 * @param {Object} opts [description]
 *
 */
function Accelerometer( opts ) {

  if ( !(this instanceof Accelerometer) ) {
    return new Accelerometer( opts );
  }

  var pinAxis, last, err, axes, changed, loPass;

  // axis keys
  axes = ["x", "y", "z"];
  // "last" values initialized as zeros for the smoother
  last = {
    x: 0,
    y: 0,
    z: 0
  };
  // Array of changed values
  changed = [];
  err = null;

  // Initialize a Device instance on a Board
  Board.Device.call(
    this, opts = Board.options( opts )
  );

  this.mode = this.firmata.MODES.ANALOG;
  this.pins = opts.pins;

  // Accelerometer instance properties
  this.voltage = opts.voltage || 3.3;

  this.sensitivity = opts.sensitivity || 0.8;

  this.freq = opts.freq || 500;

  // unconditioned response
  this.raw = {};

  // Objects for possible output

  // conditioned response, no smoother
  this.accel = {};
  // conditioned response, smoothed

  this.smooth = {};

  // smoother

  // Blending property for the smoother. Smaller is less filtering

  this.alpha = opts.alpha || 0.2;

  // default smoother is a low pass filter

  this.smoother = opts.smoother || function() {
    var alpha = this.alpha;

    axes.forEach( function( axis, index ) {
      // Simple blending with n - 1th result. last is initialized at 0 for
      // the very first run only.
      this.smooth[axis] = (last[axis] * alpha) + (1 - alpha) * this.accel[axis];
      // update change for the axischange event
      changed[index] = last[axis] - this.smooth[axis];
      // might as well set the last value here
      last[axis] = this.smooth[axis];
    }, this);
    return this.smooth;
  }.bind(this);

  // Pin to Axis mapping
  pinAxis = {};

  // Setup read listeners for each pin, update instance
  // properties as they are received. Special values are
  // calculated during the throttled event emit phase
  this.pins.forEach(function( pin, index ) {

    pinAxis[ pin ] = axes.slice( index, index + 1 )[0];

    // Set the pin to input mode to ANALOG
    this.firmata.pinMode( pin, this.mode );

    this.firmata.analogRead( pin, function( data ) {
      var paxis = pinAxis[ pin ];
      // unconditioned on voltage/sensitivity
      this.raw[ paxis ] = data;
      // the output we're interested in most of the time
      this.accel[ paxis ] = acceleration( data, this.voltage, this.sensitivity );
    }.bind(this));

  }, this );

  // Throttle event emitter
  setInterval(function() {
    var data;

    data = {
      smooth: this.smoother(),
      rough: this.accel
    };

    // Check each axis for change above some threshold
    if ( axisChange( changed , 0.5 ) ) {
      this.emit( "axischange", err, data);
    }

    this.emit( "acceleration", err, data );

  }.bind(this), this.freq );

  /**
   * raw x, y, z data
   * @property raw
   * @type Object
   */

  /**
   * smooth x, y, z data
   * @property smooth
   * @type Object
   */

   /**
    * acceleration calculated x, y, z data
    * @property axis
    * @type Object
    */

  Object.defineProperties( this, {
    /**
     * [read-only] Calculated pitch value
     * @property pitch
     * @type Number
     */
    pitch: {
      get: function() {
        return Math.abs( Math.atan2( this.accel.x, Math.sqrt( Math.pow(this.accel.y, 2) + Math.pow(this.accel.z, 2) ) ) );
      }
    },
    /**
     * [read-only] Calculated roll value
     * @property roll
     * @type Number
     */
    roll: {
      get: function() {
        return Math.abs( Math.atan2( this.accel.y, Math.sqrt( Math.pow(this.accel.x, 2) + Math.pow(this.accel.z, 2) ) ) );
      }
    }
  });
}

util.inherits( Accelerometer, events.EventEmitter );

Object.defineProperty( Accelerometer, "G", {
  /**
   * [read-only] One g is the acceleration due to gravity at the Earth's surface and is the standard gravity (symbol: gn), defined as 9.80665 metres per second squared, or equivalently 9.80665 newtons of force per kilogram of mass.
   *
   * meters/s ^ 2
   *
   * @property G
   * @type Number
   */
  value: 9.81
});

/**
 * Fires once every N ms, equal to value of `freq`. Defaults to 500ms
 *
 * @event
 * @name acceleration
 * @memberOf Accelerometer
 */

/**
 * Fires only when X, Y or Z has changed
 *
 * @event
 * @name axischange
 * @memberOf Accelerometer
 */

module.exports = Accelerometer;

// References
//
// http://www.instructables.com/id/Accelerometer-Gyro-Tutorial/
//
// Images
//
// http://www.robotshop.com/gorobotics/wp-content/uploads/2012/05/euler-angles1.jpg
// http://www.instructables.com/image/F7NMMPEG4PBOJPY/The-Accelerometer.jpg
<|endoftext|>