<commit_before>var _ = require('underscore'),
    assert = require('assert'),
    fu = require('../lib/fileUtil'),
    fs = require('fs'),
    lib = require('./lib'),
    should = require('should');

describe('mixins', function() {
  describe('loading', function() {
    var readFileSync = fs.readFileSync,
        statSync = fs.statSync,
        read = [];
    beforeEach(function() {
      read = [];
      fu.lookupPath('');
    });
    before(function() {
      fs.readFileSync = function(path) {
        if (/mixin.*\.json$/.test(path)) {
          read.push(path);
          return '{"foo": "bar"}';
        } else {
          return readFileSync.apply(this, arguments);
        }
      };
      fs.statSync = function(path) {
        if (/mixin/.test(path)) {
          return {isDirectory: function() { return !/\.json$/.test(path); }};
        } else {
          return statSync.apply(this, arguments);
        }
      };
    });
    after(function() {
      fs.readFileSync = readFileSync;
      fs.statSync = statSync;
    });

    it('should load direct mixin file references', function() {
      lib.mixinExec({}, ['mixin/file.json'], function(mixins, context) {
        read.should.eql(['mixin/file.json']);

        mixins.configs.length.should.eql(1);
        mixins.configs[0].root.should.equal('mixin/');
        context.config.attributes.foo.should.equal('bar');
      });
    });

    it('should load mixin directory references', function() {
      lib.mixinExec({}, ['mixin'], function(mixins, context) {
        read.should.eql(['mixin/lumbar.json']);

        mixins.configs.length.should.eql(1);
        mixins.configs[0].root.should.equal('mixin/');
        context.config.attributes.foo.should.equal('bar');
      });
    });
  });

  describe('modules', function() {
    it('should mixin module attributes', function(done) {
      var module = {
        mixins: ['mixin1', 'mixin2'],
        bat: 3
      };

      var mixins = {
        mixin1: { foo: 1, baz: 1, bat: 1 },
        mixin2: { bar: 2, baz: 2, bat: 2 }
      };

      lib.mixinExec(module, [{mixins: mixins}], function() {
          assert.equal(module.foo, 1, 'foo should be written');
          assert.equal(module.bar, 2, 'bar should be written');
          assert.equal(module.baz, 2, 'baz should be overwritten');
          assert.equal(module.bat, 3, 'bat should not be overwritten');

          assert.deepEqual(mixins.mixin1, {foo: 1, baz: 1, bat: 1});
          assert.deepEqual(mixins.mixin2, {bar: 2, baz: 2, bat: 2});

          done();
        });
    });

    it('should merge routes', function(done) {
      var module = {
        mixins: ['mixin1', 'mixin2'],
        routes: { bat: 3 }
      };

      var mixins = {
        mixin1: {routes: { foo: 1, baz: 1, bat: 1 }},
        mixin2: {routes: { bar: 2, baz: 2, bat: 2 }}
      };

      lib.mixinExec(module, [{mixins: mixins}], function() {
          assert.equal(module.routes.foo, 1);//, 'foo should be written');
          assert.equal(module.routes.bar, 2, 'bar should be written');
          assert.equal(module.routes.baz, 2, 'baz should be overwritten');
          assert.equal(module.routes.bat, 3, 'bat should not be overwritten');

          assert.deepEqual(mixins.mixin1.routes, {foo: 1, baz: 1, bat: 1});
          assert.deepEqual(mixins.mixin2.routes, {bar: 2, baz: 2, bat: 2});

          done();
        });
    });

    it('should merge routes without modification', function(done) {
      var module = {
        mixins: ['mixin1', 'mixin2']
      };

      var mixins = {
        mixin1: {routes: { foo: 1, baz: 1, bat: 1 }},
        mixin2: {routes: { bar: 2, baz: 2, bat: 2 }}
      };

      lib.mixinExec(module, [{mixins: mixins}], function() {
          assert.equal(module.routes.foo, 1, 'foo should be written');
          assert.equal(module.routes.bar, 2, 'bar should be written');
          assert.equal(module.routes.baz, 2, 'baz should be overwritten');
          assert.equal(module.routes.bat, 2, 'bat should not be overwritten');

          assert.deepEqual(mixins.mixin1.routes, {foo: 1, baz: 1, bat: 1});
          assert.deepEqual(mixins.mixin2.routes, {bar: 2, baz: 2, bat: 2});

          done();
        });
    });

    it('should merge file arrays', function(done) {
      var module = {
        mixins: ['mixin1', 'mixin2'],
        scripts: [ {src: 'foo0', global: true }, {src: 'foo0.1', global: true}, 'bar0.1', 'bar0.2' ],
        styles: [ 'foo0', 'bar0' ]
      };

      var mixins = [
        {
          root: 'mixin1/',
          mixins: {
            mixin1: {
              scripts: [ {src: 'foo1.1', global: true}, {src: 'foo1.2', global: true}, 'bar1.1', 'bar1.2'],
              static: [ 'baz1.1', 'baz1.2' ]
            }
          }
        },
        {
          root: 'mixin2/',
          mixins: {
            mixin2: {
              scripts: [ {src: 'foo2.1', global: true}, {src: 'foo2.2', global: true}, 'bar2.1', 'bar2.2'],
              styles: [ 'foo2', 'bar2' ],
              static: [ 'baz2.1', 'baz2.2' ]
            }
          }
        }
      ];

      lib.mixinExec(module, mixins, function(mixins) {
          mixins = mixins.mixins;

          assert.deepEqual(module.scripts, [
            {src: 'mixin1/foo1.1', global: true, mixin: mixins.mixin1}, {src: 'mixin1/foo1.2', global: true, mixin: mixins.mixin1},
            {src: 'mixin2/foo2.1', global: true, mixin: mixins.mixin2}, {src: 'mixin2/foo2.2', global: true, mixin: mixins.mixin2},
            {src: 'foo0', global: true }, {src: 'foo0.1', global: true},
            {src: 'mixin1/bar1.1', mixin: mixins.mixin1}, {src: 'mixin1/bar1.2', mixin: mixins.mixin1},
            {src: 'mixin2/bar2.1', mixin: mixins.mixin2}, {src: 'mixin2/bar2.2', mixin: mixins.mixin2},
            'bar0.1', 'bar0.2'
          ]);
          assert.deepEqual(module.styles, [
            {src: 'mixin2/foo2', mixin: mixins.mixin2}, {src: 'mixin2/bar2', mixin: mixins.mixin2},
            'foo0', 'bar0'
          ]);
          assert.deepEqual(module.static, [
            {src: 'mixin1/baz1.1', mixin: mixins.mixin1}, {src: 'mixin1/baz1.2', mixin: mixins.mixin1},
            {src: 'mixin2/baz2.1', mixin: mixins.mixin2}, {src: 'mixin2/baz2.2', mixin: mixins.mixin2}
          ]);

          assert.deepEqual(mixins.mixin1.attributes.scripts, [ {src: 'foo1.1', global: true}, {src: 'foo1.2', global: true}, 'bar1.1', 'bar1.2']);
          assert.deepEqual(mixins.mixin1.attributes.static, [ 'baz1.1', 'baz1.2' ]);

          assert.deepEqual(mixins.mixin2.attributes.scripts, [ {src: 'foo2.1', global: true}, {src: 'foo2.2', global: true}, 'bar2.1', 'bar2.2']);
          assert.deepEqual(mixins.mixin2.attributes.styles, [ 'foo2', 'bar2' ]);
          assert.deepEqual(mixins.mixin2.attributes.static, [ 'baz2.1', 'baz2.2' ]);
          done();
        });
    });

    it('should allow files to be overriden', function(done) {
      var mixinDecl = {
        name: 'mixin1',
        overrides: {
          'baz1.1': 'foo',
          'baz1.2': true
        }
      };
      var module = {
        mixins: [
          mixinDecl,
          'mixin2'
        ],
        static: [ 'baz1.1' ]
      };

      var mixins = [
        {
          root: 'mixin1/',
          mixins: {
            mixin1: {
              static: [ 'baz1.1', 'baz1.2' ]
            }
          }
        },
        {
          root: 'mixin2/',
          mixins: {
            mixin2: {
              static: [ 'baz1.1', 'baz1.2' ]
            }
          }
        }
      ];

      lib.mixinExec(module, mixins, function(mixins) {
          mixins = mixins.mixins;

          var mixin1 = _.extend({}, mixinDecl, mixins.mixin1);

          assert.deepEqual(module.static, [
            {src: 'foo', originalSrc: 'mixin1/baz1.1', mixin: mixin1},
            {src: 'baz1.2', originalSrc: 'mixin1/baz1.2', mixin: mixin1},
            {src: 'mixin2/baz1.1', mixin: mixins.mixin2},
            {src: 'mixin2/baz1.2', mixin: mixins.mixin2},
            'baz1.1'
          ]);

          assert.deepEqual(mixins.mixin1.attributes.static, [ 'baz1.1', 'baz1.2' ]);
          assert.deepEqual(mixins.mixin2.attributes.static, [ 'baz1.1', 'baz1.2' ]);
          done();
        });
    });
  });

  describe('integration', function() {
    it('should mixin all content', lib.runTest('test/artifacts/mixin.json', 'test/expected/mixin'));
  });
});

<commit_msg>Use should for mixin test asserts<commit_after>var _ = require('underscore'),
    assert = require('assert'),
    fu = require('../lib/fileUtil'),
    fs = require('fs'),
    lib = require('./lib'),
    should = require('should');

