<commit_before>;
(function(factory) {
    var objectTypes = {
        'function': true,
        'object': true
    };

    var
        freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports,
        freeSelf = objectTypes[typeof self] && self.Object && self,
        freeWindow = objectTypes[typeof window] && window && window.Object && window,
        freeModule = objectTypes[typeof module] && module && !module.nodeType && module,
        moduleExports = freeModule && freeModule.exports === freeExports && freeExports,
        freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;

    var root = root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;

    // Because of build optimizers
    if (typeof define === 'function' && define.amd) {
        define(['rx', 'exports'], function(Rx, exports) {
            root.Rx = factory(root, exports, Rx);
            return root.Rx;
        });
    } else if (typeof module === 'object' && module && module.exports === freeExports) {
        module.exports = factory(root, module.exports, root.Rx ? root.Rx : require('rx'));
    } else {
        root.Rx = factory(root, {}, root.Rx);
    }
}.call(this, function(root, exp, rx, undefined) {
    // Aliases
    //console.log(rx);
    var rxo = rx.Observable,
        rxn = rx.Observable.fromNodeCallback,
        rxed = rx.Observable.from;

    var Observable = rx.Observable;
    var observableProto = Observable.prototype;

    var fs = require('fs');
    var _ = require('lodash-fp');
    var stringify = require('json-stringify-safe'); //TODO: use this
//    var pr = require('predicate');

    var contains = function contains(val) {
        return function(arr) {
            if (!arr.indexOf) throw new Error("filterIncludes requires value implement indexOf");
            return !!~arr.indexOf(val);
        };
    }

    function pluckerFilter(args, len, filterBy) {
        return function filter(x) {
            var currentProp = x;
            // Ignore first element as its the filter
            for (var i = 0; i < len; i++) {
                var p = currentProp[args[i]];
                if (typeof p !== 'undefined') {
                    currentProp = p;
                } else {
                    return false;
                }
            }
            return filterBy(currentProp);
        };
    }

    /**
     * Uses lodash's template to map over the stream
     * @param {template_code} The template code to render
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.mapTemplate = function(template_code) {
        return this.map(function(x) {
          return _.template(x)(template_code)
        });
    };

    /**
     * Replaces the current stream with another observer
     * @param {Observer} The observe to change the stream to
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
     // Not Working
    observableProto.thenUse =
    observableProto.thenObserve =
    observableProto.mapReplace = function(observer) {
        return this.first().flatMap(function(x) {
          return observer;
        });
    };

    /**
     * Uses lodash's _.defaults to create a new object of merge properties
     * @param {obj} The object that will be merged against from the stream. Obj's parameters take precedence.
     * @param {obj2} Optional: The object that will be merged against from the stream. Stream object takes precedence.
     * @returns {Observable} Returns a new Observable sequence of property values.
     * Note: if obj1 is a string, it is used as a key to the stream object and sets the value to obj2.
     */
    observableProto.mapExtend =
        observableProto.mapMerge =
        observableProto.mergeObject =
        observableProto.objectMerge = function(obj, obj2) {
            return this.map(function(x) {
                if(typeof obj === 'string') {
                  x[obj] = obj2;
                } else {
                  return _.defualtsDeep(obj, x, obj2);
                }
            });
    };

    /**
     * Pretty stringifies object or json object in the stream
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.jsonStringify =
      observableProto.mapJsonStringify =
        observableProto.jsonToString = function(serializer, indent) {
            indent = indent || '\t';
            this.map(function(x) {
                return stringify(x, null, indent); // uses safe method
            });
    };

    /**
     * Calls toString() on the stream object
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.mapToString = function() {
            return this.map(function(x) {
                return x.toString();
            });
    };

    /**
     * Switches the subscriber function to error first and data second. The onComplete handler is not used.
     * @param {cb} Function that will be called with the reverse parameters.
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.subscribeAlt = function(cb) {
        this.subscribe(function(data, err) {
            cb(err, data);
        });
    };

    /**
     * Filters by using lodash's filtering system
     * @param {filterBy} Function or Object (equals) to filter on
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.whereDash =
        observableProto.filterDash = function(filterBy) {
            var len = arguments.length,
                args = new Array(len + 1);
            for (var i = 0; i < len; i++) {
                args[i] = arguments[i];
            }

            return this.filter(function(x) {
                args[len] = [x];
                //console.log( _.filter.apply(_, args) );
                return _.filter.apply(_, args).length !== 0;
            });
    };
    /**
     * Retrieves the value of a specified nested property from all elements in
     * the Observable sequence.
     * @param {Arguments} arguments The nested properties to pluck.
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.propertyFilter = function(props, filterBy) {
        var len = arguments.length - 1,
            args = new Array(len);
        _filterBy = arguments[len];
        if (len === 0) {
            throw new Error('List of properties cannot be empty.');
        }

        if (arguments.length === 1) args = props.split('.');
        else
            for (var i = 0; i < len; i++) {
                args[i] = arguments[i];
            }

        return this.filter(pluckerFilter(args, len, _filterBy));
    };

    // Alias for pluckFilter
    observableProto.filterProperty = observableProto.propertyFilter;

    // Filters each item that contains the specified value
    observableProto.filterIncludes = function(filterBy) {
        return this.filter(contains(filterBy));
    };

    // Alias for filterIncludes
    observableProto.filterContains = observableProto.filterIncludes;

    // Filters values that are not null or undefined
    observableProto.filterNotNull = function() {
        return this.filter(function(e) {
            return e !== null && e !== undefined;
        });
    };

    // Filters values that are not 0 or empty string or any JS value that evals to false
    observableProto.filterNotEmpty = function() {
        return this.filter(function(e) {
            return !!e;
        });
    };

    // Property includes filterBy
    observableProto.propertyContains =
        observableProto.propertyIncludes = function(props, filterBy) {
            var _filterBy = arguments[arguments.length - 1];
            arguments[arguments.length - 1] = contains(_filterBy);
            return this.propertyFilter.apply(this, arguments);
    };

    // Uses addition op with the parameter, the parameter will be used last in the operation
    observableProto.mapAdd = function(addWith) {
        return this.map(function(x) {
            return x + addWith;
        });
    };

    // Uses addition op with the parameter, with the parameter first in the operation
    observableProto.mapPreAdd = function(addWith) {
        return this.map(function(x) {
            return addWith + x;
        });
    };

    //rxo.from(["joe", "beth"]).filterIncludes('o').subscribe(console.log);
    //rxo.from(["joe", null]).filterNotNull().subscribe(console.log);

    rx.plus = {
        contains: contains
    };

    return rx;
}));
<commit_msg>flatSplit added<commit_after>;
(function(factory) {
    var objectTypes = {
        'function': true,
        'object': true
    };

    var
        freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports,
        freeSelf = objectTypes[typeof self] && self.Object && self,
        freeWindow = objectTypes[typeof window] && window && window.Object && window,
        freeModule = objectTypes[typeof module] && module && !module.nodeType && module,
        moduleExports = freeModule && freeModule.exports === freeExports && freeExports,
        freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;

    var root = root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;

    // Because of build optimizers
    if (typeof define === 'function' && define.amd) {
        define(['rx', 'exports'], function(Rx, exports) {
            root.Rx = factory(root, exports, Rx);
            return root.Rx;
        });
    } else if (typeof module === 'object' && module && module.exports === freeExports) {
        module.exports = factory(root, module.exports, root.Rx ? root.Rx : require('rx'));
    } else {
        root.Rx = factory(root, {}, root.Rx);
    }
}.call(this, function(root, exp, rx, undefined) {
    // Aliases
    //console.log(rx);
    var rxo = rx.Observable,
        rxn = rx.Observable.fromNodeCallback,
        rxed = rx.Observable.from;

    var Observable = rx.Observable;
    var observableProto = Observable.prototype;

    var fs = require('fs');
    var _ = require('lodash-fp');
    var stringify = require('json-stringify-safe'); //TODO: use this
//    var pr = require('predicate');

    var contains = function contains(val) {
        return function(arr) {
            if (!arr.indexOf) throw new Error("filterIncludes requires value implement indexOf");
            return !!~arr.indexOf(val);
        };
    }

    function pluckerFilter(args, len, filterBy) {
        return function filter(x) {
            var currentProp = x;
            // Ignore first element as its the filter
            for (var i = 0; i < len; i++) {
                var p = currentProp[args[i]];
                if (typeof p !== 'undefined') {
                    currentProp = p;
                } else {
                    return false;
                }
            }
            return filterBy(currentProp);
        };
    }

    /**
     * flatMaps + split
     * @param {seperator} The split seperator
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.flatSplit = function(seperator) {
        return this.flatMap(function(x) {
          return x.split(seperator);
        });
    };

    /**
     * Uses lodash's template to map over the stream
     * @param {template_code} The template code to render
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.mapTemplate = function(template_code) {
        return this.map(function(x) {
          return _.template(x)(template_code)
        });
    };

    /**
     * Replaces the current stream with another observer
     * @param {Observer} The observe to change the stream to
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
     // Not Working
    observableProto.thenUse =
    observableProto.thenObserve =
    observableProto.mapReplace = function(observer) {
        return this.first().flatMap(function(x) {
          return observer;
        });
    };

    /**
     * Uses lodash's _.defaults to create a new object of merge properties
     * @param {obj} The object that will be merged against from the stream. Obj's parameters take precedence.
     * @param {obj2} Optional: The object that will be merged against from the stream. Stream object takes precedence.
     * @returns {Observable} Returns a new Observable sequence of property values.
     * Note: if obj1 is a string, it is used as a key to the stream object and sets the value to obj2.
     */
    observableProto.mapExtend =
        observableProto.mapMerge =
        observableProto.mergeObject =
        observableProto.objectMerge = function(obj, obj2) {
            return this.map(function(x) {
                if(typeof obj === 'string') {
                  x[obj] = obj2;
                } else {
                  return _.defualtsDeep(obj, x, obj2);
                }
            });
    };

    /**
     * Pretty stringifies object or json object in the stream
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.jsonStringify =
      observableProto.mapJsonStringify =
        observableProto.jsonToString = function(serializer, indent) {
            indent = indent || '\t';
            this.map(function(x) {
                return stringify(x, null, indent); // uses safe method
            });
    };

    /**
     * Calls toString() on the stream object
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.mapToString = function() {
            return this.map(function(x) {
                return x.toString();
            });
    };

    /**
     * Switches the subscriber function to error first and data second. The onComplete handler is not used.
     * @param {cb} Function that will be called with the reverse parameters.
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.subscribeAlt = function(cb) {
        this.subscribe(function(data, err) {
            cb(err, data);
        });
    };

    /**
     * Filters by using lodash's filtering system
     * @param {filterBy} Function or Object (equals) to filter on
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.whereDash =
        observableProto.filterDash = function(filterBy) {
            var len = arguments.length,
                args = new Array(len + 1);
            for (var i = 0; i < len; i++) {
                args[i] = arguments[i];
            }

            return this.filter(function(x) {
                args[len] = [x];
                //console.log( _.filter.apply(_, args) );
                return _.filter.apply(_, args).length !== 0;
            });
    };
    /**
     * Retrieves the value of a specified nested property from all elements in
     * the Observable sequence.
     * @param {Arguments} arguments The nested properties to pluck.
     * @returns {Observable} Returns a new Observable sequence of property values.
     */
    observableProto.propertyFilter = function(props, filterBy) {
        var len = arguments.length - 1,
            args = new Array(len);
        _filterBy = arguments[len];
        if (len === 0) {
            throw new Error('List of properties cannot be empty.');
        }

        if (arguments.length === 1) args = props.split('.');
        else
            for (var i = 0; i < len; i++) {
                args[i] = arguments[i];
            }

        return this.filter(pluckerFilter(args, len, _filterBy));
    };

    // Alias for pluckFilter
    observableProto.filterProperty = observableProto.propertyFilter;

    // Filters each item that contains the specified value
    observableProto.filterIncludes = function(filterBy) {
        return this.filter(contains(filterBy));
    };

    // Alias for filterIncludes
    observableProto.filterContains = observableProto.filterIncludes;

    // Filters values that are not null or undefined
    observableProto.filterNotNull = function() {
        return this.filter(function(e) {
            return e !== null && e !== undefined;
        });
    };

    // Filters values that are not 0 or empty string or any JS value that evals to false
    observableProto.filterNotEmpty = function() {
        return this.filter(function(e) {
            return !!e;
        });
    };

    // Property includes filterBy
    observableProto.propertyContains =
        observableProto.propertyIncludes = function(props, filterBy) {
            var _filterBy = arguments[arguments.length - 1];
            arguments[arguments.length - 1] = contains(_filterBy);
            return this.propertyFilter.apply(this, arguments);
    };

    // Uses addition op with the parameter, the parameter will be used last in the operation
    observableProto.mapAdd = function(addWith) {
        return this.map(function(x) {
            return x + addWith;
        });
    };

    // Uses addition op with the parameter, with the parameter first in the operation
    observableProto.mapPreAdd = function(addWith) {
        return this.map(function(x) {
            return addWith + x;
        });
    };

    //rxo.from(["joe", "beth"]).filterIncludes('o').subscribe(console.log);
    //rxo.from(["joe", null]).filterNotNull().subscribe(console.log);

    rx.plus = {
        contains: contains
    };

    return rx;
}));
<|endoftext|>


