<commit_before>/**
## # Stackable Chart [Abstract]
Stackable chart is an abstract chart introduced to provide cross-chart support of stackability. Concrete implementation of
charts can then selectively mix-in this capability.

**/
dc.stackableChart = function (_chart) {
    var _groupStack = new dc.utils.GroupStack();
    var _stackLayout = d3.layout.stack()
        .offset("zero")
        .order("default")
        .values(function (d) {
            return d.points;
        });
    var _allGroups;
    var _allValueAccessors;
    var _allKeyAccessors;
    var _stackLayers;

    _chart._hidableStacks = false;

    /**
    #### .stack(group[, name, accessor])
    Stack a new crossfilter group into this chart with optionally a custom value accessor. All stacks in the same chart will
    share the same key accessor therefore share the same set of keys. In more concrete words, imagine in a stacked bar chart
    all bars will be positioned using the same set of keys on the x axis while stacked vertically. If name is specified then
    it will be used to generate legend label.
    ```js
    // stack group using default accessor
    chart.stack(valueSumGroup)
    // stack group using custom accessor
    .stack(avgByDayGroup, function(d){return d.value.avgByDay;});
    ```

    **/
    _chart.stack = function (group, name, accessor) {
        if(!arguments.length)
            _groupStack.clear();

        _groupStack.setDefaultAccessor(_chart.valueAccessor());

        if (typeof name === 'string') {
            _chart._setGroupName(group, name, accessor);
            _groupStack.addNamedGroup(group, name, accessor);
        }
        else {
            accessor = name;
            _groupStack.addGroup(group, accessor);
        }

        _chart.expireCache();

        return _chart;
    };

    _chart.hidableStacks = function(_) {
        if (!arguments.length) return _chart._hidableStacks;
        _chart._hidableStacks = _;
        return _chart;
    };

    /**
    #### .hideStack(name)
    Hide all stacks on the chart with the given name.
    The chart must be re-rendered for this change to appear.

    **/
    _chart.hideStack = function (stackName) {
        _groupStack.hideGroups(stackName, _chart._getGroupName(_chart.group()) == stackName);
    };

    /**
    #### .showStack(name)
    Show all stacks on the chart with the given name.
    The chart must be re-rendered for this change to appear.

    **/
    _chart.showStack = function (stackName) {
        _groupStack.showGroups(stackName, _chart._getGroupName(_chart.group()) == stackName);
    };

    _chart.expireCache = function () {
        _allGroups = null;
        _allValueAccessors = null;
        _allKeyAccessors = null;
        _stackLayers = null;
        return _chart;
    };

    _chart.allGroups = function () {
        if (_allGroups === null) {
            _allGroups = [];

            _allGroups.push(_chart.group());

            for (var i = 0; i < _groupStack.size(); ++i)
                _allGroups.push(_groupStack.getGroupByIndex(i));
        }

        return _allGroups;
    };

    _chart.allValueAccessors = function () {
        if (_allValueAccessors === null) {
            _allValueAccessors = [];

            _allValueAccessors.push(_chart.valueAccessor());

            for (var i = 0; i < _groupStack.size(); ++i)
                _allValueAccessors.push(_groupStack.getAccessorByIndex(i));
        }

        return _allValueAccessors;
    };

    _chart.getValueAccessorByIndex = function (groupIndex) {
        return _chart.allValueAccessors()[groupIndex];
    };

    _chart.yAxisMin = function () {
        var min, all = flattenStack();

        min = d3.min(all, function (p) {
            return  (p.y + p.y0 < p.y0) ? (p.y + p.y0) : p.y0;
        });

        min = dc.utils.subtract(min, _chart.yAxisPadding());

        return min;
    };

    _chart.yAxisMax = function () {
        var max, all = flattenStack();

        max = d3.max(all, function (p) {
            return p.y + p.y0;
        });

        max = dc.utils.add(max, _chart.yAxisPadding());

        return max;
    };

    function flattenStack() {
        var all = [];

        if (_chart.x()) {
            var xDomain = _chart.x().domain();
            var test;
            if(_chart.isOrdinal()) {
                var domainSet = d3.set(xDomain);
                test = function(p) {
                    return domainSet.has(p.x);
                };
            }
            else {
                test = function(p) {
                    return p.x >= xDomain[0] && p.x <= xDomain[xDomain.length-1];
                };
            }
            _chart.stackLayers().forEach(function (e) {
                e.points.forEach(function (p) {
                    if (test(p))
                        all.push(p);
                });
            });
        } else {
            _chart.stackLayers().forEach(function (e) {
                all = all.concat(e.points);
            });
        }

        return all;
    }

    _chart.allKeyAccessors = function () {
        if (_allKeyAccessors === null) {
            _allKeyAccessors = [];

            _allKeyAccessors.push(_chart.keyAccessor());

            for (var i = 0; i < _groupStack.size(); ++i)
                _allKeyAccessors.push(_chart.keyAccessor());
        }

        return _allKeyAccessors;
    };

    _chart.getKeyAccessorByIndex = function (groupIndex) {
        return _chart.allKeyAccessors()[groupIndex];
    };

    _chart.xAxisMin = function () {
        var min = _chart.allGroups().reduce(function(min,group,groupIndex) {
            var m = dc.utils.groupMin(group, _chart.getKeyAccessorByIndex(groupIndex));
            return (min === null || min > m) ? m : min;
        },null);

        return dc.utils.subtract(min, _chart.xAxisPadding());
    };

    _chart.xAxisMax = function () {
        var max = _chart.allGroups().reduce(function(max,group,groupIndex) {
            var m = dc.utils.groupMax(group, _chart.getKeyAccessorByIndex(groupIndex));
            return (max === null || max < m) ? m : max;
        },null);

        return dc.utils.add(max, _chart.xAxisPadding());
    };

    function calculateDataPointMatrix(group, groupIndex) {
        group.all().forEach(function(d, dataIndex) {
            var key = _chart.getKeyAccessorByIndex(groupIndex)(d);
            var value = _chart.getValueAccessorByIndex(groupIndex)(d);
            _groupStack.setDataPoint(groupIndex, dataIndex, {data: d, x: key, y: value, layer: groupIndex});
        });
    }

    _chart.calculateDataPointMatrixForAll = function () {
        _groupStack.clearDataLayers();
        _chart.allGroups().forEach(calculateDataPointMatrix);
    };

    _chart.getChartStack = function () {
        return _groupStack;
    };

    dc.override(_chart, "valueAccessor", function (_) {
        if (!arguments.length) return _chart._valueAccessor();
        _chart.expireCache();
        return _chart._valueAccessor(_);
    });

    dc.override(_chart, "keyAccessor", function (_) {
        if (!arguments.length) return _chart._keyAccessor();
        _chart.expireCache();
        return _chart._keyAccessor(_);
    });

    /**
     #### .title([stackName], [titleFunction])
     Set or get the title function. Chart class will use this function to render svg title (usually interpreted by browser
     as tooltips) for each child element in the chart, i.e. a slice in a pie chart or a bubble in a bubble chart. Almost
     every chart supports title function however in grid coordinate chart you need to turn off brush in order to use title
     otherwise the brush layer will block tooltip trigger.

     If the first argument is a stack name, the title function will get or set the title for that stack. If stackName
     is not provided, the first stack is implied.
     ```js
     // set a title function on "first stack"
     chart.title("first stack", function(d) { return d.key + ": " + d.value; });
     // get a title function from "second stack"
     var secondTitleFunction = chart.title("second stack");
    });
     ```

     **/
    dc.override(_chart, "title", function (stackName, titleAccessor) {
        if (!stackName) return _chart._title();

        var firstStack = _chart.group() && stackName === _chart._getGroupName(_chart.group());

        if (typeof stackName === 'function') {
            return _chart._title(stackName);
        }
        else if (!titleAccessor) {
            if (firstStack)
                return _chart._title();
            else
                return _groupStack.getTitle(stackName);
        }

        if (firstStack)
            return _chart._title(titleAccessor);
        else
            _groupStack.setTitle(stackName, titleAccessor);

        return _chart;
    });

    _chart.getTitleOfVisibleByIndex = function (index) {
        return _chart.title(_groupStack.getNameOfVisibleByIndex(index - 1)) || _chart.title();
    };

    _chart.stackLayout = function (stack) {
        if (!arguments.length) return _stackLayout;
        _stackLayout = stack;
        return _chart;
    };

    _chart.stackLayers = function (_) {
        if (!arguments.length) {
            if (_stackLayers === null) {
                _chart.calculateDataPointMatrixForAll();
                var layers = _groupStack.toLayers();
                if (layers.length === 0) return [];
                _stackLayers = _chart.stackLayout()(layers);
            }
            return _stackLayers;
        } else {
            _stackLayers = _;
        }
    };

    _chart._layerColorAccessor = function(d){return d.layer === undefined ? d.index : d.layer;};
    _chart.colorAccessor(_chart._layerColorAccessor);

    _chart.legendables = function () {
        return _chart.allGroups().map(function (g, i) {
            return dc.utils.createLegendable(_chart, g, _chart.getValueAccessorByIndex(i), _chart.colorCalculator()(i));
        });
    };

    return _chart;
};
<commit_msg>Removed extraneous spaces in title documentation<commit_after>/**
## # Stackable Chart [Abstract]
Stackable chart is an abstract chart introduced to provide cross-chart support of stackability. Concrete implementation of
charts can then selectively mix-in this capability.

**/
dc.stackableChart = function (_chart) {
    var _groupStack = new dc.utils.GroupStack();
    var _stackLayout = d3.layout.stack()
        .offset("zero")
        .order("default")
        .values(function (d) {
            return d.points;
        });
    var _allGroups;
    var _allValueAccessors;
    var _allKeyAccessors;
    var _stackLayers;

    _chart._hidableStacks = false;

    /**
    #### .stack(group[, name, accessor])
    Stack a new crossfilter group into this chart with optionally a custom value accessor. All stacks in the same chart will
    share the same key accessor therefore share the same set of keys. In more concrete words, imagine in a stacked bar chart
    all bars will be positioned using the same set of keys on the x axis while stacked vertically. If name is specified then
    it will be used to generate legend label.
    ```js
    // stack group using default accessor
    chart.stack(valueSumGroup)
    // stack group using custom accessor
    .stack(avgByDayGroup, function(d){return d.value.avgByDay;});
    ```

    **/
    _chart.stack = function (group, name, accessor) {
        if(!arguments.length)
            _groupStack.clear();

        _groupStack.setDefaultAccessor(_chart.valueAccessor());

        if (typeof name === 'string') {
            _chart._setGroupName(group, name, accessor);
            _groupStack.addNamedGroup(group, name, accessor);
        }
        else {
            accessor = name;
            _groupStack.addGroup(group, accessor);
        }

        _chart.expireCache();

        return _chart;
    };

    _chart.hidableStacks = function(_) {
        if (!arguments.length) return _chart._hidableStacks;
        _chart._hidableStacks = _;
        return _chart;
    };

    /**
    #### .hideStack(name)
    Hide all stacks on the chart with the given name.
    The chart must be re-rendered for this change to appear.

    **/
    _chart.hideStack = function (stackName) {
        _groupStack.hideGroups(stackName, _chart._getGroupName(_chart.group()) == stackName);
    };

    /**
    #### .showStack(name)
    Show all stacks on the chart with the given name.
    The chart must be re-rendered for this change to appear.

    **/
    _chart.showStack = function (stackName) {
        _groupStack.showGroups(stackName, _chart._getGroupName(_chart.group()) == stackName);
    };

    _chart.expireCache = function () {
        _allGroups = null;
        _allValueAccessors = null;
        _allKeyAccessors = null;
        _stackLayers = null;
        return _chart;
    };

    _chart.allGroups = function () {
        if (_allGroups === null) {
            _allGroups = [];

            _allGroups.push(_chart.group());

            for (var i = 0; i < _groupStack.size(); ++i)
                _allGroups.push(_groupStack.getGroupByIndex(i));
        }

        return _allGroups;
    };

    _chart.allValueAccessors = function () {
        if (_allValueAccessors === null) {
            _allValueAccessors = [];

            _allValueAccessors.push(_chart.valueAccessor());

            for (var i = 0; i < _groupStack.size(); ++i)
                _allValueAccessors.push(_groupStack.getAccessorByIndex(i));
        }

        return _allValueAccessors;
    };

    _chart.getValueAccessorByIndex = function (groupIndex) {
        return _chart.allValueAccessors()[groupIndex];
    };

    _chart.yAxisMin = function () {
        var min, all = flattenStack();

        min = d3.min(all, function (p) {
            return  (p.y + p.y0 < p.y0) ? (p.y + p.y0) : p.y0;
        });

        min = dc.utils.subtract(min, _chart.yAxisPadding());

        return min;
    };

    _chart.yAxisMax = function () {
        var max, all = flattenStack();

        max = d3.max(all, function (p) {
            return p.y + p.y0;
        });

        max = dc.utils.add(max, _chart.yAxisPadding());

        return max;
    };

    function flattenStack() {
        var all = [];

        if (_chart.x()) {
            var xDomain = _chart.x().domain();
            var test;
            if(_chart.isOrdinal()) {
                var domainSet = d3.set(xDomain);
                test = function(p) {
                    return domainSet.has(p.x);
                };
            }
            else {
                test = function(p) {
                    return p.x >= xDomain[0] && p.x <= xDomain[xDomain.length-1];
                };
            }
            _chart.stackLayers().forEach(function (e) {
                e.points.forEach(function (p) {
                    if (test(p))
                        all.push(p);
                });
            });
        } else {
            _chart.stackLayers().forEach(function (e) {
                all = all.concat(e.points);
            });
        }

        return all;
    }

    _chart.allKeyAccessors = function () {
        if (_allKeyAccessors === null) {
            _allKeyAccessors = [];

            _allKeyAccessors.push(_chart.keyAccessor());

            for (var i = 0; i < _groupStack.size(); ++i)
                _allKeyAccessors.push(_chart.keyAccessor());
        }

        return _allKeyAccessors;
    };

    _chart.getKeyAccessorByIndex = function (groupIndex) {
        return _chart.allKeyAccessors()[groupIndex];
    };

    _chart.xAxisMin = function () {
        var min = _chart.allGroups().reduce(function(min,group,groupIndex) {
            var m = dc.utils.groupMin(group, _chart.getKeyAccessorByIndex(groupIndex));
            return (min === null || min > m) ? m : min;
        },null);

        return dc.utils.subtract(min, _chart.xAxisPadding());
    };

    _chart.xAxisMax = function () {
        var max = _chart.allGroups().reduce(function(max,group,groupIndex) {
            var m = dc.utils.groupMax(group, _chart.getKeyAccessorByIndex(groupIndex));
            return (max === null || max < m) ? m : max;
        },null);

        return dc.utils.add(max, _chart.xAxisPadding());
    };

    function calculateDataPointMatrix(group, groupIndex) {
        group.all().forEach(function(d, dataIndex) {
            var key = _chart.getKeyAccessorByIndex(groupIndex)(d);
            var value = _chart.getValueAccessorByIndex(groupIndex)(d);
            _groupStack.setDataPoint(groupIndex, dataIndex, {data: d, x: key, y: value, layer: groupIndex});
        });
    }

    _chart.calculateDataPointMatrixForAll = function () {
        _groupStack.clearDataLayers();
        _chart.allGroups().forEach(calculateDataPointMatrix);
    };

    _chart.getChartStack = function () {
        return _groupStack;
    };

    dc.override(_chart, "valueAccessor", function (_) {
        if (!arguments.length) return _chart._valueAccessor();
        _chart.expireCache();
        return _chart._valueAccessor(_);
    });

    dc.override(_chart, "keyAccessor", function (_) {
        if (!arguments.length) return _chart._keyAccessor();
        _chart.expireCache();
        return _chart._keyAccessor(_);
    });

    /**
    #### .title([stackName], [titleFunction])
    Set or get the title function. Chart class will use this function to render svg title (usually interpreted by browser
    as tooltips) for each child element in the chart, i.e. a slice in a pie chart or a bubble in a bubble chart. Almost
    every chart supports title function however in grid coordinate chart you need to turn off brush in order to use title
    otherwise the brush layer will block tooltip trigger.

    If the first argument is a stack name, the title function will get or set the title for that stack. If stackName
    is not provided, the first stack is implied.
    ```js
    // set a title function on "first stack"
    chart.title("first stack", function(d) { return d.key + ": " + d.value; });
    // get a title function from "second stack"
    var secondTitleFunction = chart.title("second stack");
    );
    ```

    **/
    dc.override(_chart, "title", function (stackName, titleAccessor) {
        if (!stackName) return _chart._title();

        var firstStack = _chart.group() && stackName === _chart._getGroupName(_chart.group());

        if (typeof stackName === 'function') {
            return _chart._title(stackName);
        }
        else if (!titleAccessor) {
            if (firstStack)
                return _chart._title();
            else
                return _groupStack.getTitle(stackName);
        }

        if (firstStack)
            return _chart._title(titleAccessor);
        else
            _groupStack.setTitle(stackName, titleAccessor);

        return _chart;
    });

    _chart.getTitleOfVisibleByIndex = function (index) {
        return _chart.title(_groupStack.getNameOfVisibleByIndex(index - 1)) || _chart.title();
    };

    _chart.stackLayout = function (stack) {
        if (!arguments.length) return _stackLayout;
        _stackLayout = stack;
        return _chart;
    };

    _chart.stackLayers = function (_) {
        if (!arguments.length) {
            if (_stackLayers === null) {
                _chart.calculateDataPointMatrixForAll();
                var layers = _groupStack.toLayers();
                if (layers.length === 0) return [];
                _stackLayers = _chart.stackLayout()(layers);
            }
            return _stackLayers;
        } else {
            _stackLayers = _;
        }
    };

    _chart._layerColorAccessor = function(d){return d.layer === undefined ? d.index : d.layer;};
    _chart.colorAccessor(_chart._layerColorAccessor);

    _chart.legendables = function () {
        return _chart.allGroups().map(function (g, i) {
            return dc.utils.createLegendable(_chart, g, _chart.getValueAccessorByIndex(i), _chart.colorCalculator()(i));
        });
    };

    return _chart;
};
<|endoftext|>