describe('mixins', function() {
  describe('loading', function() {
    var readFileSync = fs.readFileSync,
        statSync = fs.statSync,
        read = [];
    beforeEach(function() {
      read = [];
      fu.lookupPath('');
    });
    before(function() {
      fs.readFileSync = function(path) {
        if (/mixin.*\.json$/.test(path)) {
          read.push(path);
          return '{"foo": "bar"}';
        } else {
          return readFileSync.apply(this, arguments);
        }
      };
      fs.statSync = function(path) {
        if (/mixin/.test(path)) {
          return {isDirectory: function() { return !/\.json$/.test(path); }};
        } else {
          return statSync.apply(this, arguments);
        }
      };
    });
    after(function() {
      fs.readFileSync = readFileSync;
      fs.statSync = statSync;
    });

    it('should load direct mixin file references', function() {
      lib.mixinExec({}, ['mixin/file.json'], function(mixins, context) {
        read.should.eql(['mixin/file.json']);

        mixins.configs.length.should.eql(1);
        mixins.configs[0].root.should.equal('mixin/');
        context.config.attributes.foo.should.equal('bar');
      });
    });

    it('should load mixin directory references', function() {
      lib.mixinExec({}, ['mixin'], function(mixins, context) {
        read.should.eql(['mixin/lumbar.json']);

        mixins.configs.length.should.eql(1);
        mixins.configs[0].root.should.equal('mixin/');
        context.config.attributes.foo.should.equal('bar');
      });
    });
  });

  describe('modules', function() {
    it('should mixin module attributes', function(done) {
      var module = {
        mixins: ['mixin1', 'mixin2'],
        bat: 3
      };

      var mixins = {
        mixin1: { foo: 1, baz: 1, bat: 1 },
        mixin2: { bar: 2, baz: 2, bat: 2 }
      };

      lib.mixinExec(module, [{mixins: mixins}], function() {
          assert.equal(module.foo, 1, 'foo should be written');
          assert.equal(module.bar, 2, 'bar should be written');
          assert.equal(module.baz, 2, 'baz should be overwritten');
          assert.equal(module.bat, 3, 'bat should not be overwritten');

          assert.deepEqual(mixins.mixin1, {foo: 1, baz: 1, bat: 1});
          assert.deepEqual(mixins.mixin2, {bar: 2, baz: 2, bat: 2});

          done();
        });
    });

    it('should merge routes', function(done) {
      var module = {
        mixins: ['mixin1', 'mixin2'],
        routes: { bat: 3 }
      };

      var mixins = {
        mixin1: {routes: { foo: 1, baz: 1, bat: 1 }},
        mixin2: {routes: { bar: 2, baz: 2, bat: 2 }}
      };

      lib.mixinExec(module, [{mixins: mixins}], function() {
          assert.equal(module.routes.foo, 1);//, 'foo should be written');
          assert.equal(module.routes.bar, 2, 'bar should be written');
          assert.equal(module.routes.baz, 2, 'baz should be overwritten');
          assert.equal(module.routes.bat, 3, 'bat should not be overwritten');

          assert.deepEqual(mixins.mixin1.routes, {foo: 1, baz: 1, bat: 1});
          assert.deepEqual(mixins.mixin2.routes, {bar: 2, baz: 2, bat: 2});

          done();
        });
    });

    it('should merge routes without modification', function(done) {
      var module = {
        mixins: ['mixin1', 'mixin2']
      };

      var mixins = {
        mixin1: {routes: { foo: 1, baz: 1, bat: 1 }},
        mixin2: {routes: { bar: 2, baz: 2, bat: 2 }}
      };

      lib.mixinExec(module, [{mixins: mixins}], function() {
          assert.equal(module.routes.foo, 1, 'foo should be written');
          assert.equal(module.routes.bar, 2, 'bar should be written');
          assert.equal(module.routes.baz, 2, 'baz should be overwritten');
          assert.equal(module.routes.bat, 2, 'bat should not be overwritten');

          assert.deepEqual(mixins.mixin1.routes, {foo: 1, baz: 1, bat: 1});
          assert.deepEqual(mixins.mixin2.routes, {bar: 2, baz: 2, bat: 2});

          done();
        });
    });

    it('should merge file arrays', function(done) {
      var module = {
        mixins: ['mixin1', 'mixin2'],
        scripts: [ {src: 'foo0', global: true }, {src: 'foo0.1', global: true}, 'bar0.1', 'bar0.2' ],
        styles: [ 'foo0', 'bar0' ]
      };

      var mixins = [
        {
          root: 'mixin1/',
          mixins: {
            mixin1: {
              scripts: [ {src: 'foo1.1', global: true}, {src: 'foo1.2', global: true}, 'bar1.1', 'bar1.2'],
              static: [ 'baz1.1', 'baz1.2' ]
            }
          }
        },
        {
          root: 'mixin2/',
          mixins: {
            mixin2: {
              scripts: [ {src: 'foo2.1', global: true}, {src: 'foo2.2', global: true}, 'bar2.1', 'bar2.2'],
              styles: [ 'foo2', 'bar2' ],
              static: [ 'baz2.1', 'baz2.2' ]
            }
          }
        }
      ];

      lib.mixinExec(module, mixins, function(mixins) {
          mixins = mixins.mixins;

          module.scripts.should.eql([
            {src: 'mixin1/foo1.1', global: true, mixin: mixins.mixin1}, {src: 'mixin1/foo1.2', global: true, mixin: mixins.mixin1},
            {src: 'mixin2/foo2.1', global: true, mixin: mixins.mixin2}, {src: 'mixin2/foo2.2', global: true, mixin: mixins.mixin2},
            {src: 'foo0', global: true }, {src: 'foo0.1', global: true},
            {src: 'mixin1/bar1.1', mixin: mixins.mixin1}, {src: 'mixin1/bar1.2', mixin: mixins.mixin1},
            {src: 'mixin2/bar2.1', mixin: mixins.mixin2}, {src: 'mixin2/bar2.2', mixin: mixins.mixin2},
            'bar0.1', 'bar0.2'
          ]);
          module.styles.should.eql([
            {src: 'mixin2/foo2', mixin: mixins.mixin2}, {src: 'mixin2/bar2', mixin: mixins.mixin2},
            'foo0', 'bar0'
          ]);
          module.static.should.eql([
            {src: 'mixin1/baz1.1', mixin: mixins.mixin1}, {src: 'mixin1/baz1.2', mixin: mixins.mixin1},
            {src: 'mixin2/baz2.1', mixin: mixins.mixin2}, {src: 'mixin2/baz2.2', mixin: mixins.mixin2}
          ]);

          mixins.mixin1.attributes.scripts.should.eql([{src: 'foo1.1', global: true}, {src: 'foo1.2', global: true}, 'bar1.1', 'bar1.2']);
          mixins.mixin1.attributes.static.should.eql([ 'baz1.1', 'baz1.2' ]);

          mixins.mixin2.attributes.scripts.should.eql([{src: 'foo2.1', global: true}, {src: 'foo2.2', global: true}, 'bar2.1', 'bar2.2']);
          mixins.mixin2.attributes.styles.should.eql([ 'foo2', 'bar2' ]);
          mixins.mixin2.attributes.static.should.eql([ 'baz2.1', 'baz2.2' ]);
          done();
        });
    });

    it('should allow files to be overriden', function(done) {
      var mixinDecl = {
        name: 'mixin1',
        overrides: {
          'baz1.1': 'foo',
          'baz1.2': true
        }
      };
      var module = {
        mixins: [
          mixinDecl,
          'mixin2'
        ],
        static: [ 'baz1.1' ]
      };

      var mixins = [
        {
          root: 'mixin1/',
          mixins: {
            mixin1: {
              static: [ 'baz1.1', 'baz1.2' ]
            }
          }
        },
        {
          root: 'mixin2/',
          mixins: {
            mixin2: {
              static: [ 'baz1.1', 'baz1.2' ]
            }
          }
        }
      ];

      lib.mixinExec(module, mixins, function(mixins) {
          mixins = mixins.mixins;

          var mixin1 = _.extend({}, mixinDecl, mixins.mixin1);

          module.static.should.eql([
            {src: 'foo', originalSrc: 'mixin1/baz1.1', mixin: mixin1},
            {src: 'baz1.2', originalSrc: 'mixin1/baz1.2', mixin: mixin1},
            {src: 'mixin2/baz1.1', mixin: mixins.mixin2},
            {src: 'mixin2/baz1.2', mixin: mixins.mixin2},
            'baz1.1'
          ]);

          mixins.mixin1.attributes.static.should.eql([ 'baz1.1', 'baz1.2' ]);
          mixins.mixin2.attributes.static.should.eql([ 'baz1.1', 'baz1.2' ]);
          done();
        });
    });
  });

  describe('integration', function() {
    it('should mixin all content', lib.runTest('test/artifacts/mixin.json', 'test/expected/mixin'));
  });
});

<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var collectionsForDrop = ['fighters', 'users'];
var Promise = require('bluebird');

module.exports = function (MR) {
    var prs = [];

	var user = MR.userModel({name: String, age: Number});
	var fighter = MR.model('fighter', {
			name: String,
			health: Number,
			born: Date,
			death: { type: Date, permissions: {R: 4, W: 20}},
			owner: { type: mongoose.Schema.Types.ObjectId, ref: 'user', required: true }
		}, {
			schemaInit: function (schema) {
				// if you want to call any methods on schema before model is created, you can do so in schemaInit
				schema.index({ owner: 1, name: 1 }, { unique: true, dropDups: true });
			},
			permissions: {
				C: 20,
				R: 0,
				U: 50,
				D: 50
			}
//            checkPermission: function () {    //for overriding permission check
//                return false;
//            }
		}
	);

	fighter.model.on('preupdate', function (doc, evName, previous) {
		console.log("special preupdate callback triggered " + doc.isModified()); // a good place to put custom save logic
		console.dir(doc);
		console.dir(previous);
	});

	var battleM = MR.model('battle', {
		name: String,
		year: Number,
		fighters: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Fighter' }]
	});

	collectionsForDrop.forEach(function (coll) {
        var dfd = Promise.defer();
        prs.push(dfd.promise);
        mongoose.connection.collections[coll].drop( function(err) {	//TODO rewrite ti removeAll
            console.log('collection ' + coll + ' dropped');
            dfd.resolve();
        });
    });

    Promise.all(prs).then(function () {
        console.log("all collections should be dropped");

		fighter.reInitialize();	//this is done because with dropped collection I lost indexes too

		user.model.create({
            name: 'admin', privilige_level: 50
        }).then(function () {
            console.log("admin created");
        });

        user.model.create({
            name: 'testUser', privilige_level: 10
        }).then(function () {
            console.log("testUser created");
        });

    });

};<commit_msg>dropping a collection caused problems with created indexes, so we just empty the collections instead of dropping them in the smoketest<commit_after>var mongoose = require('mongoose');
var Promise = require('bluebird');

module.exports = function (MR) {
    var prs = [];

	var user = MR.userModel({name: String, age: Number});
	var fighter = MR.model('fighter', {
			name: String,
			health: Number,
			born: Date,
			death: { type: Date, permissions: {R: 4, W: 20}},
			owner: { type: mongoose.Schema.Types.ObjectId, ref: 'user', required: true }
		}, {
			schemaInit: function (schema) {
				// if you want to call any methods on schema before model is created, you can do so in schemaInit
				schema.index({ owner: 1, name: 1 }, { unique: true, dropDups: true });
			},
			permissions: {
				C: 20,
				R: 0,
				U: 50,
				D: 50
			}
//            checkPermission: function () {    //for overriding permission check
//                return false;
//            }
		}
	);

	fighter.model.on('preupdate', function (doc, evName, previous) {
		console.log("special preupdate callback triggered " + doc.isModified()); // a good place to put custom save logic
		console.dir(doc);
		console.dir(previous);
	});

	var battleM = MR.model('battle', {
		name: String,
		year: Number,
		fighters: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Fighter' }]
	});

    var cleaningPromises = [fighter, user].map(function (mrModel) {
        var dfd = Promise.defer();

        mrModel.model.remove({}, function(err) {
            if (err) {
                dfd.reject();
            }
            dfd.resolve();
        });
        return dfd.promise;

    });

    Promise.all(cleaningPromises).then(function () {
        console.log("all collections should be clean");

        user.model.create({
            name: 'admin', privilige_level: 50
        }).then(function () {
            console.log("admin created");
        });

        user.model.create({
            name: 'testUser', privilige_level: 10
        }).then(function () {
            console.log("testUser created");
        });

    });

};<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import uuid from 'uuid/v4';
import { isFunction } from 'lodash-es';
import { isEqual } from 'lodash-es';
import { attempt } from 'lodash-es';
import isImmutable from 'is-immutable';
import immutableEqual from 'immutable-is';
import { Provider } from '../SeriesContext';
import addEventProps, { getNonEventHandlerProps } from '../../utils/events';
import getModifiedProps from '../../utils/getModifiedProps';
import { logSeriesErrorMessage } from '../../utils/warnings';

class Series extends Component {

  static propTypes = {
    id: PropTypes.oneOfType([ PropTypes.string, PropTypes.func ]).isRequired,
    type: PropTypes.string.isRequired,
    data: PropTypes.any,
    visible: PropTypes.bool,
    getChart: PropTypes.func, // Provided by ChartProvider
    getAxis: PropTypes.func, // Provided by AxisProvider
  };

  static defaultProps = {
    type: 'line',
    id: uuid,
    children: null,
    data: [],
    requiresAxis: true,
    visible: true
  };

  constructor (props) {
    super(props);

    if (process.env.NODE_ENV === 'development') {
      const { type, getHighcharts } = props;
      const seriesTypes = Object.keys(getHighcharts().seriesTypes);
      if (seriesTypes.indexOf(type) === -1) logSeriesErrorMessage(type)
    }
  }

  componentDidUpdate (prevProps) {
    const { visible, data, ...rest } = this.props;

    // Using setData is more performant than update
    if (isImmutable(data) && immutableEqual(data, prevProps.data) === false) {
      this.series.setData(data.toJS(), true);
    } else if (isEqual(data, prevProps.data) === false) {
      this.series.setData(data, true);
    }
    if (visible !== prevProps.visible) {
      this.series.setVisible(visible);
    }

    const modifiedProps = getModifiedProps(prevProps, rest);
    if (modifiedProps !== false) {
      this.series.update(modifiedProps);
    }
  }

  componentWillUnmount () {
    if (this.series && this.series.remove) {
      // Series may have already been removed, i.e. when Axis unmounted
      attempt(this.series.remove.bind(this.series));
    }
  }

