<commit_before>'use strict';

module.exports = PLS;
var Matrix = require('ml-matrix');
var Utils = require('./utils');

/**
 * Function that returns the index where the sum of each
 * column vector is maximum.
 * @param {Matrix} X
 * @returns {number} index of the maximum
 */
function maxSumColIndex(X) {
    var maxIndex = 0;
    var maxSum = -Infinity;
    for(var i = 0; i < X.columns; ++i) {
        var currentSum = X.getColumnVector(i).sum();
        if(currentSum > maxSum) {
            maxSum = currentSum;
            maxIndex = i;
        }
    }
    return maxIndex;
}

/**
 * Constructor of the PLS model.
 * @param reload - used for load purposes.
 * @param model - used for load purposes.
 * @constructor
 */
function PLS(reload, model) {
    if(reload) {
        this.E = model.E;
        this.F = model.F;
        this.ymean = model.ymean;
        this.ystd = model.ystd;
        this.PBQ = model.PBQ;
        this.T = model.T;
        this.P = model.P;
        this.U = model.U;
        this.Q = model.Q;
        this.W = model.W;
        this.B = model.B;
    }
}

/**
 * Function that fit the model with the given data and predictions, in this function is calculated the
 * following outputs:
 *
 * T - Score matrix of X
 * P - Loading matrix of X
 * U - Score matrix of Y
 * Q - Loading matrix of Y
 * B - Matrix of regression coefficient
 * W - Weight matrix of X
 *
 * @param {Matrix} trainingSet - Dataset to be apply the model
 * @param {Matrix} predictions - Predictions over each case of the dataset
 * @param {Number} options - recieves the latentVectors and the tolerance of each step of the PLS
 */
PLS.prototype.train = function (trainingSet, predictions, options) {

    if(options === undefined) options = {};

    var latentVectors = options.latentVectors;
    if(latentVectors === undefined || isNaN(latentVectors)) {
        throw new RangeError("Latent vector must be a number.");
    }

    var tolerance = options.tolerance;
    if(tolerance === undefined || isNaN(tolerance)) {
        throw new RangeError("Tolerance must be a number");
    }

    if(trainingSet.length !== predictions.length)
        throw new RangeError("The number of predictions and elements in the dataset must be the same");

    //var tolerance = 1e-9;
    var X = Utils.featureNormalize(Matrix(trainingSet).clone()).result;
    var resultY = Utils.featureNormalize(Matrix(predictions).clone());
    this.ymean = resultY.means;
    this.ystd = resultY.std;
    var Y = resultY.result;

    var rx = X.rows;
    var cx = X.columns;
    var ry = Y.rows;
    var cy = Y.columns;

    var ssqXcal = X.clone().mul(X).sum(); // for the r²

    if(rx != ry) {
        throw new RangeError("dataset cases is not the same as the predictions");
    }

    var n = latentVectors; //Math.max(cx, cy); // components of the pls
    var T = Matrix.zeros(rx, n);
    var P = Matrix.zeros(cx, n);
    var U = Matrix.zeros(ry, n);
    var Q = Matrix.zeros(cy, n);
    var B = Matrix.zeros(n, n);
    var W = P.clone();
    var k = 0;

    while(Utils.norm(Y) > tolerance && k < n) {
        var transposeX = X.transpose();
        var transposeY = Y.transpose();

        var tIndex = maxSumColIndex(X.clone().mulM(X));
        var uIndex = maxSumColIndex(Y.clone().mulM(Y));

        var t1 = X.getColumnVector(tIndex);
        var u = Y.getColumnVector(uIndex);
        var t = Matrix.zeros(rx, 1);

        while(Utils.norm(t1.clone().sub(t)) > tolerance) {
            var w = transposeX.mmul(u);
            w.div(Utils.norm(w));
            t = t1;
            t1 = X.mmul(w);
            var q = transposeY.mmul(t1);
            q.div(Utils.norm(q));
            u = Y.mmul(q);
        }

        t = t1;
        var num = transposeX.mmul(t);
        var den = (t.transpose().mmul(t))[0][0];
        var p = num.div(den);
        var pnorm = Utils.norm(p);
        p.div(pnorm);
        t.mul(pnorm);
        w.mul(pnorm);

        num = u.transpose().mmul(t);
        den = (t.transpose().mmul(t))[0][0];
        var b = (num.div(den))[0][0];
        X.sub(t.mmul(p.transpose()));
        Y.sub(t.clone().mul(b).mmul(q.transpose()));

        T.setColumn(k, t);
        P.setColumn(k, p);
        U.setColumn(k, u);
        Q.setColumn(k, q);
        W.setColumn(k, w);
        B[k][k] = b;
        k++;
    }

    k--;
    T = T.subMatrix(0, T.rows - 1, 0, k);
    P = P.subMatrix(0, P.rows - 1, 0, k);
    U = U.subMatrix(0, U.rows - 1, 0, k);
    Q = Q.subMatrix(0, Q.rows - 1, 0, k);
    W = W.subMatrix(0, W.rows - 1, 0, k);
    B = B.subMatrix(0, k, 0, k);

    this.r2cal = (1 - X.clone().mul(X).sum()) / ssqXcal;
    this.E = X;
    this.F = Y;
    this.T = T;
    this.P = P;
    this.U = U;
    this.Q = Q;
    this.W = W;
    this.B = B;
    this.PBQ = P.mmul(B).mmul(Q.transpose());
};

/**
 * Function that predict the behavior of the given dataset.
 * @param dataset - data to be predicted.
 * @returns {Matrix} - predictions of each element of the dataset.
 */
PLS.prototype.predict = function (dataset) {
    var X = Matrix(dataset).clone();
    var normalization = Utils.featureNormalize(X);
    X = normalization.result;
    var Y = X.mmul(this.PBQ).add(this.F);
    Y.mulRowVector(this.ystd);
    // be careful because its supposed to be a sumRowVector but the mean
    // is negative here
    Y.subRowVector(this.ymean);
    return Y;
};

/**
 * Function that returns the explained variance on training of the PLS model.
 * @returns {number}
 */
PLS.prototype.getExplainedVariance = function () {
    return this.r2cal;
};

/**
 * Load a PLS model from an Object
 * @param model
 * @returns {PLS} - PLS object from the given model
 */
PLS.load = function (model) {
    if(model.modelName !== 'PLS')
        throw new RangeError("The current model is invalid!");

    return new PLS(true, model);
};

/**
 * Function that exports a PLS model to an Object.
 * @returns {{modelName: string, ymean: *, ystd: *, PBQ: *}} model.
 */
PLS.prototype.export = function () {
    return {
        modelName: "PLS",
        E: this.E,
        F: this.F,
        ymean: this.ymean,
        ystd: this.ystd,
        PBQ: this.PBQ,
        T: this.T,
        P: this.P,
        U: this.U,
        Q: this.Q,
        W: this.W,
        B: this.B
    };
};
<commit_msg>fix(pls): clone matrices.<commit_after>'use strict';

module.exports = PLS;
var Matrix = require('ml-matrix');
var Utils = require('./utils');

/**
 * Function that returns the index where the sum of each
 * column vector is maximum.
 * @param {Matrix} X
 * @returns {number} index of the maximum
 */
function maxSumColIndex(X) {
    var maxIndex = 0;
    var maxSum = -Infinity;
    for(var i = 0; i < X.columns; ++i) {
        var currentSum = X.getColumnVector(i).sum();
        if(currentSum > maxSum) {
            maxSum = currentSum;
            maxIndex = i;
        }
    }
    return maxIndex;
}

/**
 * Constructor of the PLS model.
 * @param reload - used for load purposes.
 * @param model - used for load purposes.
 * @constructor
 */
function PLS(reload, model) {
    if(reload) {
        this.E = model.E;
        this.F = model.F;
        this.ymean = model.ymean;
        this.ystd = model.ystd;
        this.PBQ = model.PBQ;
        this.T = model.T;
        this.P = model.P;
        this.U = model.U;
        this.Q = model.Q;
        this.W = model.W;
        this.B = model.B;
    }
}

/**
 * Function that fit the model with the given data and predictions, in this function is calculated the
 * following outputs:
 *
 * T - Score matrix of X
 * P - Loading matrix of X
 * U - Score matrix of Y
 * Q - Loading matrix of Y
 * B - Matrix of regression coefficient
 * W - Weight matrix of X
 *
 * @param {Matrix} trainingSet - Dataset to be apply the model
 * @param {Matrix} predictions - Predictions over each case of the dataset
 * @param {Number} options - recieves the latentVectors and the tolerance of each step of the PLS
 */
PLS.prototype.train = function (trainingSet, predictions, options) {

    if(options === undefined) options = {};

    var latentVectors = options.latentVectors;
    if(latentVectors === undefined || isNaN(latentVectors)) {
        throw new RangeError("Latent vector must be a number.");
    }

    var tolerance = options.tolerance;
    if(tolerance === undefined || isNaN(tolerance)) {
        throw new RangeError("Tolerance must be a number");
    }

    if(trainingSet.length !== predictions.length)
        throw new RangeError("The number of predictions and elements in the dataset must be the same");

    //var tolerance = 1e-9;
    var X = Utils.featureNormalize(Matrix(trainingSet, true)).result;
    var resultY = Utils.featureNormalize(Matrix(predictions, true));
    this.ymean = resultY.means;
    this.ystd = resultY.std;
    var Y = resultY.result;

    var rx = X.rows;
    var cx = X.columns;
    var ry = Y.rows;
    var cy = Y.columns;

    var ssqXcal = X.clone().mul(X).sum(); // for the r²

    if(rx != ry) {
        throw new RangeError("dataset cases is not the same as the predictions");
    }

    var n = latentVectors; //Math.max(cx, cy); // components of the pls
    var T = Matrix.zeros(rx, n);
    var P = Matrix.zeros(cx, n);
    var U = Matrix.zeros(ry, n);
    var Q = Matrix.zeros(cy, n);
    var B = Matrix.zeros(n, n);
    var W = P.clone();
    var k = 0;

    while(Utils.norm(Y) > tolerance && k < n) {
        var transposeX = X.transpose();
        var transposeY = Y.transpose();

        var tIndex = maxSumColIndex(X.clone().mulM(X));
        var uIndex = maxSumColIndex(Y.clone().mulM(Y));

        var t1 = X.getColumnVector(tIndex);
        var u = Y.getColumnVector(uIndex);
        var t = Matrix.zeros(rx, 1);

        while(Utils.norm(t1.clone().sub(t)) > tolerance) {
            var w = transposeX.mmul(u);
            w.div(Utils.norm(w));
            t = t1;
            t1 = X.mmul(w);
            var q = transposeY.mmul(t1);
            q.div(Utils.norm(q));
            u = Y.mmul(q);
        }

        t = t1;
        var num = transposeX.mmul(t);
        var den = (t.transpose().mmul(t))[0][0];
        var p = num.div(den);
        var pnorm = Utils.norm(p);
        p.div(pnorm);
        t.mul(pnorm);
        w.mul(pnorm);

        num = u.transpose().mmul(t);
        den = (t.transpose().mmul(t))[0][0];
        var b = (num.div(den))[0][0];
        X.sub(t.mmul(p.transpose()));
        Y.sub(t.clone().mul(b).mmul(q.transpose()));

        T.setColumn(k, t);
        P.setColumn(k, p);
        U.setColumn(k, u);
        Q.setColumn(k, q);
        W.setColumn(k, w);
        B[k][k] = b;
        k++;
    }

    k--;
    T = T.subMatrix(0, T.rows - 1, 0, k);
    P = P.subMatrix(0, P.rows - 1, 0, k);
    U = U.subMatrix(0, U.rows - 1, 0, k);
    Q = Q.subMatrix(0, Q.rows - 1, 0, k);
    W = W.subMatrix(0, W.rows - 1, 0, k);
    B = B.subMatrix(0, k, 0, k);

    this.r2cal = (1 - X.clone().mul(X).sum()) / ssqXcal;
    this.E = X;
    this.F = Y;
    this.T = T;
    this.P = P;
    this.U = U;
    this.Q = Q;
    this.W = W;
    this.B = B;
    this.PBQ = P.mmul(B).mmul(Q.transpose());
};