<commit_before>'use strict';

const { parse } = require('graphql');

const { EngineError } = require('../../../../error');
const { memoize } = require('../../../../utilities');

// Raw GraphQL parsing
const parseQuery = memoize(({ query, goal, operationName }) => {
  if (!query) {
    const message = 'Missing GraphQL query';
    throw new EngineError(message, { reason: 'GRAPHQL_NO_QUERY' });
  }

  try {
    const queryDocument = parse(query);
    const { graphqlMethod } = validateQuery({
      queryDocument,
      goal,
      operationName,
    });
    return { queryDocument, graphqlMethod };
  } catch (error) {
    const message = 'Could not parse GraphQL query';
    throw new EngineError(message, {
      reason: 'GRAPHQL_SYNTAX_ERROR',
      innererror: error,
    });
  }
});

// Make sure GraphQL query is valid
const validateQuery = function ({ queryDocument, goal, operationName }) {
  // Get all query|mutation definitions
  const operationDefinitions = queryDocument.definitions.filter(({ kind }) =>
    kind === 'OperationDefinition'
  );
  const definitions = operationDefinitions.filter(({
    name: { value: name } = {},
  }) => !operationName || name === operationName);

  if (definitions.length === 0) {
    if (operationName) {
      const message = `Could not find GraphQL operation ${operationName}`;
      throw new EngineError(message, { reason: 'GRAPHQL_SYNTAX_ERROR' });
    } else {
      const message = 'Missing GraphQL query';
      throw new EngineError(message, { reason: 'GRAPHQL_NO_QUERY' });
    }
  }

  const [definition] = definitions;

  // GraphQL-anywhere do not support operationName yet,
  // so we must patch it until they do
  // See https://github.com/apollographql/graphql-anywhere/issues/34
  if (operationDefinitions.length > 1) {
    queryDocument.definitions = queryDocument.definitions.filter(def =>
      !operationDefinitions.includes(def) || def === definition
    );
  }

  if (goal === 'find' && definition.operation !== 'query') {
    const message = 'Can only perform GraphQL queries, not mutations, with the current protocol method';
    throw new EngineError(message, { reason: 'GRAPHQL_SYNTAX_ERROR' });
  }

  return { graphqlMethod: definition.operation };
};

module.exports = {
  parseQuery,
  validateQuery,
};
<commit_msg>Small refactoring<commit_after>'use strict';

const { parse } = require('graphql');

const { EngineError } = require('../../../../error');
const { memoize } = require('../../../../utilities');

// Raw GraphQL parsing
const parseQuery = memoize(({ query, goal, operationName }) => {
  if (!query) {
    const message = 'Missing GraphQL query';
    throw new EngineError(message, { reason: 'GRAPHQL_NO_QUERY' });
  }

  try {
    const queryDocument = parse(query);
    const { graphqlMethod } = validateQuery({
      queryDocument,
      goal,
      operationName,
    });
    return { queryDocument, graphqlMethod };
  } catch (error) {
    const message = 'Could not parse GraphQL query';
    throw new EngineError(message, {
      reason: 'GRAPHQL_SYNTAX_ERROR',
      innererror: error,
    });
  }
});

// Make sure GraphQL query is valid
const validateQuery = function ({ queryDocument, goal, operationName }) {
  // Get all query|mutation definitions
  const operationDefinitions = queryDocument.definitions.filter(({ kind }) =>
    kind === 'OperationDefinition'
  );
  const definition = getDefinition({ operationDefinitions, operationName });

  // GraphQL-anywhere do not support operationName yet,
  // so we must patch it until they do
  // See https://github.com/apollographql/graphql-anywhere/issues/34
  if (operationDefinitions.length > 1) {
    queryDocument.definitions = queryDocument.definitions.filter(def =>
      !operationDefinitions.includes(def) || def === definition
    );
  }

  if (goal === 'find' && definition.operation !== 'query') {
    const message = 'Can only perform GraphQL queries, not mutations, with the current protocol method';
    throw new EngineError(message, { reason: 'GRAPHQL_SYNTAX_ERROR' });
  }

  return { graphqlMethod: definition.operation };
};

const getDefinition = function ({ operationDefinitions, operationName }) {
  const definitions = operationDefinitions.filter(({
    name: { value: name } = {},
  }) => !operationName || name === operationName);

  if (definitions.length === 0) {
    if (operationName) {
      const message = `Could not find GraphQL operation ${operationName}`;
      throw new EngineError(message, { reason: 'GRAPHQL_SYNTAX_ERROR' });
    } else {
      const message = 'Missing GraphQL query';
      throw new EngineError(message, { reason: 'GRAPHQL_NO_QUERY' });
    }
  }

  const [definition] = definitions;
  return definition;
};

module.exports = {
  parseQuery,
  validateQuery,
};
<|endoftext|>


<commit_before>import { isArray } from 'underscore';

const ComponentsView = require('./ComponentsView');