  getSeriesConfig = () => {
    const { id, data, requiresAxis, getAxis, children, ...rest } = this.props;

    const seriesId = isFunction(id) ? id() : id
    const seriesData = isImmutable(data) ? data.toJS() : data;
    const nonEventProps = getNonEventHandlerProps(rest);

    const config = {
      id: seriesId,
      data: seriesData,
      ...nonEventProps
    }

    if (requiresAxis) {
      const axis = getAxis();
      config[axis.type] = axis.id;
    }

    return config;
  }

  createSeries () {
    const chart = this.props.getChart();

    // Create Highcharts Series
    const opts = this.getSeriesConfig();
    this.series = chart.addSeries(opts, false);

    const update = this.series.update.bind(this.series);

    // we rely addEventProps to call redraw
    addEventProps(update, this.props, true);
  }

  render () {
    if (!this.series) this.createSeries();

    return (
      <Provider value={this.series}>
        {this.props.children}
      </Provider>
    );
  }
}

export default Series;
<commit_msg>Update packages/react-jsx-highcharts/src/components/Series/Series.js<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import uuid from 'uuid/v4';
import { isFunction } from 'lodash-es';
import { isEqual } from 'lodash-es';
import { attempt } from 'lodash-es';
import isImmutable from 'is-immutable';
import immutableEqual from 'immutable-is';
import { Provider } from '../SeriesContext';
import addEventProps, { getNonEventHandlerProps } from '../../utils/events';
import getModifiedProps from '../../utils/getModifiedProps';
import { logSeriesErrorMessage } from '../../utils/warnings';

class Series extends Component {

  static propTypes = {
    id: PropTypes.oneOfType([ PropTypes.string, PropTypes.func ]).isRequired,
    type: PropTypes.string.isRequired,
    data: PropTypes.any,
    visible: PropTypes.bool,
    getChart: PropTypes.func, // Provided by ChartProvider
    getAxis: PropTypes.func, // Provided by AxisProvider
  };

  static defaultProps = {
    type: 'line',
    id: uuid,
    children: null,
    data: [],
    requiresAxis: true,
    visible: true
  };

  constructor (props) {
    super(props);

    if (process.env.NODE_ENV === 'development') {
      const { type, getHighcharts } = props;
      const seriesTypes = Object.keys(getHighcharts().seriesTypes);
      if (seriesTypes.indexOf(type) === -1) logSeriesErrorMessage(type)
    }
  }

  componentDidUpdate (prevProps) {
    const { visible, data, ...rest } = this.props;

    // Using setData is more performant than update
    if (isImmutable(data) && immutableEqual(data, prevProps.data) === false) {
      this.series.setData(data.toJS(), true);
    } else if (isEqual(data, prevProps.data) === false) {
      this.series.setData(data, true);
    }
    if (visible !== prevProps.visible) {
      this.series.setVisible(visible);
    }

    const modifiedProps = getModifiedProps(prevProps, rest);
    if (modifiedProps !== false) {
      this.series.update(modifiedProps);
    }
  }

  componentWillUnmount () {
    if (this.series && this.series.remove) {
      // Series may have already been removed, i.e. when Axis unmounted
      attempt(this.series.remove.bind(this.series));
    }
  }

  getSeriesConfig = () => {
    const { id, data, requiresAxis, getAxis, children, ...rest } = this.props;

    const seriesId = isFunction(id) ? id() : id
    const seriesData = isImmutable(data) ? data.toJS() : data;
    const nonEventProps = getNonEventHandlerProps(rest);

    const config = {
      id: seriesId,
      data: seriesData,
      ...nonEventProps
    }

    if (requiresAxis) {
      const axis = getAxis();
      config[axis.type] = axis.id;
    }

    return config;
  }

  createSeries = () => {
    const chart = this.props.getChart();

    // Create Highcharts Series
    const opts = this.getSeriesConfig();
    this.series = chart.addSeries(opts, false);

    const update = this.series.update.bind(this.series);

    // we rely addEventProps to call redraw
    addEventProps(update, this.props, true);
  }

  render () {
    if (!this.series) this.createSeries();

    return (
      <Provider value={this.series}>
        {this.props.children}
      </Provider>
    );
  }
}

export default Series;
<|endoftext|>


<commit_before><commit_msg>simplified normalization<commit_after><|endoftext|>


<commit_before>//Marker Icons
var MapObj = new Map();
var StorylineMapObj = new StorylineMap();
var ListPOI = [];
var ListPOT = [];
var floorDiff = 1;
var baseMaps = {};
var map;

var markerIconPOIBlue = MapObj.createMarker('images/marker-icon-blue.png', 64, 64, 30, 64, 1, 1);
var markerIconPOIGreen = MapObj.createMarker('images/marker-icon-green.png', 64, 64, 30, 64, 1, 1);
var markerIconPOIRed = MapObj.createMarker('images/marker-icon-red.png', 64, 64, 30, 64, 1, 1);
var markerIconNode = MapObj.createMarker('images/none-marker-icon.png');
var mapMinZoom = 1;
var mapMaxZoom = 5;
var floors = [];
var storyline;
var storylineSelectedID;
var lastVisitedNodeID = localStorage.getItem("lastVisitedNodeID");
var navigationPath = new Navigation([], false);
var startNode;

function displayStoryline() {
    //Test - next POI button
    $("#nextBtn").hide();
    $("#scanBtn").hide();
    $("#endBtn").hide();
    $("#scanText").html(tools.getLocalization(translation, ['map', 'scan']));

    $('#currentStoryline').text("Current storyline: " + localStorage.getItem("currentStoryline"));
    $('#previewStoryline').text("Previewing storyline: " + localStorage.getItem("currentStoryline"));
    storylineSelectedID = localStorage.getItem("currentStoryline");
    //browser testing (default storyline)
    if (storylineSelectedID == null) {
        storylineSelectedID= "0";
    }
    floors = MapObj.parseFloors();
    floors = MapObj.parsePOI(floors);
    floors = MapObj.parsePOT(floors);
    floors = MapObj.createFloorTileLayers(floors, mapMinZoom, mapMaxZoom);
    MapObj.parseEdges();
    storyline = StorylineMapObj.parseStoryline(storylineSelectedID);
    storyline = StorylineMapObj.parseNodePath(storyline);

    if (lastVisitedNodeID != null && lastVisitedNodeID != storyline.nodePath[0]+"") {
        var dijkstras = new Dijkstra(ListPOI, ListPOT);
        start = lastVisitedNodeID;
        finish = storyline.nodePath[0]+"";
        var shortestPathID = dijkstras.shortestPath(start, finish);
        navigationPath = new Navigation(shortestPathID, true);
        navigationPath = StorylineMapObj.parseNodePath(navigationPath);
        floors = StorylineMapObj.createPolyline(floors, navigationPath);
        floors = MapObj.groupLayers(floors);
        floors = StorylineMapObj.addPolylines(floors);

        startNode = ListPOI[navigationPath.nodePath[0]+""];
        //$('#currentStoryline').text("Navigate to the start");
    } else {
        floors = StorylineMapObj.createPolyline(floors, storyline);
        floors = MapObj.groupLayers(floors);
        floors = StorylineMapObj.addPolylines(floors);
        startNode = ListPOI[storyline.nodePath[0]+""];
    }

    //floor radio buttons
    for (i = 0; i < floors.length; i++) {
        var property = (i + floorDiff)+"";
        if (i == 0) {
            baseMaps[property] = floors[i].groupLayer;
        } else {
            baseMaps[property] = floors[i].groupLayer;
        }
    }
    //floor overlay radio buttons
    var overlayMaps = {
        //"Markers": floor1Overlay
    };

    //create map
    map = L.map('map', {
        maxZoom: mapMaxZoom,
        minZoom: mapMinZoom,
        crs: L.CRS.Simple    });
    map.on("load", function () {
            map.addLayer(floors[parseInt(startNode.floorID) - floorDiff].groupLayer);

            if (localStorage.getItem("startIsSelected") == "true") {
            startStoryline();
        }

    });
    map.setView([0, 0], mapMaxZoom);
    //map bounds
    var mapBounds = new L.LatLngBounds(
        map.unproject([0, 6144], mapMaxZoom),
        map.unproject([3072, 0], mapMaxZoom));

    //add bounds to map
    map.fitBounds(mapBounds);
    //Add controls (radio buttons) to map in order to switch between floors
    L.control.layers(baseMaps, overlayMaps, { collapsed: false }).addTo(map).setPosition('bottomright');
}

function endPreview() {
    localStorage.removeItem("currentStoryline");
    window.location.replace("storylines.html");
}

function endStoryline() {
    localStorage.removeItem("currentStoryline");
    localStorage.removeItem("startIsSelected");
    window.location.replace("storylines.html");
}

function startStoryline() {
    localStorage.setItem("startIsSelected", "true");
    $("#starBtn").hide();
    $("#backBtn").hide();
    $("#previewStoryline").hide();
    $("#nextBtn").show();
    $("#scanBtn").show();
    $("#endBtn").show();

    focusOnStart();

    jsBridge.startScanningForIBeacons();
}

function focusOnStart() {
    if (navigationPath.isNotAtStart) {
        firstNodeID = navigationPath.nodePath[0]+"";
        firstNode = navigationPath.nodes[firstNodeID];
    } else {
        firstNodeID = storyline.nodePath[0]+"";
        firstNode = storyline.nodes[firstNodeID];
    }
    focusOnNode(firstNode, 3);
}

//***TODO***
//When beacon in proximity function is fired, should call this method
//Check whether beacon uuid == next Node.iBeacon.uuid
//if true -> fire popup
function currentPOI(minor, major) {

    // Check if the given minor,major match the first poi in the storyline
    if (lastVisitedNodeID === null) {
        if ((""+storyline.nodes[0].iBeacon.minor) === minor && (""+storyline.nodes[0].iBeacon.major) === major) {
            nextPOI();
            jsBridge.confirmIBeacon(minor, major);
            iBeaconDiscovered(minor, major);
        }
    } else { // Check if the given minor,major match the next poi in the storyline
        var nextNodeID = parseInt(lastVisitedNodeID) + 1;
        if (nextNodeID < storyline.nodes.length) {
            var nextBeacon = storyline.nodes[nextNodeID].iBeacon;
            if (nextBeacon.minor === minor && nextBeacon.major === major) {
                nextPOI();
                jsBridge.confirmIBeacon(minor, major);
                iBeaconDiscovered(minor, major);
            }
        }
    }
}

function nextPOI() {
    var node;
    var floorIDInt;

    for (i = 0; i < storyline.nodePath.length; i++) {
        //if isPOI
        node = storyline.nodes[storyline.nodePath[i] + ""];
        floorIDInt = parseInt(node.floorID);
        if (ListPOI[storyline.nodePath[i] + ""] != null && localStorage.getItem("lastVisitedNodeID") != storyline.nodePath[i] + "") {
            focusOnNode(node, 3);
            localStorage.setItem("lastVisitedNodeID", storyline.nodePath[i] + "");
            lastVisitedNodeID = storyline.nodePath[i];
            storyline.nodePath.splice(0, i);
            break;
        } else {

            var marker = floors[floorIDInt - floorDiff].markersById[node.id + ""];
            floors[floorIDInt - floorDiff].groupLayer.removeLayer(marker);
            map.removeLayer(marker);
            //remove marker from floor.groupLayer too
        }
    }
    floors = StorylineMapObj.createPolyline(floors, storyline);
    map.removeLayer(floors[floorIDInt - floorDiff].polyline);

    for (i = 0; i < floors.length; i++) {
        floors[i].groupLayer.removeLayer(floors[i].polyline);
        //floors[i].groupLayers();
        floors[i].addPolylineLayer();
    }
    map.addLayer(floors[floorIDInt - floorDiff].polyline);
}

function focusOnNode(node, zoom) {
        var floors = $('input[name=leaflet-base-layers]:radio');
        jQuery.each(floors, function (index, radio) {
            if ($(radio).next()[0].innerHTML.trim() == node.floorID+"") {
                if (radio.checked) {
                    map.setView(new L.LatLng(node.y, node.x), zoom, { animate: true });
                } else {
                    $(radio).prop("checked", true).trigger("click");
                    map.panTo(new L.LatLng(node.y, node.x));
                    map.setZoom(zoom);
                }
                //openMarkerPopup(markerId);
                return;
            }
        });
}