/**
 * Function that predict the behavior of the given dataset.
 * @param dataset - data to be predicted.
 * @returns {Matrix} - predictions of each element of the dataset.
 */
PLS.prototype.predict = function (dataset) {
    var X = Matrix(dataset, true);
    var normalization = Utils.featureNormalize(X);
    X = normalization.result;
    var Y = X.mmul(this.PBQ).add(this.F);
    Y.mulRowVector(this.ystd);
    // be careful because its supposed to be a sumRowVector but the mean
    // is negative here
    Y.subRowVector(this.ymean);
    return Y;
};

/**
 * Function that returns the explained variance on training of the PLS model.
 * @returns {number}
 */
PLS.prototype.getExplainedVariance = function () {
    return this.r2cal;
};

/**
 * Load a PLS model from an Object
 * @param model
 * @returns {PLS} - PLS object from the given model
 */
PLS.load = function (model) {
    if(model.modelName !== 'PLS')
        throw new RangeError("The current model is invalid!");

    return new PLS(true, model);
};

/**
 * Function that exports a PLS model to an Object.
 * @returns {{modelName: string, ymean: *, ystd: *, PBQ: *}} model.
 */
PLS.prototype.export = function () {
    return {
        modelName: "PLS",
        E: this.E,
        F: this.F,
        ymean: this.ymean,
        ystd: this.ystd,
        PBQ: this.PBQ,
        T: this.T,
        P: this.P,
        U: this.U,
        Q: this.Q,
        W: this.W,
        B: this.B
    };
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Grid, Row, Col, FormGroup, FormControl, ControlLabel } from 'react-bootstrap';
import AddEntryControls from './AddEntryControls';

class TextForm extends Component {
    constructor(props) {
        super(props);

        this.state = {
            value: props.initialValue
        };

        this.continue = this.continue.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }

    continue(event) {
        event.preventDefault();
        this.props.save({text: this.state.value});
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        });
    }

    render() {
        return (
            <Grid>
                <Row>
                    <Col>
                        <FormGroup controlId="media">
                            <ControlLabel>I just want to say...</ControlLabel>
                            <FormControl
                                componentClass="textarea"
                                placeholder=""
                                value={this.state.value}
                                onChange={this.handleChange} />
                        </FormGroup>
                    </Col>
                    <Col>
                        <AddEntryControls
                            onNext={this.continue}
                            disableNext={!this.state.value}
                            />
                    </Col>
                </Row>
            </Grid>

        );
    }
}

TextForm.propTypes = {
    initialValue: React.PropTypes.string,
    save: React.PropTypes.func
};

TextForm.defaultProps = {
    initialValue: ''
};

export default TextForm;
<commit_msg>Add maxLength and counter to TextForm<commit_after>import React, { Component } from 'react';
import { Grid, Row, Col, FormGroup, FormControl, ControlLabel, HelpBlock } from 'react-bootstrap';
import AddEntryControls from './AddEntryControls';

class TextForm extends Component {
    constructor(props) {
        super(props);

        this.state = {
            value: props.initialValue
        };

        this.continue = this.continue.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }

    continue(event) {
        event.preventDefault();
        this.props.save({text: this.state.value});
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        });
    }

    render() {
        return (
            <Grid>
                <Row>
                    <Col>
                        <FormGroup controlId="media">
                            <ControlLabel>I just want to say...</ControlLabel>
                            <FormControl
                                componentClass="textarea"
                                maxLength={this.props.maxLength}
                                placeholder=""
                                value={this.state.value}
                                onChange={this.handleChange} />
                            <HelpBlock>{this.state.value.length} of {this.props.maxLength} letters used</HelpBlock>
                        </FormGroup>
                    </Col>
                    <Col>
                        <AddEntryControls
                            onNext={this.continue}
                            disableNext={!this.state.value}
                            />
                    </Col>
                </Row>
            </Grid>

        );
    }
}

TextForm.propTypes = {
    initialValue: React.PropTypes.string,
    save: React.PropTypes.func
};

TextForm.defaultProps = {
    initialValue: '',
    maxLength: 250
};

export default TextForm;
<|endoftext|>


<commit_before>
import { resolve } from 'rus-diff'

function isvalue (a) {
  return a !== undefined && a !== null
}

function* kvs (a) {
  for (let k of Object.keys(a)) {
    if (a.hasOwnProperty(k)) {
      yield [k, a[k]]
    }
  }
}

function isdeep (a, b) {
  var as, bs, i, k, sf, v, _i, _len, _ref;
  if ((a !== null) && (b !== null) && (typeof a === 'object') && (typeof b === 'object')) {
    as = (function() {
      var _results;
      _results = [];
      for (k in a) {
        if (!__hasProp.call(a, k)) continue;
        v = a[k];
        _results.push({
          k: k,
          v: v
        });
      }
      return _results;
    })();
    bs = (function() {
      var _results;
      _results = [];
      for (k in b) {
        if (!__hasProp.call(b, k)) continue;
        v = b[k];
        _results.push({
          k: k,
          v: v
        });
      }
      return _results;
    })();
    if (as.length === bs.length) {
      sf = function(x, y) {
        return x.k > y.k;
      };
      as.sort(sf);
      bs.sort(sf);
      for (i = _i = 0, _len = as.length; _i < _len; i = ++_i) {
        _ref = as[i], k = _ref.k, v = _ref.v;
        if (!(isdeep(k, bs[i].k) && isdeep(v, bs[i].v))) {
          return false;
        }
      }
      return true;
    } else {
      return false;
    }
  } else {
    return a === b;
  }
}

class Criteria {

  constructor () {
    this.registry = {
      transforms: [],
      conditions: [],
      expansions: []
    }
  }

  append (t, k, f) {
    this.registry[t].push([ k, f ])
  }

  prepend (t, k, f) {
    this.registry[t].shift([ k, f ])
  }

  // Find rule with k name.
  rule (k) {
    let r = [ undefined, undefined ]
    for (let [ tk, tv ] of kvs(this.registry)) {
      for (let [ rk, rf ] of tv) {
        if (k === rk) {
          r = [ tk, rf ]
          break;
        }
      }
    }
    return r
  }

  test (d, q) {
    let r = true
    for (let [ qk, qv ] of kvs(q)) {
      if (qk[0] === '$') {

        let [ t, f ] = this.rule(qk)

        switch (t) {

          case 'expansions':
            r = r && this.test(d, f)
            break

          case 'transforms':
            r = r && this.test(f.bind(this)(d, qv), qv)
            break

          case 'conditions':
            r = r && f.bind(this)(d, qv, q)
            break

          default:
            throw new Error(`Unknown rule ${qk}`)

        }

        if (r === false) {
          break
        }
      } else {
        let [ dvp, dk ] = resolve(d, qk)
        if (dvp !== null && dk.length === 1) { // ...it's resolved
          r = r && this.test(dvp[dk[0]], qv)
        } else {
          r = r && this.test(undefined, v) // we can still match `{ $exists: false }`, possibly in nested `{ $or: [] }`.
        }
      }
    }
    return r
  }

}

let c = new Criteria()

// Logical ops.

c.append('conditions', '$and', (a) => { return a.reduce(((p, c) => p && this.test(a, c)), true) })
c.append('conditions', '$or', (a) => { return a.reduce(((p, c) => p || this.test(a, c)), false) })
c.append('conditions', '$nor', (a) => { return a.reduce(((p, c) => p && !this.test(a, c)), true) })
c.append('conditions', '$not', (a) => { return !this.test(a, c) })

// Equality ops.

c.append('conditions', '$eq', (a, b) => isdeep(a, b) )
c.append('conditions', '$ne', (a, b) => !isdeep(a, b) )
c.append('conditions', '$lt', (a, b) => a < b )
c.append('conditions', '$lte', (a, b) => a <= b )
c.append('conditions', '$gt', (a, b) => a > b )
c.append('conditions', '$gte', (a, b) => a > b )
c.append('conditions', '$in', (a, b) => { let aa = arrize(a); arrize(b).some((e) => e in aa) } )
c.append('conditions', '$nin', (a, b) => { let aa = arrize(a); arrize(b).every((e) => !(e in aa)) } )

c.append('conditions', '$exists', (a, b) => a ^ isvalue(b) )
c.append('conditions', '$typeof', (a, b) => typeof(a) === b )

c.append('conditions', '$regex', (a, b, c) => !!a.match(new RegExp(b, c.$options)) )

c.append('expansions', '$email', { $typeof: 'string', $regex: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i } )

c.append('transforms', '$length', (a) => {
  let r = undefined
  let t = typeof(a)
  if (t === 'string' || (t === 'object' && a !== null && a.hasOwnProperty('length'))) {
    r = a.length
  }
  return r
})

export function test (a, q) {
  return c.test(a, q)
}
<commit_msg>Mongo ops.<commit_after>
import { resolve } from 'rus-diff'

function isvalue (a) {
  return a !== undefined && a !== null
}

function* kvs (a) {
  for (let k of Object.keys(a)) {
    if (a.hasOwnProperty(k)) {
      yield [k, a[k]]
    }
  }
}

function isdeep (a, b) {
  var as, bs, i, k, sf, v, _i, _len, _ref;
  if ((a !== null) && (b !== null) && (typeof a === 'object') && (typeof b === 'object')) {
    as = (function() {
      var _results;
      _results = [];
      for (k in a) {
        if (!__hasProp.call(a, k)) continue;
        v = a[k];
        _results.push({
          k: k,
          v: v
        });
      }
      return _results;
    })();
    bs = (function() {
      var _results;
      _results = [];
      for (k in b) {
        if (!__hasProp.call(b, k)) continue;
        v = b[k];
        _results.push({
          k: k,
          v: v
        });
      }
      return _results;
    })();
    if (as.length === bs.length) {
      sf = function(x, y) {
        return x.k > y.k;
      };
      as.sort(sf);
      bs.sort(sf);
      for (i = _i = 0, _len = as.length; _i < _len; i = ++_i) {
        _ref = as[i], k = _ref.k, v = _ref.v;
        if (!(isdeep(k, bs[i].k) && isdeep(v, bs[i].v))) {
          return false;
        }
      }
      return true;
    } else {
      return false;
    }
  } else {
    return a === b;
  }
}

class Criteria {

  constructor () {
    this.registry = {
      transforms: [],
      conditions: [],
      expansions: []
    }
  }

  append (t, k, f) {
    this.registry[t].push([ k, f ])
  }

  prepend (t, k, f) {
    this.registry[t].shift([ k, f ])
  }