module.exports = Backbone.View.extend({

  className() {
    return this.getClasses();
  },

  tagName() {
    return this.model.get('tagName');
  },

  initialize(opt = {}) {
    const model = this.model;
    const config = opt.config || {};
    this.opts = opt;
    this.config = config;
    this.em = config.em || '';
    this.pfx = config.stylePrefix || '';
    this.ppfx = config.pStylePrefix || '';
    this.attr = model.get('attributes');
    this.classe = this.attr.class || [];
    const $el = this.$el;
    const classes = model.get('classes');
    this.listenTo(model, 'destroy remove', this.remove);
    this.listenTo(model, 'change:style', this.updateStyle);
    this.listenTo(model, 'change:attributes', this.updateAttributes);
    this.listenTo(model, 'change:highlightable', this.updateHighlight);
    this.listenTo(model, 'change:status', this.updateStatus);
    this.listenTo(model, 'change:state', this.updateState);
    this.listenTo(model, 'change:script', this.render);
    this.listenTo(model, 'change', this.handleChange);
    this.listenTo(classes, 'add remove change', this.updateClasses);
    $el.data('model', model);
    $el.data('collection', model.get('components'));
    model.view = this;
    classes.length && this.importClasses();
    this.init();
  },

  remove() {
    Backbone.View.prototype.remove.apply(this);
    const children = this.childrenView;
    children && children.stopListening();
  },

  /**
   * Initialize callback
   */
  init() {},

  /**
   * Handle any property change
   * @private
   */
  handleChange() {
    var em = this.em;
    if(em) {
      var model = this.model;
      em.trigger('component:update', model);

      for(var prop in model.changed) {
        em.trigger('component:update:' + prop, model);
      }
    }
  },

  /**
   * Import, if possible, classes inside main container
   * @private
   * */
  importClasses() {
    var clm = this.config.em.get('SelectorManager');

    if(clm){
      this.model.get('classes').each(m => {
          clm.add(m.get('name'));
      });
    }
  },

  /**
   * Fires on state update. If the state is not empty will add a helper class
   * @param  {Event} e
   * @private
   * */
  updateState(e) {
    var cl = 'hc-state';
    var state = this.model.get('state');

    if(state){
      this.$el.addClass(cl);
    }else{
      this.$el.removeClass(cl);
    }
  },

  /**
   * Update item on status change
   * @param  {Event} e
   * @private
   * */
  updateStatus(e) {
    var el = this.el;
    var status = this.model.get('status');
    var pfx = this.pfx;
    var ppfx = this.ppfx;
    var selectedCls = pfx + 'selected';
    var selectedParentCls = selectedCls + '-parent';
    var freezedCls = `${ppfx}freezed`;
    var actualCls = el.getAttribute('class') || '';
    var cls = '';

    switch (status) {
        case 'selected':
          cls = `${actualCls} ${selectedCls}`;
          break;
        case 'selected-parent':
          cls = `${actualCls} ${selectedParentCls}`;
          break;
        case 'freezed':
          cls = `${actualCls} ${freezedCls}`;
          break;
        default:
          this.$el.removeClass(`${selectedCls} ${selectedParentCls} ${freezedCls}`);
    }

    cls = cls.trim();

    if (cls) {
      el.setAttribute('class', cls);
    }
  },

  /**
   * Update highlight attribute
   * @private
   * */
  updateHighlight() {
    const hl = this.model.get('highlightable');
    this.setAttribute('data-highlightable', hl ? 1 : '');
  },

  /**
   * Update style attribute
   * @private
   * */
  updateStyle() {
    if (this.config.avoidInlineStyle) {
      const model = this.model;
      this.el.id = model.getId();
      model.setStyle(model.getStyle());
    } else {
      this.setAttribute('style', this.getStyleString());
    }
  },

  /**
   * Return style string
   * @return  {string}
   * @private
   * */
  getStyleString() {
    var style  = '';
    this.style = this.model.get('style');
    for(var key in this.style) {
        if(this.style.hasOwnProperty(key))
          style += key + ':' + this.style[key] + ';';
    }

    return style;
  },

  /**
   * Update classe attribute
   * @private
   * */
  updateClasses() {
    const str = this.model.get('classes').pluck('name').join(' ');
    this.setAttribute('class', str);

    // Regenerate status class
    this.updateStatus();
  },

  /**
   * Update single attribute
   * @param {[type]} name  [description]
   * @param {[type]} value [description]
   */
  setAttribute(name, value) {
    const el = this.$el;
    value ? el.attr(name, value) : el.removeAttr(name);
  },

  /**
   * Get classes from attributes.
   * This method is called before initialize
   *
   * @return  {Array}|null
   * @private
   * */
  getClasses() {
    var attr = this.model.get("attributes"),
      classes  = attr['class'] || [];
    classes = isArray(classes) ? classes : [classes];

    if (classes.length) {
      if (!classes.join) {
        console.log('class is',classes);
      }
      return classes.join(' ');
    }else
      return null;
  },

  /**
   * Update attributes
   * @private
   * */
  updateAttributes() {
    const model = this.model;
    const attrs = {}
    const attr = model.get('attributes');
    const src = model.get('src');

    for (let key in attr) {
      attrs[key] = attr[key];
    }

    src && (attrs.src = src);
    this.$el.attr(attrs);
    this.updateHighlight();
    this.updateStyle();
  },

  /**
   * Update component content
   * @private
   * */
  updateContent() {
    this.getChildrenContainer().innerHTML = this.model.get('content');
  },

  /**
   * Prevent default helper
   * @param  {Event} e
   * @private
   */
  prevDef(e) {
    e.preventDefault();
  },

  /**
   * Render component's script
   * @private
   */
  updateScript() {
    if (!this.model.get('script')) {
      return;
    }

    var em = this.em;
    if(em) {
      var canvas = em.get('Canvas');
      canvas.getCanvasView().updateScript(this);
    }
  },

  /**
   * Return children container
   * Differently from a simple component where children container is the
   * component itself
   * <my-comp>
   *
   * </my-comp>
   * You could have the children container more deeper
   * <my-comp>
   *

   *

   *

   *

   *
   *

   *

   * </my-comp>
   * @return HTMLElement
   * @private
   */
  getChildrenContainer() {
    var container = this.el;

    if (typeof this.getChildrenSelector == 'function') {
      container = this.el.querySelector(this.getChildrenSelector());
    } else if (typeof this.getTemplate == 'function') {
      // Need to find deepest first child
    }

    return container;
  },

  /**
   * Render children components
   * @private
   */
  renderChildren() {
    const container = this.getChildrenContainer();
    const view = new ComponentsView({
      collection: this.model.get('components'),
      config: this.config,
      componentTypes: this.opts.componentTypes,
    });

    view.render(container);
    this.childrenView = view;
    const childNodes = Array.prototype.slice.call(view.el.childNodes);

    for (var i = 0, len = childNodes.length ; i < len; i++) {
      container.appendChild(childNodes.shift());
    }

    // If the children container is not the same as the component
    // (so likely fetched with getChildrenSelector()) is necessary
    // to disable pointer-events for all nested components as they
    // might prevent the component to be selected
    if (container !== this.el) {
      var disableNode = el => {
        var children = Array.prototype.slice.call(el.children);
        children.forEach(el => {
          el.style['pointer-events'] = 'none';
          if (container !== el) {
            disableNode(el);
          }
        });
      };
      disableNode(this.el);
    }
  },

  renderAttributes() {
    this.updateAttributes();
    this.updateClasses();
  },

  render() {
    this.renderAttributes();
    this.updateContent();
    this.renderChildren();
    this.updateScript();
    return this;
  },

});
<commit_msg>Update `getClasses`<commit_after>import { isArray } from 'underscore';

const ComponentsView = require('./ComponentsView');

module.exports = Backbone.View.extend({

  className() {
    return this.getClasses();
  },

  tagName() {
    return this.model.get('tagName');
  },

  initialize(opt = {}) {
    const model = this.model;
    const config = opt.config || {};
    this.opts = opt;
    this.config = config;
    this.em = config.em || '';
    this.pfx = config.stylePrefix || '';
    this.ppfx = config.pStylePrefix || '';
    this.attr = model.get('attributes');
    this.classe = this.attr.class || [];
    const $el = this.$el;
    const classes = model.get('classes');
    this.listenTo(model, 'destroy remove', this.remove);
    this.listenTo(model, 'change:style', this.updateStyle);
    this.listenTo(model, 'change:attributes', this.updateAttributes);
    this.listenTo(model, 'change:highlightable', this.updateHighlight);
    this.listenTo(model, 'change:status', this.updateStatus);
    this.listenTo(model, 'change:state', this.updateState);
    this.listenTo(model, 'change:script', this.render);
    this.listenTo(model, 'change', this.handleChange);
    this.listenTo(classes, 'add remove change', this.updateClasses);
    $el.data('model', model);
    $el.data('collection', model.get('components'));
    model.view = this;
    classes.length && this.importClasses();
    this.init();
  },

  remove() {
    Backbone.View.prototype.remove.apply(this);
    const children = this.childrenView;
    children && children.stopListening();
  },

  /**
   * Initialize callback
   */
  init() {},

  /**
   * Handle any property change
   * @private
   */
  handleChange() {
    var em = this.em;
    if(em) {
      var model = this.model;
      em.trigger('component:update', model);

      for(var prop in model.changed) {
        em.trigger('component:update:' + prop, model);
      }
    }
  },

  /**
   * Import, if possible, classes inside main container
   * @private
   * */
  importClasses() {
    var clm = this.config.em.get('SelectorManager');

    if(clm){
      this.model.get('classes').each(m => {
          clm.add(m.get('name'));
      });
    }
  },

  /**
   * Fires on state update. If the state is not empty will add a helper class
   * @param  {Event} e
   * @private
   * */
  updateState(e) {
    var cl = 'hc-state';
    var state = this.model.get('state');

    if(state){
      this.$el.addClass(cl);
    }else{
      this.$el.removeClass(cl);
    }
  },

  /**
   * Update item on status change
   * @param  {Event} e
   * @private
   * */
  updateStatus(e) {
    var el = this.el;
    var status = this.model.get('status');
    var pfx = this.pfx;
    var ppfx = this.ppfx;
    var selectedCls = pfx + 'selected';
    var selectedParentCls = selectedCls + '-parent';
    var freezedCls = `${ppfx}freezed`;
    var actualCls = el.getAttribute('class') || '';
    var cls = '';

    switch (status) {
        case 'selected':
          cls = `${actualCls} ${selectedCls}`;
          break;
        case 'selected-parent':
          cls = `${actualCls} ${selectedParentCls}`;
          break;
        case 'freezed':
          cls = `${actualCls} ${freezedCls}`;
          break;
        default:
          this.$el.removeClass(`${selectedCls} ${selectedParentCls} ${freezedCls}`);
    }

    cls = cls.trim();

    if (cls) {
      el.setAttribute('class', cls);
    }
  },

  /**
   * Update highlight attribute
   * @private
   * */
  updateHighlight() {
    const hl = this.model.get('highlightable');
    this.setAttribute('data-highlightable', hl ? 1 : '');
  },

  /**
   * Update style attribute
   * @private
   * */
  updateStyle() {
    if (this.config.avoidInlineStyle) {
      const model = this.model;
      this.el.id = model.getId();
      model.setStyle(model.getStyle());
    } else {
      this.setAttribute('style', this.getStyleString());
    }
  },

  /**
   * Return style string
   * @return  {string}
   * @private
   * */
  getStyleString() {
    var style  = '';
    this.style = this.model.get('style');
    for(var key in this.style) {
        if(this.style.hasOwnProperty(key))
          style += key + ':' + this.style[key] + ';';
    }

    return style;
  },

  /**
   * Update classe attribute
   * @private
   * */
  updateClasses() {
    const str = this.model.get('classes').pluck('name').join(' ');
    this.setAttribute('class', str);

    // Regenerate status class
    this.updateStatus();
  },

  /**
   * Update single attribute
   * @param {[type]} name  [description]
   * @param {[type]} value [description]
   */
  setAttribute(name, value) {
    const el = this.$el;
    value ? el.attr(name, value) : el.removeAttr(name);
  },

  /**
   * Get classes from attributes.
   * This method is called before initialize
   *
   * @return  {Array}|null
   * @private
   * */
  getClasses() {
    var attr = this.model.get("attributes"),
      classes  = attr['class'] || [];
    classes = isArray(classes) ? classes : [classes];

    if (classes.length) {
      return classes.join(' ');
    } else {
      return null;
    }
  },

  /**
   * Update attributes
   * @private
   * */
  updateAttributes() {
    const model = this.model;
    const attrs = {}
    const attr = model.get('attributes');
    const src = model.get('src');

    for (let key in attr) {
      attrs[key] = attr[key];
    }

    src && (attrs.src = src);
    this.$el.attr(attrs);
    this.updateHighlight();
    this.updateStyle();
  },

  /**
   * Update component content
   * @private
   * */
  updateContent() {
    this.getChildrenContainer().innerHTML = this.model.get('content');
  },

  /**
   * Prevent default helper
   * @param  {Event} e
   * @private
   */
  prevDef(e) {
    e.preventDefault();
  },

  /**
   * Render component's script
   * @private
   */
  updateScript() {
    if (!this.model.get('script')) {
      return;
    }

    var em = this.em;
    if(em) {
      var canvas = em.get('Canvas');
      canvas.getCanvasView().updateScript(this);
    }
  },

  /**
   * Return children container
   * Differently from a simple component where children container is the
   * component itself
   * <my-comp>
   *
   * </my-comp>
   * You could have the children container more deeper
   * <my-comp>
   *

   *

   *

   *

   *
   *

   *

   * </my-comp>
   * @return HTMLElement
   * @private
   */
  getChildrenContainer() {
    var container = this.el;

    if (typeof this.getChildrenSelector == 'function') {
      container = this.el.querySelector(this.getChildrenSelector());
    } else if (typeof this.getTemplate == 'function') {
      // Need to find deepest first child
    }

    return container;
  },

  /**
   * Render children components
   * @private
   */
  renderChildren() {
    const container = this.getChildrenContainer();
    const view = new ComponentsView({
      collection: this.model.get('components'),
      config: this.config,
      componentTypes: this.opts.componentTypes,
    });

    view.render(container);
    this.childrenView = view;
    const childNodes = Array.prototype.slice.call(view.el.childNodes);

    for (var i = 0, len = childNodes.length ; i < len; i++) {
      container.appendChild(childNodes.shift());
    }

    // If the children container is not the same as the component
    // (so likely fetched with getChildrenSelector()) is necessary
    // to disable pointer-events for all nested components as they
    // might prevent the component to be selected
    if (container !== this.el) {
      var disableNode = el => {
        var children = Array.prototype.slice.call(el.children);
        children.forEach(el => {
          el.style['pointer-events'] = 'none';
          if (container !== el) {
            disableNode(el);
          }
        });
      };
      disableNode(this.el);
    }
  },

  renderAttributes() {
    this.updateAttributes();
    this.updateClasses();
  },

  render() {
    this.renderAttributes();
    this.updateContent();
    this.renderChildren();
    this.updateScript();
    return this;
  },

});
<|endoftext|>