<commit_before>function gltf_rv(canvasId, index, headless = false, onRendererReady = undefined)
{
    let canvas = document.getElementById(canvasId);
    if (!canvas)
    {
        console.warn("Failed to retrieve the WebGL canvas!");
        return null;
    }

    gl = getWebGlContext();
    if (!gl)
    {
        console.warn("Failed to get an WebGL rendering context!");
        return null;
    }

    let viewer = new gltfViewer(canvas, index, headless, onRendererReady);

    canvas.onmousedown = viewer.onMouseDown.bind(viewer);
    document.onmouseup = viewer.onMouseUp.bind(viewer);
    document.onmousemove = viewer.onMouseMove.bind(viewer);
    canvas.onwheel = viewer.onMouseWheel.bind(viewer);
    canvas.ontouchstart = viewer.onTouchStart.bind(viewer);
    document.ontouchend = viewer.onTouchEnd.bind(viewer);
    document.ontouchmove = viewer.onTouchMove.bind(viewer);

    canvas.ondrop = viewer.dropEventHandler.bind(viewer);
    canvas.ondragover = viewer.dragOverHandler.bind(viewer);

    return viewer; // Succeeded in creating a glTF viewer!
}

function getWebGlContext()
{
    const parameters = { alpha: false, antialias: true };
    const type = [ "webgl", "experimental-webgl" ];

    let context;

    for (const name of names)
    {
        context = canvas.getContext(type, parameters);
        if (context)
        {
            return context;
        }
    }
}
<commit_msg>Renamed name of context type variable.<commit_after>function gltf_rv(canvasId, index, headless = false, onRendererReady = undefined)
{
    let canvas = document.getElementById(canvasId);
    if (!canvas)
    {
        console.warn("Failed to retrieve the WebGL canvas!");
        return null;
    }

    gl = getWebGlContext();
    if (!gl)
    {
        console.warn("Failed to get an WebGL rendering context!");
        return null;
    }

    let viewer = new gltfViewer(canvas, index, headless, onRendererReady);

    canvas.onmousedown = viewer.onMouseDown.bind(viewer);
    document.onmouseup = viewer.onMouseUp.bind(viewer);
    document.onmousemove = viewer.onMouseMove.bind(viewer);
    canvas.onwheel = viewer.onMouseWheel.bind(viewer);
    canvas.ontouchstart = viewer.onTouchStart.bind(viewer);
    document.ontouchend = viewer.onTouchEnd.bind(viewer);
    document.ontouchmove = viewer.onTouchMove.bind(viewer);

    canvas.ondrop = viewer.dropEventHandler.bind(viewer);
    canvas.ondragover = viewer.dragOverHandler.bind(viewer);

    return viewer; // Succeeded in creating a glTF viewer!
}

function getWebGlContext()
{
    const parameters = { alpha: false, antialias: true };
    const contextTypes = [ "webgl", "experimental-webgl" ];

    let context;

    for (const contextType of contextTypes)
    {
        context = canvas.getContext(contextType, parameters);
        if (context)
        {
            return context;
        }
    }
}
<|endoftext|>


<commit_before>const fs = require('fs');
const glob = require('glob');

function saveState(game_state) {
  const fileName = [Date.now(), game_state.game_id, game_state.round, 'game_state.json'].join('.');

  try {
    fs.writeFile(fileName, JSON.stringify(game_state), function (err) {
      console.error(err);
    });
  } catch (err) {
    console.error(err);
  }
}

var loadState = function(res) {
	glob("*.json", options, function (er, files) {
		files.forEach(function(file) {
			// req
			// hand
			// pot
			// win or lose

			// max pot
		});

		// res.json();
	});
};

module.exports = {
	saveState: saveState,
	loadState: loadState
};
<commit_msg>display file names<commit_after>const fs = require('fs');
const glob = require('glob');

function saveState(game_state) {
  const fileName = [Date.now(), game_state.game_id, game_state.round, 'game_state.json'].join('.');

  try {
    fs.writeFile(fileName, JSON.stringify(game_state), function (err) {
      console.error(err);
    });
  } catch (err) {
    console.error(err);
  }
}

var loadState = function(res) {
	glob("*.game_state.json", function (err, files) {
    if (err) {
      console.err(err);
      res.sendStatus(504);
    }

    res.json({
      files: files
    });
    return;

		files.forEach(function (file) {
			// req
			// hand
			// pot
			// win or lose

			// max pot
		});

		// res.json();
	});
};

module.exports = {
	saveState: saveState,
	loadState: loadState
};
<|endoftext|>


<commit_before><commit_msg>new names for routes<commit_after><|endoftext|>