  // Find rule with k name.
  rule (k) {
    let r = [ undefined, undefined ]
    for (let [ tk, tv ] of kvs(this.registry)) {
      for (let [ rk, rf ] of tv) {
        if (k === rk) {
          r = [ tk, rf ]
          break;
        }
      }
    }
    return r
  }

  test (d, q) {
    let r = true
    for (let [ qk, qv ] of kvs(q)) {
      if (qk[0] === '$') {

        let [ t, f ] = this.rule(qk)

        switch (t) {
          case 'expansions': r = r && this.test(d, f); break
          case 'transforms': r = r && this.test(f.bind(this)(d, qv), qv); break
          case 'conditions': r = r && f.bind(this)(d, qv, q); break
          default: throw new Error(`Unknown rule ${qk}`)
        }

        if (r === false) {
          break
        }
      } else {
        let [ dvp, dk ] = resolve(d, qk) || []
        if (dvp !== null && dk.length === 1) { // ...it's resolved
          r = r && this.test(dvp[dk[0]], qv)
        } else {
          r = r && this.test(undefined, v) // we can still match `{ $exists: false }`, possibly in nested `{ $or: [] }`.
        }
      }
    }
    return r
  }
}

let c = new Criteria()

// Comparision

c.append('conditions', '$eq', (a, b) => isdeep(a, b) )
c.append('conditions', '$gt', (a, b) => a > b )
c.append('conditions', '$gte', (a, b) => a > b )
c.append('conditions', '$lt', (a, b) => a < b )
c.append('conditions', '$lte', (a, b) => a <= b )
c.append('conditions', '$ne', (a, b) => !isdeep(a, b) )
c.append('conditions', '$in', (a, b) => { let aa = arrize(a); arrize(b).some((e) => e in aa) } )
c.append('conditions', '$nin', (a, b) => { let aa = arrize(a); arrize(b).every((e) => !(e in aa)) } )

// Logical

c.append('conditions', '$or', (a) => { return a.reduce(((p, c) => p || this.test(a, c)), false) })
c.append('conditions', '$and', (a) => { return a.reduce(((p, c) => p && this.test(a, c)), true) })
c.append('conditions', '$not', (a) => { return !this.test(a, c) })
c.append('conditions', '$nor', (a) => { return a.reduce(((p, c) => p && !this.test(a, c)), true) })

// Element

c.append('conditions', '$exists', (a, b) => a ^ isvalue(b) )
c.append('conditions', '$typeof', (a, b) => typeof(a) === b ) // MongoDB discrepancy

// Evaluation

c.append('conditions', '$mod', (a, b) => (a % b[0]) === b[1] )
c.append('conditions', '$regex', (a, b, c) => !!a.match(new RegExp(b, c.$options)) )
c.append('expansions', '$options', true ) // hack
// $text
c.append('conditions', '$where', (a, b, c) => b(a) )

// Geospatial

// $geoWithin
// $geoIntersects
// $near
// $nearSphere

// Array

c.append('conditions', '$all', (a, b) => { b.every((e) => e in a) } )
c.append('conditions', '$elemMatch', (a, b) => { Array.isArray(a) && a.some((e) => this.test(e, b)) } )
c.append('conditions', '$size', (a, b) => { Array.isArray(a) ? b.length : 0 } )

// Extras

c.append('expansions', '$integer', { $typeof: 'number', $mod: [ 1, 0 ] } )
c.append('expansions', '$natural', { $typeof: 'number', $mod: [ 1, 0 ], $gte: 0 } )
c.append('expansions', '$email', { $typeof: 'string', $regex: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i } )

// $every
// $any
// $sorted
// $unique
// $type = array
// $date:format
// $date:iso
// $keys
// $exact / $iff
// $creditcard
// $guid
// $hostname http://tools.ietf.org/html/rfc1123
// $downcase
// $upcase
// $trim
//

c.append('transforms', '$length', (a) => {
  let r = undefined
  let t = typeof(a)
  if (t === 'string' || (t === 'object' && a !== null && a.hasOwnProperty('length'))) {
    r = a.length
  }
  return r
})

export function test (a, q) {
  return c.test(a, q)
}
<|endoftext|>


<commit_before>const {updated} = require(`../lib/updated`);
const wrapHandler = require(`../lib/wrap-handler`);
const {list} = require(`../util/package`);

module.exports = {
  command: `list`,
  desc: `List packages`,
  builder: {
    fortests: {
      default: false,
      description: `list packages that should be tested in CI`,
      type: `boolean`
    },
    forpipeline: {
      default: false,
      description: `list packages that should be tested in a pipeline gating job`,
      type: `boolean`
    }
  },
  handler: wrapHandler(async ({fortests, forpipeline}) => {
    let packages;
    if (fortests || forpipeline) {
      const changed = await updated({});
      if (changed.includes(`tooling`) || forpipeline) {
        packages = await list();
      }
      else {
        packages = await updated({dependents: true});
      }

      if (packages.includes(`legacy`)) {
        packages = packages.filter((p) => p !== `legacy`);
        packages.push(`legacy-node`);
        packages.push(`legacy-browser`);
      }

      packages = packages
        .filter((p) => !p.includes(`bin-`))
        .filter((p) => !p.includes(`test-helper-`))
        .filter((p) => !p.includes(`eslint-config`))
        .filter((p) => !p.includes(`xunit-with-logs`));
    }
    else {
      packages = await list();
    }

    for (const pkg of packages) {
      console.info(pkg);
    }
  })
};
<commit_msg>fix(tooling): do not invoke git when listing packages for pipeline<commit_after>const {updated} = require(`../lib/updated`);
const wrapHandler = require(`../lib/wrap-handler`);
const {list} = require(`../util/package`);

module.exports = {
  command: `list`,
  desc: `List packages`,
  builder: {
    fortests: {
      default: false,
      description: `list packages that should be tested in CI`,
      type: `boolean`
    },
    forpipeline: {
      default: false,
      description: `list packages that should be tested in a pipeline gating job`,
      type: `boolean`
    }
  },
  handler: wrapHandler(async ({fortests, forpipeline}) => {
    let packages;
    if (fortests) {
      const changed = await updated({});
      if (changed.includes(`tooling`)) {
        packages = await list();
      }
      else {
        packages = await updated({dependents: true});
      }
    }
    else {
      packages = await list();
    }

    if (forpipeline || fortests) {
      if (packages.includes(`legacy`)) {
        packages = packages.filter((p) => p !== `legacy`);
        packages.push(`legacy-node`);
        packages.push(`legacy-browser`);
      }

      packages = packages
        .filter((p) => !p.includes(`bin-`))
        .filter((p) => !p.includes(`test-helper-`))
        .filter((p) => !p.includes(`eslint-config`))
        .filter((p) => !p.includes(`xunit-with-logs`));
    }

    for (const pkg of packages) {
      console.info(pkg);
    }
  })
};
<|endoftext|>


<commit_before>const ActionTypes = {
  PERFORM_ACTION: 'PERFORM_ACTION',
  RESET: 'RESET',
  ROLLBACK: 'ROLLBACK',
  COMMIT: 'COMMIT',
  SWEEP: 'SWEEP',
  TOGGLE_ACTION: 'TOGGLE_ACTION',
  JUMP_TO_STATE: 'JUMP_TO_STATE',
  SET_MONITOR_STATE: 'SET_MONITOR_STATE',
  RECOMPUTE_STATES: 'RECOMPUTE_STATES'
};

const INIT_ACTION = {
  type: '@@INIT'
};

function toggle(obj, key) {
  const clone = { ...obj };
  if (clone[key]) {
    delete clone[key];
  } else {
    clone[key] = true;
  }
  return clone;
}

/**
 * Computes the next entry in the log by applying an action.
 */
function computeNextEntry(reducer, action, state, error) {
  if (error) {
    return {
      state,
      error: 'Interrupted by an error up the chain'
    };
  }

  let nextState = state;
  let nextError;
  try {
    nextState = reducer(state, action);
  } catch (err) {
    nextError = err.toString();
    console.error(err.stack || err);
  }

  return {
    state: nextState,
    error: nextError
  };
}

/**
 * Runs the reducer on all actions to get a fresh computation log.
 * It's probably a good idea to do this only if the code has changed,
 * but until we have some tests we'll just do it every time an action fires.
 */
function recomputeStates(reducer, committedState, stagedActions, skippedActions) {
  const computedStates = [];

  for (let i = 0; i < stagedActions.length; i++) {
    const action = stagedActions[i];

    const previousEntry = computedStates[i - 1];
    const previousState = previousEntry ? previousEntry.state : committedState;
    const previousError = previousEntry ? previousEntry.error : undefined;

    const shouldSkip = Boolean(skippedActions[i]);
    const entry = shouldSkip ?
      previousEntry :
      computeNextEntry(reducer, action, previousState, previousError);

    computedStates.push(entry);
  }

  return computedStates;
}

/**
 * Lifts the app state reducer into a DevTools state reducer.
 */
function liftReducer(reducer, initialState) {
  const initialLiftedState = {
    committedState: initialState,
    stagedActions: [INIT_ACTION],
    skippedActions: {},
    currentStateIndex: 0,
    monitorState: {
      isVisible: true
    },
    timestamps: [Date.now()]
  };

  /**
   * Manages how the DevTools actions modify the DevTools state.
   */
  return function liftedReducer(liftedState = initialLiftedState, liftedAction) {
    let {
      committedState,
      stagedActions,
      skippedActions,
      computedStates,
      currentStateIndex,
      monitorState,
      timestamps
    } = liftedState;

    switch (liftedAction.type) {
    case ActionTypes.RESET:
      committedState = initialState;
      stagedActions = [INIT_ACTION];
      skippedActions = {};
      currentStateIndex = 0;
      timestamps = [liftedAction.timestamp];
      break;
    case ActionTypes.COMMIT:
      committedState = computedStates[currentStateIndex].state;
      stagedActions = [INIT_ACTION];
      skippedActions = {};
      currentStateIndex = 0;
      timestamps = [liftedAction.timestamp];
      break;
    case ActionTypes.ROLLBACK:
      stagedActions = [INIT_ACTION];
      skippedActions = {};
      currentStateIndex = 0;
      timestamps = [liftedAction.timestamp];
      break;
    case ActionTypes.TOGGLE_ACTION:
      skippedActions = toggle(skippedActions, liftedAction.index);
      break;
    case ActionTypes.JUMP_TO_STATE:
      currentStateIndex = liftedAction.index;
      break;
    case ActionTypes.SWEEP:
      stagedActions = stagedActions.filter((_, i) => !skippedActions[i]);
      timestamps = timestamps.filter((_, i) => !skippedActions[i]);
      skippedActions = {};
      currentStateIndex = Math.min(currentStateIndex, stagedActions.length - 1);
      break;
    case ActionTypes.PERFORM_ACTION:
      if (currentStateIndex === stagedActions.length - 1) {
        currentStateIndex++;
      }
      stagedActions = [...stagedActions, liftedAction.action];
      timestamps = [...timestamps, liftedAction.timestamp];
      break;
    case ActionTypes.SET_MONITOR_STATE:
      monitorState = liftedAction.monitorState;
      break;
    case ActionTypes.RECOMPUTE_STATES:
      stagedActions = liftedAction.stagedActions;
      committedState = liftedAction.committedState;
      currentStateIndex = stagedActions.length - 1;
      skippedActions = {};
      break;
    default:
      break;
    }

    computedStates = recomputeStates(
      reducer,
      committedState,
      stagedActions,
      skippedActions
    );

    return {
      committedState,
      stagedActions,
      skippedActions,
      computedStates,
      currentStateIndex,
      monitorState,
      timestamps
    };
  };
}