<commit_before>(function () {
    var search = location.search.substring(1);
    var obj = search ? JSON.parse("{'" + search.replace(/&/g, "'").replace(/=/g, "':'") + "\"}",
      function ( key, value) {
          return key === "" ? value : decodeURIComponent(value);
      }) : {};

    document.title = "Information About " + obj.symbol;
    $("#gene-name").text(obj.symbol);
    // This is cite used to find the parsing:
    // https://stackoverflow.com/questions/8648892/convert-url-parameters-to-a-javascript-object

    var api = window.api;
    api.getGeneInformation(obj.symbol).done(function (gene) {

        var sgdHrefTemplate = "https://www.yeastgenome.org/locus/";
        var sgdId = gene.sgd.sgdID;
        $(".sgd-link").text(sgdId).attr({ href: sgdHrefTemplate + sgdId });

        var ncbiHrefTemplate = "https://www.ncbi.nlm.nih.gov/gene/";
        var ncbiId = gene.ncbi.ncbiID;
        $(".ncbi-link").text(ncbiId).attr({ href: ncbiHrefTemplate + ncbiId });

        var ensemblHrefTemplate = "https://www.ensembl.org/Saccharomyces_cerevisiae/Gene/" +
        "/Summary?db=core;g=YFL039C;r=VI:53260-54696;t=";
        var ensemblId = gene.ensembl.ensemblID;
        $(".ensembl-link").text(ensemblId).attr({ href: ensemblHrefTemplate + ensemblId });

        var uniprotHrefTemplate = "http://www.uniprot.org/uniprot/";
        var uniprotId = gene.uniprot.uniprotID;
        $(".uniprot-link").text(uniprotId).attr({ href: uniprotHrefTemplate + uniprotId });

        var jasparHrefTemplate = "http://jaspar.genereg.net/matrix/";
        var jasparId = gene.jaspar.jasparID;
        $(".jaspar-link").text(jasparId).attr({ href: jasparHrefTemplate + jasparId });
        // General Information Section

        var ensemblInfo = gene.ensembl.description;
        $(".ensemblDescription").text(ensemblInfo).attr({ href: ensemblHrefTemplate + ensemblInfo });

        var uniSpecies = gene.uniprot.species;
        $(".uniProtSpecies").text(uniSpecies).attr({ href: uniprotHrefTemplate + uniSpecies });

        var ncbiLocus = gene.ncbi.locusTag;
        $(".ncbiLocusTag").text(ncbiLocus).attr({ href: ncbiHrefTemplate + ncbiLocus });

        var jasparFam = gene.jaspar.family;
        $(".jasparFamily").text(jasparFam).attr({ href: jasparHrefTemplate + jasparFam });

        var ncbiChromosome = gene.ncbi.chromosomeSequence;
        $(".chromosomeSequence").text(ncbiChromosome).attr({ href: ncbiHrefTemplate + ncbiChromosome });

      // DNA Sequence Tab
        var ensemblDNA = gene.ensembl.dnaSequence;
        $(".dnaSequence").text(ensemblDNA).attr({ href: ensemblHrefTemplate + ensemblDNA });

      // Protein Information

        var uniprotProteinType = gene.uniprot.proteinType;
        $(".proteinType").text(uniprotProteinType).attr({ href: uniprotHrefTemplate + uniprotProteinType });

        var uniprotProteinSequence = gene.uniprot.proteinSequence;
        $(".proteinSequence").text(uniprotProteinSequence).attr({ href: uniprotHrefTemplate + uniprotProteinSequence });

      // Gene mapping
        var geneMap = gene.ensembl.geneMap;
        $(".geneMap").text(geneMap).attr({ href: ensemblHrefTemplate + geneMap });

      // Regulation Information
        var sgdRequlators = gene.sgd.regulators;
        $(".regulators").text(sgdRequlators).attr({ href: sgdHrefTemplate + sgdRequlators });
        $("1").appendTo(".regulators");

        var sgdTargets = gene.sgd.targets;
        $(".targets").text(sgdTargets).attr({ href: sgdHrefTemplate + sgdTargets });
        $("1").appendTo(".targets");

      // Interaction: Physical Reaction

        var sgdInteractions = gene.sgd.totalInteractions;
        $(".totalInteractions").text(sgdInteractions).attr({ href: sgdHrefTemplate + sgdInteractions });

        var sgdAffinityCaptureMS = gene.sgd.affinityCaptureMS;
        $(".affinityCaptureMS").text(sgdAffinityCaptureMS).attr({ href: sgdHrefTemplate + sgdAffinityCaptureMS });

        var sgdAffinityCaptureRNA = gene.sgd.affinityCaptureRNA;
        $(".affinityCaptureRNA").text(sgdAffinityCaptureRNA).attr({ href: sgdHrefTemplate + sgdAffinityCaptureRNA });

        var sgdAffinityCaptureWesterns = gene.sgd.affinityCaptureWestern;
        $(".affinityCaptureWestern").text(sgdAffinityCaptureWesterns).attr(
            { href: sgdHrefTemplate + sgdAffinityCaptureWesterns });

        var sgdBiochemicalActivity = gene.sgd.biochemicalActivity;
        $(".biochemicalActivity").text(sgdBiochemicalActivity).attr({ href: sgdHrefTemplate + sgdBiochemicalActivity });

        var sgdColocalization = gene.sgd.colocalization;
        $(".colocalization").text(sgdColocalization).attr({ href: sgdHrefTemplate + sgdColocalization });

        var sgdReconstitutedComplex = gene.sgd.reconstitutedComplex;
        $(".reconstitutedComplex").text(sgdReconstitutedComplex).attr(
            { href: sgdHrefTemplate + sgdReconstitutedComplex });

        var sgdTwoHybrid = gene.sgd.twoHybrid;
        $(".twoHybrid").text(sgdTwoHybrid).attr({ href: sgdHrefTemplate + sgdTwoHybrid });

      // Genetic Interactions

        var sgdDosage = gene.sgd.dosageRescue;
        $(".dosageRescue").text(sgdDosage).attr({ href: sgdHrefTemplate + sgdDosage });

        var sgdNegGen = gene.sgd.negativeGenetic;
        $(".negativeGenetic").text(sgdNegGen).attr({ href: sgdHrefTemplate + sgdNegGen });

        var sgdEnhance = gene.sgd.phenotypicEnhancement;
        $(".phenotypicEnhancement").text(sgdEnhance).attr({ href: sgdHrefTemplate + sgdEnhance });

        var sgdSuppress = gene.sgd.phenotypicSuppression;
        $(".phenotypicSuppression").text(sgdSuppress).attr({ href: sgdHrefTemplate + sgdSuppress });

        var sgdGrowthDefect = gene.sgd.syntheticGrowthDefect;
        $(".syntheticGrowthDefect").text(sgdGrowthDefect).attr({ href: sgdHrefTemplate + sgdGrowthDefect });

        var sgdHaploin = gene.sgd.syntheticHaploinsufficiency;
        $(".syntheticHaploinsufficiency").text(sgdHaploin).attr({ href: sgdHrefTemplate + sgdHaploin });

        var sgdLethality = gene.sgd.syntheticLethality;
        $(".syntheticLethality").text(sgdLethality).attr({ href: sgdHrefTemplate + sgdLethality });

        var sgdRescue = gene.sgd.sgdRescue;
        $(".syntheticRescue").text(sgdRescue).attr({ href: sgdHrefTemplate + sgdRescue });

      // Gene Ontology
        var sgdSummary = gene.sgd.geneOntologySummary;
        $(".geneSummary").text(sgdSummary).attr({ href: sgdHrefTemplate + sgdSummary });

        var sgdMolecularFunction = gene.sgd.molecularFunction;
        $(".molecularFunction").text(sgdMolecularFunction).attr({ href: sgdHrefTemplate + sgdMolecularFunction });

        var sgdBiologicalProcess = gene.sgd.biologicalProcess;
        $(".biologicalProcess").text(sgdBiologicalProcess).attr({ href: sgdHrefTemplate + sgdBiologicalProcess });

        var sgdCellularComponent = gene.sgd.cellularComponent;
        $(".cellularComponent").text(sgdCellularComponent).attr({ href: sgdHrefTemplate + sgdCellularComponent });

        $("#sgdSource").text("Saccharomycese Genome Database");
        $("1").appendTo(".sgdSource");
        $("#uniprotSource").text("UniProt");
        $("2").appendTo(".uniprotSource");
        $("#ensemblSource").text("Ensembl");
        $("3").appendTo(".ensemblSource");
        $("#ncbiSource").text("NCBI Database");
        $("4").appendTo(".ncbiSource");
        $("#jasparSource").text("Jaspar Database");
        $("5").appendTo(".jasparSource");

        // Fequency Matrix and Sequence Logo
        var sequenceLogo = gene.jaspar.sequenceLogo;
        $(".sequenceLogo").attr({ src : sequenceLogo });

        var frequencyMatrix = gene.jaspar.frequencyMatrix;
        var a = "";
        for (var i = 0; i < frequencyMatrix.A.length; i++) {
            a += "" + frequencyMatrix.A[i] + "	";
        }
        $(".frequencyOfA").append($(a));
        var c = "";
        for (var k = 0; k < frequencyMatrix.C.length; k++) {
            c += "" + frequencyMatrix.C[k] + "	";
        }
        $(".frequencyOfC").append($(c));
        var g = "";
        for (var j = 0; j < frequencyMatrix.G.length; j++) {
            g += "" + frequencyMatrix.G[j] + "	";
        }
        $(".frequencyOfG").append($(g));
        var t = "";
        for (var h = 0; h < frequencyMatrix.T.length; h++) {
            t += "" + frequencyMatrix.T[h] + "	";
        }
        $(".frequencyOfT").append($(t));
    });
})();
// All api calls and page design elements have been linked
<commit_msg>Found a small parsing error<commit_after>(function () {
    var search = location.search.substring(1);
    var obj = search ? JSON.parse("{\"" + search.replace(/&/g, "','").replace(/=/g, "\":\"") + "\"}",
      function ( key, value) {
          return key === "" ? value : decodeURIComponent(value);
      }) : {};

    document.title = "Information About " + obj.symbol;
    $("#gene-name").text(obj.symbol);
    // This is cite used to find the parsing:
    // https://stackoverflow.com/questions/8648892/convert-url-parameters-to-a-javascript-object

    var api = window.api;
    api.getGeneInformation(obj.symbol).done(function (gene) {

        var sgdHrefTemplate = "https://www.yeastgenome.org/locus/";
        var sgdId = gene.sgd.sgdID;
        $(".sgd-link").text(sgdId).attr({ href: sgdHrefTemplate + sgdId });

        var ncbiHrefTemplate = "https://www.ncbi.nlm.nih.gov/gene/";
        var ncbiId = gene.ncbi.ncbiID;
        $(".ncbi-link").text(ncbiId).attr({ href: ncbiHrefTemplate + ncbiId });

        var ensemblHrefTemplate = "https://www.ensembl.org/Saccharomyces_cerevisiae/Gene/" +
        "/Summary?db=core;g=YFL039C;r=VI:53260-54696;t=";
        var ensemblId = gene.ensembl.ensemblID;
        $(".ensembl-link").text(ensemblId).attr({ href: ensemblHrefTemplate + ensemblId });

        var uniprotHrefTemplate = "http://www.uniprot.org/uniprot/";
        var uniprotId = gene.uniprot.uniprotID;
        $(".uniprot-link").text(uniprotId).attr({ href: uniprotHrefTemplate + uniprotId });

        var jasparHrefTemplate = "http://jaspar.genereg.net/matrix/";
        var jasparId = gene.jaspar.jasparID;
        $(".jaspar-link").text(jasparId).attr({ href: jasparHrefTemplate + jasparId });
        // General Information Section

        var ensemblInfo = gene.ensembl.description;
        $(".ensemblDescription").text(ensemblInfo).attr({ href: ensemblHrefTemplate + ensemblInfo });

        var uniSpecies = gene.uniprot.species;
        $(".uniProtSpecies").text(uniSpecies).attr({ href: uniprotHrefTemplate + uniSpecies });

        var ncbiLocus = gene.ncbi.locusTag;
        $(".ncbiLocusTag").text(ncbiLocus).attr({ href: ncbiHrefTemplate + ncbiLocus });

        var jasparFam = gene.jaspar.family;
        $(".jasparFamily").text(jasparFam).attr({ href: jasparHrefTemplate + jasparFam });

        var ncbiChromosome = gene.ncbi.chromosomeSequence;
        $(".chromosomeSequence").text(ncbiChromosome).attr({ href: ncbiHrefTemplate + ncbiChromosome });

      // DNA Sequence Tab
        var ensemblDNA = gene.ensembl.dnaSequence;
        $(".dnaSequence").text(ensemblDNA).attr({ href: ensemblHrefTemplate + ensemblDNA });

      // Protein Information

        var uniprotProteinType = gene.uniprot.proteinType;
        $(".proteinType").text(uniprotProteinType).attr({ href: uniprotHrefTemplate + uniprotProteinType });

        var uniprotProteinSequence = gene.uniprot.proteinSequence;
        $(".proteinSequence").text(uniprotProteinSequence).attr({ href: uniprotHrefTemplate + uniprotProteinSequence });

      // Gene mapping
        var geneMap = gene.ensembl.geneMap;
        $(".geneMap").text(geneMap).attr({ href: ensemblHrefTemplate + geneMap });

      // Regulation Information
        var sgdRequlators = gene.sgd.regulators;
        $(".regulators").text(sgdRequlators).attr({ href: sgdHrefTemplate + sgdRequlators });
        $("1").appendTo(".regulators");

        var sgdTargets = gene.sgd.targets;
        $(".targets").text(sgdTargets).attr({ href: sgdHrefTemplate + sgdTargets });
        $("1").appendTo(".targets");

      // Interaction: Physical Reaction

        var sgdInteractions = gene.sgd.totalInteractions;
        $(".totalInteractions").text(sgdInteractions).attr({ href: sgdHrefTemplate + sgdInteractions });

        var sgdAffinityCaptureMS = gene.sgd.affinityCaptureMS;
        $(".affinityCaptureMS").text(sgdAffinityCaptureMS).attr({ href: sgdHrefTemplate + sgdAffinityCaptureMS });

        var sgdAffinityCaptureRNA = gene.sgd.affinityCaptureRNA;
        $(".affinityCaptureRNA").text(sgdAffinityCaptureRNA).attr({ href: sgdHrefTemplate + sgdAffinityCaptureRNA });

        var sgdAffinityCaptureWesterns = gene.sgd.affinityCaptureWestern;
        $(".affinityCaptureWestern").text(sgdAffinityCaptureWesterns).attr(
            { href: sgdHrefTemplate + sgdAffinityCaptureWesterns });

        var sgdBiochemicalActivity = gene.sgd.biochemicalActivity;
        $(".biochemicalActivity").text(sgdBiochemicalActivity).attr({ href: sgdHrefTemplate + sgdBiochemicalActivity });

        var sgdColocalization = gene.sgd.colocalization;
        $(".colocalization").text(sgdColocalization).attr({ href: sgdHrefTemplate + sgdColocalization });

        var sgdReconstitutedComplex = gene.sgd.reconstitutedComplex;
        $(".reconstitutedComplex").text(sgdReconstitutedComplex).attr(
            { href: sgdHrefTemplate + sgdReconstitutedComplex });

        var sgdTwoHybrid = gene.sgd.twoHybrid;
        $(".twoHybrid").text(sgdTwoHybrid).attr({ href: sgdHrefTemplate + sgdTwoHybrid });

      // Genetic Interactions

        var sgdDosage = gene.sgd.dosageRescue;
        $(".dosageRescue").text(sgdDosage).attr({ href: sgdHrefTemplate + sgdDosage });

        var sgdNegGen = gene.sgd.negativeGenetic;
        $(".negativeGenetic").text(sgdNegGen).attr({ href: sgdHrefTemplate + sgdNegGen });

        var sgdEnhance = gene.sgd.phenotypicEnhancement;
        $(".phenotypicEnhancement").text(sgdEnhance).attr({ href: sgdHrefTemplate + sgdEnhance });

        var sgdSuppress = gene.sgd.phenotypicSuppression;
        $(".phenotypicSuppression").text(sgdSuppress).attr({ href: sgdHrefTemplate + sgdSuppress });

        var sgdGrowthDefect = gene.sgd.syntheticGrowthDefect;
        $(".syntheticGrowthDefect").text(sgdGrowthDefect).attr({ href: sgdHrefTemplate + sgdGrowthDefect });

        var sgdHaploin = gene.sgd.syntheticHaploinsufficiency;
        $(".syntheticHaploinsufficiency").text(sgdHaploin).attr({ href: sgdHrefTemplate + sgdHaploin });

        var sgdLethality = gene.sgd.syntheticLethality;
        $(".syntheticLethality").text(sgdLethality).attr({ href: sgdHrefTemplate + sgdLethality });

        var sgdRescue = gene.sgd.sgdRescue;
        $(".syntheticRescue").text(sgdRescue).attr({ href: sgdHrefTemplate + sgdRescue });

      // Gene Ontology
        var sgdSummary = gene.sgd.geneOntologySummary;
        $(".geneSummary").text(sgdSummary).attr({ href: sgdHrefTemplate + sgdSummary });

        var sgdMolecularFunction = gene.sgd.molecularFunction;
        $(".molecularFunction").text(sgdMolecularFunction).attr({ href: sgdHrefTemplate + sgdMolecularFunction });

        var sgdBiologicalProcess = gene.sgd.biologicalProcess;
        $(".biologicalProcess").text(sgdBiologicalProcess).attr({ href: sgdHrefTemplate + sgdBiologicalProcess });

        var sgdCellularComponent = gene.sgd.cellularComponent;
        $(".cellularComponent").text(sgdCellularComponent).attr({ href: sgdHrefTemplate + sgdCellularComponent });

        $("#sgdSource").text("Saccharomycese Genome Database");
        $("1").appendTo(".sgdSource");
        $("#uniprotSource").text("UniProt");
        $("2").appendTo(".uniprotSource");
        $("#ensemblSource").text("Ensembl");
        $("3").appendTo(".ensemblSource");
        $("#ncbiSource").text("NCBI Database");
        $("4").appendTo(".ncbiSource");
        $("#jasparSource").text("Jaspar Database");
        $("5").appendTo(".jasparSource");

        // Fequency Matrix and Sequence Logo
        var sequenceLogo = gene.jaspar.sequenceLogo;
        $(".sequenceLogo").attr({ src : sequenceLogo });

        var frequencyMatrix = gene.jaspar.frequencyMatrix;
        var a = "";
        for (var i = 0; i < frequencyMatrix.A.length; i++) {
            a += "" + frequencyMatrix.A[i] + "	";
        }
        $(".frequencyOfA").append($(a));
        var c = "";
        for (var k = 0; k < frequencyMatrix.C.length; k++) {
            c += "" + frequencyMatrix.C[k] + "	";
        }
        $(".frequencyOfC").append($(c));
        var g = "";
        for (var j = 0; j < frequencyMatrix.G.length; j++) {
            g += "" + frequencyMatrix.G[j] + "	";
        }
        $(".frequencyOfG").append($(g));
        var t = "";
        for (var h = 0; h < frequencyMatrix.T.length; h++) {
            t += "" + frequencyMatrix.T[h] + "	";
        }
        $(".frequencyOfT").append($(t));
    });
})();
// All api calls and page design elements have been linked
<|endoftext|>