<commit_before>!function(exports) {
  'use strict';

  var Component = exports.Component,
      ComponentList = exports.ComponentList;

  /*
   * Constructor
   * -----------
   */

  var SceneNode = Component.extend(function SceneNode(x, y, z) {
    Component.call(this);
    this.x = x || 0;
    this.y = y || 0;
    this.z = z || 0;

    this._parent = null;

    this._children = new ComponentList;
    this.components = new ComponentList;
  });

  SceneNode.prototype.push = function(child) {
    this._children.push(child);
    child.parent = this;
  };

  SceneNode.prototype.remove = function(child) {
    var curr = this._children.remove(child);
    if(curr) curr.parent = null;
    return curr;
  };

  /*
   * Lifecycle Methods
   * -----------------
   */

  SceneNode.prototype.init = function() {
    this.enter();
    this.components.init();
    this._children.init();
  };

  SceneNode.prototype.enter = function() {};

  SceneNode.prototype.destroy = function() {
    this._children.destroy();
    this.components.destroy();
    this.exit();
  };

  SceneNode.prototype.exit = function() {};

  /*
   * Tick Methods
   * ------------
   */

  SceneNode.prototype.before = nodeMethod('before');
  SceneNode.prototype.update = nodeMethod('update');
  SceneNode.prototype.after = nodeMethod('after');

  /*
   * Render Methods
   * --------------
   */

  SceneNode.prototype.preprocess = nodeMethod('preprocess');
  SceneNode.prototype.render = nodeMethod('render');
  SceneNode.prototype.postprocess = nodeMethod('postprocess');

  /*
   * Coordinate Methods
   * ------------------
   */

  SceneNode.prototype.xAbsolute = absoluteCoordMethod('x', 'xAbsolute');
  SceneNode.prototype.yAbsolute = absoluteCoordMethod('y', 'yAbsolute');
  SceneNode.prototype.zAbsolute = absoluteCoordMethod('z', 'zAbsolute');

  /*
   * Private Methods
   * ---------------
   */

  function nodeMethod(method) {
    return function(delta, x, y, z) {
      this.components[method](delta, this.x + x, this.y + y, this.z + z);
      this._children[method](delta, this.x + x, this.y + y, this.z + z);
    };
  }

  function absoluteCoordMethod(coord, methodName) {
    return function() {
      return this[coord] + this._parent ? this._parent[methodName]() : 0;
    };
  }

  /*
   * Exports
   * -------
   */

  exports.SceneNode = SceneNode;

}(seine);
<commit_msg>[FIX] Incorrect instance var reference.<commit_after>!function(exports) {
  'use strict';

  var Component = exports.Component,
      ComponentList = exports.ComponentList;

  /*
   * Constructor
   * -----------
   */

  var SceneNode = Component.extend(function SceneNode(x, y, z) {
    Component.call(this);
    this.x = x || 0;
    this.y = y || 0;
    this.z = z || 0;

    this._parent = null;

    this._children = new ComponentList;
    this.components = new ComponentList;
  });

  SceneNode.prototype.push = function(child) {
    this._children.push(child);
    child._parent = this;
  };

  SceneNode.prototype.remove = function(child) {
    var curr = this._children.remove(child);
    if(curr) curr._parent = null;
    return curr;
  };

  /*
   * Lifecycle Methods
   * -----------------
   */

  SceneNode.prototype.init = function() {
    this.enter();
    this.components.init();
    this._children.init();
  };

  SceneNode.prototype.enter = function() {};

  SceneNode.prototype.destroy = function() {
    this._children.destroy();
    this.components.destroy();
    this.exit();
  };

  SceneNode.prototype.exit = function() {};

  /*
   * Tick Methods
   * ------------
   */

  SceneNode.prototype.before = nodeMethod('before');
  SceneNode.prototype.update = nodeMethod('update');
  SceneNode.prototype.after = nodeMethod('after');

  /*
   * Render Methods
   * --------------
   */

  SceneNode.prototype.preprocess = nodeMethod('preprocess');
  SceneNode.prototype.render = nodeMethod('render');
  SceneNode.prototype.postprocess = nodeMethod('postprocess');

  /*
   * Coordinate Methods
   * ------------------
   */

  SceneNode.prototype.xAbsolute = absoluteCoordMethod('x', 'xAbsolute');
  SceneNode.prototype.yAbsolute = absoluteCoordMethod('y', 'yAbsolute');
  SceneNode.prototype.zAbsolute = absoluteCoordMethod('z', 'zAbsolute');

  /*
   * Private Methods
   * ---------------
   */

  function nodeMethod(method) {
    return function(delta, x, y, z) {
      this.components[method](delta, this.x + x, this.y + y, this.z + z);
      this._children[method](delta, this.x + x, this.y + y, this.z + z);
    };
  }

  function absoluteCoordMethod(coord, methodName) {
    return function() {
      return this[coord] + this._parent ? this._parent[methodName]() : 0;
    };
  }

  /*
   * Exports
   * -------
   */

  exports.SceneNode = SceneNode;

}(seine);
<|endoftext|>


<commit_before>import React from 'react';
import AppComponent from './components/app';

let tempY = 0;

let app = React.render(
    React.createElement( AppComponent, {history: true} ),
    document.getElementById('app')
);

function animate() {
    tempY++;
    app.props.robotPosition = new THREE.Vector3(0, tempY, 0);
    app.render();
    requestAnimationFrame(animate);
}

animate();
<commit_msg>Switch app updates to use React.render()<commit_after>import React from 'react';
import AppComponent from './components/app';

let tempY = 0;

let appState = { history: true, robotPosition: new THREE.Vector3(0,0,0) }

function animate() {
    tempY++;
    appState.robotPosition.y = tempY;
    React.render(
        React.createElement( AppComponent, appState ),
        document.getElementById('app')
    );

    requestAnimationFrame(animate);
}

animate();
<|endoftext|>


<commit_before>(function () {
    var scheduleClass = function (sys) {
        this.sys = sys;
    }
    scheduleClass.prototype.run = function () {
        var schedule = require('node-schedule');
        var sys = this.sys;
        sys.db.all('SELECT adminID,name,email,interval FROM admin WHERE email IS NOT NULL AND interval IS NOT NULL AND role=2',[],function(err,rows){
            if (err) {return 'Error in scheduler(1)'};
            if (rows) {
                for (var i=0,ilen=rows.length;i<ilen;i+=1) {
                    var row = rows[i];
                    var adminID = row.adminID;
                    var name = row.name;
                    var email = row.email;
                    var adminKey = sys.getRandomKey(8,36);
                    var oldAdminKey = row.adminKey;
                    var dow = row.interval;
                    updateCommenterKeys(oldAdminKey,adminID,name,email,adminKey,dow);
                }
            }

            function updateCommenterKeys (oldAdminKey,adminID,name,email,adminKey,dow) {
                sys.db.run('UPDATE admin SET adminKey=? WHERE adminID=?',[adminKey,adminID],function(err){
                    if (err) {return 'Error in scheduler(2)'};

                    sys.admin[adminKey] = {name:name,role:2,id:adminID};
                    delete sys.admin[oldAdminKey];

                    scheduleMail(adminID,name,email,adminKey,dow);
                });
            };

            function scheduleMail(adminID,name,email,adminKey,dow) {
                // var hostname
                var hostname = sys.proxy_hostname;
                // var port
                var port = ':' + sys.real_port;
                var email_account = sys.email_account;

                var rule = new schedule.RecurrenceRule();
                rule.dayOfWeek = [dow];
                rule.hour = 22;
                rule.minute = 35;

                var msg = name + ':\n\n'
                    + 'Thank you for offering to comment on student work in our\n'
                    + 'writing program. We appreciate the value of your time, and\n'
                    + 'our students will benefit greatly from any constructive\n'
                    + 'feedback you can offer.\n\n'
                    + 'Your personal link to the commenting system is updated regularly\n'
                    + 'as a security measure. The link below is valid for the coming\n'
                    + 'week:\n\n'
                    + '    http://our.law.nagoya-u.ac.jp/quizzer/staff.html?commenter=@@COMMENTER_ID@@\n\n'
                    + 'After navigating to the quizzes for a class, you will find a\n'
                    + 'list of mistaken responses students have made to questions on\n'
                    + 'grammatical and style issues. Many responses are tagged with the\n'
                    + 'native language of students who missed that particular question.\n'
                    + "Comments in the students' own language can be particularly helpful,\n"
                    + 'as this is often beyond our own capacity.\n\n'
                    + 'A few shorthand forms are available to make preparing clear, targeted\n'
                    + 'guidance as simple as possible. To set up the "wrong" answer as an\n'
                    + 'example, paste it into the text box, and put a single ">" character\n'
                    + 'at the beginning of the line:\n\n'
                    + '    > This article is of the laws of Utopia nowadays.\n\n'
                    + 'Mark a specific portion of the example by enclosing it in double\\n'
                    + 'parens, and adding a single letter or number after the opening parens:\n\n'
                    + '    > This article is ((1 of)) the laws of Utopia ((2 nowadays)).\n\n'
                    + 'To state a pattern, begin the line with two ">" characters (the example)\n'
                    + 'below also illustrates how to add italics):\n\n'
                    + '    >> The story is *about* soccer.\n\n'
                    + 'To state a rule, use three ">" characters:\n\n'
                    + '    >>> Never use the word "nowadays" in formal writing.\n\n'
                    + 'Circled markers can also be written by enclosing a single letter\n'
                    + 'or number in double parens:\n\n'
                    + '    This is ((1)) pen.\n\n'
                    + "That's about all there is to it. Again, we are grateful for your\n"
                    + 'contribution. If you can spend a few minutes this week reviewing\n'
                    + 'quiz errors, our students will be motivated to put in their very\n'
                    + 'effort during their period of study.\\n'
                    + 'Sincerely yours,\n'
                    + 'Frank Bennett\n'
                    + 'Faculty of Law\n'
                    + 'Nagoya University\n'
                    + 'Japan';

                var j = schedule.scheduleJob(rule, function(){
                    sys.mailer.send({
                        text:    msg.replace(/@@COMMENTER_ID@@/,adminKey),
                        from:    "Academic Writing Central <" + email_account + ">",
                        to:      email,
                        subject: 'Quizzer calling'
                    }, function(err, message) { console.log(err || message); });
                });
            };
        });
    }
    exports.scheduleClass = scheduleClass;
})();
<commit_msg>Mailer confirmed to work, adjust time setting<commit_after>(function () {
    var scheduleClass = function (sys) {
        this.sys = sys;
    }
    scheduleClass.prototype.run = function () {
        var schedule = require('node-schedule');
        var sys = this.sys;
        sys.db.all('SELECT adminID,name,email,interval FROM admin WHERE email IS NOT NULL AND interval IS NOT NULL AND role=2',[],function(err,rows){
            if (err) {return 'Error in scheduler(1)'};
            if (rows) {
                for (var i=0,ilen=rows.length;i<ilen;i+=1) {
                    var row = rows[i];
                    var adminID = row.adminID;
                    var name = row.name;
                    var email = row.email;
                    var adminKey = sys.getRandomKey(8,36);
                    var oldAdminKey = row.adminKey;
                    var dow = row.interval;
                    updateCommenterKeys(oldAdminKey,adminID,name,email,adminKey,dow);
                }
            }

            function updateCommenterKeys (oldAdminKey,adminID,name,email,adminKey,dow) {
                sys.db.run('UPDATE admin SET adminKey=? WHERE adminID=?',[adminKey,adminID],function(err){
                    if (err) {return 'Error in scheduler(2)'};

                    sys.admin[adminKey] = {name:name,role:2,id:adminID};
                    delete sys.admin[oldAdminKey];

                    scheduleMail(adminID,name,email,adminKey,dow);
                });
            };

            function scheduleMail(adminID,name,email,adminKey,dow) {
                // var hostname
                var hostname = sys.proxy_hostname;
                // var port
                var port = ':' + sys.real_port;
                var email_account = sys.email_account;

                var rule = new schedule.RecurrenceRule();
                rule.dayOfWeek = [dow];
                rule.hour = 8;
                rule.minute = 20;

                var msg = name + ':\n\n'
                    + 'Thank you for offering to comment on student work in our\n'
                    + 'writing program. We appreciate the value of your time, and\n'
                    + 'our students will benefit greatly from any constructive\n'
                    + 'feedback you can offer.\n\n'
                    + 'Your personal link to the commenting system is updated regularly\n'
                    + 'as a security measure. The link below is valid for the coming\n'
                    + 'week:\n\n'
                    + '    http://our.law.nagoya-u.ac.jp/quizzer/staff.html?commenter=@@COMMENTER_ID@@\n\n'
                    + 'After navigating to the quizzes for a class, you will find a\n'
                    + 'list of mistaken responses students have made to questions on\n'
                    + 'grammatical and style issues. Many responses are tagged with the\n'
                    + 'native language of students who missed that particular question.\n'
                    + "Comments in the students' own language can be particularly helpful,\n"
                    + 'as this is often beyond our own capacity.\n\n'
                    + 'A few shorthand forms are available to make preparing clear, targeted\n'
                    + 'guidance as simple as possible. To set up the "wrong" answer as an\n'
                    + 'example, paste it into the text box, and put a single ">" character\n'
                    + 'at the beginning of the line:\n\n'
                    + '    > This article is of the laws of Utopia nowadays.\n\n'
                    + 'Mark a specific portion of the example by enclosing it in double\n'
                    + 'parens, and adding a single letter or number after the opening parens:\n\n'
                    + '    > This article is ((1 of)) the laws of Utopia ((2 nowadays)).\n\n'
                    + 'To state a pattern, begin the line with two ">" characters (the example\n'
                    + 'below also illustrates how to add italics):\n\n'
                    + '    >> The story is *about* soccer.\n\n'
                    + 'To state a rule, use three ">" characters:\n\n'
                    + '    >>> Never use the word "nowadays" in formal writing.\n\n'
                    + 'Circled markers can also be written by enclosing a single letter\n'
                    + 'or number in double parens:\n\n'
                    + '    This was ((1)) first reform of corporate law.\n\n'
                    + "That's about all there is to it. Again, we are grateful for your\n"
                    + 'contribution. If you can spend a few minutes this week reviewing\n'
                    + 'quiz errors, our students will be motivated to put in their very\n'
                    + 'effort during their period of study.\n\n'
                    + 'Sincerely yours,\n\n'
                    + 'Frank Bennett\n'
                    + 'Faculty of Law\n'
                    + 'Nagoya University\n'
                    + 'Japan';

                var j = schedule.scheduleJob(rule, function(){
                    sys.mailer.send({
                        text:    msg.replace(/@@COMMENTER_ID@@/,adminKey),
                        from:    "Academic Writing Central <" + email_account + ">",
                        to:      email,
                        subject: 'Quizzer calling'
                    }, function(err, message) { console.log(err || message); });
                });
            };
        });
    }
    exports.scheduleClass = scheduleClass;
})();
<|endoftext|>