//testing
function simulateBeacon() {
    if (navigationPath.isNotAtStart) {
        currentPOI(navigationPath);
        if (localStorage.getItem("lastVisitedNodeID") == storyline.nodePath[0]+"") {
            navigationPath.isNotAtStart = false;
            localStorage.removeItem("lastVisitedNodeID");
            //Readd all markers
            floors = StorylineMapObj.createPolyline(floors, storyline);

            for (i = 0; i < floors.length; i++) {
                for (j = 0; j < floors[i].markers.length; j++) {
                    floors[i].groupLayer.addLayer(floors[i].markers[j]);
                }
            }
            floors = StorylineMapObj.addPolylines(floors);
            focusOnStart();
        }
    } else {
        currentPOI(storyline);
        //iBeaconDiscovered(9377, 54177);
    }
}

var ids = [{ minor: "56840", major: "59520" }, { minor: "7229", major: "11163" }, { minor: "47495", major: "32561" }];
var nextidsIndex = 0;
function advanceStoryLine() {
    if (nextidsIndex == ids.length)
        goBack();
    else {
        currentPOI(ids[nextidsIndex].minor, ids[nextidsIndex].major);
        nextidsIndex++;
    }
}

function goBack() {
    storyline = navigationPath;
    nextPOI(); // Start navigation back
    //if (localStorage.getItem("lastVisitedNodeID") == storyline.nodePath[0] + "") {
    navigationPath.isNotAtStart = false;
    localStorage.removeItem("lastVisitedNodeID");
    //Readd all markers
    floors = StorylineMapObj.createPolyline(floors, storyline);

    for (i = 0; i < floors.length; i++) {
        for (j = 0; j < floors[i].markers.length; j++) {
            floors[i].groupLayer.addLayer(floors[i].markers[j]);
        }
    }
    floors = StorylineMapObj.addPolylines(floors);
    focusOnStart();
    //}
}<commit_msg>Skeleteon code for justin's refactored storyline .js logic<commit_after>//Marker Icons
var MapObj = new Map();
var StorylineMapObj = new StorylineMap();
var ListPOI = [];
var ListPOT = [];
var floorDiff = 1;
var baseMaps = {};
var map;

var markerIconPOIBlue = MapObj.createMarker('images/marker-icon-blue.png', 64, 64, 30, 64, 1, 1);
var markerIconPOIGreen = MapObj.createMarker('images/marker-icon-green.png', 64, 64, 30, 64, 1, 1);
var markerIconPOIRed = MapObj.createMarker('images/marker-icon-red.png', 64, 64, 30, 64, 1, 1);
var markerIconNode = MapObj.createMarker('images/none-marker-icon.png');
var mapMinZoom = 1;
var mapMaxZoom = 5;
var floors = [];
var storyline;
var storylineSelectedID;
var lastVisitedNodeID = localStorage.getItem("lastVisitedNodeID");
var navigationPath = new Navigation([], false);
var startNode;

function displayStoryline() {
    //Test - next POI button
    $("#nextBtn").hide();
    $("#scanBtn").hide();
    $("#endBtn").hide();
    $("#scanText").html(tools.getLocalization(translation, ['map', 'scan']));

    $('#currentStoryline').text("Current storyline: " + localStorage.getItem("currentStoryline"));
    $('#previewStoryline').text("Previewing storyline: " + localStorage.getItem("currentStoryline"));
    storylineSelectedID = localStorage.getItem("currentStoryline");
    //browser testing (default storyline)
    if (storylineSelectedID == null) {
        storylineSelectedID= "0";
    }
    floors = MapObj.parseFloors();
    floors = MapObj.parsePOI(floors);
    floors = MapObj.parsePOT(floors);
    floors = MapObj.createFloorTileLayers(floors, mapMinZoom, mapMaxZoom);
    MapObj.parseEdges();
    storyline = StorylineMapObj.parseStoryline(storylineSelectedID);
    storyline = StorylineMapObj.parseNodePath(storyline);

    if (lastVisitedNodeID != null && lastVisitedNodeID != storyline.nodePath[0]+"") {
        var dijkstras = new Dijkstra(ListPOI, ListPOT);
        start = lastVisitedNodeID;
        finish = storyline.nodePath[0]+"";
        var shortestPathID = dijkstras.shortestPath(start, finish);
        navigationPath = new Navigation(shortestPathID, true);
        navigationPath = StorylineMapObj.parseNodePath(navigationPath);
        floors = StorylineMapObj.createPolyline(floors, navigationPath);
        floors = MapObj.groupLayers(floors);
        floors = StorylineMapObj.addPolylines(floors);

        startNode = ListPOI[navigationPath.nodePath[0]+""];
        //$('#currentStoryline').text("Navigate to the start");
    } else {
        floors = StorylineMapObj.createPolyline(floors, storyline);
        floors = MapObj.groupLayers(floors);
        floors = StorylineMapObj.addPolylines(floors);
        startNode = ListPOI[storyline.nodePath[0]+""];
    }

    //floor radio buttons
    for (i = 0; i < floors.length; i++) {
        var property = (i + floorDiff)+"";
        if (i == 0) {
            baseMaps[property] = floors[i].groupLayer;
        } else {
            baseMaps[property] = floors[i].groupLayer;
        }
    }
    //floor overlay radio buttons
    var overlayMaps = {
        //"Markers": floor1Overlay
    };

    //create map
    map = L.map('map', {
        maxZoom: mapMaxZoom,
        minZoom: mapMinZoom,
        crs: L.CRS.Simple    });
    map.on("load", function () {
            map.addLayer(floors[parseInt(startNode.floorID) - floorDiff].groupLayer);

            if (localStorage.getItem("startIsSelected") == "true") {
            startStoryline();
        }

    });
    map.setView([0, 0], mapMaxZoom);
    //map bounds
    var mapBounds = new L.LatLngBounds(
        map.unproject([0, 6144], mapMaxZoom),
        map.unproject([3072, 0], mapMaxZoom));

    //add bounds to map
    map.fitBounds(mapBounds);
    //Add controls (radio buttons) to map in order to switch between floors
    L.control.layers(baseMaps, overlayMaps, { collapsed: false }).addTo(map).setPosition('bottomright');
}

function endPreview() {
    localStorage.removeItem("currentStoryline");
    window.location.replace("storylines.html");
}

function endStoryline() {
    localStorage.removeItem("currentStoryline");
    localStorage.removeItem("startIsSelected");
    window.location.replace("storylines.html");
}

function startStoryline() {
    localStorage.setItem("startIsSelected", "true");
    $("#starBtn").hide();
    $("#backBtn").hide();
    $("#previewStoryline").hide();
    $("#nextBtn").show();
    $("#scanBtn").show();
    $("#endBtn").show();

    focusOnStart();

    jsBridge.startScanningForIBeacons();
}

function focusOnStart() {
    if (navigationPath.isNotAtStart) {
        firstNodeID = navigationPath.nodePath[0]+"";
        firstNode = navigationPath.nodes[firstNodeID];
    } else {
        firstNodeID = storyline.nodePath[0]+"";
        firstNode = storyline.nodes[firstNodeID];
    }
    focusOnNode(firstNode, 3);
}

//***TODO***
//When beacon in proximity function is fired, should call this method
//Check whether beacon uuid == next Node.iBeacon.uuid
//if true -> fire popup
function currentPOI(minor, major) {
    // a global variable
    var modeSelected; // Either 'storyline' or 'free'
    // a global variable, last known position
    var lastKnownIBeacon; // {minor: ..., major: ...}

    if (modeSelected == 'storyline') {
        // storyline global variable
        var currentStorylineIndex; // Initialised as -1 when "Start" is clicked for a storyline

        // Iterate through the storyline path and check
        // if the given minor,major pair matches the next point in the storyline
        // That is, if (LinkPOI[storyline.nodePath[currentStorylineIndex+1]].iBeacon.minor === minor && ...

        // If so, do:
        iBeaconDiscovered(minor, major); // Display this iBeacon's content
        advanceStoryLine(); // Create this function (check out commented out code below for next())
        currentStorylineIndex++;
        // And focus on currentPOI in the storylin
    }
    if (modeSelected == 'free') {

    }

    // Check if the given minor,major match the first poi in the storyline
    /*if (lastVisitedNodeID === null) {
        if ((""+storyline.nodes[0].iBeacon.minor) === minor && (""+storyline.nodes[0].iBeacon.major) === major) {
            nextPOI();
            //jsBridge.confirmIBeacon(minor, major);
            iBeaconDiscovered(minor, major);
        }
    } else { // Check if the given minor,major match the next poi in the storyline
        var nextNodeID = parseInt(lastVisitedNodeID) + 1;
        if (nextNodeID < storyline.nodes.length) {
            var nextBeacon = storyline.nodes[nextNodeID].iBeacon;
            if (nextBeacon.minor === minor && nextBeacon.major === major) {
                nextPOI();
                jsBridge.confirmIBeacon(minor, major);
                iBeaconDiscovered(minor, major);
            }
        }
    }*/
}

/*function nextPOI() {
    var node;
    var floorIDInt;

    for (i = 0; i < storyline.nodePath.length; i++) {
        //if isPOI
        node = storyline.nodes[storyline.nodePath[i] + ""];
        floorIDInt = parseInt(node.floorID);
        if (ListPOI[storyline.nodePath[i] + ""] != null && localStorage.getItem("lastVisitedNodeID") != storyline.nodePath[i] + "") {
            focusOnNode(node, 3);
            localStorage.setItem("lastVisitedNodeID", storyline.nodePath[i] + "");
            lastVisitedNodeID = storyline.nodePath[i];
            storyline.nodePath.splice(0, i);
            break;
        } else {

            var marker = floors[floorIDInt - floorDiff].markersById[node.id + ""];
            floors[floorIDInt - floorDiff].groupLayer.removeLayer(marker);
            map.removeLayer(marker);
            //remove marker from floor.groupLayer too
        }
    }
    floors = StorylineMapObj.createPolyline(floors, storyline);
    map.removeLayer(floors[floorIDInt - floorDiff].polyline);

    for (i = 0; i < floors.length; i++) {
        floors[i].groupLayer.removeLayer(floors[i].polyline);
        //floors[i].groupLayers();
        floors[i].addPolylineLayer();
    }
    map.addLayer(floors[floorIDInt - floorDiff].polyline);
}*/

function focusOnNode(node, zoom) {
        var floors = $('input[name=leaflet-base-layers]:radio');
        jQuery.each(floors, function (index, radio) {
            if ($(radio).next()[0].innerHTML.trim() == node.floorID+"") {
                if (radio.checked) {
                    map.setView(new L.LatLng(node.y, node.x), zoom, { animate: true });
                } else {
                    $(radio).prop("checked", true).trigger("click");
                    map.panTo(new L.LatLng(node.y, node.x));
                    map.setZoom(zoom);
                }
                //openMarkerPopup(markerId);
                return;
            }
        });
}

//testing
function simulateBeacon() {
    if (navigationPath.isNotAtStart) {
        currentPOI(navigationPath);
        if (localStorage.getItem("lastVisitedNodeID") == storyline.nodePath[0]+"") {
            navigationPath.isNotAtStart = false;
            localStorage.removeItem("lastVisitedNodeID");
            //Readd all markers
            floors = StorylineMapObj.createPolyline(floors, storyline);

            for (i = 0; i < floors.length; i++) {
                for (j = 0; j < floors[i].markers.length; j++) {
                    floors[i].groupLayer.addLayer(floors[i].markers[j]);
                }
            }
            floors = StorylineMapObj.addPolylines(floors);
            focusOnStart();
        }
    } else {
        currentPOI(storyline);
        //iBeaconDiscovered(9377, 54177);
    }
}

/*var ids = [{ minor: "56840", major: "59520" }, { minor: "7229", major: "11163" }, { minor: "47495", major: "32561" }];
var nextidsIndex = 0;
function advanceStoryLine() {
    if (nextidsIndex == ids.length)
        goBack();
    else {
        currentPOI(ids[nextidsIndex].minor, ids[nextidsIndex].major);
        nextidsIndex++;
    }
}*/