<commit_before>// ==UserScript==
// @name        WaniKani Denial Mode
// @version     1.0
// @author Niklas Barsk
// @description Make the dashboard look like you're level 50 and have burnt everything.
// @include     https://www.wanikani.com/*
// @exclude     https://www.wanikani.com/review/*
// @exclude     https://www.wanikani.com/lesson/*
// @run-at      document-end
// @copyright   2015, Niklas Barsk
// ==/UserScript==

var level = document.getElementsByClassName("dropdown-toggle")[0].children[0];
var lessons = document.getElementsByClassName("lessons")[0].getElementsByTagName("span")[0];
var reviews = document.getElementsByClassName("reviews")[0].getElementsByTagName("span")[0];
make(level,  "50");
make(lessons, "0");
make(reviews, "0");

if (isDashboard()) {
    var reviewStatus = document.getElementsByClassName("review-status")[0];
    var nextHour = reviewStatus.getElementsByClassName("one-hour")[0].children[0];
    var oneDay = reviewStatus.getElementsByClassName("one-day")[0].children[0];
    var nextReview = reviewStatus.getElementsByTagName("time")[0];
    make(nextHour, "0");
    make(oneDay, "0");
    make(nextReview, "∞");

    fixSRSLevels("apprentice");
    fixSRSLevels("guru");
    fixSRSLevels("master");
    fixSRSLevels("enlightened");
    fixSRSLevels("burned");

    fixProgression();
}

function make(elem, what) {
	elem.innerHTML = what;
}

function fixSRSLevels(which) {
	var levelElement = document.getElementById(which);
	var data = levelElement.getAttribute("data-content");
    var fixedData = replaceInDataContent(which, data);
	levelElement.setAttribute("data-content", fixedData);

    var numberHolder = levelElement.children[0];
	if (which == "burned") {
        // 453 radicals
        // 1680 kanji
        // 5146 vocabulary
        make(numberHolder, "7279");
	}
    else {
        make(numberHolder, "0");
    }
}

function fixProgression() {
    var progression = document.getElementsByClassName("progression")[0];
    var radicalProgressTitle = progression.getElementsByTagName("h3")[0];
    var kanjiProgressTitle = progression.getElementsByTagName("h3")[1];
    replaceInProgressString(radicalProgressTitle);
    replaceInProgressString(kanjiProgressTitle);

    var radicalProgressBar = document.getElementsByClassName("bar")[0];
    radicalProgressBar.setAttribute("style", "width: 100%;");
    var kanjiProgressBar = document.getElementsByClassName("bar")[1];
    kanjiProgressBar.setAttribute("style", "width: 100%;");

    var radicalProgressBarLabel = radicalProgressBar.getElementsByTagName("b")[0]
    var kanjiProgressBarLabel = kanjiProgressBar.getElementsByTagName("b")[0]
    make(radicalProgressBarLabel, "100%");
    make(kanjiProgressBarLabel, "100%");

    var radicalTotal = document.getElementsByClassName("pull-right total")[0];
    var kanjiTotal = document.getElementsByClassName("pull-right total")[1];
    make(radicalTotal, "3"); // total radials for level 50
    make(kanjiTotal, "35"); // total kanji for level 50
}

function replaceInProgressString(which) {
	var splitString = which.innerHTML.split(/([0-9]+)/); //split on each number
    var newString = "";
    for (i = 0; i < splitString.length; i++) {
        if (isNaN(splitString[i])) {
            newString += splitString[i]; // not a number, just use it as it is
        }
        else {
        	newString += "50";
        }
    }
    make(which, newString);
}

function replaceInDataContent(which, data) {
    var splitString = data.split(/([0-9]+)/); //split on each number
    var newData = "";
    var burnCounter = 0;
    var burnCounts = ["453", "1680", "5146"];
    for (i = 0; i < splitString.length; i++) {
        if (isNaN(splitString[i])) {
            newData += splitString[i]; // not a number, just use it as it is
        }
        else if (which == "burned") {
            newData += burnCounts[burnCounter++];
        }
        else {
        	newData += "0";
        }
    }
    return newData;
}

function isDashboard() {
    return document.URL.indexOf("dashboard") != -1;
}
<commit_msg>Add update url to Denial Mode script.<commit_after>// ==UserScript==
// @name        WaniKani Denial Mode
// @version     1.0
// @author Niklas Barsk
// @description Make the dashboard look like you're level 50 and have burnt everything.
// @include     https://www.wanikani.com/*
// @exclude     https://www.wanikani.com/review/*
// @exclude     https://www.wanikani.com/lesson/*
// @updateURL   https://github.com/nibarius/wk-userscripts/raw/master/wk-denial-mode.user.js
// @run-at      document-end
// @copyright   2015, Niklas Barsk
// ==/UserScript==

var level = document.getElementsByClassName("dropdown-toggle")[0].children[0];
var lessons = document.getElementsByClassName("lessons")[0].getElementsByTagName("span")[0];
var reviews = document.getElementsByClassName("reviews")[0].getElementsByTagName("span")[0];
make(level,  "50");
make(lessons, "0");
make(reviews, "0");

if (isDashboard()) {
    var reviewStatus = document.getElementsByClassName("review-status")[0];
    var nextHour = reviewStatus.getElementsByClassName("one-hour")[0].children[0];
    var oneDay = reviewStatus.getElementsByClassName("one-day")[0].children[0];
    var nextReview = reviewStatus.getElementsByTagName("time")[0];
    make(nextHour, "0");
    make(oneDay, "0");
    make(nextReview, "∞");

    fixSRSLevels("apprentice");
    fixSRSLevels("guru");
    fixSRSLevels("master");
    fixSRSLevels("enlightened");
    fixSRSLevels("burned");

    fixProgression();
}