<commit_before>(function () {
  var Env = Ibis.Env;
  var Parser = Ibis.Parser;
  var Inferer = Ibis.Inferer;
  var Eva = Ibis.Eva;
  var Type = Ibis.Type;
  var Value = Ibis.Value;
  var Compat = Ibis.Compat;
  var IbisError = Ibis.IbisError;

  var valueEnv = Env.createGlobal({});
  var typeEnv = Env.createGlobal({});

  Compat.catchEvent(window, "load", setup);

  function setup(event) {
    var inputForm = document.getElementById("inputForm");
    var outputArea = document.getElementById("outputArea");
    Compat.catchEvent(inputForm, "submit", interpretForm);
    outputArea.value = "> ";
  }

  function interpretForm(event) {
    var theEvent = event ? event : window.event;

    var inputArea = document.getElementById("inputArea");
    var outputArea = document.getElementById("outputArea");

    var inputStr = inputArea.value;
    outputArea.value += inputStr + "\n" + interpret(inputStr) + "> ";
    inputArea.value = "";

    Compat.cancelEvent(theEvent);
  }

  function interpret(string) {
    var result = "";
    var parser = Parser.ofString(string);
    try {
      while (true) {
        var expr = Parser.parse(parser);
        if (!expr) {
          break;
        }
        var type = Inferer.infer(typeEnv, expr);
        var value = Eva.eval(valueEnv, expr);
        result += "- : " + type + " = " + value + "\n";
      }
    } catch (e) {
      if (e instanceof IbisError) {
        result += "ERROR: " + e.message + "\n";
      } else {
        throw e;
      }
    }
    return result;
  }

  function binOpType(lhs, rhs, ret) {
    return Type.createFun(lhs, Type.createFun(rhs, ret));
  }

  Env.add(typeEnv, "+", binOpType(Type.Int, Type.Int, Type.Int));
  Env.add(valueEnv, "+", Value.createSubr(function (lhs) {
    return Value.createSubr(function (rhs) {
      return Value.createInt(lhs.intValue + rhs.intValue);
    });
  }));

  Env.add(typeEnv, "-", binOpType(Type.Int, Type.Int, Type.Int));
  Env.add(valueEnv, "-", Value.createSubr(function (lhs) {
    return Value.createSubr(function (rhs) {
      return Value.createInt(lhs.intValue - rhs.intValue);
    });
  }));

  Env.add(typeEnv, "*", binOpType(Type.Int, Type.Int, Type.Int));
  Env.add(valueEnv, "*", Value.createSubr(function (lhs) {
    return Value.createSubr(function (rhs) {
      return Value.createInt(lhs.intValue * rhs.intValue);
    });
  }));

  Env.add(typeEnv, "/", binOpType(Type.Int, Type.Int, Type.Int));
  Env.add(valueEnv, "/", Value.createSubr(function (lhs) {
    return Value.createSubr(function (rhs) {
      return Value.createInt(lhs.intValue / rhs.intValue);
    });
  }));
})();
<commit_msg>Make outputArea auto-scroll to bottom<commit_after>(function () {
  var Env = Ibis.Env;
  var Parser = Ibis.Parser;
  var Inferer = Ibis.Inferer;
  var Eva = Ibis.Eva;
  var Type = Ibis.Type;
  var Value = Ibis.Value;
  var Compat = Ibis.Compat;
  var IbisError = Ibis.IbisError;

  var valueEnv = Env.createGlobal({});
  var typeEnv = Env.createGlobal({});

  Compat.catchEvent(window, "load", setup);

  function setup(event) {
    var inputForm = document.getElementById("inputForm");
    var outputArea = document.getElementById("outputArea");
    Compat.catchEvent(inputForm, "submit", interpretForm);
    Compat.catchEvent(inputForm, "submit", scrollToBottom);
    outputArea.value = "> ";
  }

  function scrollToBottom(event) {
    var outputArea = document.getElementById("outputArea");
    setTimeout(function () {  // for IE8
      outputArea.scrollTop = outputArea.scrollHeight - outputArea.clientHeight;
    }, 0);
  }

  function interpretForm(event) {
    var theEvent = event ? event : window.event;

    var inputArea = document.getElementById("inputArea");
    var outputArea = document.getElementById("outputArea");

    var inputStr = inputArea.value;
    outputArea.value += inputStr + "\n" + interpret(inputStr) + "> ";
    inputArea.value = "";

    Compat.cancelEvent(theEvent);
  }

  function interpret(string) {
    var result = "";
    var parser = Parser.ofString(string);
    try {
      while (true) {
        var expr = Parser.parse(parser);
        if (!expr) {
          break;
        }
        var type = Inferer.infer(typeEnv, expr);
        var value = Eva.eval(valueEnv, expr);
        result += "- : " + type + " = " + value + "\n";
      }
    } catch (e) {
      if (e instanceof IbisError) {
        result += "ERROR: " + e.message + "\n";
      } else {
        throw e;
      }
    }
    return result;
  }

  function binOpType(lhs, rhs, ret) {
    return Type.createFun(lhs, Type.createFun(rhs, ret));
  }

  Env.add(typeEnv, "+", binOpType(Type.Int, Type.Int, Type.Int));
  Env.add(valueEnv, "+", Value.createSubr(function (lhs) {
    return Value.createSubr(function (rhs) {
      return Value.createInt(lhs.intValue + rhs.intValue);
    });
  }));

  Env.add(typeEnv, "-", binOpType(Type.Int, Type.Int, Type.Int));
  Env.add(valueEnv, "-", Value.createSubr(function (lhs) {
    return Value.createSubr(function (rhs) {
      return Value.createInt(lhs.intValue - rhs.intValue);
    });
  }));

  Env.add(typeEnv, "*", binOpType(Type.Int, Type.Int, Type.Int));
  Env.add(valueEnv, "*", Value.createSubr(function (lhs) {
    return Value.createSubr(function (rhs) {
      return Value.createInt(lhs.intValue * rhs.intValue);
    });
  }));

  Env.add(typeEnv, "/", binOpType(Type.Int, Type.Int, Type.Int));
  Env.add(valueEnv, "/", Value.createSubr(function (lhs) {
    return Value.createSubr(function (rhs) {
      return Value.createInt(lhs.intValue / rhs.intValue);
    });
  }));
})();
<|endoftext|>


<commit_before>// 'use strict';

var schedule = require('node-schedule');
// var c = require('./channels.js');
// var d = require('./daily.js');
// var date = require('./date.js');
// var slack = require('./slack.js');
var glob = require('glob');
var path = require('path');

module.exports = scheduler;