/**
 * Lifts an app action to a DevTools action.
 */
function liftAction(action) {
  const liftedAction = {
    type: ActionTypes.PERFORM_ACTION,
    action,
    timestamp: Date.now()
  };
  return liftedAction;
}

/**
 * Unlifts the DevTools state to the app state.
 */
function unliftState(liftedState) {
  const { computedStates, currentStateIndex } = liftedState;
  const { state } = computedStates[currentStateIndex];
  return state;
}

/**
 * Unlifts the DevTools store to act like the app's store.
 */
function unliftStore(liftedStore, reducer) {
  return {
    ...liftedStore,
    devToolsStore: liftedStore,
    dispatch(action) {
      liftedStore.dispatch(liftAction(action));
      return action;
    },
    getState() {
      return unliftState(liftedStore.getState());
    },
    getReducer() {
      return reducer;
    },
    replaceReducer(nextReducer) {
      liftedStore.replaceReducer(liftReducer(nextReducer));
    }
  };
}

/**
 * Action creators to change the DevTools state.
 */
export const ActionCreators = {
  reset() {
    return { type: ActionTypes.RESET, timestamp: Date.now() };
  },
  rollback() {
    return { type: ActionTypes.ROLLBACK, timestamp: Date.now() };
  },
  commit() {
    return { type: ActionTypes.COMMIT, timestamp: Date.now() };
  },
  sweep() {
    return { type: ActionTypes.SWEEP };
  },
  toggleAction(index) {
    return { type: ActionTypes.TOGGLE_ACTION, index };
  },
  jumpToState(index) {
    return { type: ActionTypes.JUMP_TO_STATE, index };
  },
  setMonitorState(monitorState) {
    return { type: ActionTypes.SET_MONITOR_STATE, monitorState };
  },
  recomputeStates(committedState, stagedActions) {
    return {
      type: ActionTypes.RECOMPUTE_STATES,
      committedState,
      stagedActions
    };
  }
};

/**
 * Redux DevTools middleware.
 */
export default function devTools() {
  return next => (reducer, initialState) => {
    const liftedReducer = liftReducer(reducer, initialState);
    const liftedStore = next(liftedReducer);
    const store = unliftStore(liftedStore, reducer);
    return store;
  };
}
<commit_msg>Update timestamps on RECOMPUTE_STATES<commit_after>const ActionTypes = {
  PERFORM_ACTION: 'PERFORM_ACTION',
  RESET: 'RESET',
  ROLLBACK: 'ROLLBACK',
  COMMIT: 'COMMIT',
  SWEEP: 'SWEEP',
  TOGGLE_ACTION: 'TOGGLE_ACTION',
  JUMP_TO_STATE: 'JUMP_TO_STATE',
  SET_MONITOR_STATE: 'SET_MONITOR_STATE',
  RECOMPUTE_STATES: 'RECOMPUTE_STATES'
};

const INIT_ACTION = {
  type: '@@INIT'
};

function toggle(obj, key) {
  const clone = { ...obj };
  if (clone[key]) {
    delete clone[key];
  } else {
    clone[key] = true;
  }
  return clone;
}

/**
 * Computes the next entry in the log by applying an action.
 */
function computeNextEntry(reducer, action, state, error) {
  if (error) {
    return {
      state,
      error: 'Interrupted by an error up the chain'
    };
  }

  let nextState = state;
  let nextError;
  try {
    nextState = reducer(state, action);
  } catch (err) {
    nextError = err.toString();
    console.error(err.stack || err);
  }

  return {
    state: nextState,
    error: nextError
  };
}

/**
 * Runs the reducer on all actions to get a fresh computation log.
 * It's probably a good idea to do this only if the code has changed,
 * but until we have some tests we'll just do it every time an action fires.
 */
function recomputeStates(reducer, committedState, stagedActions, skippedActions) {
  const computedStates = [];

  for (let i = 0; i < stagedActions.length; i++) {
    const action = stagedActions[i];

    const previousEntry = computedStates[i - 1];
    const previousState = previousEntry ? previousEntry.state : committedState;
    const previousError = previousEntry ? previousEntry.error : undefined;

    const shouldSkip = Boolean(skippedActions[i]);
    const entry = shouldSkip ?
      previousEntry :
      computeNextEntry(reducer, action, previousState, previousError);

    computedStates.push(entry);
  }

  return computedStates;
}

/**
 * Lifts the app state reducer into a DevTools state reducer.
 */
function liftReducer(reducer, initialState) {
  const initialLiftedState = {
    committedState: initialState,
    stagedActions: [INIT_ACTION],
    skippedActions: {},
    currentStateIndex: 0,
    monitorState: {
      isVisible: true
    },
    timestamps: [Date.now()]
  };

  /**
   * Manages how the DevTools actions modify the DevTools state.
   */
  return function liftedReducer(liftedState = initialLiftedState, liftedAction) {
    let {
      committedState,
      stagedActions,
      skippedActions,
      computedStates,
      currentStateIndex,
      monitorState,
      timestamps
    } = liftedState;

    switch (liftedAction.type) {
    case ActionTypes.RESET:
      committedState = initialState;
      stagedActions = [INIT_ACTION];
      skippedActions = {};
      currentStateIndex = 0;
      timestamps = [liftedAction.timestamp];
      break;
    case ActionTypes.COMMIT:
      committedState = computedStates[currentStateIndex].state;
      stagedActions = [INIT_ACTION];
      skippedActions = {};
      currentStateIndex = 0;
      timestamps = [liftedAction.timestamp];
      break;
    case ActionTypes.ROLLBACK:
      stagedActions = [INIT_ACTION];
      skippedActions = {};
      currentStateIndex = 0;
      timestamps = [liftedAction.timestamp];
      break;
    case ActionTypes.TOGGLE_ACTION:
      skippedActions = toggle(skippedActions, liftedAction.index);
      break;
    case ActionTypes.JUMP_TO_STATE:
      currentStateIndex = liftedAction.index;
      break;
    case ActionTypes.SWEEP:
      stagedActions = stagedActions.filter((_, i) => !skippedActions[i]);
      timestamps = timestamps.filter((_, i) => !skippedActions[i]);
      skippedActions = {};
      currentStateIndex = Math.min(currentStateIndex, stagedActions.length - 1);
      break;
    case ActionTypes.PERFORM_ACTION:
      if (currentStateIndex === stagedActions.length - 1) {
        currentStateIndex++;
      }
      stagedActions = [...stagedActions, liftedAction.action];
      timestamps = [...timestamps, liftedAction.timestamp];
      break;
    case ActionTypes.SET_MONITOR_STATE:
      monitorState = liftedAction.monitorState;
      break;
    case ActionTypes.RECOMPUTE_STATES:
      stagedActions = liftedAction.stagedActions;
      timestamps = liftedAction.timestamps;
      committedState = liftedAction.committedState;
      currentStateIndex = stagedActions.length - 1;
      skippedActions = {};
      break;
    default:
      break;
    }

    computedStates = recomputeStates(
      reducer,
      committedState,
      stagedActions,
      skippedActions
    );

    return {
      committedState,
      stagedActions,
      skippedActions,
      computedStates,
      currentStateIndex,
      monitorState,
      timestamps
    };
  };
}

/**
 * Lifts an app action to a DevTools action.
 */
function liftAction(action) {
  const liftedAction = {
    type: ActionTypes.PERFORM_ACTION,
    action,
    timestamp: Date.now()
  };
  return liftedAction;
}

/**
 * Unlifts the DevTools state to the app state.
 */
function unliftState(liftedState) {
  const { computedStates, currentStateIndex } = liftedState;
  const { state } = computedStates[currentStateIndex];
  return state;
}

/**
 * Unlifts the DevTools store to act like the app's store.
 */
function unliftStore(liftedStore, reducer) {
  return {
    ...liftedStore,
    devToolsStore: liftedStore,
    dispatch(action) {
      liftedStore.dispatch(liftAction(action));
      return action;
    },
    getState() {
      return unliftState(liftedStore.getState());
    },
    getReducer() {
      return reducer;
    },
    replaceReducer(nextReducer) {
      liftedStore.replaceReducer(liftReducer(nextReducer));
    }
  };
}

/**
 * Action creators to change the DevTools state.
 */
export const ActionCreators = {
  reset() {
    return { type: ActionTypes.RESET, timestamp: Date.now() };
  },
  rollback() {
    return { type: ActionTypes.ROLLBACK, timestamp: Date.now() };
  },
  commit() {
    return { type: ActionTypes.COMMIT, timestamp: Date.now() };
  },
  sweep() {
    return { type: ActionTypes.SWEEP };
  },
  toggleAction(index) {
    return { type: ActionTypes.TOGGLE_ACTION, index };
  },
  jumpToState(index) {
    return { type: ActionTypes.JUMP_TO_STATE, index };
  },
  setMonitorState(monitorState) {
    return { type: ActionTypes.SET_MONITOR_STATE, monitorState };
  },
  recomputeStates(committedState, stagedActions) {
    return {
      type: ActionTypes.RECOMPUTE_STATES,
      committedState,
      stagedActions
    };
  }
};

/**
 * Redux DevTools middleware.
 */
export default function devTools() {
  return next => (reducer, initialState) => {
    const liftedReducer = liftReducer(reducer, initialState);
    const liftedStore = next(liftedReducer);
    const store = unliftStore(liftedStore, reducer);
    return store;
  };
}
<|endoftext|>


<commit_before>'use strict';

var fn   = require('./fn'),
    set  = require('./list/set'),
    util = require('./util');

var self;

/**
 * This module defines operations on objects.
 *
 * @module fkit/obj
 * @summary Objects
 * @author Josh Bassett
 */