function make(elem, what) {
	elem.innerHTML = what;
}

function fixSRSLevels(which) {
	var levelElement = document.getElementById(which);
	var data = levelElement.getAttribute("data-content");
    var fixedData = replaceInDataContent(which, data);
	levelElement.setAttribute("data-content", fixedData);

    var numberHolder = levelElement.children[0];
	if (which == "burned") {
        // 453 radicals
        // 1680 kanji
        // 5146 vocabulary
        make(numberHolder, "7279");
	}
    else {
        make(numberHolder, "0");
    }
}

function fixProgression() {
    var progression = document.getElementsByClassName("progression")[0];
    var radicalProgressTitle = progression.getElementsByTagName("h3")[0];
    var kanjiProgressTitle = progression.getElementsByTagName("h3")[1];
    replaceInProgressString(radicalProgressTitle);
    replaceInProgressString(kanjiProgressTitle);

    var radicalProgressBar = document.getElementsByClassName("bar")[0];
    radicalProgressBar.setAttribute("style", "width: 100%;");
    var kanjiProgressBar = document.getElementsByClassName("bar")[1];
    kanjiProgressBar.setAttribute("style", "width: 100%;");

    var radicalProgressBarLabel = radicalProgressBar.getElementsByTagName("b")[0]
    var kanjiProgressBarLabel = kanjiProgressBar.getElementsByTagName("b")[0]
    make(radicalProgressBarLabel, "100%");
    make(kanjiProgressBarLabel, "100%");

    var radicalTotal = document.getElementsByClassName("pull-right total")[0];
    var kanjiTotal = document.getElementsByClassName("pull-right total")[1];
    make(radicalTotal, "3"); // total radials for level 50
    make(kanjiTotal, "35"); // total kanji for level 50
}

function replaceInProgressString(which) {
	var splitString = which.innerHTML.split(/([0-9]+)/); //split on each number
    var newString = "";
    for (i = 0; i < splitString.length; i++) {
        if (isNaN(splitString[i])) {
            newString += splitString[i]; // not a number, just use it as it is
        }
        else {
        	newString += "50";
        }
    }
    make(which, newString);
}

function replaceInDataContent(which, data) {
    var splitString = data.split(/([0-9]+)/); //split on each number
    var newData = "";
    var burnCounter = 0;
    var burnCounts = ["453", "1680", "5146"];
    for (i = 0; i < splitString.length; i++) {
        if (isNaN(splitString[i])) {
            newData += splitString[i]; // not a number, just use it as it is
        }
        else if (which == "burned") {
            newData += burnCounts[burnCounter++];
        }
        else {
        	newData += "0";
        }
    }
    return newData;
}

function isDashboard() {
    return document.URL.indexOf("dashboard") != -1;
}
<|endoftext|>


<commit_before>import { LD, Wall, SpritePlayer, SpriteEnemy } from "SpriteConstants";
import { CameraVelocity, Bounds, FlashColor, FlashDuration } from "Constants";

import Player from "objects/Character";
import Room from "objects/Room";
import Enemy from "objects/Enemy";

const needCamera = false;

class MainMenu extends Phaser.State {

  create() {
    this.game.world.setBounds(0, 0, Bounds, Bounds);
    this.game.add.sprite(50,100, LD);
    this.room = new Room(this.game);
    this.game.add.existing(this.room);

    this.hero = new Player(this.game,150,100);
    this.game.add.existing(this.hero);

    this.enemy = new Enemy(this.game,300,100);
    this.game.add.existing(this.enemy);

    if(needCamera) {
      this.cursors = this.game.input.keyboard.createCursorKeys();
    }
    //this.room.createRandomLine(32, 128, 32 + 9 * 32, 128, 3);
    //this.room.createLine(20, 400, 400, 400);
    this.camera.follow(this.hero);
    this.room.createRandomSquare(32,0,18,1, +2, 1 );
  }

  update() {
    this.game.physics.arcade.collide(this.hero, this.room);
    this.game.physics.arcade.overlap(this.hero, this.enemy, this.damage, null, this);
    if(!this.game.physics.arcade.collide(this.enemy, this.room, this.pushBlock)) {
    } // else if pushblocks function
    if(this.hero.body.position) this.enemy.follow(this.hero.body.position);
  }

  damage() {
    this.hero.damage();
    this.camera.flash(FlashColor, FlashDuration);
  }

  //temp
  pushBlock(sprite1, sprite2) {
    sprite2.body.velocity.x += 1;
    sprite1.body.velocity.x = 100;
  }

  moveCamera() {
    if(needCamera) {
      if (this.cursors.up.isDown)
      {
        this.game.camera.y -= CameraVelocity;
      }
      else if (this.cursors.down.isDown)
      {
        this.game.camera.y += CameraVelocity;
      }

      if (this.cursors.left.isDown)
      {
        this.game.camera.x -= CameraVelocity;
      }
      else if (this.cursors.right.isDown)
      {
        this.game.camera.x += CameraVelocity;
      }
    }
  }

  preload() {
    this.game.load.image(LD, "res/LD.png");
    this.game.load.image(Wall, "res/1.png");
    this.game.load.image(SpritePlayer, "res/player.png");
    this.game.load.image(SpriteEnemy, "res/enemy.png");
  }

  render() {
     //this.game.debug.spriteInfo(this.hero, 32, 32);
  }

}

export default MainMenu;
<commit_msg>add bullet sprite + remove fx during programmation<commit_after>import { LD, Wall, SpritePlayer, SpriteEnemy, SpriteBullet } from "SpriteConstants";
import { CameraVelocity, Bounds, FlashColor, FlashDuration } from "Constants";

import Player from "objects/Character";
import Room from "objects/Room";
import Enemy from "objects/Enemy";

const needCamera = false;

class MainMenu extends Phaser.State {

  create() {
    this.game.world.setBounds(0, 0, Bounds, Bounds);
    this.game.add.sprite(50,100, LD);
    this.room = new Room(this.game);
    this.game.add.existing(this.room);

    this.hero = new Player(this.game,150,100);
    this.game.add.existing(this.hero);

    this.enemy = new Enemy(this.game,300,100);
    this.game.add.existing(this.enemy);

    if(needCamera) {
      this.cursors = this.game.input.keyboard.createCursorKeys();
    }
    //this.room.createRandomLine(32, 128, 32 + 9 * 32, 128, 3);
    //this.room.createLine(20, 400, 400, 400);
    this.camera.follow(this.hero);
    this.room.createRandomSquare(32,0,18,1, +2, 1 );
  }

  update() {
    this.game.physics.arcade.collide(this.hero, this.room);
    this.game.physics.arcade.overlap(this.hero, this.enemy, /*this.damage*/null, null, this);
    if(!this.game.physics.arcade.collide(this.enemy, this.room, this.pushBlock)) {
    } // else if pushblocks function
    if(this.hero.body.position) this.enemy.follow(this.hero.body.position);
  }

  damage() {
    this.hero.damage();
    this.camera.flash(FlashColor, FlashDuration);
  }

  //temp
  pushBlock(sprite1, sprite2) {
    sprite2.body.velocity.x += 1;
    sprite1.body.velocity.x = 100;
  }

  moveCamera() {
    if(needCamera) {
      if (this.cursors.up.isDown)
      {
        this.game.camera.y -= CameraVelocity;
      }
      else if (this.cursors.down.isDown)
      {
        this.game.camera.y += CameraVelocity;
      }

      if (this.cursors.left.isDown)
      {
        this.game.camera.x -= CameraVelocity;
      }
      else if (this.cursors.right.isDown)
      {
        this.game.camera.x += CameraVelocity;
      }
    }
  }

  preload() {
    this.game.load.image(LD, "res/LD.png");
    this.game.load.image(Wall, "res/1.png");
    this.game.load.image(SpritePlayer, "res/player.png");
    this.game.load.image(SpriteEnemy, "res/enemy.png");
    this.game.load.image(SpriteBullet, "res/bullet.png");
  }

  render() {
     //this.game.debug.spriteInfo(this.hero, 32, 32);
  }

}

export default MainMenu;
<|endoftext|>


<commit_before>//By Kevin Le - http://stackoverflow.com/users/1244013/khnle

angular.module('ui.bootstrap.progresscircle', [])

.constant('progressConfig', {
  elementWidth: 400,
  elementHeight: 400,
  outerCircleWidth: 20,
  innerCircleWidth: 5,
  outerCircleRadius: 100,
  innerCircleRadius: 70,
  labelFont: '30pt Calibri',
  outerCircleBackgroundColor: '#d9d9d9', //#505769',
  outerCircleForegroundColor: '#428bca', //#5cb85c',
  innerCircleColor: '#d9d9d9',
  labelColor: '#428bca', //'#12eeb9'
  percentFormat: false,
  displayPercentSign: true,
  max: 60,
  displayMax: true
})

.controller('ProgressCircleController', ['$scope', '$attrs', '$timeout', 'progressConfig', function($scope, $attrs, $timeout, progressConfig) {

}])

.directive('progressCircle', ['$parse', 'progressConfig', function(parse, progressConfig) {
  return {
    restrict: 'EA',
    replace: true,
    transclude: true,
    controller: 'ProgressCircleController',
    link: function(s, e, a, progressCtrl) {

      var width = parse(a.elementWidth)(s) || progressConfig.elementWidth,
          height = parse(a.elementHeight)(s) || progressConfig.elementHeight,
          outerCircleWidth = parse(a.outerCircleWidth)(s) || progressConfig.outerCircleWidth,
          innerCircleWidth = parse(a.innerCircleWidth)(s) || progressConfig.innerCircleWidth,
          outerCircleBackgroundColor = parse(a.outerCircleBackgroundColor)(s) || progressConfig.outerCircleBackgroundColor,
          outerCircleForegroundColor = parse(a.outerCircleForegroundColor)(s) || progressConfig.outerCircleForegroundColor,
          innerCircleColor = parse(a.innerCircleColor)(s) || progressConfig.innerCircleColor,
          labelColor = parse(a.labelColor)(s) || progressConfig.labelColor,
          outerCircleRadius = parse(a.outerCircleRadius)(s) || progressConfig.outerCircleRadius,
          innerCircleRadius = parse(a.innerCircleRadius)(s) || progressConfig.innerCircleRadius,
          labelFont = parse(a.labelFont)(s) || progressConfig.labelFont,
          percentFormat = parse(a.percentFormat)(s) || progressConfig.percentFormat,
          displayPercentSign = parse(a.displayPercentSign)(s) || progressConfig.displayPercentSign,
          max = parse(a.max)(s) || progressConfig.max,
          displayMax = parse(a.displayMax)(s) || progressConfig.displayMax;

      var canvas = angular.element('<canvas>').attr({'width': width, 'height': height});

      e.replaceWith(canvas);

      s.$watch(a.progressCircleModel, function(newValue) {
        // Create the content of the canvas
        var ctx = canvas[0].getContext('2d');
        ctx.clearRect(0, 0, width, height);

        // The "background" circle
        var x = width / 2;
        var y = height / 2;
        ctx.beginPath();
        ctx.arc(x, y, outerCircleRadius, 0, Math.PI * 2, false);
        ctx.lineWidth = outerCircleWidth;
        ctx.strokeStyle = outerCircleBackgroundColor;
        ctx.stroke();

        // The inner circle
        ctx.beginPath();
        ctx.arc(x, y, innerCircleRadius, 0, Math.PI * 2, false);
        ctx.lineWidth = innerCircleWidth;
        ctx.strokeStyle = innerCircleColor;
        ctx.stroke();

        // The inner number
        ctx.font = labelFont;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillStyle = labelColor;
        if (percentFormat) {
          if (displayPercentSign) {
            ctx.fillText(newValue.value + ' %', x, y);
          } else {
            ctx.fillText(newValue.value, x, y);
          }
        } else {
          if (displayMax) {
            ctx.fillText(newValue.value + '/' + max, x, y);
          } else {
            ctx.fillText(newValue.value, x, y);
          }
        }

        // The "foreground" circle
        var startAngle = - (Math.PI / 2);
        var endAngle = percentFormat ? ((Math.PI * 2 ) * (newValue.value/100)) - (Math.PI / 2):
          ((Math.PI * 2 ) * (newValue.value/max)) - (Math.PI / 2);
        var anticlockwise = false;
        ctx.beginPath();
        ctx.arc(x, y, outerCircleRadius, startAngle, endAngle, anticlockwise);
        ctx.lineWidth = outerCircleWidth;
        ctx.strokeStyle = outerCircleForegroundColor;
        ctx.stroke();
      }, true);
    }
  };
}]);

  <commit_msg>add version, tidy up<commit_after>//By Kevin Le - http://stackoverflow.com/users/1244013/khnle