function scheduler() {

  var events = [];

  glob(path.resolve('./schedules/**/*.js'), function(err, files) {
    files.forEach(function (file) {
      events = events.concat(require(file));
    });
  });

  console.log(events);

  events = events.concat('../schedules/_juniors_daily.js');
  events = events.concat('../schedules/_seniors_daily.js');
  events = events.concat('../schedules/_students_daily.js');

  events = events.concat('../schedules/W1D4.js');
  events = events.concat('../schedules/W7D4.js');

  events.forEach(function (event) {
    schedule.scheduleJob(event.when, function () {
      if(Array.isArray(event.who)) {
        event.who.forEach(function (channel) {
          channel.send(event.message);
        });
      } else {
        event.who.send(event.message);
      }
    }.bind(this));
  });
}
<commit_msg>debugging<commit_after>// 'use strict';

var schedule = require('node-schedule');
// var c = require('./channels.js');
// var d = require('./daily.js');
// var date = require('./date.js');
// var slack = require('./slack.js');
var glob = require('glob');
var path = require('path');

module.exports = scheduler;

function scheduler() {

  var events = [];

  glob(path.resolve('./schedules/**/*.js'), function(err, files) {
    files.forEach(function (file) {
      console.log(file);
      events = events.concat(require(file));
    });
  });

  console.log(events);

  events = events.concat('../schedules/_juniors_daily.js');
  events = events.concat('../schedules/_seniors_daily.js');
  events = events.concat('../schedules/_students_daily.js');

  events = events.concat('../schedules/W1D4.js');
  events = events.concat('../schedules/W7D4.js');

  events.forEach(function (event) {
    schedule.scheduleJob(event.when, function () {
      if(Array.isArray(event.who)) {
        event.who.forEach(function (channel) {
          channel.send(event.message);
        });
      } else {
        event.who.send(event.message);
      }
    }.bind(this));
  });
}
<|endoftext|>


<commit_before>const Player = require('./Player');
const stayBottom = require('./stayBottom');
const Element = require('./createElementWithEvent');
const partial = require('../templates/');
const DomInterface = require('./DomInterface');

require('../scss/main.scss');

const init = (models = {}) => {
  const selectors = require('./selectors');
  const containers = document.querySelectorAll(selectors.container);

  const players =
    Array.prototype.slice.call(containers)
    .map(container => {
      // An instance of h4p.Player
      const player = new Player();

      // DOM renderer interface
      const dom = new DomInterface({
        container,
        selectors,
        template: partial.content,
        partial
      });

      dom.classNames = selectors.htmlClass;

      const fileOpen = (event) => {
        const file = event.target.files[0];
        const reader = new FileReader();
        reader.onload = ({target:{result}}) => {
          const files = [{ name: file.name, filename: file.name, code: result }];
          player.restart('screen', {files});
          player.restart('editor', {files});
          event.target.value = ''; // Can upload same file
        };
        reader.readAsText(file);
      };

      dom.menuButtons = [
        Element({ label: 'HACK', onClick: () => player.toggle('editor') }),
        Element({ label: 'RELOAD', onClick: () => player.restart('screen') }),
        Element({ label: 'OPEN', input: {type: 'file', accept: 'text/javascript'}, onChange: fileOpen })
      ];

      // Inline script
      const query = container.getAttribute('data-target');
      const code = query && document.querySelector(query).textContent;

      const resizeTask = stayBottom(dom);
      dom.addEventListener('screen.resize', resizeTask);
      player.on('screen.resize', resizeTask);

      player.on('screen.load', ({child}) => {
        const frame = child.frame;
        player.show('screen');

        const resized = ({width, height}) => player.emit('screen.resize', {frame, width, height});
        child.get('size').then(resized);
        child.on('resize', resized);
      });

      // eval them
      player.on('editor.run', function ({child}, files) {
        player.restart('screen', {files});
      });

      const alignment = ({child}, view) => {
        const {x, y} = view.edge;
        switch (view.align) {
          case 'top':
            player.setRect('editor', 0, 0, '100vw', y);
            break;
          case 'right':
            player.setRect('editor', x, 0, innerWidth - x, '100vh');
            break;
          case 'left':
            player.setRect('editor', 0, 0, x, '100vh');
            break;
          case 'bottom':
            player.setRect('editor', 0, y, '100vw', innerHeight - y);
            break;
        }
      };
      player.on('editor.resize', alignment);

      player.on('editor.load', ({child}) => {
        child.on('run', (files) => player.emit('editor.run', {child}, files));
        child.on('render', (view) => player.emit('editor.resize', {child}, view));
        const resized = () => child.get('view').then((view) => alignment({child}, view));
        resized();
        addEventListener('resize', resized);
        player.once('editor.beforeunload', () => removeEventListener('resize', task));
      });

      // Default
      const files = [{
        name: 'main',
        filename: 'main.js',
        code
      }];
      const view = {
        align: 'right',
        edge: {
          x: innerWidth / 2,
          y: innerHeight / 2
        }
      };

      player.start('screen', Object.assign({}, {files}, models.screen));
      player.start('editor', Object.assign({}, {files}, view, models.editor));

      return player;
    });

  return players;
};

const h4p = (...args) =>
  new Promise((resolve, reject) => {
    document.readyState === 'complete' ?
      resolve(init(...args)) :
      addEventListener('load', () => {
        return resolve(init(...args));
      });
  });

h4p.Player = Player;
h4p.trigger = require('./keyEvent')(EXPORT_VAR_NAME).trigger;

// export global
window[EXPORT_VAR_NAME] = h4p;
<commit_msg>Add default param<commit_after>const Player = require('./Player');
const stayBottom = require('./stayBottom');
const Element = require('./createElementWithEvent');
const partial = require('../templates/');
const DomInterface = require('./DomInterface');

require('../scss/main.scss');

const init = (models = {}) => {
  const selectors = require('./selectors');
  const containers = document.querySelectorAll(selectors.container);

  const players =
    Array.prototype.slice.call(containers)
    .map(container => {
      // An instance of h4p.Player
      const player = new Player();

      // DOM renderer interface
      const dom = new DomInterface({
        container,
        selectors,
        template: partial.content,
        partial
      });

      dom.classNames = selectors.htmlClass;

      const fileOpen = (event) => {
        const file = event.target.files[0];
        const reader = new FileReader();
        reader.onload = ({target:{result}}) => {
          const files = [{ name: file.name, filename: file.name, code: result }];
          player.restart('screen', {files});
          player.restart('editor', {files});
          event.target.value = ''; // Can upload same file
        };
        reader.readAsText(file);
      };

      dom.menuButtons = [
        Element({ label: 'HACK', onClick: () => player.toggle('editor') }),
        Element({ label: 'RELOAD', onClick: () => player.restart('screen') }),
        Element({ label: 'OPEN', input: {type: 'file', accept: 'text/javascript'}, onChange: fileOpen })
      ];

      // Inline script
      const query = container.getAttribute('data-target');
      const code = query && document.querySelector(query).textContent;

      const resizeTask = stayBottom(dom);
      dom.addEventListener('screen.resize', resizeTask);
      player.on('screen.resize', resizeTask);

      player.on('screen.load', ({child}) => {
        const frame = child.frame;
        player.show('screen');

        const resized = ({width, height}) => player.emit('screen.resize', {frame, width, height});
        child.get('size').then(resized);
        child.on('resize', resized);
      });

      // eval them
      player.on('editor.run', function ({child}, files) {
        player.restart('screen', {files});
      });

      const alignment = ({child}, view) => {
        const {x, y} = view.edge;
        switch (view.align) {
          case 'top':
            player.setRect('editor', 0, 0, '100vw', y);
            break;
          case 'right':
            player.setRect('editor', x, 0, innerWidth - x, '100vh');
            break;
          case 'left':
            player.setRect('editor', 0, 0, x, '100vh');
            break;
          case 'bottom':
            player.setRect('editor', 0, y, '100vw', innerHeight - y);
            break;
        }
      };
      player.on('editor.resize', alignment);

      player.on('editor.load', ({child}) => {
        child.on('run', (files) => player.emit('editor.run', {child}, files));
        child.on('render', (view) => player.emit('editor.resize', {child}, view));
        const resized = () => child.get('view').then((view) => alignment({child}, view));
        resized();
        addEventListener('resize', resized);
        player.once('editor.beforeunload', () => removeEventListener('resize', task));
      });

      // Default
      const files = [{
        name: 'main',
        filename: 'main.js',
        code,
        isEntryPoint: true
      }];
      const view = {
        align: 'right',
        edge: {
          x: innerWidth / 2,
          y: innerHeight / 2
        }
      };

      player.start('screen', Object.assign({}, {files}, models.screen));
      player.start('editor', Object.assign({}, {files}, view, models.editor));

      return player;
    });

  return players;
};

const h4p = (...args) =>
  new Promise((resolve, reject) => {
    document.readyState === 'complete' ?
      resolve(init(...args)) :
      addEventListener('load', () => {
        return resolve(init(...args));
      });
  });

h4p.Player = Player;
h4p.trigger = require('./keyEvent')(EXPORT_VAR_NAME).trigger;

// export global
window[EXPORT_VAR_NAME] = h4p;
<|endoftext|>


<commit_before>// TODO: Locking like ruby does

var EventEmitter = require('events').EventEmitter;
var util         = require("util");
var connection   = require(__dirname + "/connection.js").connection;
var queue        = require(__dirname + "/queue.js").queue;

var scheduler = function(options, jobs, callback){
  var self = this;
  var defaults = self.defaults();
  for(var i in defaults){
    if(options[i] == null){
      options[i] = defaults[i];
    }
  }
  if(typeof jobs == 'function' && callback == null){
    callback = jobs;
    jobs = {};
  }
  self.options = options;
  self.connection = new connection(options.connection);
  self.running = false;
  self.connection.connect(function(err){
    self.queue = new queue({connection: options.connection}, jobs, function(){
      if(typeof callback == 'function'){ callback(); }
    });
  });
}