/*function goBack() {
    storyline = navigationPath;
    nextPOI(); // Start navigation back
    //if (localStorage.getItem("lastVisitedNodeID") == storyline.nodePath[0] + "") {
    navigationPath.isNotAtStart = false;
    localStorage.removeItem("lastVisitedNodeID");
    //Readd all markers
    floors = StorylineMapObj.createPolyline(floors, storyline);

    for (i = 0; i < floors.length; i++) {
        for (j = 0; j < floors[i].markers.length; j++) {
            floors[i].groupLayer.addLayer(floors[i].markers[j]);
        }
    }
    floors = StorylineMapObj.addPolylines(floors);
    focusOnStart();
    //}
}*/<|endoftext|>


<commit_before>const environment = process.env.ENV || 'dev';
const dbConfig = require('../../database.json')[environment.trim().toLowerCase()];

const shortId = require('../utils/shortid');

const HttpError = require('../express/httperror');

const knex = (function createPool() {
  const knex = require('knex')({
    client: 'pg',
    connection: dbConfig,
    pool: { min: 1, max: 10 }
  });

  return knex;
}());

const st = require('knex-postgis')(knex);

function createNewChannel(channelInfo) {
  console.log(channelInfo);
  return knex('channel')
    .insert({
      name: channelInfo.name,
      email: channelInfo.email,
      tags: channelInfo.tags || '',
    })
    .then((dbResponse) => {
      return { created: channelInfo.name };
    }).catch((err) => {
      throw {
        message: err.detail
      };
    });
}

function createNewBeacon(channel, beaconData) {
  console.log('creating new beacon');
  if (!beaconData) {
    throw new HttpError(400, 'Beacon data not specified in the request body', 'EINVAL');
  }

  if (!beaconData.content_attachment) {
    throw new HttpError(400, 'Beacon data does not specify a \'content_attachment\'.', 'EINVAL');
  }

  return knex('beacon')
    .insert({
      channel_name: channel.trim(),
      canonical_url: beaconData.content_attachment.url,
      call_to_action: JSON.stringify(beaconData.content_attachment.calls_to_action || {}),
      extra_metadata: JSON.stringify(beaconData.content_attachment.additional_metadata || {}),
      location: st.geography(st.makePoint(beaconData.location.long, beaconData.location.lat)),
      is_virtual: beaconData.is_virtual
    }, 'id').then((dbResponse) => {
      return { id: dbResponse[0], shortId: shortId.numToShortId(dbResponse[0]) };
    });
}

function searchBeacons(lat, long, radius) {

  // ST_MakePoint is (x,y) so reverse conventional 'lat, long' to 'long, lat'
  const point = st.makePoint(long, lat);

  return knex('beacon')
    .select('channel_name', 'id', st.asGeoJSON('location'))
    .where(st.dwithin('location', point, radius))
    .then((dbResponse) => {
      return dbResponse.map((entry) => {
        const parsedGeoJson = JSON.parse(entry.location);
        return {
          slug: shortId.numToShortId(entry.id),
          channel_name: entry.channel_name,
          location: {
            latitude: parsedGeoJson.coordinates[1],
            longitude: parsedGeoJson.coordinates[0],
          }
        };
      });
    });
}

function searchSlugs(slugs) {
  const resultsToReturn = slugs.reduce((obj, slug) => {
    obj[slug] = false;
    return obj;
  }, {});

  return knex('beacon')
    .select('channel_name', 'id', st.asGeoJSON('location'))
    .whereIn('id', slugs.map(shortId.shortIdToNum))
    .then((dbResponse) => {
      dbResponse.forEach((entry) => {
        const parsedGeoJson = JSON.parse(entry.location);
        const slug = shortId.numToShortId(entry.id);
        resultsToReturn[slug] = {
          channel_name: entry.channel_name,
          location: {
            latitude: parsedGeoJson.coordinates[1],
            longitude: parsedGeoJson.coordinates[0],
          }
        };
      });

      return resultsToReturn;
    });
};

function getCanonicalUrlForShortId(id) {
  console.log(shortId);
  return knex('beacon')
    .select('channel_name', 'canonical_url')
    .where('id', shortId.shortIdToNum(id))
    .then((response) => {
      if (response.length > 0) {
        return response[0];
      }

      throw new HttpError(404, `Could not find short url: ${id}`, 'ENOTFOUND');
    });
}

/*
 * Returns a geojson representation of every point in the database,
 * must be authenticated, might take a while!
 */
function getAllPointsInDatabase() {
  return knex('beacon')
    .select('canonical_url', 'channel_name', st.asGeoJSON('location'))
    .then((response) => {
      return response.map((entry) => {
        return {
          type: 'Feature',
          properties: {
            url: entry.canonical_url,
            channel: entry.channel_name
          },
          geometry: JSON.parse(entry.location)
        };
      });
      return response;
    })
    .then((features) => {
      return {
        type: 'FeatureCollection',
        features,
      };
    });
}

module.exports = {
  createNewBeacon,
  createNewChannel,
  searchBeacons,
  getCanonicalUrlForShortId,
  searchSlugs,
  getAllPointsInDatabase,
};
<commit_msg>Add API request limits<commit_after>const environment = process.env.ENV || 'dev';
const dbConfig = require('../../database.json')[environment.trim().toLowerCase()];

const shortId = require('../utils/shortid');

const HttpError = require('../express/httperror');

const knex = (function createPool() {
  const knex = require('knex')({
    client: 'pg',
    connection: dbConfig,
    pool: { min: 1, max: 10 }
  });

  return knex;
}());

const st = require('knex-postgis')(knex);

function createNewChannel(channelInfo) {
  console.log(channelInfo);
  return knex('channel')
    .insert({
      name: channelInfo.name,
      email: channelInfo.email,
      tags: channelInfo.tags || '',
    })
    .then((dbResponse) => {
      return { created: channelInfo.name };
    }).catch((err) => {
      throw {
        message: err.detail
      };
    });
}

function createNewBeacon(channel, beaconData) {
  console.log('creating new beacon');
  if (!beaconData) {
    throw new HttpError(400, 'Beacon data not specified in the request body', 'EINVAL');
  }

  if (!beaconData.content_attachment) {
    throw new HttpError(400, 'Beacon data does not specify a \'content_attachment\'.', 'EINVAL');
  }

  return knex('beacon')
    .insert({
      channel_name: channel.trim(),
      canonical_url: beaconData.content_attachment.url,
      call_to_action: JSON.stringify(beaconData.content_attachment.calls_to_action || {}),
      extra_metadata: JSON.stringify(beaconData.content_attachment.additional_metadata || {}),
      location: st.geography(st.makePoint(beaconData.location.long, beaconData.location.lat)),
      is_virtual: beaconData.is_virtual
    }, 'id').then((dbResponse) => {
      return { id: dbResponse[0], shortId: shortId.numToShortId(dbResponse[0]) };
    });
}

function searchBeacons(lat, long, radius) {

  // ST_MakePoint is (x,y) so reverse conventional 'lat, long' to 'long, lat'
  const point = st.makePoint(long, lat);

  return knex('beacon')
    .select('channel_name', 'id', st.asGeoJSON('location'))
    .where(st.dwithin('location', point, radius))
    .limit(100)
    .then((dbResponse) => {
      return dbResponse.map((entry) => {
        const parsedGeoJson = JSON.parse(entry.location);
        return {
          slug: shortId.numToShortId(entry.id),
          channel_name: entry.channel_name,
          location: {
            latitude: parsedGeoJson.coordinates[1],
            longitude: parsedGeoJson.coordinates[0],
          }
        };
      });
    });
}

function searchSlugs(slugs) {

  if (!Array.isArray(slugs)) {
    throw new HttpError(400, 'Request body must be an array', 'EINVAL');
  }

  if (slugs.length > 100) {
    throw new HttpError(400, 'Request body too large (limit of 100 items)', 'E2BIG');
  }

  if (slugs.length === 0) {
    return Promise.resolve({});
  }

  const resultsToReturn = slugs.reduce((obj, slug) => {
    obj[slug] = false;
    return obj;
  }, {});

  return knex('beacon')
    .select('channel_name', 'id', st.asGeoJSON('location'))
    .whereIn('id', slugs.map(shortId.shortIdToNum))
    .then((dbResponse) => {
      dbResponse.forEach((entry) => {
        const parsedGeoJson = JSON.parse(entry.location);
        const slug = shortId.numToShortId(entry.id);
        resultsToReturn[slug] = {
          channel_name: entry.channel_name,
          location: {
            latitude: parsedGeoJson.coordinates[1],
            longitude: parsedGeoJson.coordinates[0],
          }
        };
      });

      return resultsToReturn;
    });
};

function getCanonicalUrlForShortId(id) {
  console.log(shortId);
  return knex('beacon')
    .select('channel_name', 'canonical_url')
    .where('id', shortId.shortIdToNum(id))
    .limit(1)
    .then((response) => {
      if (response.length > 0) {
        return response[0];
      }

      throw new HttpError(404, `Could not find short url: ${id}`, 'ENOTFOUND');
    });
}

/*
 * Returns a geojson representation of every point in the database,
 * must be authenticated, might take a while!
 */
function getAllPointsInDatabase() {
  return knex('beacon')
    .select('canonical_url', 'channel_name', st.asGeoJSON('location'))
    .then((response) => {
      return response.map((entry) => {
        return {
          type: 'Feature',
          properties: {
            url: entry.canonical_url,
            channel: entry.channel_name
          },
          geometry: JSON.parse(entry.location)
        };
      });
      return response;
    })
    .then((features) => {
      return {
        type: 'FeatureCollection',
        features,
      };
    });
}

module.exports = {
  createNewBeacon,
  createNewChannel,
  searchBeacons,
  getCanonicalUrlForShortId,
  searchSlugs,
  getAllPointsInDatabase,
};
<|endoftext|>


<commit_before>const assert = require('assert');

const PalindromeTwo = str => {

  // match only numbers and letters, ignore punctuation
  let arr = str.replace(/[a-z0-9]+/gi).toLowerCase();

  // join into string
  let joined = arr.split('').reverse().join('');

  // check for palindrome
  return arr === joined;

};

// console.log(PalindromeTwo("Anne, I vote more cars race Rome-to-Vienna"));

t1 = PalindromeTwo(8);
console.log(t1);
assert(t1);
<commit_msg>wip-function with array<commit_after>const assert = require('assert');

const PalindromeTwo = str => {

  // match only numbers and letters, ignore punctuation
  let arr = str.replace(/[a-z0-9]+/gi);
  console.log('true');

  // join into string
  let joined = arr.split('').reverse().join('');

  // check for palindrome
  return arr === joined;

};

console.log(PalindromeTwo('Tony - sees Gizmo'));

t1 = PalindromeTwo(8);
console.log(t1);
assert(t1);

// Input:'Tony - sees Gizmo'

// Output:"true"
<|endoftext|>


<commit_before>function pp(a) {
  if (a.forEach) a.forEach(printjson)
  else printjson(a)
}

// lowercase emails
pp(db.Person.find({email:/[A-Z]/}, {email:1}));
db.Person.find({email:/[A-Z]/}).forEach(function(p) { p.email = p.email.toLowerCase(); db.Person.save(p) });
pp(db.Person.count({email:/[A-Z]/}));

// fix Tj email
pp(db.Person.find({ name: 'Tj Holowaychuk' }, { name: 1, email: 1 }));
db.Person.update({ name: 'Tj Holowaychuk' }, { $set: { email: 'tjholowayhuk@gmail.com' } }, false, false)
pp(db.Person.find({ name: 'Tj Holowaychuk' }, { name: 1, email: 1 }));

// find dupes
function countDupes() {
  return db.Person.group({
      key: { email: true },
      initial: { count: 0 },
      reduce: function(obj, prev) { prev.count += 1; } })
    .filter(function(g) { return g.count > 1; });
}