self = module.exports = {
  /**
   * Returns the result of the method `k` of object `o` applied to the value
   * `a`.
   *
   * @summary Applies a function to a method.
   *
   * @example
   *   var person = {sayHi: function(a) { return ['Hi', a, '!'].join(' '); }};
   *   F.applyMethod(sayHi, 'Jane', person); // Hi Jane!
   *
   * @curried
   * @function
   * @param k A string.
   * @param a A value.
   * @param o An object.
   * @returns A value.
   */
  applyMethod: fn.curry(function(k, a, o) {
    return o[k](a);
  }),

  /**
   * Returns the result of the method `k` of object `o` applied to the values
   * `a` and `b`.
   *
   * @summary Applies a function to a method.
   *
   * @example
   *   var person = {sayHi: function(a, b) { return ['Hi', a, b, '!'].join(' '); }};
   *   F.applyMethod2(sayHi, 'Jane', 'Appleseed', person); // Hi Jane Appleseed!
   *
   * @curried
   * @function
   * @param k A string.
   * @param a A value.
   * @param b A value.
   * @param o An object.
   * @returns A value.
   */
  applyMethod2: fn.curry(function(k, a, b, o) {
    return o[k](a, b);
  }),

  /**
   * Returns the result of the method `k` of object `o` applied to the values
   * `a`, `b`, and `c`.
   *
   * @summary Applies a function to a method.
   *
   * @example
   *   var person = {sayHi: function(a, b, c) { return ['Hi', a, b, c, '!'].join(' '); }};
   *   F.applyMethod3(sayHi, 'Ms', 'Jane', 'Appleseed', person); // Hi Ms Jane Appleseed!
   *
   * @curried
   * @function
   * @param k A string.
   * @param a A value.
   * @param b A value.
   * @param c A value.
   * @param o An object.
   * @returns A value.
   */
  applyMethod3: fn.curry(function(k, a, b, c, o) {
    return o[k](a, b, c);
  }),

  /**
   * Returns a copy of the objects in the list of `os`.
   *
   * Properties with the same key will take precedence from right to left.
   *
   * The copy will have the *same* prototype as the *first* object in the list.
   *
   * @summary Creates a copy of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.copy(person, {name: 'bob'}); // {name: 'bob', age: 20, city: 'Melbourne'}
   *
   * @function
   * @param os A list.
   * @returns A new object.
   */
  copy: fn.variadic(function(o, ps) {
    return util.extend(new o.constructor(), [o].concat(ps));
  }),

  /**
   * Returns the property `k` of the object `o`.
   *
   * @summary Gets a property of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.get('name', person); // 'jane'
   *
   * @curried
   * @function
   * @param k A string.
   * @param o An object.
   * @returns A value.
   */
  get: fn.curry(function(k, o) { return o[k]; }),

  /**
   * Returns a copy of the object `o` with the property `k` set to the value
   * `v`.
   *
   * @summary Sets a property of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.set('name', 'bob', person); // {name: 'bob', age: 20, city: 'Melbourne'}
   *
   * @curried
   * @function
   * @param k A string.
   * @param v A value.
   * @param o An object.
   * @returns A new object.
   */
  set: fn.curry(function(k, v, o) {
    var p = {};
    p[k] = v;
    return self.copy(o, p);
  }),

  /**
   * Returns a copy of the object `o` with the property `k` updated with the
   * function `f`.
   *
   * @summary Updates a property of an object with a function.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.update('age', F.inc, person); // {name: 'jane', age: 21, city: 'Melbourne'}
   *
   * @curried
   * @function
   * @param k A string.
   * @param f A function.
   * @param o An object.
   * @returns A new object.
   */
  update: fn.curry(function(k, f, o) {
    return self.set(k, f(self.get(k, o)), o);
  }),

  /**
   * Returns a copy of the object `o` *with* the properties in the list of
   * `ks`.
   *
   * @summary Picks properties of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.pick(['name', 'age'], person); // {name: 'jane', age: 20}
   *
   * @curried
   * @function
   * @param o An object.
   * @param ks A list.
   * @returns A new object.
   */
  pick: fn.curry(function(ks, o) {
    return ks.reduce(function(p, k) {
      return self.set(k, self.get(k, o), p);
    }, {});
  }),

  /**
   * Returns a copy of the object `o` *without* the properties in the list of
   * `ks`.
   *
   * @summary Omits properties of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.omit(['name', 'age'], person); // {city: 'Melbourne'}
   *
   * @curried
   * @function
   * @param o An object.
   * @param ks A list.
   * @returns A new object.
   */
  omit: fn.curry(function(ks, o) {
    return set
      .difference(self.keys(o), ks)
      .reduce(function(p, k) {
        return self.set(k, self.get(k, o), p);
      }, {});
  }),

  /**
   * Returns a list of key-value pairs for the properties of the object `o`.
   *
   * @summary Gets the key-value pairs of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.pairs(person); // [['name', 'jane'], ['age', 20], ['city', 'Melbourne']]
   *
   * @param o An object.
   * @returns A new list.
   */
  pairs: function(o) {
    return Object.keys(o).map(function(k) {
      return [k, self.get(k, o)];
    });
  },

  /**
   * Returns a list of keys for the properties of the object `o`.
   *
   * @summary Gets the keys of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.keys(person); // ['name', 'age', 'city']
   *
   * @param o An object.
   * @returns A new list.
   */
  keys: function(o) {
    return Object.keys(o);
  },

  /**
   * Returns a list of values for the properties of the object `o`.
   *
   * @summary Gets the values of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.values(person); // ['jane', 20, 'Melbourne']
   *
   * @param o An object.
   * @returns A new list.
   */
  values: function(o) {
    return Object
      .keys(o)
      .map(fn.flip(self.get)(o));
  },
};
<commit_msg>Fix .applyMethod summary.<commit_after>'use strict';

var fn   = require('./fn'),
    set  = require('./list/set'),
    util = require('./util');

var self;

/**
 * This module defines operations on objects.
 *
 * @module fkit/obj
 * @summary Objects
 * @author Josh Bassett
 */
self = module.exports = {
  /**
   * Returns the result of the method `k` of object `o` applied to the value
   * `a`.
   *
   * @summary Applies a method to a method.
   *
   * @example
   *   var person = {sayHi: function(a) { return ['Hi', a, '!'].join(' '); }};
   *   F.applyMethod(sayHi, 'Jane', person); // Hi Jane!
   *
   * @curried
   * @function
   * @param k A string.
   * @param a A value.
   * @param o An object.
   * @returns A value.
   */
  applyMethod: fn.curry(function(k, a, o) {
    return o[k](a);
  }),

  /**
   * Returns the result of the method `k` of object `o` applied to the values
   * `a` and `b`.
   *
   * @summary Applies a method to two values.
   *
   * @example
   *   var person = {sayHi: function(a, b) { return ['Hi', a, b, '!'].join(' '); }};
   *   F.applyMethod2(sayHi, 'Jane', 'Appleseed', person); // Hi Jane Appleseed!
   *
   * @curried
   * @function
   * @param k A string.
   * @param a A value.
   * @param b A value.
   * @param o An object.
   * @returns A value.
   */
  applyMethod2: fn.curry(function(k, a, b, o) {
    return o[k](a, b);
  }),

  /**
   * Returns the result of the method `k` of object `o` applied to the values
   * `a`, `b`, and `c`.
   *
   * @summary Applies a method to three values.
   *
   * @example
   *   var person = {sayHi: function(a, b, c) { return ['Hi', a, b, c, '!'].join(' '); }};
   *   F.applyMethod3(sayHi, 'Ms', 'Jane', 'Appleseed', person); // Hi Ms Jane Appleseed!
   *
   * @curried
   * @function
   * @param k A string.
   * @param a A value.
   * @param b A value.
   * @param c A value.
   * @param o An object.
   * @returns A value.
   */
  applyMethod3: fn.curry(function(k, a, b, c, o) {
    return o[k](a, b, c);
  }),

  /**
   * Returns a copy of the objects in the list of `os`.
   *
   * Properties with the same key will take precedence from right to left.
   *
   * The copy will have the *same* prototype as the *first* object in the list.
   *
   * @summary Creates a copy of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.copy(person, {name: 'bob'}); // {name: 'bob', age: 20, city: 'Melbourne'}
   *
   * @function
   * @param os A list.
   * @returns A new object.
   */
  copy: fn.variadic(function(o, ps) {
    return util.extend(new o.constructor(), [o].concat(ps));
  }),

  /**
   * Returns the property `k` of the object `o`.
   *
   * @summary Gets a property of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.get('name', person); // 'jane'
   *
   * @curried
   * @function
   * @param k A string.
   * @param o An object.
   * @returns A value.
   */
  get: fn.curry(function(k, o) { return o[k]; }),

  /**
   * Returns a copy of the object `o` with the property `k` set to the value
   * `v`.
   *
   * @summary Sets a property of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.set('name', 'bob', person); // {name: 'bob', age: 20, city: 'Melbourne'}
   *
   * @curried
   * @function
   * @param k A string.
   * @param v A value.
   * @param o An object.
   * @returns A new object.
   */
  set: fn.curry(function(k, v, o) {
    var p = {};
    p[k] = v;
    return self.copy(o, p);
  }),

  /**
   * Returns a copy of the object `o` with the property `k` updated with the
   * function `f`.
   *
   * @summary Updates a property of an object with a function.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.update('age', F.inc, person); // {name: 'jane', age: 21, city: 'Melbourne'}
   *
   * @curried
   * @function
   * @param k A string.
   * @param f A function.
   * @param o An object.
   * @returns A new object.
   */
  update: fn.curry(function(k, f, o) {
    return self.set(k, f(self.get(k, o)), o);
  }),

  /**
   * Returns a copy of the object `o` *with* the properties in the list of
   * `ks`.
   *
   * @summary Picks properties of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.pick(['name', 'age'], person); // {name: 'jane', age: 20}
   *
   * @curried
   * @function
   * @param o An object.
   * @param ks A list.
   * @returns A new object.
   */
  pick: fn.curry(function(ks, o) {
    return ks.reduce(function(p, k) {
      return self.set(k, self.get(k, o), p);
    }, {});
  }),

  /**
   * Returns a copy of the object `o` *without* the properties in the list of
   * `ks`.
   *
   * @summary Omits properties of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.omit(['name', 'age'], person); // {city: 'Melbourne'}
   *
   * @curried
   * @function
   * @param o An object.
   * @param ks A list.
   * @returns A new object.
   */
  omit: fn.curry(function(ks, o) {
    return set
      .difference(self.keys(o), ks)
      .reduce(function(p, k) {
        return self.set(k, self.get(k, o), p);
      }, {});
  }),

  /**
   * Returns a list of key-value pairs for the properties of the object `o`.
   *
   * @summary Gets the key-value pairs of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.pairs(person); // [['name', 'jane'], ['age', 20], ['city', 'Melbourne']]
   *
   * @param o An object.
   * @returns A new list.
   */
  pairs: function(o) {
    return Object.keys(o).map(function(k) {
      return [k, self.get(k, o)];
    });
  },

  /**
   * Returns a list of keys for the properties of the object `o`.
   *
   * @summary Gets the keys of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.keys(person); // ['name', 'age', 'city']
   *
   * @param o An object.
   * @returns A new list.
   */
  keys: function(o) {
    return Object.keys(o);
  },

  /**
   * Returns a list of values for the properties of the object `o`.
   *
   * @summary Gets the values of an object.
   *
   * @example
   *   var person = {name: 'jane', age: 20, city: 'Melbourne'};
   *   F.values(person); // ['jane', 20, 'Melbourne']
   *
   * @param o An object.
   * @returns A new list.
   */
  values: function(o) {
    return Object
      .keys(o)
      .map(fn.flip(self.get)(o));
  },
};
<|endoftext|>


<commit_before>var map = require('through2-map');
var fs = require('fs');

module.exports.create = function create_json_parse_stream(dataDirectory) {
  return map.obj(function(record) {
    try {
      return JSON.parse(fs.readFileSync(dataDirectory + record.path));
    } catch (err) {
      console.error('exception on %s:', record.path, err);
      console.error('Inability to parse JSON usually means that WOF has been cloned ' +
                    'without using git-lfs, please see instructions here: ' +
                    'https://github.com/whosonfirst/whosonfirst-data#git-and-large-files');
      return {};
    }
  });
};
<commit_msg>Load JSON files in parallel<commit_after>var fs = require('fs');
var parallelStream = require('pelias-parallel-stream');

var maxInFlight = 10;

module.exports.create = function create_json_parse_stream(dataDirectory) {
  return parallelStream(maxInFlight, function(record, enc, next) {
    fs.readFile(dataDirectory + record.path, function(err, data) {
      if (err) {
        next(err);
      } else {
        try {
          var object = JSON.parse(data);
          next(null, object);
        } catch (parse_err) {
          console.error('exception on %s:', record.path, parse_err);
          console.error('Inability to parse JSON usually means that WOF has been cloned ' +
                        'without using git-lfs, please see instructions here: ' +
                        'https://github.com/whosonfirst/whosonfirst-data#git-and-large-files');
          next(null, {});
        }
      }
    });
  });
};
<|endoftext|>