util.inherits(scheduler, EventEmitter);

scheduler.prototype.defaults = function(){
  var self = this;
  return {
    timeout: 5000,
  }
}

scheduler.prototype.start = function() {
  var self = this;
  if (!self.running) {
    self.emit('start')
    self.running = true;
    self.processing = false;
    self.timer = setTimeout((function() {
      self.poll();
    }), self.options.timeout);
  }
};

scheduler.prototype.end = function(callback) {
  var self = this;
  self.running = false;
  if(self.processing == false){
    clearTimeout(self.timer);
    self.emit('end');
    callback();
  }else if(self.processing == true){
    setTimeout(function(){
      self.end(callback);
    }, (self.options.timeout / 2));
  }
};

scheduler.prototype.poll = function(callback) {
  var self = this;
  self.processing = true;
  clearTimeout(self.timer);
  self.emit('poll');
  self.nextDelayedTimestamp(function(err, timestamp){
    if(!err && timestamp){
      self.emit('working_timestamp', timestamp);
      self.enqueueDelayedItemsForTimestamp(timestamp, function(err){
        if(err){ self.emit('error', err); }
        self.poll(callback);
      });
    }else{
      if(err){ self.emit('error', err); }
      self.processing = false;
      if(self.running === true){
        self.timer = setTimeout((function() {
          self.poll();
        }), self.options.timeout);
      }
      if(typeof callback === "function"){ callback(); }
    }
  });
};

scheduler.prototype.nextDelayedTimestamp = function(callback) {
  var self = this;
  var time = Math.round(new Date().getTime() / 1000);
  self.connection.redis.zrangebyscore(self.connection.key('delayed_queue_schedule'), '-inf', time, 'limit', 0, 1, function(err, items) {
    if (err || items === null || items.length === 0) {
      callback(err);
    } else {
      callback(null, items[0]);
    }
  });
};

scheduler.prototype.enqueueDelayedItemsForTimestamp = function(timestamp, callback) {
  var self = this;
  self.nextItemForTimestamp(timestamp, function(err, job){
    if (!err && job ) {
      self.transfer(timestamp, job, function(){
        self.enqueueDelayedItemsForTimestamp(timestamp, callback);
      });
    } else {
      callback(err);
    }
  });
};

scheduler.prototype.nextItemForTimestamp = function(timestamp, callback) {
  var self = this;
  var key = self.connection.key("delayed:" + timestamp);
  self.connection.redis.lpop(key, function(err, job){
    if(err){
      callback(err);
    }else{
      self.connection.redis.srem(self.connection.key("timestamps:" + job), key, function(err){
        self.cleanupTimestamp(timestamp, function(){
          if (err) {
            callback(err);
          } else {
            callback(null, JSON.parse(job));
          }
        });
      });
    }
  });
};

scheduler.prototype.transfer = function(timestamp, job, callback) {
  var self = this;
  self.queue.enqueue(job["queue"], job["class"], job.args, function(err){
    if(err){ self.emit('error', err); }
    self.emit('transferred_job', timestamp, job);
    callback();
  });
};

scheduler.prototype.cleanupTimestamp = function(timestamp, callback) {
  var self = this;
  var key = self.connection.key("delayed:" + timestamp);
  self.connection.redis.llen(key, function(err, len) {
    if (len === 0) {
      self.connection.redis.del(key);
      self.connection.redis.zrem(self.connection.key('delayed_queue_schedule'), timestamp);
    }
    callback();
  });
};

exports.scheduler = scheduler;<commit_msg>no sync callback for secheduler<commit_after>// TODO: Locking like ruby does

var EventEmitter = require('events').EventEmitter;
var util         = require("util");
var connection   = require(__dirname + "/connection.js").connection;
var queue        = require(__dirname + "/queue.js").queue;

var scheduler = function(options, jobs, callback){
  var self = this;
  var defaults = self.defaults();
  for(var i in defaults){
    if(options[i] == null){
      options[i] = defaults[i];
    }
  }
  if(typeof jobs == 'function' && callback == null){
    callback = jobs;
    jobs = {};
  }
  self.options = options;
  self.connection = new connection(options.connection);
  self.running = false;
  self.connection.connect(function(err){
    self.queue = new queue({connection: options.connection}, jobs, function(){
      if(typeof callback == 'function'){ callback(); }
    });
  });
}

util.inherits(scheduler, EventEmitter);

scheduler.prototype.defaults = function(){
  var self = this;
  return {
    timeout: 5000,
  }
}

scheduler.prototype.start = function() {
  var self = this;
  if (!self.running) {
    self.emit('start')
    self.running = true;
    self.processing = false;
    self.timer = setTimeout((function() {
      self.poll();
    }), self.options.timeout);
  }
};

scheduler.prototype.end = function(callback) {
  var self = this;
  self.running = false;
  if(self.processing == false){
    clearTimeout(self.timer);
    self.emit('end');
    process.nextTick(function(){
      callback();
    });
  }else if(self.processing == true){
    setTimeout(function(){
      self.end(callback);
    }, (self.options.timeout / 2));
  }
};

scheduler.prototype.poll = function(callback) {
  var self = this;
  self.processing = true;
  clearTimeout(self.timer);
  self.emit('poll');
  self.nextDelayedTimestamp(function(err, timestamp){
    if(!err && timestamp){
      self.emit('working_timestamp', timestamp);
      self.enqueueDelayedItemsForTimestamp(timestamp, function(err){
        if(err){ self.emit('error', err); }
        self.poll(callback);
      });
    }else{
      if(err){ self.emit('error', err); }
      self.processing = false;
      if(self.running === true){
        self.timer = setTimeout((function() {
          self.poll();
        }), self.options.timeout);
      }
      if(typeof callback === "function"){ callback(); }
    }
  });
};

scheduler.prototype.nextDelayedTimestamp = function(callback) {
  var self = this;
  var time = Math.round(new Date().getTime() / 1000);
  self.connection.redis.zrangebyscore(self.connection.key('delayed_queue_schedule'), '-inf', time, 'limit', 0, 1, function(err, items) {
    if (err || items === null || items.length === 0) {
      callback(err);
    } else {
      callback(null, items[0]);
    }
  });
};

scheduler.prototype.enqueueDelayedItemsForTimestamp = function(timestamp, callback) {
  var self = this;
  self.nextItemForTimestamp(timestamp, function(err, job){
    if (!err && job ) {
      self.transfer(timestamp, job, function(){
        self.enqueueDelayedItemsForTimestamp(timestamp, callback);
      });
    } else {
      callback(err);
    }
  });
};

scheduler.prototype.nextItemForTimestamp = function(timestamp, callback) {
  var self = this;
  var key = self.connection.key("delayed:" + timestamp);
  self.connection.redis.lpop(key, function(err, job){
    if(err){
      callback(err);
    }else{
      self.connection.redis.srem(self.connection.key("timestamps:" + job), key, function(err){
        self.cleanupTimestamp(timestamp, function(){
          if (err) {
            callback(err);
          } else {
            callback(null, JSON.parse(job));
          }
        });
      });
    }
  });
};

scheduler.prototype.transfer = function(timestamp, job, callback) {
  var self = this;
  self.queue.enqueue(job["queue"], job["class"], job.args, function(err){
    if(err){ self.emit('error', err); }
    self.emit('transferred_job', timestamp, job);
    callback();
  });
};

scheduler.prototype.cleanupTimestamp = function(timestamp, callback) {
  var self = this;
  var key = self.connection.key("delayed:" + timestamp);
  self.connection.redis.llen(key, function(err, len) {
    if (len === 0) {
      self.connection.redis.del(key);
      self.connection.redis.zrem(self.connection.key('delayed_queue_schedule'), timestamp);
    }
    callback();
  });
};

exports.scheduler = scheduler;<|endoftext|>


<commit_before>/**
 * The main entrypoint for our react-component render server.
 */

'use strict';

const argparse = require("argparse");
const express = require("express");
const expressWinston = require('express-winston');
const winston = require('winston');

const app = require("./server.js");
const cache = require("./cache.js");
const fetchPackage = require("./fetch_package.js");
const packageInfo = require("../package.json");
const render = require("./render.js");
const renderSecret = require("./secret.js");

const logging = winston;     // just an alias, for clarity

const parser = new argparse.ArgumentParser({
    version: packageInfo.version,
    addHelp: true,
    description: packageInfo.description,
});
parser.addArgument(['-p', '--port'],
                   {type: 'int', defaultValue: 8060,
                    help: "Port to run on."});
parser.addArgument(['--dev'],
                   {action: 'storeTrue',
                    help: "Set if running on dev; controls caching/etc."});
parser.addArgument(['--cache-size'],
                   {type: 'int', defaultValue: 100,
                    help: "Internal cache size, in MB."});
parser.addArgument(['--log-level'],
                   {defaultValue: 'info',
                    choices: ['silly', 'debug', 'verbose', 'info',
                              'warn', 'error'],
                    help: "What level to log at."});

const args = parser.parseArgs();

const port = args.port;

// Set up our globals and singletons
if (args.dev) {
    // In dev, we do an if-modified-since query rather than trusting
    // the cache never gets out of date.  (In prod the default cache
    // behavior is fine because package-names include their md5 in the
    // filename.)
    fetchPackage.setDefaultCacheBehavior('ims');
    render.setDefaultCacheBehavior('ignore');
    // We also turn off the timeout in dev; it's not as important there.
    fetchPackage.setTimeout(null);
    // Disable the need for secrets.
    renderSecret.matches = (actual) => true;
    process.env.NODE_ENV = 'dev';
} else {
    // This is important for the default catch-all error handler:
    // http://expressjs.com/en/guide/error-handling.html
    process.env.NODE_ENV = 'production';
}