function findDupes() {
  return db.Person.find({
    email: { $in: countDupes()
      .map(function(g) { return g.email; }) } },
    { type: 1, email: 1 })
    .sort({ email: 1 })
    .map(function(p) {
      p.teams = db.Team.find({ 'members._id': p._id },
        { name: 1 }).map(function(m) { return m.name; });
      return p; });
}

// remove duplicate emails
dupes = findDupes()
invalid = dupes.filter(function(d) { return d.type == 'Participant' && !d.teams.length })
pp(dupes)
pp(invalid)

pp({ dupes: dupes.length, invalid: invalid.length, people: db.Person.count() })
db.Person.remove({ _id: { $in: invalid.map(function(i) { return i._id; }) } })
pp({ dupes: findDupes(), people: db.Person.count() })

// clear votes
db.Vote.remove({})

// ensure uniqueness at the db level
db.Person.ensureIndex({email: 1}, {unique: true});
db.Team.ensureIndex({slug: 1}, {unique: true});
db.Vote.ensureIndex({'team._id': 1, 'person._id': 1}, {unique: true});

// other misc indexes
db.Vote.ensureIndex({'team._id': 1 });
db.Vote.ensureIndex({'person._id': 1 });
<commit_msg>debugging output for cleanup<commit_after>function pp(a) {
  if (a.forEach) a.forEach(printjson)
  else printjson(a)
}

// lowercase emails
print("--- uppercase letter in email:");
pp(db.Person.find({email:/[A-Z]/}, {email:1}));
print("--- downcasing");
db.Person.find({email:/[A-Z]/}).forEach(function(p) { p.email = p.email.toLowerCase(); db.Person.save(p) });
print("--- post-downcase uppercase letter in email total:");
pp(db.Person.count({email:/[A-Z]/}));

// fix Tj email
print("--- tweaking tj's email");
pp(db.Person.find({ name: 'Tj Holowaychuk' }, { name: 1, email: 1 }));
db.Person.update({ name: 'Tj Holowaychuk' }, { $set: { email: 'tj@vision-media.ca' } }, false, false)
pp(db.Person.find({ name: 'Tj Holowaychuk' }, { name: 1, email: 1 }));

// find dupes
function countDupes() {
  return db.Person.group({
      key: { email: true },
      initial: { count: 0 },
      reduce: function(obj, prev) { prev.count += 1; } })
    .filter(function(g) { return g.count > 1; });
}

function findDupes() {
  return db.Person.find({
    email: { $in: countDupes()
      .map(function(g) { return g.email; }) } },
    { type: 1, email: 1 })
    .sort({ email: 1 })
    .map(function(p) {
      p.teams = db.Team.find({ 'members._id': p._id },
        { name: 1 }).map(function(m) { return m.name; });
      return p; });
}

// remove duplicate emails
dupes = findDupes()
invalid = dupes.filter(function(d) { return d.type == 'Participant' && !d.teams.length })
print("--- duplicates:");
pp(dupes)

print("--- duplicate stats:");
pp({ dupes: dupes.length, invalid: invalid.length, people: db.Person.count() })
db.Person.remove({ _id: { $in: invalid.map(function(i) { return i._id; }) } })
print("--- post-remove duplicate stats:");
pp({ dupes: findDupes(), people: db.Person.count() })

// clear votes
print("--- clearing votes");
db.Vote.remove({})

// ensure uniqueness at the db level
print("--- creating indexes");
db.Person.ensureIndex({email: 1}, {unique: true});
db.Team.ensureIndex({slug: 1}, {unique: true});
db.Vote.ensureIndex({'team._id': 1, 'person._id': 1}, {unique: true});

// other misc indexes
db.Vote.ensureIndex({'team._id': 1 });
db.Vote.ensureIndex({'person._id': 1 });
<|endoftext|>


<commit_before>// --- Begin Awkward Hackzorz ---

const REACTOTRON_VERSION = '@@REACTOTRON_VERSION@@'
const R = require('ramda')

// client enabled flag
let reactotronEnabled = true

// Then we set a userAgent so socket.io works.
if (!window.navigator || !window.navigator.userAgent) {
  window.navigator.userAgent = 'react-native'
}

// Finally, we load socket.io. This has to be done as a require to preserve
// the order of user agent being set first.
var io = require('socket.io-client/socket.io')

// --- End Awkward Hackzorz ---

const RS = require('ramdasauce')
const defaultPerformanceNow = () => Date.now()
const nativePerformance = window && (window.performance || window.msPerformance || window.webkitPerformance)
const nativePerformanceNow = () => nativePerformance.now()
const performanceNow = nativePerformance ? nativePerformanceNow : defaultPerformanceNow

// me?  not much, just creating some
// global mutable variables.
let socket = null

// the thing that shall be returned from this file
const client = {}

// inbound command handlers
const commandHandlers = {}

// a way to register command handlers
client.onCommand = (event, handler) => {
  commandHandlers[event] = commandHandlers[event] || []
  commandHandlers[event].push(handler)
}

// handles requests to reload the app (current iOS only)
client.onCommand('devMenu.reload', (action, client) => {
  // doesn't seem to work on android.
  // const devMenu = RS.dotPath('NativeModules.DevMenu', React)
  // devMenu && devMenu.reload()
})

/*
 * Get React Native server IP if hostname is `localhost`
 * On Android emulator, the IP of host is `10.0.2.2` (Genymotion: 10.0.3.2)
 */
function getHost(hostname) {
  if (
    (hostname === 'localhost' || hostname === '127.0.0.1') &&
    typeof window !== 'undefined' &&
    window.__fbBatchedBridge &&
    window.__fbBatchedBridge.RemoteModules &&
    window.__fbBatchedBridge.RemoteModules.AndroidConstants
  ) {
    const {
      ServerHost = hostname
    } = window.__fbBatchedBridge.RemoteModules.AndroidConstants;
    return ServerHost.split(':')[0];
  }

  return hostname;
}

/**
  Connect to the server.
  @param userConfigurations Client configuration for connecting to Reactotron
  @param {string} userConfigurations.name Name of the client, displayed in the dashboard
  @param {string} userConfigurations.server IP of the server to connect to
  @param {number} userConfigurations.port Port of the server to connect to
  @param {boolean} userConfigurations.enabled Whether or not Reactotron is enabled.
 */
client.connect = (userConfigurations = {}) => {
  const defaults = {
    name: 'React',
    version: REACTOTRON_VERSION,
    server: 'localhost',
    port: 3334,
    enabled: true
  }

  // merge user input with defaults
  const config = {
    ...defaults,
    ...userConfigurations,
    server: getHost(userConfigurations.server || defaults.server)
  }

  // keep track for all ops
  reactotronEnabled = config.enabled

  if (config.enabled) {
    socket = io(`ws://${config.server}:${config.port}`, {
      jsonp: false,
      transports: ['websocket']
    })

    socket.on('connect', () => {
      socket.emit('ready', config)
    })

    socket.on('command', (data) => {
      const action = JSON.parse(data)
      const {type} = action
      const handlers = commandHandlers[type] || []
      R.forEach((handler) => { handler(action, client) }, handlers)
    })

    client.hookErrors()
  }
}

/**
  Log out something to the server.
 */
client.log = (message) => {
  client.sendCommand('content.log', message)
}

/**
  Log out something to the server.
 */
client.apiLog = (response, title) => {
  client.sendCommand('api.log', {response, title})
}

client.sendCommand = (type, message) => {
  const payload = {type, message}
  if (socket) {
    socket.emit('command', JSON.stringify(payload))
  }
}

client.createSubscriptionListener = (store) => {
  // shortcircuit if disabled
  if (!reactotronEnabled) return store
  let subscriptions = []

  // send the subscriptions to the client
  const sendSubscriptions = () => {
    const state = store.getState()
    const expanded = R.pipe(
      R.filter(RS.endsWith('.*')),
      R.map((key) => {
        const keyMinusWildcard = R.slice(0, -2, key)
        const value = RS.dotPath(keyMinusWildcard, state)
        if (R.is(Object, value) && !RS.isNilOrEmpty(value)) {
          return R.pipe(
            R.keys,
            R.map((key) => `${keyMinusWildcard}.${key}`)
          )(value)
        }
        return null
      }),
      R.concat(subscriptions),
      R.flatten,
      R.reject(RS.endsWith('.*')),
      R.uniq,
      R.sortBy(R.identity)
    )(subscriptions)

    const values = R.map((key) => [key, RS.dotPath(key, state)], expanded)
    if (R.length(values) > 0) {
      client.sendCommand('redux.subscribe.values', {values})
    }
  }

  client.onCommand('redux.subscribe.request', (action, client) => {
    subscriptions = R.flatten(R.clone(action.paths || []))
    sendSubscriptions()
  })

  return sendSubscriptions
}

client.addReduxStore = (store) => {
  store.subscribe(client.createSubscriptionListener(store))

  // return the store at the given path
  client.onCommand('redux.value.request', (action, client) => {
    const path = action.path
    const state = store.getState()
    if (RS.isNilOrEmpty(path)) {
      client.sendCommand('redux.value.response', {path: null, values: state})
    } else {
      client.sendCommand('redux.value.response', {path: path, values: RS.dotPath(path, state)})
    }
  })

  // return the keys at the given path
  client.onCommand('redux.key.request', (action, client) => {
    const path = action.path
    const state = store.getState()
    if (RS.isNilOrEmpty(path)) {
      client.sendCommand('redux.key.response', {path: null, keys: R.keys(state)})
    } else {
      const keys = R.keys(RS.dotPath(path, state))
      client.sendCommand('redux.key.response', {path, keys})
    }
  })

  // dispatch an action
  client.onCommand('redux.dispatch', (action, client) => {
    store.dispatch(action.action)
  })

  return store
}

client.hookErrors = () => {
  // prevent double assignments
  if (console._swizzledFromReactotron) {
    return
  }

  // remember the previous one
  console._swizzledFromReactotron = console.error.bind(console)

  // swizzle and go straight to hell
  console.error = function reactotronConsoleOnError () {
    // always call the previous one
    console._swizzledFromReactotron.apply(null, arguments)
    const message = arguments[0]
    const stack = message && message.stack
    // if we have a message, pass it along
    if (message) {
      client.sendCommand('console.error', {message, stack})
    }
  }
}

const MIDDLEWARE_ACTION_IGNORE = ['EFFECT_TRIGGERED', 'EFFECT_RESOLVED', 'EFFECT_REJECTED']

// Returns a function that can track performance.
client.trackPerformance = (action) => {
  let {type} = action
  const start = performanceNow()

  const stopTracking = () => {
    const ms = (performanceNow() - start).toFixed(0)

    if (!R.contains(action.type, MIDDLEWARE_ACTION_IGNORE)) {
      // Transform Symbol to Text
      if (typeof type === 'symbol') {
        type = type.toString().replace(/^Symbol\(/, '').replace(/\)$/, '');
      }

      client.sendCommand('redux.action.done', {type, ms, action})
    }
  }

  return stopTracking
}

// Enhances the store by wrapping the main reducer
// with our own reduxReducer, as well as setting up
// the store listener.
client.storeEnhancer = () => {
  return (createStore) => (reducer, initialState, enhancer) => {
    // create this store
    const store = createStore(reducer, initialState, enhancer)

    // jet with what we got if the master switch is off
    if (!reactotronEnabled) return store

    // fish out the previous dispatch
    const previousDispatch = store.dispatch

    // create a new dispatch that times & calls the previous one
    const dispatch = (action) => {
      const stopTracking = client.trackPerformance(action)
      const result = previousDispatch(action)
      stopTracking()
      return result
    }

    // attach the subscription to the store
    client.addReduxStore(store)

    // return the store but with our new dispatcher
    return R.merge(store, {dispatch})
  }
}

client.reduxMiddleware = (store) => (next) => (action) => {
  if (!reactotronEnabled) {
    return next(action)
  }

  // Begin tracking performance.
  const performanceTracker = client.trackPerformance(action)

  const result = next(action)

  // Stop tracking performance.
  performanceTracker()

  return result
}