<commit_before>_.off = function(target, events, fn) {
	if (!events) {
		return _.wipe(target);
	}

	var listeners = _.listener(target).s;
	for (var i=0,m=events.length; i<m; i++) {
		var type = events[i],
			filter = { fn: fn, target: target };
		type = filter.type = _.parse(type, filter);

		if (type) {
			_.filter(listeners[type], filter);
		} else {
			for (type in listeners) {
				_.clean(listeners[type], filter);
			}
			if (_.empty(listeners)) {
				_.wipe(target);
			}
		}
	}
};
_.empty = function(o){ for (var k in o){ return !k; } return true; };
_.wipe = function(target){ delete target[_._key]; };

_.clean = function(handlers, filter) {
	for (var i=0,m=handlers.length; i<m; i++) {
		if (_.cleans(handlers[i], filter)) {
			_.cleaned(handlers.splice(i--, 1)[0]);
		}
	}
	if (!handlers.length && filter.target.removeEventListener) {
		filter.target.removeEventListener(filter.type, _.listener(filter.target));
		return true;
	}
};
_.cleans = function(handler, filter) {
	return _.handles(handler, filter) &&
		(!filter.detail || handler.detail === filter.detail) &&
		(!filter.fn || handler.fn === filter.fn);
};
_.cleaned = _.noop;// extension hook (called with cleaned handler as arg)

Eventi.off = _.wrap('off', 3);
<commit_msg>clean up all kinds of problems<commit_after>_.off = function(target, events, fn) {
	var listener = target[_._key];
	if (listener) {
		for (var i=0, m=events.length; i<m; i++) {
			var filter = { fn:fn },
				type = _.parse(events[i], filter.match = {});
			if (type) {
				_.clean(type, filter, listener, target);
			} else {
				for (type in listener.s) {
					_.clean(type, filter, listener, target);
				}
			}
		}
		if (_.empty(listener.s)) {
			delete target[_._key];
		}
	}
};
_.empty = function(o){ for (var k in o){ return !k; } return true; };
_.clean = function(type, filter, listener, target) {
	var handlers = listener.s[type];
	if (handlers) {
		for (var i=0, m=handlers.length; i<m; i++) {
			if (_.cleans(handlers[i], filter)) {
				_.cleaned(handlers.splice(i--, 1)[0]);
				m--;
			}
		}
	}
	if (!handlers.length) {
		if (target.removeEventListener) {
			target.removeEventListener(type, listener);
		}
		delete listener.s[type];
	}
};
_.cleans = function(handler, filter) {
	return _.matches(handler.match, filter.match) && (!filter.fn || handler.fn === filter.fn);
};
_.cleaned = _.noop;// extension hook (called with cleaned handler as arg)

Eventi.off = _.wrap('off', 3);
<|endoftext|>


<commit_before>const Vue = require('vue/dist/vue.common.js');
import jsmediatags from 'jsmediatags';
import fs from 'fs';
import jetpack from 'fs-jetpack'; // module loaded from npm
import firstBy from '../helpers/thenBy.js';
const { dialog, app } = require('electron').remote;

console.log(app.getPath('userData'));
//Basic object for a song
var Song = function(data, path) {
    this.artist = data.artist || 'Unknown Artist';
    this.album = data.album || 'Unknown Album';
    this.title = data.title || 'Unknown Title';
    this.track = parseInt(data.track) || 0;

    var image = data.picture;
    if(image) {
        var base64String = "";
        for (var i = 0; i < image.data.length; i++) {
            base64String += String.fromCharCode(image.data[i]);
        }
        var base64 = "data:" + image.format + ";base64," +
                window.btoa(base64String);
        this.picture = base64;
    }
    else {
        this.picture = './img/albumPlaceHolder.png';
    }

    this.path = path;
}

const musicBar = Vue.component('music-bar', {
    template: '#music-bar',
    props: ['musicInit'],
    data: function() {
        return {
            slash: (function() {
                if(process.platform === 'darwin' || process.platform === 'linux') {
                    return '/';
                }
                else return '\\'
            })(),
            flexOpt: 1,
            musicLoaded: false,
            audio: '',
            isPlaying: false,
            library: [],
            currentSong: {
                artist: 'No song',
                title: 'No title',
                picture: './img/albumPlaceHolder.png',
                path: './'
            },
            index: 0,
            percentageTime: 0,
            dragging: "none",
            directory: app.getPath('userData'),
            userPrefs: {},
        }
    },
    events: {
        fireOpenFileExplorer: function() {
            this.openFileExplorer();
        }
    },
    methods: {
        getMusicData: function(path) {
            var musicBar = this;
            return new Promise(function(resolve, reject) {
                jsmediatags.read(path, {
                    onSuccess: function(data) {
                        console.log(data.tags);
                        musicBar.library.push(new Song(data.tags, path));
                        resolve();
                    },
                    onError: function(error) {
                        console.log(':(', error.type, error.info);
                        reject();
                    }
                })
            });
        },
        searchDir: function(path, promises, callback) {
            var fileList = jetpack.list(path);
            for(var i = 0; i < fileList.length; i++) {
                var file = path + this.slash + fileList[i];

                if(fs.lstatSync(file).isDirectory()) {
                    this.searchDir(file, promises);
                }
                else if(file.substr(file.length - 4) === '.mp3') {
                    promises.push(this.getMusicData(file));
                }
                else {

                }
            }

            if(callback) {
                callback(promises);
            }
        },
        sortLibrary: function() {
            this.library.sort(
                firstBy(function (v) { return v.artist })
                .thenBy("album")
                .thenBy("track")
            );
            console.log(this.library);
        },
        openFileExplorer: function() {
            var musicBar = this;
            dialog.showOpenDialog({properties: ['openDirectory']}, function(files) {
                var musicFolder = files[0];
                var promises = []
                musicBar.searchDir(musicFolder, promises, function() {
                    Promise.all(promises).then(function() {
                        musicBar.sortLibrary();
                        musicBar.currentSong = musicBar.library[0];
                        musicBar.musicLoaded = true;
                        musicBar.flexOpt = 'none';
                        musicBar.$emit('init');
                        musicBar.userPrefs.library = musicBar.library;
                        jetpack.write(musicBar.directory + musicBar.slash + 'vizzyPrefs.json', musicBar.userPrefs);
                        console.log('done');
                    });
                });
            });
        },
        play: function() {
            this.audio.play();
            this.isPlaying = true;
        },
        pause: function() {
            this.audio.pause();
            this.isPlaying = false;
        },
        prev: function() {
            if(this.index === 0) {
                this.index = this.library.length - 1;
            }
            else {
                this.index--;
            }

            var song = this.library[this.index]
            if(jetpack.exists(song.path)) {
                this.currentSong = song;
            }
            else {
                this.prev();
            }
            var musicBar = this;
            setTimeout(function() {
                musicBar.pause();
                musicBar.play();
            },100);
        },
        next: function() {
            if(this.index === this.library.length - 1) {
                this.index = 0;
            }
            else {
                this.index++;
            }

            var song = this.library[this.index]
            if(jetpack.exists(song.path)) {
                this.currentSong = song;
            }
            else {
                console.log('file does not exist skipping');
                this.next();
            }
            var musicBar = this;
            setTimeout(function() {
                musicBar.pause();
                musicBar.play();
            },100);
        },
        updateTracker: function() {
            if(this.musicLoaded) {
                var x = event.clientX;
                var width = window.innerWidth;

                var percentage = x/width;
                this.percentageTime = percentage * 100;
                this.audio.currentTime = this.audio.duration * percentage;
            }
        },
        checkPrefs: function() {
            if(jetpack.exists(this.directory + this.slash + 'vizzyPrefs.json')) {
                var prefs = JSON.parse(jetpack.read(this.directory + this.slash + 'vizzyPrefs.json', ['jsonWithDates']));
                console.log(prefs);
                this.library = prefs.library;
                this.sortLibrary();
                this.currentSong = this.library[0];
                this.musicLoaded = true;
                this.flexOpt = 'none';
                this.$emit('init');
                console.log('preferences exist!');
            }
            else {
                console.log('preferences do not exist');
            }
        }
    },
    mounted: function () {
        this.checkPrefs();

        var musicBar = this;

        this.audio = document.getElementById('vizzy-audio');
        this.audio.onended = function() {
            musicBar.next();
        }

        var tracker = document.getElementById('tracker');
        var container = document.getElementById('drag-container');

        tracker.addEventListener('mousedown', function() {
            console.log('mouse down');
            musicBar.updateTracker();
            musicBar.dragging = 'block';
        }, false);

        container.addEventListener('mousemove', function() {
            if (musicBar.dragging === "block") {
                musicBar.updateTracker();
            };
        }, false);

        container.addEventListener('mouseup', function() {
            musicBar.dragging = 'none';
        }, false);

        function updateTime() {
            if(musicBar.isPlaying) {
                var currentTime = musicBar.audio.currentTime;
                var duration = musicBar.audio.duration;
                musicBar.percentageTime = (currentTime/duration) * 100;
            }
            window.requestAnimationFrame(updateTime);
        }

        window.requestAnimationFrame(updateTime);
    }
});

export default {
    musicBar
}
<commit_msg>Reverting my fuck up<commit_after>const Vue = require('vue/dist/vue.common.js');
import jsmediatags from 'jsmediatags';
import fs from 'fs';
import jetpack from 'fs-jetpack'; // module loaded from npm
import firstBy from '../helpers/thenBy.js';
const { dialog, app } = require('electron').remote;

console.log(app.getPath('userData'));
//Basic object for a song
var Song = function(data, path) {
    this.artist = data.artist || 'Unknown Artist';
    this.album = data.album || 'Unknown Album';
    this.title = data.title || 'Unknown Title';
    this.track = parseInt(data.track) || 0;

    var image = data.picture;
    if(image) {
        var base64String = "";
        for (var i = 0; i < image.data.length; i++) {
            base64String += String.fromCharCode(image.data[i]);
        }
        var base64 = "data:" + image.format + ";base64," +
                window.btoa(base64String);
        this.picture = base64;
    }
    else {
        this.picture = './img/albumPlaceHolder.png';
    }
    // this.number = data.track.no;
    // this.albumImg = data.picture[0].data;
    // this.albumImgExtension = data.picture[0].format;

    this.path = path;
}