// Add logging support, based on
//   https://cloud.google.com/nodejs/getting-started/logging-application-events
winston.level = args.log_level;
const appWithLogging = express();
appWithLogging.use(expressWinston.logger({      // request logging
    transports: [
        new winston.transports.Console({
            json: false,
            colorize: args.dev,    // colorize for dev, but not prod
        }),
    ],
    expressFormat: true,
    meta: false,
}));
appWithLogging.use(expressWinston.errorLogger({      // error logging
    transports: [
        new winston.transports.Console({
            json: true,
            colorize: args.dev,
        }),
    ],
}));
appWithLogging.use(app);

cache.init(args.cacheSize * 1024 * 1024);

// Don't let unhandled Promise rejections fail silently.
//
// Ideally this would result in the request containing the unhandled rejection,
// if any, 500'ing, but I don't know how you'd be able to recover a reference
// to the request from reason or p.
process.on('unhandledRejection', (reason, p) => {
    logging.error("Unhandled Rejection at: Promise ", p,
                  " reason: ", reason.stack);
});

const server = appWithLogging.listen(port, () => {
    const host = server.address().address;
    const port = server.address().port;

    logging.info('react-render-server running at http://%s:%s', host, port);
});

<commit_msg>Remove the unhandledRejection handler.<commit_after>/**
 * The main entrypoint for our react-component render server.
 */

'use strict';

const argparse = require("argparse");
const express = require("express");
const expressWinston = require('express-winston');
const winston = require('winston');

const app = require("./server.js");
const cache = require("./cache.js");
const fetchPackage = require("./fetch_package.js");
const packageInfo = require("../package.json");
const render = require("./render.js");
const renderSecret = require("./secret.js");

const logging = winston;     // just an alias, for clarity

const parser = new argparse.ArgumentParser({
    version: packageInfo.version,
    addHelp: true,
    description: packageInfo.description,
});
parser.addArgument(['-p', '--port'],
                   {type: 'int', defaultValue: 8060,
                    help: "Port to run on."});
parser.addArgument(['--dev'],
                   {action: 'storeTrue',
                    help: "Set if running on dev; controls caching/etc."});
parser.addArgument(['--cache-size'],
                   {type: 'int', defaultValue: 100,
                    help: "Internal cache size, in MB."});
parser.addArgument(['--log-level'],
                   {defaultValue: 'info',
                    choices: ['silly', 'debug', 'verbose', 'info',
                              'warn', 'error'],
                    help: "What level to log at."});

const args = parser.parseArgs();

const port = args.port;

// Set up our globals and singletons
if (args.dev) {
    // In dev, we do an if-modified-since query rather than trusting
    // the cache never gets out of date.  (In prod the default cache
    // behavior is fine because package-names include their md5 in the
    // filename.)
    fetchPackage.setDefaultCacheBehavior('ims');
    render.setDefaultCacheBehavior('ignore');
    // We also turn off the timeout in dev; it's not as important there.
    fetchPackage.setTimeout(null);
    // Disable the need for secrets.
    renderSecret.matches = (actual) => true;
    process.env.NODE_ENV = 'dev';
} else {
    // This is important for the default catch-all error handler:
    // http://expressjs.com/en/guide/error-handling.html
    process.env.NODE_ENV = 'production';
}

// Add logging support, based on
//   https://cloud.google.com/nodejs/getting-started/logging-application-events
winston.level = args.log_level;
const appWithLogging = express();
appWithLogging.use(expressWinston.logger({      // request logging
    transports: [
        new winston.transports.Console({
            json: false,
            colorize: args.dev,    // colorize for dev, but not prod
        }),
    ],
    expressFormat: true,
    meta: false,
}));
appWithLogging.use(expressWinston.errorLogger({      // error logging
    transports: [
        new winston.transports.Console({
            json: true,
            colorize: args.dev,
        }),
    ],
}));
appWithLogging.use(app);

cache.init(args.cacheSize * 1024 * 1024);

const server = appWithLogging.listen(port, () => {
    const host = server.address().address;
    const port = server.address().port;

    logging.info('react-render-server running at http://%s:%s', host, port);
});

<|endoftext|>


<commit_before>var express = require('express'),
    memwatch,
    childProcess = require('child_process'),
    hd,
    app = express(),
    arguments = process.argv.splice(2),
    port = arguments[0] !== 'undefined' ? arguments[0] : 3000,
    config = require('../bin/config'),
    getContent,
    respond,
    openedProcesses= 0,
    URLQueue = [],
    diff,
    start,
    is404 = false,
    is500 = false;

var log = require('./log');

if (config.debug) {
  memwatch = require('memwatch');

  // initialises the necessary variables and listeners to write everything about memory
  start = new Date();

  function msFromStart() {
    return new Date() - start;
  }
  // report to console postgc heap size
  memwatch.on('stats', function(d) {
    log.info("MEMWATCH postgc:", msFromStart(), d.current_base);
  });

  memwatch.on('leak', function(d) {
    log.error("MEMWATCH leak:", d);
  });
}

getContent = function(url, callback) {
  var checkMemory;
  var content = '';
  var timeStart = new Date().getTime();

  if (config.debug) {
    hd = new memwatch.HeapDiff();
  }
  openedProcesses++;

  var phantom = childProcess.execFile('phantomjs',
    [ '--ignore-ssl-errors='+config.ignoreSSLErrors, __dirname + '/phantom-server.js', url],
    {timeout: config.phantomTimeout, killSignal: 'SIGKILL'}, function(error, stdout) {
      if (error !== null && error.killed) {
        callback(504);
      } else {
        callback(stdout);
      }

      if (config.debug) {
        clearInterval(checkMemory);
      }
    });

  phantom.stdout.setEncoding('utf8');

  phantom.stderr.on('data', function (data) {
      log.error('Phantom.js STDERR: ' + data);

      if(data === '404') {
        is404 = true;
      } else if(data === '500') {
        is500 = true;
      }
  });

  phantom.on('exit', function(code) {
    if (config.verbose) {
      if (code !== 0) {
        log.info('url: ' + url + ' ERROR: PhantomJS Exited with code: ' + code);
      } else {
        log.info(
          'url: ' + url +
            ' HTMLSnapshot completed successfully.' +
            ' Content-Length: ' + content.length
        );
      }
    }
    if (config.debug) {
      diff = hd.end();
      log.info('MEMWATCH report: ');
      log.info(JSON.stringify(diff));
    }

    // measure the time it taken
    var timeFinish = new Date().getTime();
    log.info('In '+((timeFinish-timeStart)/1000)+' seconds');
  });

  if (config.debug) {
    checkMemory = setInterval(function() {
      childProcess.exec('ps -p' + phantom.pid + ' -o vsize -o pcpu -o pmem',  function (err, stdout, stderr) {
        err = err || stderr;
        if (!err) {
          log.info('PARENT Heap used: ',process.memoryUsage());
          log.info('CHILD memory consumption:\n ', stdout);
        }
      });
    }, 500);
  }
};

// function that manages the number of processes
function sendURL(data) {
  if (config.maxProcesses>openedProcesses) {
    getContent(data.url, data.callback);
  } else {
    URLQueue.push(data);
  }
}

respond = function (req, res) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");

  var url;

  if(req.headers.referer) {
    url = req.headers.referer;
  }

  if (config.verbose) {
    log.info(req.headers);
  }

  if(req.headers['x-forwarded-host']) {
    var protocol = (typeof req.headers['x-forwarded-proto'] != 'undefined' && req.headers['x-forwarded-proto'] === 'https') ? 'https' : 'http';
    url = protocol + '://' + req.headers['x-forwarded-host'] + req.params[0];
  }

  log.info('Fetching URL: ' + url);

  sendURL({
    url: url,
    callback: function (content) {
      // the precedence is to the not found because it is a broken link
      if (is404) {
        res.status(404);
      }
      else if(is500) {
        res.status(500);
      }

      is404 = false;
      is500 = false;

      res.send(content);
      openedProcesses--;

      // checks if is there any element in the queue to process
      var next;

      if ((next=URLQueue.shift()) !== undefined)
      {
        getContent(next.url, next.callback);
      }

    }});
}

app.get(/(.*)/, respond);

log.info('Server started on port ' + port);
app.listen(port);<commit_msg>Add some more useful logging.<commit_after>var express = require('express'),
    memwatch,
    childProcess = require('child_process'),
    hd,
    app = express(),
    arguments = process.argv.splice(2),
    port = arguments[0] !== 'undefined' ? arguments[0] : 3000,
    config = require('../bin/config'),
    getContent,
    respond,
    openedProcesses= 0,
    URLQueue = [],
    diff,
    start,
    is404 = false,
    is500 = false;

var log = require('./log');

if (config.debug) {
  memwatch = require('memwatch');

  // initialises the necessary variables and listeners to write everything about memory
  start = new Date();

  function msFromStart() {
    return new Date() - start;
  }
  // report to console postgc heap size
  memwatch.on('stats', function(d) {
    log.info("MEMWATCH postgc:", msFromStart(), d.current_base);
  });

  memwatch.on('leak', function(d) {
    log.error("MEMWATCH leak:", d);
  });
}