//v1.0

angular.module('ui.bootstrap.progresscircle', [])

.constant('progressConfig', {
  elementWidth: 400,
  elementHeight: 400,
  outerCircleWidth: 20,
  innerCircleWidth: 5,
  outerCircleRadius: 100,
  innerCircleRadius: 70,
  labelFont: '30pt Calibri',
  outerCircleBackgroundColor: '#d9d9d9',
  outerCircleForegroundColor: '#428bca',
  innerCircleColor: '#d9d9d9',
  labelColor: '#428bca',
  percentFormat: false,
  displayPercentSign: true,
  max: 60,
  displayMax: true
})

.controller('ProgressCircleController', ['$scope', '$attrs', '$timeout', 'progressConfig', function($scope, $attrs, $timeout, progressConfig) {
//just a place holder for now
}])

.directive('progressCircle', ['$parse', 'progressConfig', function(parse, progressConfig) {
  return {
    restrict: 'EA',
    replace: true,
    transclude: true,
    controller: 'ProgressCircleController',
    link: function(s, e, a, progressCtrl) {

      var width = parse(a.elementWidth)(s) || progressConfig.elementWidth,
          height = parse(a.elementHeight)(s) || progressConfig.elementHeight,
          outerCircleWidth = parse(a.outerCircleWidth)(s) || progressConfig.outerCircleWidth,
          innerCircleWidth = parse(a.innerCircleWidth)(s) || progressConfig.innerCircleWidth,
          outerCircleBackgroundColor = parse(a.outerCircleBackgroundColor)(s) || progressConfig.outerCircleBackgroundColor,
          outerCircleForegroundColor = parse(a.outerCircleForegroundColor)(s) || progressConfig.outerCircleForegroundColor,
          innerCircleColor = parse(a.innerCircleColor)(s) || progressConfig.innerCircleColor,
          labelColor = parse(a.labelColor)(s) || progressConfig.labelColor,
          outerCircleRadius = parse(a.outerCircleRadius)(s) || progressConfig.outerCircleRadius,
          innerCircleRadius = parse(a.innerCircleRadius)(s) || progressConfig.innerCircleRadius,
          labelFont = parse(a.labelFont)(s) || progressConfig.labelFont,
          percentFormat = parse(a.percentFormat)(s) || progressConfig.percentFormat,
          displayPercentSign = parse(a.displayPercentSign)(s) || progressConfig.displayPercentSign,
          max = parse(a.max)(s) || progressConfig.max,
          displayMax = parse(a.displayMax)(s) || progressConfig.displayMax;

      var canvas = angular.element('<canvas>').attr({'width': width, 'height': height});

      e.replaceWith(canvas);

      s.$watch(a.progressCircleModel, function(newValue) {
        // Create the content of the canvas
        var ctx = canvas[0].getContext('2d');
        ctx.clearRect(0, 0, width, height);

        // The "background" circle
        var x = width / 2;
        var y = height / 2;
        ctx.beginPath();
        ctx.arc(x, y, outerCircleRadius, 0, Math.PI * 2, false);
        ctx.lineWidth = outerCircleWidth;
        ctx.strokeStyle = outerCircleBackgroundColor;
        ctx.stroke();

        // The inner circle
        ctx.beginPath();
        ctx.arc(x, y, innerCircleRadius, 0, Math.PI * 2, false);
        ctx.lineWidth = innerCircleWidth;
        ctx.strokeStyle = innerCircleColor;
        ctx.stroke();

        // The inner number
        ctx.font = labelFont;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillStyle = labelColor;
        if (percentFormat) {
          if (displayPercentSign) {
            ctx.fillText(newValue.value + ' %', x, y);
          } else {
            ctx.fillText(newValue.value, x, y);
          }
        } else {
          if (displayMax) {
            ctx.fillText(newValue.value + '/' + max, x, y);
          } else {
            ctx.fillText(newValue.value, x, y);
          }
        }

        // The "foreground" circle
        var startAngle = - (Math.PI / 2);
        var endAngle = percentFormat ? ((Math.PI * 2 ) * (newValue.value/100)) - (Math.PI / 2):
          ((Math.PI * 2 ) * (newValue.value/max)) - (Math.PI / 2);
        var anticlockwise = false;
        ctx.beginPath();
        ctx.arc(x, y, outerCircleRadius, startAngle, endAngle, anticlockwise);
        ctx.lineWidth = outerCircleWidth;
        ctx.strokeStyle = outerCircleForegroundColor;
        ctx.stroke();
      }, true);
    }
  };
}]);

<|endoftext|>


<commit_before>import _ from 'lodash';
import * as types from '../constants/actionTypes';

const INITIAL_STATE = { all: {}, showId: null};

export default function(state = INITIAL_STATE, action) {
  switch(action.type) {
    case types.FETCH_HOUSEHOLDS:
      // Object-based storage with household id as key
      const newHouseholds = _.mapKeys(action.households, 'id');
      return {
        ...state,
        all: { ...state.all, ...newHouseholds}
      };
    case types.FETCH_HOUSEHOLD:
      // Add household to list or replace an existing one
      return {
        ...state,
        all: { ...state.all, [action.household.id]: action.household },
        showId: action.household.id
      };
    case types.CREATE_HOUSEHOLD:
      // Add a new household to the list
      console.log(action);
      return {
        ...state,
        all: { ...state.all, [action.household.id]: action.household }
      };
    case types.DELETE_HOUSEHOLD:
      // action.payload === id of household to delete
      return {
        ...state,
        all: _.omit(state.all, action.householdId)
      };
    default:
      return state;
  }
}
<commit_msg>Removed console.log<commit_after>import _ from 'lodash';
import * as types from '../constants/actionTypes';

const INITIAL_STATE = { all: {}, showId: null};

export default function(state = INITIAL_STATE, action) {
  switch(action.type) {
    case types.FETCH_HOUSEHOLDS:
      // Object-based storage with household id as key
      const newHouseholds = _.mapKeys(action.households, 'id');
      return {
        ...state,
        all: { ...state.all, ...newHouseholds}
      };
    case types.FETCH_HOUSEHOLD:
      // Add household to list or replace an existing one
      return {
        ...state,
        all: { ...state.all, [action.household.id]: action.household },
        showId: action.household.id
      };
    case types.CREATE_HOUSEHOLD:
      // Add a new household to the list
      return {
        ...state,
        all: { ...state.all, [action.household.id]: action.household }
      };
    case types.DELETE_HOUSEHOLD:
      // action.payload === id of household to delete
      return {
        ...state,
        all: _.omit(state.all, action.householdId)
      };
    default:
      return state;
  }
}
<|endoftext|>


<commit_before>/**
 * =================
 * MODULE - Sunspot
 * =================
 * Driver to handle Sunspot
 */

/**
 * add
 * ====
 * Add the sensor to the system.
 * Parameters:
 *	- customId (String):		Custom ID of the new device for the driver
 *	- cb (Function(error)):		Callback with an error or *null* as parameter
 */
function add(customId, cb) {
	// TO DO
	cb(null);
}

/**
 * update
 * ====
 * Change the custom ID of the device.
 * Parameters:
 *	- prevCustomId (String):	Previous ID
 *	- newCustomId (String):		New ID
 *	- cb (Function(error)):		Callback with an error or *null* as parameter
 */
function update(prevCustomId, newCustomId, cb) {
	// TO DO
	cb(null);
}

/**
 * remove
 * ====
 * Remove a device.
 * Parameters:
 *	- customId (String):		ID
 *	- cb (Function(error)):		Callback with an error or *null* as parameter
 */
function remove(customId, cb) {
	// TO DO
	cb(null);
}

exports.add = add;
exports.update = update;
exports.remove = remove;
<commit_msg>SunSPOT drivers: Add and Remove implemented<commit_after>/**
 * =================
 * MODULE - Sunspot
 * =================
 * Driver to handle Sunspot
 */

var baseStationAddr;
var serverPublicDNS;
var sunspots = new Array();
var numSunSpots = 0;

/**
 * add
 * ====
 * Add the sensor to the system.
 * Parameters:
 *	- customId (String):		Custom ID of the new device for the driver
 *  - baseStationUrl (String):  Direction of the machine where the base station app is running
 *  - serverUrl (String):       Direction of the machine where the main server is running
 *	- cb (Function(error)):		Callback with an error or *null* as parameter
 */
function add(customId, baseStationUrl, serverUrl, cb) {

	if(a.indexOf(customId) < 0){
		baseStationAddr = baseStationUrl;
		serverPublicDNS = serverUrl;
		var options = {
				host : baseStationUrl,
				port: 8000,
				path : '/register/sensor/?status=registered&url=http://'+serverUrl+':8080/measures&port=8080',
				method : 'GET'
			}
		var data;
		var request = http.request(options, function(response){

			console.log("Connecting to http://" + baseStationUrl +"/register/sensor?status=registered&url=http://"+serverUrl+":8080/measures&port=8080");

			response.on('data', function(chunk){
			});

			response.on('end', function(){
				a.splice(numSunSpots, 1, customId);
				numSunSpots++;

			});

			request.on('error', function(e) {
			   cb('Problem with request: ' + e.message);
		    });
		});
		request.end();
	}else{
		cb('SunSPOT already installed');
	}

}

/**
 * update
 * ====
 * Change the custom ID of the device.
 * Parameters:
 *	- prevCustomId (String):	Previous ID
 *	- newCustomId (String):		New ID
 *	- cb (Function(error)):		Callback with an error or *null* as parameter
 */
function update(prevCustomId, newCustomId, cb) {
	// TO DO
	cb(null);
}

/**
 * remove
 * ====
 * Remove a device.
 * Parameters:
 *	- customId (String):		ID
 *	- cb (Function(error)):		Callback with an error or *null* as parameter
 */
function remove(customId, cb) {
	if(sunspots.indexOf(customId)>=0){
		var options = {
			host : baseStationAddr,
			port: 8000,
			path : '/unregister/sensor/?status=unregistered',
			method : 'GET'
		}
		var data;
		var request = http.request(options, function(response){

			response.on('data', function(chunk){
			});

			response.on('end', function(){
				a.splice(indexOf(customId), 1);
				numSunSpots--;

			});

			request.on('error', function(e) {
			   cb('Problem with request: ' + e.message);
		    });
		});
		request.end();
	}else{
		cb('SunSPOT not registered. It is not possible to delete it');
	}
}

exports.add = add;
exports.update = update;
exports.remove = remove;
<|endoftext|>


<commit_before>var ls = ls || {};