client.bench = (title) => {
  const steps = []
  const step = (stepTitle) => steps.push({title: stepTitle, time: performanceNow()})
  step(title)
  const stop = (stopTitle) => {
    step(stopTitle)
    client.sendCommand('bench.report', {title, steps})
  }
  return {step, stop}
}

module.exports = client
<commit_msg>Add WSS support (#98)<commit_after>// --- Begin Awkward Hackzorz ---

const REACTOTRON_VERSION = '@@REACTOTRON_VERSION@@'
const R = require('ramda')

// client enabled flag
let reactotronEnabled = true

// Then we set a userAgent so socket.io works.
if (!window.navigator || !window.navigator.userAgent) {
  window.navigator.userAgent = 'react-native'
}

// Finally, we load socket.io. This has to be done as a require to preserve
// the order of user agent being set first.
var io = require('socket.io-client/socket.io')

// --- End Awkward Hackzorz ---

const RS = require('ramdasauce')
const defaultPerformanceNow = () => Date.now()
const nativePerformance = window && (window.performance || window.msPerformance || window.webkitPerformance)
const nativePerformanceNow = () => nativePerformance.now()
const performanceNow = nativePerformance ? nativePerformanceNow : defaultPerformanceNow

// me?  not much, just creating some
// global mutable variables.
let socket = null

// the thing that shall be returned from this file
const client = {}

// inbound command handlers
const commandHandlers = {}

// a way to register command handlers
client.onCommand = (event, handler) => {
  commandHandlers[event] = commandHandlers[event] || []
  commandHandlers[event].push(handler)
}

// handles requests to reload the app (current iOS only)
client.onCommand('devMenu.reload', (action, client) => {
  // doesn't seem to work on android.
  // const devMenu = RS.dotPath('NativeModules.DevMenu', React)
  // devMenu && devMenu.reload()
})

/*
 * Get React Native server IP if hostname is `localhost`
 * On Android emulator, the IP of host is `10.0.2.2` (Genymotion: 10.0.3.2)
 */
function getHost(hostname) {
  if (
    (hostname === 'localhost' || hostname === '127.0.0.1') &&
    typeof window !== 'undefined' &&
    window.__fbBatchedBridge &&
    window.__fbBatchedBridge.RemoteModules &&
    window.__fbBatchedBridge.RemoteModules.AndroidConstants
  ) {
    const {
      ServerHost = hostname
    } = window.__fbBatchedBridge.RemoteModules.AndroidConstants;
    return ServerHost.split(':')[0];
  }

  return hostname;
}

/**
  Connect to the server.
  @param userConfigurations Client configuration for connecting to Reactotron
  @param {string} userConfigurations.name Name of the client, displayed in the dashboard
  @param {string} userConfigurations.server IP of the server to connect to
  @param {number} userConfigurations.port Port of the server to connect to
  @param {boolean} userConfigurations.enabled Whether or not Reactotron is enabled.
 */
client.connect = (userConfigurations = {}) => {
  const defaults = {
    name: 'React',
    version: REACTOTRON_VERSION,
    server: 'localhost',
    port: 3334,
    enabled: true,
    secure: false
  }

  // merge user input with defaults
  const config = {
    ...defaults,
    ...userConfigurations,
    server: getHost(userConfigurations.server || defaults.server)
  }

  // keep track for all ops
  reactotronEnabled = config.enabled

  if (config.enabled) {
    socket = io(`${config.secure ? 'wss' : 'ws'}://${config.server}:${config.port}`, {
      jsonp: false,
      transports: ['websocket']
    })

    socket.on('connect', () => {
      socket.emit('ready', config)
    })

    socket.on('command', (data) => {
      const action = JSON.parse(data)
      const {type} = action
      const handlers = commandHandlers[type] || []
      R.forEach((handler) => { handler(action, client) }, handlers)
    })

    client.hookErrors()
  }
}

/**
  Log out something to the server.
 */
client.log = (message) => {
  client.sendCommand('content.log', message)
}

/**
  Log out something to the server.
 */
client.apiLog = (response, title) => {
  client.sendCommand('api.log', {response, title})
}

client.sendCommand = (type, message) => {
  const payload = {type, message}
  if (socket) {
    socket.emit('command', JSON.stringify(payload))
  }
}

client.createSubscriptionListener = (store) => {
  // shortcircuit if disabled
  if (!reactotronEnabled) return store
  let subscriptions = []

  // send the subscriptions to the client
  const sendSubscriptions = () => {
    const state = store.getState()
    const expanded = R.pipe(
      R.filter(RS.endsWith('.*')),
      R.map((key) => {
        const keyMinusWildcard = R.slice(0, -2, key)
        const value = RS.dotPath(keyMinusWildcard, state)
        if (R.is(Object, value) && !RS.isNilOrEmpty(value)) {
          return R.pipe(
            R.keys,
            R.map((key) => `${keyMinusWildcard}.${key}`)
          )(value)
        }
        return null
      }),
      R.concat(subscriptions),
      R.flatten,
      R.reject(RS.endsWith('.*')),
      R.uniq,
      R.sortBy(R.identity)
    )(subscriptions)

    const values = R.map((key) => [key, RS.dotPath(key, state)], expanded)
    if (R.length(values) > 0) {
      client.sendCommand('redux.subscribe.values', {values})
    }
  }

  client.onCommand('redux.subscribe.request', (action, client) => {
    subscriptions = R.flatten(R.clone(action.paths || []))
    sendSubscriptions()
  })

  return sendSubscriptions
}

client.addReduxStore = (store) => {
  store.subscribe(client.createSubscriptionListener(store))

  // return the store at the given path
  client.onCommand('redux.value.request', (action, client) => {
    const path = action.path
    const state = store.getState()
    if (RS.isNilOrEmpty(path)) {
      client.sendCommand('redux.value.response', {path: null, values: state})
    } else {
      client.sendCommand('redux.value.response', {path: path, values: RS.dotPath(path, state)})
    }
  })

  // return the keys at the given path
  client.onCommand('redux.key.request', (action, client) => {
    const path = action.path
    const state = store.getState()
    if (RS.isNilOrEmpty(path)) {
      client.sendCommand('redux.key.response', {path: null, keys: R.keys(state)})
    } else {
      const keys = R.keys(RS.dotPath(path, state))
      client.sendCommand('redux.key.response', {path, keys})
    }
  })

  // dispatch an action
  client.onCommand('redux.dispatch', (action, client) => {
    store.dispatch(action.action)
  })

  return store
}

client.hookErrors = () => {
  // prevent double assignments
  if (console._swizzledFromReactotron) {
    return
  }

  // remember the previous one
  console._swizzledFromReactotron = console.error.bind(console)

  // swizzle and go straight to hell
  console.error = function reactotronConsoleOnError () {
    // always call the previous one
    console._swizzledFromReactotron.apply(null, arguments)
    const message = arguments[0]
    const stack = message && message.stack
    // if we have a message, pass it along
    if (message) {
      client.sendCommand('console.error', {message, stack})
    }
  }
}

const MIDDLEWARE_ACTION_IGNORE = ['EFFECT_TRIGGERED', 'EFFECT_RESOLVED', 'EFFECT_REJECTED']

// Returns a function that can track performance.
client.trackPerformance = (action) => {
  let {type} = action
  const start = performanceNow()

  const stopTracking = () => {
    const ms = (performanceNow() - start).toFixed(0)

    if (!R.contains(action.type, MIDDLEWARE_ACTION_IGNORE)) {
      // Transform Symbol to Text
      if (typeof type === 'symbol') {
        type = type.toString().replace(/^Symbol\(/, '').replace(/\)$/, '');
      }

      client.sendCommand('redux.action.done', {type, ms, action})
    }
  }

  return stopTracking
}

// Enhances the store by wrapping the main reducer
// with our own reduxReducer, as well as setting up
// the store listener.
client.storeEnhancer = () => {
  return (createStore) => (reducer, initialState, enhancer) => {
    // create this store
    const store = createStore(reducer, initialState, enhancer)

    // jet with what we got if the master switch is off
    if (!reactotronEnabled) return store

    // fish out the previous dispatch
    const previousDispatch = store.dispatch

    // create a new dispatch that times & calls the previous one
    const dispatch = (action) => {
      const stopTracking = client.trackPerformance(action)
      const result = previousDispatch(action)
      stopTracking()
      return result
    }

    // attach the subscription to the store
    client.addReduxStore(store)

    // return the store but with our new dispatcher
    return R.merge(store, {dispatch})
  }
}

client.reduxMiddleware = (store) => (next) => (action) => {
  if (!reactotronEnabled) {
    return next(action)
  }

  // Begin tracking performance.
  const performanceTracker = client.trackPerformance(action)

  const result = next(action)

  // Stop tracking performance.
  performanceTracker()

  return result
}

client.bench = (title) => {
  const steps = []
  const step = (stepTitle) => steps.push({title: stepTitle, time: performanceNow()})
  step(title)
  const stop = (stopTitle) => {
    step(stopTitle)
    client.sendCommand('bench.report', {title, steps})
  }
  return {step, stop}
}

module.exports = client
<|endoftext|>


<commit_before>import React from 'react'
import { graphql } from 'react-apollo'
import { withRouter } from 'react-router'
import gql from 'graphql-tag'

import PokemonPreview from '../components/PokemonPreview'
import AddPokemonPreview from '../components/AddPokemonPreview'
import PageNavigation from '../components/PageNavigation'

const POKEMONS_PER_PAGE = 3

class Pokedex extends React.Component {

  static propTypes = {
    data: React.PropTypes.shape({
      loading: React.PropTypes.bool,
      error: React.PropTypes.object,
      Trainer: React.PropTypes.object,
    }).isRequired,
    router: React.PropTypes.object.isRequired,
  }

  _nextPage = () => {
    this.props.router.replace(`/${+this.props.params.page + 1}`)
  }

  _previousPage = () => {
    this.props.router.replace(`/${+this.props.params.page - 1}`)
  }

  _isFirstPage = () => {
    return this.props.params.page === '1'
  }

  _isLastPage = () => {
    return this.props.data.Trainer._ownedPokemonsMeta.count <= this.props.params.page * POKEMONS_PER_PAGE
  }

  render () {
    if (this.props.data.loading) {
      return (
Loading
)
    }

    if (this.props.data.error) {
      console.log(this.props.data.error)
      return (
An unexpexted error occured
)
    }

    return (

          Hey {this.props.data.Trainer.name}, there are {this.props.data.Trainer.ownedPokemons.length} Pokemons in your pokedex

          {this._isFirstPage() && <AddPokemonPreview trainerId={this.props.data.Trainer.id} />}
          {this.props.data.Trainer.ownedPokemons.map((pokemon) =>
            <PokemonPreview key={pokemon.id} pokemon={pokemon} />
          )}

    )
  }
}

const TrainerQuery = gql`query TrainerQuery($name: String!) {
  Trainer(name: $name) {
    id
    name
    ownedPokemons {
      id
      name
      url
    }
    _ownedPokemonsMeta {
      count
    }
  }
}`

const PokedexWithData = graphql(TrainerQuery, {
    options: (ownProps) => ({
      variables: {
        name: '__NAME__',
      }
      },
      forceFetch: true,
    })
  }
)(withRouter(Pokedex))

export default PokedexWithData
<commit_msg>fix additional bracket<commit_after>import React from 'react'
import { graphql } from 'react-apollo'
import { withRouter } from 'react-router'
import gql from 'graphql-tag'

import PokemonPreview from '../components/PokemonPreview'
import AddPokemonPreview from '../components/AddPokemonPreview'
import PageNavigation from '../components/PageNavigation'

const POKEMONS_PER_PAGE = 3

class Pokedex extends React.Component {

  static propTypes = {
    data: React.PropTypes.shape({
      loading: React.PropTypes.bool,
      error: React.PropTypes.object,
      Trainer: React.PropTypes.object,
    }).isRequired,
    router: React.PropTypes.object.isRequired,
  }

  _nextPage = () => {
    this.props.router.replace(`/${+this.props.params.page + 1}`)
  }

  _previousPage = () => {
    this.props.router.replace(`/${+this.props.params.page - 1}`)
  }