getContent = function(url, callback) {
  var checkMemory;
  var content = '';
  var timeStart = new Date().getTime();

  if (config.debug) {
    hd = new memwatch.HeapDiff();
  }
  openedProcesses++;

  var phantom = childProcess.execFile('phantomjs',
    [ '--ignore-ssl-errors='+config.ignoreSSLErrors, __dirname + '/phantom-server.js', url],
    {timeout: config.phantomTimeout, killSignal: 'SIGKILL'}, function(error, stdout) {
      if (error !== null && error.killed) {
        callback(504);
      } else {
        callback(stdout);
      }

      if (config.debug) {
        clearInterval(checkMemory);
      }
    });

  phantom.stdout.setEncoding('utf8');

  phantom.stderr.on('data', function (data) {
      log.error('Phantom.js STDERR: ' + data);

      if(data === '404') {
        is404 = true;
      } else if(data === '500') {
        is500 = true;
      }
  });

  phantom.on('exit', function(code) {
    if (config.verbose) {
      if (code !== 0) {
        log.info('url: ' + url + ' ERROR: PhantomJS Exited with code: ' + code);
      } else {
        log.info(
          'url: ' + url +
            ' HTMLSnapshot completed successfully.' +
            ' Content-Length: ' + content.length
        );
      }
    }
    if (config.debug) {
      diff = hd.end();
      log.info('MEMWATCH report: ');
      log.info(JSON.stringify(diff));
    }

    // measure the time it taken
    var timeFinish = new Date().getTime();
    log.info('Phantom JS finished fetch in '+((timeFinish-timeStart)/1000)+' seconds');
  });

  if (config.debug) {
    checkMemory = setInterval(function() {
      childProcess.exec('ps -p' + phantom.pid + ' -o vsize -o pcpu -o pmem',  function (err, stdout, stderr) {
        err = err || stderr;
        if (!err) {
          log.info('PARENT Heap used: ',process.memoryUsage());
          log.info('CHILD memory consumption:\n ', stdout);
        }
      });
    }, 500);
  }
};

// function that manages the number of processes
function sendURL(data) {
  if (config.maxProcesses>openedProcesses) {
    getContent(data.url, data.callback);
  } else {
    URLQueue.push(data);
  }
}

respond = function (req, res) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");

  var url;

  /*
  WHYYY???
  */
  if(req.headers.referer) {
    url = req.headers.referer;
  }

  log.info('Incoming request, headers:', req.headers);

  if(req.headers['x-forwarded-host']) {
    var protocol = (typeof req.headers['x-forwarded-proto'] != 'undefined' && req.headers['x-forwarded-proto'] === 'https') ? 'https' : 'http';
    url = protocol + '://' + req.headers['x-forwarded-host'] + req.params[0];
  }

  log.info('Fetching ', url);

  sendURL({
    url: url,
    callback: function (content) {
      // the precedence is to the not found because it is a broken link
      if (is404) {
        res.status(404);
      }
      else if(is500) {
        res.status(500);
      }

      is404 = false;
      is500 = false;

      res.send(content);
      openedProcesses--;

      // checks if is there any element in the queue to process
      var next;

      if ((next=URLQueue.shift()) !== undefined)
      {
        getContent(next.url, next.callback);
      }

    }});
}

app.get(/(.*)/, respond);

log.info('Server started on port ' + port);
app.listen(port);
<|endoftext|>


<commit_before>// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import {ClientTable, Event} from 'vue-tables-2'
import 'bootstrap/dist/css/bootstrap.min.css'
import axios from 'axios'
import _ from 'lodash'
import serialize from './lib/serialize'
import Modal from './components/Modal'

Vue.config.productionTip = false

var data = []
var metadata = { log: [] }
var getAndLoadDict = function (url) {
  axios.get(url).then((response) => {
    var displayData = serialize.dictToDisplay(response.data)
    loadDict(displayData)
  })
}

var loadDict = function (displayData) {
  data.push.apply(data, displayData.display)
  metadata = _.cloneDeep(displayData.metadata)
}

var addEntry = function (entry) {
  var term = _.get(entry, 'wikidata.labels.en.value')
  if (!(term === undefined)) {
    data.push({
      wikidata: entry.text,
      contentmine: getNextID(),
      name: term,
      term
    })
  }
}

var logQuery = function (queryString) {
  metadata.log.push({
    type: 'wdqs',
    query: queryString,
    time: Date.now()
  })
}

var logPagePile = function (PagePileID) {
  metadata.log.push({
    type: 'pagepile',
    id: PagePileID,
    time: Date.now()
  })
}

var getNextID = function () {
  var ids = data.map((row) => {
    return parseInt(row.contentmine.match(/(\d+)$/)[0])
  })
  var max = _.max(ids)
  if (max === undefined) max = -1
  var newid = parseInt(max) + 1
  return 'CM.' + metadata.id + newid
}

Vue.component('wikidata', {
  props: ['data'],
  template: '{{data.wikidata}}',
  computed: {
    wUrl () {
      return 'https://wikidata.org/wiki/' + this.data.wikidata
    }
  }
})

Vue.component('modal', Modal)

Vue.use(ClientTable)
/* eslint-disable no-new */
new Vue({
  el: '#app',
  data: {
    showModal: false,
    downloadContent: null,
    showDictSelector: true,
    showTable: false,
    columns: ['contentmine', 'term', 'name', 'wikidata'],
    tableData: data,
    metadata: metadata,
    options: {
      templates: {
        wikidata: 'wikidata'
      },
      customFilters: [{
        name: 'prefix',
        callback: (row, query) => {
          return _.upperCase(row.term[0]) === query
        }
      }]
    },
    dicts: [
      {name: 'Cochrane', url: 'https://rawgit.com/ContentMine/dictionaries/master/json/cochrane.json'},
      {name: 'Wikidata Country', url: 'https://rawgit.com/ContentMine/dictionaries/master/json/wikidatacountry.json'},
      {name: 'insecticides', url: 'https://rawgit.com/ContentMine/dictionaries/master/json/insecticides.json'},
      {name: 'disease', url: 'https://rawgit.com/ContentMine/dictionaries/master/json/disease.json'}
    ],
    prefixes: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
  },
  methods: {
    dictLoad (dict) {
      getAndLoadDict(dict.url)
      this.showDictSelector = false
      this.showTable = true
    },
    prefixFilter (prefix) {
      Event.$emit('vue-tables.filter::prefix', prefix)
    },
    startDownload () {
      this.downloadContent = 'data:application/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(serialize.displayToDict(this.tableData, this.metadata)))
    },
    newDict () {
      this.showDictSelector = false
      this.showTable = true
    },
    loadDictionary (e) {
      var fReader = new window.FileReader()
      var self = this
      fReader.onload = function (event) {
        var displayData = serialize.dictToDisplay(JSON.parse(event.target.result))
        loadDict(displayData)
        self.showDictSelector = false
        self.showTable = true
      }
      fReader.readAsText(e.target.files[0])
    }
  }
})
.$on('newentity', addEntry)
.$on('updateQuery', logQuery)
.$on('updatePagePile', logPagePile)
<commit_msg>pretty format dictionary out<commit_after>// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import {ClientTable, Event} from 'vue-tables-2'
import 'bootstrap/dist/css/bootstrap.min.css'
import axios from 'axios'
import _ from 'lodash'
import serialize from './lib/serialize'
import Modal from './components/Modal'

Vue.config.productionTip = false

var data = []
var metadata = { log: [] }
var getAndLoadDict = function (url) {
  axios.get(url).then((response) => {
    var displayData = serialize.dictToDisplay(response.data)
    loadDict(displayData)
  })
}

var loadDict = function (displayData) {
  data.push.apply(data, displayData.display)
  metadata = _.cloneDeep(displayData.metadata)
}

var addEntry = function (entry) {
  var term = _.get(entry, 'wikidata.labels.en.value')
  if (!(term === undefined)) {
    data.push({
      wikidata: entry.text,
      contentmine: getNextID(),
      name: term,
      term
    })
  }
}

var logQuery = function (queryString) {
  metadata.log.push({
    type: 'wdqs',
    query: queryString,
    time: Date.now()
  })
}

var logPagePile = function (PagePileID) {
  metadata.log.push({
    type: 'pagepile',
    id: PagePileID,
    time: Date.now()
  })
}

var getNextID = function () {
  var ids = data.map((row) => {
    return parseInt(row.contentmine.match(/(\d+)$/)[0])
  })
  var max = _.max(ids)
  if (max === undefined) max = -1
  var newid = parseInt(max) + 1
  return 'CM.' + metadata.id + newid
}

Vue.component('wikidata', {
  props: ['data'],
  template: '{{data.wikidata}}',
  computed: {
    wUrl () {
      return 'https://wikidata.org/wiki/' + this.data.wikidata
    }
  }
})

Vue.component('modal', Modal)

Vue.use(ClientTable)
/* eslint-disable no-new */
new Vue({
  el: '#app',
  data: {
    showModal: false,
    downloadContent: null,
    showDictSelector: true,
    showTable: false,
    columns: ['contentmine', 'term', 'name', 'wikidata'],
    tableData: data,
    metadata: metadata,
    options: {
      templates: {
        wikidata: 'wikidata'
      },
      customFilters: [{
        name: 'prefix',
        callback: (row, query) => {
          return _.upperCase(row.term[0]) === query
        }
      }]
    },
    dicts: [
      {name: 'Cochrane', url: 'https://rawgit.com/ContentMine/dictionaries/master/json/cochrane.json'},
      {name: 'Wikidata Country', url: 'https://rawgit.com/ContentMine/dictionaries/master/json/wikidatacountry.json'},
      {name: 'insecticides', url: 'https://rawgit.com/ContentMine/dictionaries/master/json/insecticides.json'},
      {name: 'disease', url: 'https://rawgit.com/ContentMine/dictionaries/master/json/disease.json'}
    ],
    prefixes: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
  },
  methods: {
    dictLoad (dict) {
      getAndLoadDict(dict.url)
      this.showDictSelector = false
      this.showTable = true
    },
    prefixFilter (prefix) {
      Event.$emit('vue-tables.filter::prefix', prefix)
    },
    startDownload () {
      this.downloadContent = 'data:application/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(serialize.displayToDict(this.tableData, this.metadata), null, 4))
    },
    newDict () {
      this.showDictSelector = false
      this.showTable = true
    },
    loadDictionary (e) {
      var fReader = new window.FileReader()
      var self = this
      fReader.onload = function (event) {
        var displayData = serialize.dictToDisplay(JSON.parse(event.target.result))
        loadDict(displayData)
        self.showDictSelector = false
        self.showTable = true
      }
      fReader.readAsText(e.target.files[0])
    }
  }
})
.$on('newentity', addEntry)
.$on('updateQuery', logQuery)
.$on('updatePagePile', logPagePile)
<|endoftext|>