const musicBar = Vue.component('music-bar', {
    template: '#music-bar',
    props: ['musicInit'],
    data: function() {
        return {
            slash: (function() {
                if(process.platform === 'darwin' || process.platform === 'linux') {
                    return '/';
                }
                else return '\\'
            })(),
            flexOpt: 1,
            musicLoaded: false,
            audio: '',
            isPlaying: false,
            library: [],
            currentSong: {
                artist: 'No song',
                title: 'No title',
                picture: './img/albumPlaceHolder.png',
                path: './'
            },
            index: 0,
            percentageTime: 0,
            dragging: "none",
            directory: app.getPath('userData'),
            userPrefs: {},
        }
    },
    events: {
        fireOpenFileExplorer: function() {
            this.openFileExplorer();
        }
    },
    methods: {
        getMusicData: function(path) {
            var musicBar = this;
            return new Promise(function(resolve, reject) {
                jsmediatags.read(path, {
                    onSuccess: function(data) {
                        console.log(data.tags);
                        musicBar.library.push(new Song(data.tags, path));
                        resolve();
                    },
                    onError: function(error) {
                        console.log(':(', error.type, error.info);
                        reject();
                    }
                })
            });
        },
        searchDir: function(path, promises, callback) {
            var fileList = jetpack.list(path);
            for(var i = 0; i < fileList.length; i++) {
                var file = path + this.slash + fileList[i];

                if(fs.lstatSync(file).isDirectory()) {
                    this.searchDir(file, promises);
                }
                else if(file.substr(file.length - 4) === '.mp3') {
                    promises.push(this.getMusicData(file));
                }
                else {

                }
            }

            if(callback) {
                callback(promises);
            }
        },
        sortLibrary: function() {
            this.library.sort(
                firstBy(function (v) { return v.artist })
                .thenBy("album")
                .thenBy("track")
            );
            console.log(this.library);
        },
        openFileExplorer: function() {
            var musicBar = this;
            dialog.showOpenDialog({properties: ['openDirectory']}, function(files) {
                var musicFolder = files[0];
                var promises = []
                musicBar.searchDir(musicFolder, promises, function() {
                    Promise.all(promises).then(function() {
                        musicBar.sortLibrary();
                        musicBar.currentSong = musicBar.library[0];
                        musicBar.musicLoaded = true;
                        musicBar.flexOpt = 'none';
                        musicBar.$emit('init');
                        musicBar.userPrefs.library = musicBar.library;
                        jetpack.write(musicBar.directory + musicBar.slash + 'vizzyPrefs.json', musicBar.userPrefs);
                        console.log('done');
                    });
                });
            });
        },
        play: function() {
            this.audio.play();
            this.isPlaying = true;
        },
        pause: function() {
            this.audio.pause();
            this.isPlaying = false;
        },
        prev: function() {
            if(this.index === 0) {
                this.index = this.library.length - 1;
            }
            else {
                this.index--;
            }

            var song = this.library[this.index]
            if(jetpack.exists(song.path)) {
                this.currentSong = song;
            }
            else {
                this.prev();
            }
            var musicBar = this;
            setTimeout(function() {
                musicBar.pause();
                musicBar.play();
            },100);
        },
        next: function() {
            if(this.index === this.library.length - 1) {
                this.index = 0;
            }
            else {
                this.index++;
            }

            var song = this.library[this.index]
            if(jetpack.exists(song.path)) {
                this.currentSong = song;
            }
            else {
                console.log('file does not exist skipping');
                this.next();
            }
            var musicBar = this;
            setTimeout(function() {
                musicBar.pause();
                musicBar.play();
            },100);
        },
        updateTracker: function() {
            if(this.musicLoaded) {
                var x = event.clientX;
                var width = window.innerWidth;

                var percentage = x/width;
                this.percentageTime = percentage * 100;
                this.audio.currentTime = this.audio.duration * percentage;
            }
        },
        checkPrefs: function() {
            if(jetpack.exists(this.directory + this.slash + 'vizzyPrefs.json')) {
                var prefs = JSON.parse(jetpack.read(this.directory + this.slash + 'vizzyPrefs.json', ['jsonWithDates']));
                console.log(prefs);
                this.library = prefs.library;
                this.sortLibrary();
                this.currentSong = this.library[0];
                this.musicLoaded = true;
                this.flexOpt = 'none';
                this.$emit('init');
                console.log('preferences exist!');
            }
            else {
                console.log('preferences do not exist');
            }
        }
    },
    mounted: function () {
        this.checkPrefs();

        var musicBar = this;

        this.audio = document.getElementById('vizzy-audio');
        this.audio.onended = function() {
            musicBar.next();
        }

        //initialize audio context & audio nodes
        var audioContext = new (window.AudioContext || window.webkitAudioContext)();
        var source = audioContext.createMediaElementSource(this.audio);
        var analyze = audioContext.createAnalyser();
        analyze.fftsize=2048;
        analyze.smoothingTimeConstant=.5; //smoothing time is important for vizualization

        //connect audio nodes
        source.connect(analyze);
        analyze.connect(audioContext.destination);

        var tracker = document.getElementById('tracker');
        var container = document.getElementById('drag-container');

        tracker.addEventListener('mousedown', function() {
            console.log('mouse down');
            musicBar.updateTracker();
            musicBar.dragging = 'block';
        }, false);

        container.addEventListener('mousemove', function() {
            if (musicBar.dragging === "block") {
                musicBar.updateTracker();
            };
        }, false);

        container.addEventListener('mouseup', function() {
            musicBar.dragging = 'none';
        }, false);

        function musicData(){
            var buffer = analyze.frequencyBinCount;
            var data = new Uint8Array(buffer);
            analyze.getByteFrequencyData(data);

            //find the dominant frequency bin
            var max = 0;
            var index = -1;
            for (var i = 0; i < buffer; i++){
                if (data[i]>max){
                    max = data[i];
                    index = i;
                }
            }
            //calculate the dominant frequency
            var frequency = (index * 44100)/ 2048.0;

            return {
                'frequency': frequency
            };
        }

        function updateTime() {
            if(musicBar.isPlaying) {
                var currentTime = musicBar.audio.currentTime;
                var duration = musicBar.audio.duration;
                musicBar.percentageTime = (currentTime/duration) * 100;
            }
            window.requestAnimationFrame(refresh);
        }

        function refresh(){
            updateTime();
            console.log(musicData());
        }

        window.requestAnimationFrame(refresh);
    }
});

export default {
    musicBar
}
<|endoftext|>


<commit_before>import VeeValidate from '../plugin';
import RuleContainer from '../core/ruleContainer';
import { normalizeEvents, isEvent } from '../utils/events';
import { createFlags, normalizeRules, warn, isCallable, debounce } from '../utils';
import { findModel, extractVNodes, addVNodeListener, getInputEventName, createRenderless } from '../utils/vnode';

let $validator = null;

export function createValidationCtx (ctx) {
  return {
    errors: ctx.messages,
    flags: ctx.flags,
    classes: ctx.classes,
    valid: ctx.isValid,
    reset: () => ctx.reset(),
    validate: (...args) => ctx.validate(...args),
    aria: {
      'aria-invalid': ctx.flags.invalid ? 'true' : 'false',
      'aria-required': ctx.isRequired ? 'true' : 'false'
    }
  };
}

export function onRenderUpdate (model) {
  let validateNow = this.value !== model.value || this._needsValidation;
  let shouldRevalidate = this.flags.validated;
  if (!this.initialized) {
    this.initialValue = model.value;
  }

  if (!this.initialized && model.value === undefined) {
    validateNow = true;
  }

  if (validateNow) {
    const silentHandler = ({ valid }) => {
      // initially assign the valid/invalid flags.
      this.setFlags({
        valid,
        invalid: !valid
      });
    };

    this.value = model.value;
    this.validateSilent().then(this.immediate || shouldRevalidate ? this.applyResult : silentHandler);
  }

  this._needsValidation = false;
}

// Creates the common handlers for a validatable context.
export function createCommonHandlers (ctx) {
  const onInput = (e) => {
    ctx.syncValue(e); // track and keep the value updated.
    ctx.setFlags({ dirty: true, pristine: false });
  };

  // Blur event listener.
  const onBlur = () => {
    ctx.setFlags({ touched: true, untouched: false });
  };

  const onValidate = debounce(
    () => {
      const pendingPromise = ctx.validate();
      // avoids race conditions between successive validations.
      ctx._waiting = pendingPromise;
      pendingPromise.then(result => {
        if (pendingPromise === ctx._waiting) {
          ctx.applyResult(result);
          ctx._waiting = null;
        }
      });
    },
    ctx.debounce
  );

  return { onInput, onBlur, onValidate };
}

// Adds all plugin listeners to the vnode.
function addListeners (node) {
  const model = findModel(node);
  // cache the input eventName.
  this._inputEventName = this._inputEventName || getInputEventName(node, model);

  onRenderUpdate.call(this, model);

  const { onInput, onBlur, onValidate } = createCommonHandlers(this);
  addVNodeListener(node, this._inputEventName, onInput);
  addVNodeListener(node, 'blur', onBlur);

  // add the validation listeners.
  this.normalizedEvents.forEach(evt => {
    addVNodeListener(node, evt, onValidate);
  });

  this.initialized = true;
}

function createValuesLookup (ctx) {
  let providers = ctx.$_veeObserver.refs;

  return ctx.fieldDeps.reduce((acc, depName) => {
    if (!providers[depName]) {
      return acc;
    }

    acc[depName] = providers[depName].value;

    return acc;
  }, {});
}

function updateRenderingContextRefs (ctx) {
  const { id, vid } = ctx;

  // Nothing has changed.
  if (id === vid && ctx.$_veeObserver.refs[id]) {
    return;
  }

  // vid was changed.
  if (id !== vid && ctx.$_veeObserver.refs[id] === ctx) {
    ctx.$_veeObserver.$unsubscribe(ctx);
  }

  ctx.$_veeObserver.$subscribe(ctx);
  ctx.id = vid;
}

function createObserver () {
  return {
    refs: {},
    $subscribe (ctx) {
      this.refs[ctx.vid] = ctx;
    },
    $unsubscribe (ctx) {
      delete this.refs[ctx.vid];
    }
  };
}

let id = 0;