ls.photoset =( function ($) {

	this.idLast=0;
	this.isLoading=false;
	this.swfu;

	this.initSwfUpload = function(opt) {
		opt=opt || {};
		opt.button_placeholder_id = 'photoset-start-upload';
		opt.post_params.ls_photoset_target_tmp = $.cookie('ls_photoset_target_tmp') ? $.cookie('ls_photoset_target_tmp') : 0;

		$(ls.swfupload).unbind('load').bind('load',function() {
			this.swfu = ls.swfupload.init(opt);

			$(this.swfu).bind('eUploadProgress',this.swfHandlerUploadProgress);
			$(this.swfu).bind('eFileDialogComplete',this.swfHandlerFileDialogComplete);
			$(this.swfu).bind('eUploadSuccess',this.swfHandlerUploadSuccess);
			$(this.swfu).bind('eUploadComplete',this.swfHandlerUploadComplete);
		}.bind(this));

		ls.swfupload.loadSwf();
	}

	this.swfHandlerUploadProgress = function(e, file, bytesLoaded, percent) {
		$('#photoset_photo_empty_progress').text(file.name+': '+( percent==100 ? 'resize..' : percent +'%'));
	}

	this.swfHandlerFileDialogComplete = function(e, numFilesSelected, numFilesQueued) {
		if (numFilesQueued>0) {
			ls.photoset.addPhotoEmpty();
		}
	}

	this.swfHandlerUploadSuccess = function(e, file, serverData) {
		ls.photoset.addPhoto(jQuery.parseJSON(serverData));
	}

	this.swfHandlerUploadComplete = function(e, file, next) {
		if (next>0) {
			ls.photoset.addPhotoEmpty();
		}
	}

	this.addPhotoEmpty = function() {
		template = '
'
					+'

';
		$('#swfu_images').append(template);
	}

	this.addPhoto = function(response) {
		$('#photoset_photo_empty').remove();
		if (!response.bStateError) {
			template = '
'
						+'<textarea onBlur="ls.photoset.setPreviewDescription('+response.id+', this.value)"></textarea>
'
						+''+ls.lang.get('topic_photoset_photo_delete')+''
						+''+ls.lang.get('topic_photoset_mark_as_preview')+'
';
			$('#swfu_images').append(template);
			ls.msg.notice(response.sMsgTitle,response.sMsg);
		} else {
			ls.msg.error(response.sMsgTitle,response.sMsg);
		}
		ls.photoset.closeForm();
	}

	this.deletePhoto = function(id)
	{
		if (!confirm(ls.lang.get('topic_photoset_photo_delete_confirm'))) {return;}
		ls.ajax(aRouter['content']+'photo/delete', {'id':id}, function(response){
			if (!response.bStateError) {
				$('#photo_'+id).remove();
				ls.msg.notice(response.sMsgTitle,response.sMsg);
			} else {
				ls.msg.error(response.sMsgTitle,response.sMsg);
			}
		});
	}

	this.setPreview =function(id)
	{
		$('#topic_main_photo').val(id);

		$('.marked-as-preview').each(function (index, el) {
			$(el).removeClass('marked-as-preview');
			tmpId = $(el).attr('id').slice($(el).attr('id').lastIndexOf('_')+1);
			$('#photo_preview_state_'+tmpId).html(''+ls.lang.get('topic_photoset_mark_as_preview')+'');
		});
		$('#photo_'+id).addClass('marked-as-preview');
		$('#photo_preview_state_'+id).html(ls.lang.get('topic_photoset_is_preview'));
	}

	this.setPreviewDescription = function(id, text)
	{
		ls.ajax(aRouter['content']+'setimagedescription', {'id':id, 'text':text},  function(result){
			if (!result.bStateError) {

			} else {
				ls.msg.error('Error','Please try again later');
			}
		}
		)
	}

	this.getMore = function(topic_id)
	{
		if (this.isLoading) return;
		this.isLoading=true;

		ls.ajax(aRouter['content']+'getmore', {'topic_id':topic_id, 'last_id':this.idLast}, function(result){
			this.isLoading=false;
			if (!result.bStateError) {
				if (result.photos) {
					$.each(result.photos, function(index, photo) {
						var image = '

';
						$('#topic-photo-images').append(image);
						this.idLast=photo.id;
						$('.photoset-image').unbind('click');
						$('.photoset-image').prettyPhoto({
							social_tools:'',
							show_title: false,
							slideshow:false,
							deeplinking: false
						});
					}.bind(this));
				}
				if (!result.bHaveNext || !result.photos) {
					$('#topic-photo-more').remove();
				}
			} else {
				ls.msg.error('Error','Please try again later');
			}
		}.bind(this));
	}

	this.upload = function()
	{
		ls.photoset.addPhotoEmpty();
		ls.ajaxSubmit(aRouter['content']+'upload/',$('#photoset-upload-form'),function(data){
			if (data.bStateError) {
				$('#photoset_photo_empty').remove();
				ls.msg.error(data.sMsgTitle,data.sMsg);
			} else {
				ls.photoset.addPhoto(data);
			}
		});
		ls.photoset.closeForm();
	}

	this.closeForm = function()
	{
		$('#photoset-upload-form').jqmHide();
	}

	this.showForm = function()
	{
		var $select = $('#photoset-start-upload');
		if ($select.length) {
			var pos = $select.offset();
			w = $select.outerWidth();
			h = $select.outerHeight();
			t = pos.top + h - 30  + 'px';
			l = pos.left - 15 + 'px';
			$('#photoset-upload-form').css({'top':t,'left':l});
		}
		$('#photoset-upload-form').show();
	}

	this.showMainPhoto = function(id) {
		$('#photoset-main-preview-'+id).css('width',$('#photoset-main-image-'+id).outerWidth());
		$('#photoset-photo-count-'+id).show();
		$('#photoset-photo-desc-'+id).show();
	}

	return this;
}).call(ls.photoset || {},jQuery);<commit_msg>photoset.js - fix<commit_after>var ls = ls || {};

ls.photoset =( function ($) {

	this.idLast=0;
	this.isLoading=false;
	this.swfu;

	this.initSwfUpload = function(opt) {
		opt=opt || {};
		opt.button_placeholder_id = 'photoset-start-upload';
		opt.post_params.ls_photoset_target_tmp = $.cookie('ls_photoset_target_tmp') ? $.cookie('ls_photoset_target_tmp') : 0;

		$(ls.swfupload).unbind('load').bind('load',function() {
			this.swfu = ls.swfupload.init(opt);

			$(this.swfu).bind('eUploadProgress',this.swfHandlerUploadProgress);
			$(this.swfu).bind('eFileDialogComplete',this.swfHandlerFileDialogComplete);
			$(this.swfu).bind('eUploadSuccess',this.swfHandlerUploadSuccess);
			$(this.swfu).bind('eUploadComplete',this.swfHandlerUploadComplete);
		}.bind(this));

		ls.swfupload.loadSwf();
	}

	this.swfHandlerUploadProgress = function(e, file, bytesLoaded, percent) {
		$('#photoset_photo_empty_progress').text(file.name+': '+( percent==100 ? 'resize..' : percent +'%'));
	}

	this.swfHandlerFileDialogComplete = function(e, numFilesSelected, numFilesQueued) {
		if (numFilesQueued>0) {
			ls.photoset.addPhotoEmpty();
		}
	}

	this.swfHandlerUploadSuccess = function(e, file, serverData) {
		ls.photoset.addPhoto(jQuery.parseJSON(serverData));
	}

	this.swfHandlerUploadComplete = function(e, file, next) {
		if (next>0) {
			ls.photoset.addPhotoEmpty();
		}
	}

	this.addPhotoEmpty = function() {
		template = '
'
					+'

';
		$('#swfu_images').append(template);
	}

	this.addPhoto = function(response) {
		$('#photoset_photo_empty').remove();
		if (!response.bStateError) {
			template = '
'
						+'<textarea onBlur="ls.photoset.setPreviewDescription('+response.id+', this.value)"></textarea>
'
						+''+ls.lang.get('topic_photoset_photo_delete')+''
						+''+ls.lang.get('topic_photoset_mark_as_preview')+'
';
			$('#swfu_images').append(template);
			ls.msg.notice(response.sMsgTitle,response.sMsg);
		} else {
			ls.msg.error(response.sMsgTitle,response.sMsg);
		}
		ls.photoset.closeForm();
	}

	this.deletePhoto = function(id)
	{
		if (!confirm(ls.lang.get('topic_photoset_photo_delete_confirm'))) {return;}
		ls.ajax(aRouter['content']+'photo/delete', {'id':id}, function(response){
			if (!response.bStateError) {
				$('#photo_'+id).remove();
				ls.msg.notice(response.sMsgTitle,response.sMsg);
			} else {
				ls.msg.error(response.sMsgTitle,response.sMsg);
			}
		});
	}

	this.setPreview =function(id)
	{
		$('#topic_main_photo').val(id);

		$('.marked-as-preview').each(function (index, el) {
			$(el).removeClass('marked-as-preview');
			tmpId = $(el).attr('id').slice($(el).attr('id').lastIndexOf('_')+1);
			$('#photo_preview_state_'+tmpId).html(''+ls.lang.get('topic_photoset_mark_as_preview')+'');
		});
		$('#photo_'+id).addClass('marked-as-preview');
		$('#photo_preview_state_'+id).html(ls.lang.get('topic_photoset_is_preview'));
	}

	this.setPreviewDescription = function(id, text)
	{
		ls.ajax(aRouter['content']+'photo/description', {'id':id, 'text':text},  function(result){
			if (!result.bStateError) {

			} else {
				ls.msg.error('Error','Please try again later');
			}
		}
		)
	}

	this.getMore = function(topic_id)
	{
		if (this.isLoading) return;
		this.isLoading=true;

		ls.ajax(aRouter['content']+'photo/getmore', {'topic_id':topic_id, 'last_id':this.idLast}, function(result){
			this.isLoading=false;
			if (!result.bStateError) {
				if (result.photos) {
					$.each(result.photos, function(index, photo) {
						var image = '

';
						$('#topic-photo-images').append(image);
						this.idLast=photo.id;
						$('.photoset-image').unbind('click');
						$('.photoset-image').prettyPhoto({
							social_tools:'',
							show_title: false,
							slideshow:false,
							deeplinking: false
						});
					}.bind(this));
				}
				if (!result.bHaveNext || !result.photos) {
					$('#topic-photo-more').remove();
				}
			} else {
				ls.msg.error('Error','Please try again later');
			}
		}.bind(this));
	}

	this.upload = function()
	{
		ls.photoset.addPhotoEmpty();
		ls.ajaxSubmit(aRouter['content']+'photo/upload/',$('#photoset-upload-form'),function(data){
			if (data.bStateError) {
				$('#photoset_photo_empty').remove();
				ls.msg.error(data.sMsgTitle,data.sMsg);
			} else {
				ls.photoset.addPhoto(data);
			}
		});
		ls.photoset.closeForm();
	}

	this.closeForm = function()
	{
		$('#photoset-upload-form').jqmHide();
	}

	this.showForm = function()
	{
		var $select = $('#photoset-start-upload');
		if ($select.length) {
			var pos = $select.offset();
			w = $select.outerWidth();
			h = $select.outerHeight();
			t = pos.top + h - 30  + 'px';
			l = pos.left - 15 + 'px';
			$('#photoset-upload-form').css({'top':t,'left':l});
		}
		$('#photoset-upload-form').show();
	}

	this.showMainPhoto = function(id) {
		$('#photoset-main-preview-'+id).css('width',$('#photoset-main-image-'+id).outerWidth());
		$('#photoset-photo-count-'+id).show();
		$('#photoset-photo-desc-'+id).show();
	}

	return this;
}).call(ls.photoset || {},jQuery);<|endoftext|>


<commit_before>'use strict';

var spawn = require('child_process').spawn,
    exec = require('child_process').exec,
    os = require('os'),
    port = process.env.MB_PORT || 2525,
    mbPath = process.env.MB_EXECUTABLE || 'bin/mb',
    pidfile = 'mb-grunt.pid';

function isWindows () {
    return os.platform().indexOf('win') === 0;
}

function start (done) {
    var mbArgs = ['restart', '--port', port, '--pidfile', pidfile, '--allowInjection', '--mock', '--debug'],
        mb;

    if (isWindows) {
        mbArgs.unshift(mbPath);
        mb = spawn('node', mbArgs);
    }
    else {
        mb = spawn(mbPath, mbArgs);
    }

    mb.on('error', function (error) {
        throw error;
    });
    mb.stderr.on('data', function (data) {
        console.error(data.toString('utf8'));
        done();
    });
    mb.stdout.on('data', function (data) {
        // Looking for "mountebank va.b.c (node vx.y.z) now taking orders..."
        if (data.toString('utf8').indexOf('now taking orders') > 0) {
            done();
        }
    });
}

function stop (done) {
    exec(mbPath + ' stop --pidfile ' + pidfile, function () { done(); });
}

module.exports = function (grunt) {
    grunt.registerTask('mb', 'start or stop mountebank', function (command) {
        command = command || 'start';
        if (['start', 'stop'].indexOf(command) === -1) {
            throw 'mb: the only targets are start and stop';
        }

        if (command === 'start') {
            start();
        }
        else {
            stop();
        }
    });
};
<commit_msg>Fix bug finishing task<commit_after>'use strict';

var spawn = require('child_process').spawn,
    exec = require('child_process').exec,
    os = require('os'),
    port = process.env.MB_PORT || 2525,
    mbPath = process.env.MB_EXECUTABLE || 'bin/mb',
    pidfile = 'mb-grunt.pid';

function isWindows () {
    return os.platform().indexOf('win') === 0;
}

function start (done) {
    var mbArgs = ['restart', '--port', port, '--pidfile', pidfile, '--allowInjection', '--mock', '--debug'],
        mb;

    if (isWindows) {
        mbArgs.unshift(mbPath);
        mb = spawn('node', mbArgs);
    }
    else {
        mb = spawn(mbPath, mbArgs);
    }

    mb.on('error', function (error) {
        throw error;
    });
    mb.stderr.on('data', function (data) {
        console.error(data.toString('utf8'));
        done();
    });
    mb.stdout.on('data', function (data) {
        // Looking for "mountebank va.b.c (node vx.y.z) now taking orders..."
        if (data.toString('utf8').indexOf('now taking orders') > 0) {
            done();
        }
    });
}

function stop (done) {
    exec(mbPath + ' stop --pidfile ' + pidfile, function () { done(); });
}

module.exports = function (grunt) {
    grunt.registerTask('mb', 'start or stop mountebank', function (command) {
        var done = this.async();

        command = command || 'start';
        if (['start', 'stop'].indexOf(command) === -1) {
            throw 'mb: the only targets are start and stop';
        }

        if (command === 'start') {
            start(done);
        }
        else {
            stop(done);
        }
    });
};
<|endoftext|>