  _isFirstPage = () => {
    return this.props.params.page === '1'
  }

  _isLastPage = () => {
    return this.props.data.Trainer._ownedPokemonsMeta.count <= this.props.params.page * POKEMONS_PER_PAGE
  }

  render () {
    if (this.props.data.loading) {
      return (
Loading
)
    }

    if (this.props.data.error) {
      console.log(this.props.data.error)
      return (
An unexpexted error occured
)
    }

    return (

          Hey {this.props.data.Trainer.name}, there are {this.props.data.Trainer.ownedPokemons.length} Pokemons in your pokedex

          {this._isFirstPage() && <AddPokemonPreview trainerId={this.props.data.Trainer.id} />}
          {this.props.data.Trainer.ownedPokemons.map((pokemon) =>
            <PokemonPreview key={pokemon.id} pokemon={pokemon} />
          )}

    )
  }
}

const TrainerQuery = gql`query TrainerQuery($name: String!) {
  Trainer(name: $name) {
    id
    name
    ownedPokemons {
      id
      name
      url
    }
    _ownedPokemonsMeta {
      count
    }
  }
}`

const PokedexWithData = graphql(TrainerQuery, {
    options: (ownProps) => ({
      variables: {
        name: '__NAME__',
      },
      forceFetch: true,
    })
  }
)(withRouter(Pokedex))

export default PokedexWithData
<|endoftext|>


<commit_before>/**
 * @file Entry-point script for the OpenAddresses import pipeline.
 */

'use strict';

var peliasConfig = require( 'pelias-config' ).generate();

require('./configValidation').validate(peliasConfig);

var logger = require( 'pelias-logger' ).get( 'openaddresses' );

var parameters = require( './lib/parameters' );
var importPipeline = require( './lib/importPipeline' );

const adminLookup = require('pelias-wof-admin-lookup').createLookupStream();
var deduplicatorStream = require('./lib/streams/deduplicatorStream');

var addressDeduplicator = require('pelias-address-deduplicator');

// Pretty-print the total time the import took.
function startTiming() {
  var startTime = new Date().getTime();
  process.on( 'exit', function (){
    var totalTimeTaken = (new Date().getTime() - startTime).toString();
    var seconds = totalTimeTaken.slice(0, totalTimeTaken.length - 3);
    var milliseconds = totalTimeTaken.slice(totalTimeTaken.length - 3);
    logger.info( 'Total time taken: %s.%ss', seconds, milliseconds );
  });
}

var args = parameters.interpretUserArgs( process.argv.slice( 2 ) );

if( 'exitCode' in args ){
  ((args.exitCode > 0) ? console.error : console.info)( args.errMessage );
  process.exit( args.exitCode );
} else {
  startTiming();

  if (peliasConfig.imports.openaddresses.hasOwnProperty('adminLookup')) {
    logger.info('imports.openaddresses.adminLookup has been deprecated, ' +
                'enabled adminLookup using imports.adminLookup.enabled = true');
  }

  var files = parameters.getFileList(peliasConfig, args);

  var deduplicator = deduplicatorStream.create(peliasConfig, addressDeduplicator);

  importPipeline.create( files, args.dirPath, deduplicator, adminLookup );
}
<commit_msg>updated to create()<commit_after>/**
 * @file Entry-point script for the OpenAddresses import pipeline.
 */

'use strict';

var peliasConfig = require( 'pelias-config' ).generate();

require('./configValidation').validate(peliasConfig);

var logger = require( 'pelias-logger' ).get( 'openaddresses' );

var parameters = require( './lib/parameters' );
var importPipeline = require( './lib/importPipeline' );

const adminLookupStream = require('pelias-wof-admin-lookup');
var deduplicatorStream = require('./lib/streams/deduplicatorStream');

var addressDeduplicator = require('pelias-address-deduplicator');

// Pretty-print the total time the import took.
function startTiming() {
  var startTime = new Date().getTime();
  process.on( 'exit', function (){
    var totalTimeTaken = (new Date().getTime() - startTime).toString();
    var seconds = totalTimeTaken.slice(0, totalTimeTaken.length - 3);
    var milliseconds = totalTimeTaken.slice(totalTimeTaken.length - 3);
    logger.info( 'Total time taken: %s.%ss', seconds, milliseconds );
  });
}

var args = parameters.interpretUserArgs( process.argv.slice( 2 ) );

if( 'exitCode' in args ){
  ((args.exitCode > 0) ? console.error : console.info)( args.errMessage );
  process.exit( args.exitCode );
} else {
  startTiming();

  if (peliasConfig.imports.openaddresses.hasOwnProperty('adminLookup')) {
    logger.info('imports.openaddresses.adminLookup has been deprecated, ' +
                'enabled adminLookup using imports.adminLookup.enabled = true');
  }

  var files = parameters.getFileList(peliasConfig, args);

  var deduplicator = deduplicatorStream.create(peliasConfig, addressDeduplicator);

  importPipeline.create( files, args.dirPath, deduplicator, adminLookupStream.create() );
}
<|endoftext|>


<commit_before>export const initial = () => ({
  friendsList: []
})

const convertUserToFriend = (user) => ({
  name: `${user.first} ${user.last}`
})

const fetchRandomFriends = () =>
  fetch('https://randomapi.com/api/6de6abfedb24f889e0b5f675edc50deb?fmt=raw&sole')
    .then(res => res.json())
    .then(users => users.map(convertUserToFriend))

export const load = async (props, prevProps) => {
  if (!prevProps) {
    const newFriends = await fetchRandomFriends()
    return ({ friendsList }) => ({ friendsList: friendsList.concat(newFriends) })
  }
}

export const addFriend = (props, { name }) => ({ friendsList }) => ({ friendsList: friendsList.concat({ name }) })

export const addRandomFriend = async ({ handlers }) => {
  const [ newFriend ] = await fetchRandomFriends()
  handlers.addFriend(newFriend)
}<commit_msg>Example: shorten number of friends loaded<commit_after>export const initial = () => ({
  friendsList: []
})

const convertUserToFriend = (user) => ({
  name: `${user.first} ${user.last}`
})

const fetchRandomFriends = () =>
  fetch('https://randomapi.com/api/6de6abfedb24f889e0b5f675edc50deb?fmt=raw&sole')
    .then(res => res.json())
    .then(users => users.slice(0, 10))
    .then(users => users.map(convertUserToFriend))

export const load = async (props, prevProps) => {
  if (!prevProps) {
    const newFriends = await fetchRandomFriends()
    return ({ friendsList }) => ({ friendsList: friendsList.concat(newFriends) })
  }
}

export const addFriend = (props, { name }) => ({ friendsList }) => ({ friendsList: friendsList.concat({ name }) })

export const addRandomFriend = async ({ handlers }) => {
  const [ newFriend ] = await fetchRandomFriends()
  handlers.addFriend(newFriend)
}<|endoftext|>


<commit_before>"use strict";

angular.module("wuw.controllers")

.controller("LecturesWeeklyCtrl", function($scope, $ionicHistory, $state, $ionicPopup, $compile, $timeout, $filter, Lectures, Settings, uiCalendarConfig) {

    var date = new Date();
    var d = date.getDate();
    var m = date.getMonth();
    var y = date.getFullYear();

    /* config object */
    $scope.uiConfig = {
        calendar: {
            weekends: false, //TODO: look if we have a lecture on saturday, then set it to corresponding value
            minTime: "08:00:00",
            height: "9000",
            editable: false,
            defaultView: "agendaWeek",
            header: false,
            dayClick: $scope.alertEventOnClick,
            eventDrop: $scope.alertOnDrop,
            eventResize: $scope.alertOnResize
        }
    };

    $scope.events = [];
    $scope.eventSource = [$scope.events];

    $scope.loadLectures = function() {
        Lectures.lecturesThisWeek().then(function(lectures){

            // add full-calendar specific properties
            $scope.events.length = 0;
            for (var i = 0; i < lectures.length; i++) {
                var l = {
                    title: lectures[i].lectureName,
                    start: new Date(lectures[i].startTime),
                    end: new Date(lectures[i].endTime),
                    stick: true,
                    allDay: false
                };
                $scope.events.push(l);
            }

            $scope.$broadcast("czErrorMessage.hide"); //hide an eventually shown error message

        }, function(error) {
            if (error === "httpFailed") {
                // show the error message with some delay to prevent flickering
                $timeout(function() {
                    $scope.$broadcast("czErrorMessage.show");
                }, 300);
            }
        }).finally(function () {
            // remove the refresh spinner a little bit later to prevent flickering
            $timeout(function() {
                $scope.$broadcast("scroll.refreshComplete");
            }, 400);
        });
    };

    $scope.doRefresh = function() {
        $scope.loadLectures();
    };

    $scope.switchToList = function() {
        Settings.setSetting("lecturesView", "lecturesList");
        $ionicHistory.nextViewOptions({
            disableAnimate: true,
            disableBack: true
        });
        $state.go("tab.lecturesList", {location: "replace"});
    };

    $scope.$on('$ionicView.enter', function(){
        // get the number of selected lectures, if its zero, we display a message to select courses
        $scope.selectedLectures = JSON.parse(Settings.getSetting("selectedLectures") || "[]").length;

        // get lectures from cache, and if the cache is older then 10 seconds load from the API
        $scope.lectures = Lectures.fromCache("weekly");
        if (Lectures.secondsSinceCache("weekly") > 10) {
            $scope.loadLectures();
        }
    });
});
<commit_msg>lecturesWeekly: hide allDaySlot<commit_after>"use strict";

angular.module("wuw.controllers")

.controller("LecturesWeeklyCtrl", function($scope, $ionicHistory, $state, $ionicPopup, $compile, $timeout, $filter, Lectures, Settings, uiCalendarConfig) {

    var date = new Date();
    var d = date.getDate();
    var m = date.getMonth();
    var y = date.getFullYear();

    /* config object */
    $scope.uiConfig = {
        calendar: {
            allDaySlot: false,
            weekends: false, //TODO: look if we have a lecture on saturday, then set it to corresponding value
            minTime: "08:00:00",
            height: "9000",
            editable: false,
            defaultView: "agendaWeek",
            header: false,
            dayClick: $scope.alertEventOnClick,
            eventDrop: $scope.alertOnDrop,
            eventResize: $scope.alertOnResize
        }
    };

    $scope.events = [];
    $scope.eventSource = [$scope.events];

    $scope.loadLectures = function() {
        Lectures.lecturesThisWeek().then(function(lectures){

            // add full-calendar specific properties
            $scope.events.length = 0;
            for (var i = 0; i < lectures.length; i++) {
                var l = {
                    title: lectures[i].lectureName,
                    start: new Date(lectures[i].startTime),
                    end: new Date(lectures[i].endTime),
                    stick: true,
                    allDay: false
                };
                $scope.events.push(l);
            }

            $scope.$broadcast("czErrorMessage.hide"); //hide an eventually shown error message

        }, function(error) {
            if (error === "httpFailed") {
                // show the error message with some delay to prevent flickering
                $timeout(function() {
                    $scope.$broadcast("czErrorMessage.show");
                }, 300);
            }
        }).finally(function () {
            // remove the refresh spinner a little bit later to prevent flickering
            $timeout(function() {
                $scope.$broadcast("scroll.refreshComplete");
            }, 400);
        });
    };

    $scope.doRefresh = function() {
        $scope.loadLectures();
    };

    $scope.switchToList = function() {
        Settings.setSetting("lecturesView", "lecturesList");
        $ionicHistory.nextViewOptions({
            disableAnimate: true,
            disableBack: true
        });
        $state.go("tab.lecturesList", {location: "replace"});
    };

    $scope.$on('$ionicView.enter', function(){
        // get the number of selected lectures, if its zero, we display a message to select courses
        $scope.selectedLectures = JSON.parse(Settings.getSetting("selectedLectures") || "[]").length;

        // get lectures from cache, and if the cache is older then 10 seconds load from the API
        $scope.lectures = Lectures.fromCache("weekly");
        if (Lectures.secondsSinceCache("weekly") > 10) {
            $scope.loadLectures();
        }
    });
});
<|endoftext|>