export const ValidationProvider = {
  $__veeInject: false,
  inject: {
    $_veeObserver: {
      from: '$_veeObserver',
      default () {
        if (!this.$vnode.context.$_veeObserver) {
          this.$vnode.context.$_veeObserver = createObserver();
        }

        return this.$vnode.context.$_veeObserver;
      }
    }
  },
  props: {
    vid: {
      type: [String, Number],
      default: () => {
        id++;
        return id;
      }
    },
    name: {
      type: String,
      default: null
    },
    events: {
      type: [Array, String],
      default: () => ['input']
    },
    rules: {
      type: [Object, String],
      default: null
    },
    immediate: {
      type: Boolean,
      default: false
    },
    bails: {
      type: Boolean,
      default: () => VeeValidate.config.fastExit
    },
    debounce: {
      type: Number,
      default: () => VeeValidate.config.delay || 0
    }
  },
  watch: {
    rules: {
      deep: true,
      handler () {
        this._needsValidation = true;
      }
    }
  },
  data: () => ({
    messages: [],
    value: undefined,
    initialized: false,
    initialValue: undefined,
    flags: createFlags(),
    id: null
  }),
  methods: {
    setFlags (flags) {
      Object.keys(flags).forEach(flag => {
        this.flags[flag] = flags[flag];
      });
    },
    syncValue (e) {
      const value = isEvent(e) ? e.target.value : e;

      this.value = value;
      this.flags.changed = this.initialValue === value;
    },
    reset () {
      this.messages = [];
      this._waiting = null;
      this.initialValue = this.value;
      const flags = createFlags();
      this.setFlags(flags);
    },
    validate (...args) {
      if (args[0]) {
        this.syncValue(args[0]);
      }

      return this.validateSilent().then(result => {
        this.applyResult(result);

        return result;
      });
    },
    validateSilent () {
      this.setFlags({ pending: true });

      return $validator.verify(this.value, this.rules, {
        name: this.name,
        values: createValuesLookup(this),
        bails: this.bails
      }).then(result => {
        this.setFlags({ pending: false });

        return result;
      });
    },
    applyResult ({ errors }) {
      this.messages = errors;
      this.setFlags({
        valid: !errors.length,
        changed: this.value !== this.initialValue,
        invalid: !!errors.length,
        validated: true
      });
    },
    registerField () {
      if (!$validator) {
        /* istanbul ignore next */
        if (process.env.NODE_ENV !== 'production') {
          if (!VeeValidate.instance) {
            warn('You must install vee-validate first before using this component.');
          }
        }

        $validator = VeeValidate.instance._validator;
      }

      updateRenderingContextRefs(this);
    }
  },
  computed: {
    isValid () {
      return this.flags.valid;
    },
    fieldDeps () {
      const rules = normalizeRules(this.rules);
      let providers = this.$_veeObserver.refs;

      return Object.keys(rules).filter(RuleContainer.isTargetRule).map(rule => {
        const depName = rules[rule][0];
        const watcherName = `$__${depName}`;
        if (!isCallable(this[watcherName])) {
          this[watcherName] = providers[depName].$watch('value', () => {
            this.validate();
          });
        }

        return depName;
      });
    },
    normalizedEvents () {
      return normalizeEvents(this.events).map(e => {
        if (e === 'input') {
          return this._inputEventName;
        }

        return e;
      });
    },
    isRequired () {
      const rules = normalizeRules(this.rules);

      return !!rules.required;
    },
    classes () {
      const names = VeeValidate.config.classNames;
      return Object.keys(this.flags).reduce((classes, flag) => {
        const className = (names && names[flag]) || flag;
        if (flag === 'invalid') {
          classes[className] = !!this.messages.length;

          return classes;
        }

        if (flag === 'valid') {
          classes[className] = !this.messages.length;

          return classes;
        }

        if (className) {
          classes[className] = this.flags[flag];
        }

        return classes;
      }, {});
    }
  },
  render (h) {
    this.registerField();
    const ctx = createValidationCtx(this);

    // Gracefully handle non-existent scoped slots.
    let slot = this.$scopedSlots.default;
    if (!isCallable(slot)) {
      if (process.env.NODE_ENV !== 'production') {
        warn('ValidationProvider expects a scoped slot. Did you forget to add "slot-scope" to your slot?');
      }

      return createRenderless(h, this.$slots.default);
    }

    const nodes = slot(ctx);
    // Handle single-root slot.
    extractVNodes(nodes).forEach(input => {
      addListeners.call(this, input);
    });

    return createRenderless(h, nodes);
  },
  beforeDestroy () {
    // cleanup reference.
    this.$_veeObserver.$unsubscribe(this);
  }
};
<commit_msg>fix: ensure no nullable provider ids<commit_after>import VeeValidate from '../plugin';
import RuleContainer from '../core/ruleContainer';
import { normalizeEvents, isEvent } from '../utils/events';
import { createFlags, normalizeRules, warn, isCallable, debounce, isNullOrUndefined } from '../utils';
import { findModel, extractVNodes, addVNodeListener, getInputEventName, createRenderless } from '../utils/vnode';

let $validator = null;

let PROVIDER_COUNTER = 0;

export function createValidationCtx (ctx) {
  return {
    errors: ctx.messages,
    flags: ctx.flags,
    classes: ctx.classes,
    valid: ctx.isValid,
    reset: () => ctx.reset(),
    validate: (...args) => ctx.validate(...args),
    aria: {
      'aria-invalid': ctx.flags.invalid ? 'true' : 'false',
      'aria-required': ctx.isRequired ? 'true' : 'false'
    }
  };
}

export function onRenderUpdate (model) {
  let validateNow = this.value !== model.value || this._needsValidation;
  let shouldRevalidate = this.flags.validated;
  if (!this.initialized) {
    this.initialValue = model.value;
  }

  if (!this.initialized && model.value === undefined) {
    validateNow = true;
  }

  if (validateNow) {
    const silentHandler = ({ valid }) => {
      // initially assign the valid/invalid flags.
      this.setFlags({
        valid,
        invalid: !valid
      });
    };

    this.value = model.value;
    this.validateSilent().then(this.immediate || shouldRevalidate ? this.applyResult : silentHandler);
  }

  this._needsValidation = false;
}

// Creates the common handlers for a validatable context.
export function createCommonHandlers (ctx) {
  const onInput = (e) => {
    ctx.syncValue(e); // track and keep the value updated.
    ctx.setFlags({ dirty: true, pristine: false });
  };

  // Blur event listener.
  const onBlur = () => {
    ctx.setFlags({ touched: true, untouched: false });
  };

  const onValidate = debounce(
    () => {
      const pendingPromise = ctx.validate();
      // avoids race conditions between successive validations.
      ctx._waiting = pendingPromise;
      pendingPromise.then(result => {
        if (pendingPromise === ctx._waiting) {
          ctx.applyResult(result);
          ctx._waiting = null;
        }
      });
    },
    ctx.debounce
  );

  return { onInput, onBlur, onValidate };
}

// Adds all plugin listeners to the vnode.
function addListeners (node) {
  const model = findModel(node);
  // cache the input eventName.
  this._inputEventName = this._inputEventName || getInputEventName(node, model);

  onRenderUpdate.call(this, model);

  const { onInput, onBlur, onValidate } = createCommonHandlers(this);
  addVNodeListener(node, this._inputEventName, onInput);
  addVNodeListener(node, 'blur', onBlur);

  // add the validation listeners.
  this.normalizedEvents.forEach(evt => {
    addVNodeListener(node, evt, onValidate);
  });

  this.initialized = true;
}

function createValuesLookup (ctx) {
  let providers = ctx.$_veeObserver.refs;

  return ctx.fieldDeps.reduce((acc, depName) => {
    if (!providers[depName]) {
      return acc;
    }

    acc[depName] = providers[depName].value;

    return acc;
  }, {});
}

function updateRenderingContextRefs (ctx) {
  // IDs should not be nullable.
  if (isNullOrUndefined(ctx.id) && ctx.id === ctx.vid) {
    ctx.id = PROVIDER_COUNTER;
    PROVIDER_COUNTER++;
  }

  const { id, vid } = ctx;
  // Nothing has changed.
  if (id === vid && ctx.$_veeObserver.refs[id]) {
    return;
  }

  // vid was changed.
  if (id !== vid && ctx.$_veeObserver.refs[id] === ctx) {
    ctx.$_veeObserver.$unsubscribe(ctx);
  }

  ctx.$_veeObserver.$subscribe(ctx);
  ctx.id = vid;
}

function createObserver () {
  return {
    refs: {},
    $subscribe (ctx) {
      this.refs[ctx.vid] = ctx;
    },
    $unsubscribe (ctx) {
      delete this.refs[ctx.vid];
    }
  };
}

export const ValidationProvider = {
  $__veeInject: false,
  inject: {
    $_veeObserver: {
      from: '$_veeObserver',
      default () {
        if (!this.$vnode.context.$_veeObserver) {
          this.$vnode.context.$_veeObserver = createObserver();
        }

        return this.$vnode.context.$_veeObserver;
      }
    }
  },
  props: {
    vid: {
      type: [String, Number],
      default: () => {
        PROVIDER_COUNTER++;

        return PROVIDER_COUNTER;
      }
    },
    name: {
      type: String,
      default: null
    },
    events: {
      type: [Array, String],
      default: () => ['input']
    },
    rules: {
      type: [Object, String],
      default: null
    },
    immediate: {
      type: Boolean,
      default: false
    },
    bails: {
      type: Boolean,
      default: () => VeeValidate.config.fastExit
    },
    debounce: {
      type: Number,
      default: () => VeeValidate.config.delay || 0
    }
  },
  watch: {
    rules: {
      deep: true,
      handler () {
        this._needsValidation = true;
      }
    }
  },
  data: () => ({
    messages: [],
    value: undefined,
    initialized: false,
    initialValue: undefined,
    flags: createFlags(),
    id: null
  }),
  methods: {
    setFlags (flags) {
      Object.keys(flags).forEach(flag => {
        this.flags[flag] = flags[flag];
      });
    },
    syncValue (e) {
      const value = isEvent(e) ? e.target.value : e;

      this.value = value;
      this.flags.changed = this.initialValue === value;
    },
    reset () {
      this.messages = [];
      this._waiting = null;
      this.initialValue = this.value;
      const flags = createFlags();
      this.setFlags(flags);
    },
    validate (...args) {
      if (args[0]) {
        this.syncValue(args[0]);
      }

      return this.validateSilent().then(result => {
        this.applyResult(result);

        return result;
      });
    },
    validateSilent () {
      this.setFlags({ pending: true });

      return $validator.verify(this.value, this.rules, {
        name: this.name,
        values: createValuesLookup(this),
        bails: this.bails
      }).then(result => {
        this.setFlags({ pending: false });

        return result;
      });
    },
    applyResult ({ errors }) {
      this.messages = errors;
      this.setFlags({
        valid: !errors.length,
        changed: this.value !== this.initialValue,
        invalid: !!errors.length,
        validated: true
      });
    },
    registerField () {
      if (!$validator) {
        /* istanbul ignore next */
        if (process.env.NODE_ENV !== 'production') {
          if (!VeeValidate.instance) {
            warn('You must install vee-validate first before using this component.');
          }
        }

        $validator = VeeValidate.instance._validator;
      }

      updateRenderingContextRefs(this);
    }
  },
  computed: {
    isValid () {
      return this.flags.valid;
    },
    fieldDeps () {
      const rules = normalizeRules(this.rules);
      let providers = this.$_veeObserver.refs;

      return Object.keys(rules).filter(RuleContainer.isTargetRule).map(rule => {
        const depName = rules[rule][0];
        const watcherName = `$__${depName}`;
        if (!isCallable(this[watcherName])) {
          this[watcherName] = providers[depName].$watch('value', () => {
            this.validate();
          });
        }

        return depName;
      });
    },
    normalizedEvents () {
      return normalizeEvents(this.events).map(e => {
        if (e === 'input') {
          return this._inputEventName;
        }

        return e;
      });
    },
    isRequired () {
      const rules = normalizeRules(this.rules);

      return !!rules.required;
    },
    classes () {
      const names = VeeValidate.config.classNames;
      return Object.keys(this.flags).reduce((classes, flag) => {
        const className = (names && names[flag]) || flag;
        if (flag === 'invalid') {
          classes[className] = !!this.messages.length;

          return classes;
        }

        if (flag === 'valid') {
          classes[className] = !this.messages.length;

          return classes;
        }

        if (className) {
          classes[className] = this.flags[flag];
        }

        return classes;
      }, {});
    }
  },
  render (h) {
    this.registerField();
    const ctx = createValidationCtx(this);

    // Gracefully handle non-existent scoped slots.
    let slot = this.$scopedSlots.default;
    if (!isCallable(slot)) {
      if (process.env.NODE_ENV !== 'production') {
        warn('ValidationProvider expects a scoped slot. Did you forget to add "slot-scope" to your slot?');
      }

      return createRenderless(h, this.$slots.default);
    }

    const nodes = slot(ctx);
    // Handle single-root slot.
    extractVNodes(nodes).forEach(input => {
      addListeners.call(this, input);
    });

    return createRenderless(h, nodes);
  },
  beforeDestroy () {
    // cleanup reference.
    this.$_veeObserver.$unsubscribe(this);
  }
};
<|endoftext|>