<commit_before>import FX from 'FX/FX';
import Easing from 'FX/Easing/Easing';
import Deferred from 'Core/Deferred';
import Dom from 'Core/Dom';

/*jshint devel: true*/
/**
 *
 */
class Display {
    constructor(options, target) {
        console.log('[Display] Init()', options.name/*, options, target*/);

        let prefix = (function () {
            let styles = window.getComputedStyle(document.documentElement, ''),
                pre = (Array.prototype.slice
                    .call(styles)
                    .join('')
                    .match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o'])
                )[1],
                dom = ('WebKit|Moz|MS|O').match(new RegExp('(' + pre + ')', 'i'))[1];
            return {
                dom: dom,
                lowercase: pre,
                css: '-' + pre + '-',
                js: pre[0].toUpperCase() + pre.substr(1)
            };
        })();

        this.layers = new Array(options.numLayers);

        this.prefix = prefix.lowercase;

        this.target = target || new Dom('div').attr('id', 'display_' + options.name).appendTo('body');
        this.width = options.width;
        this.height = options.height;

        this.type = options.type || '2d';

        this.fxCtx = null;

        this._createLayers();

        this.fxQueue = {
            'pre': {},
            'post': {}
        };
    }

    getBuffer(w, h) {
        let ctx = new Dom('canvas').attr({
            width: w + 'px',
            height: h + 'px'
        })[0].getContext('2d');

        ctx['imageSmoothingEnabled'] = false;

        return ctx;
    }

    _createLayers() {
        let i;

        for (i = 0; i < this.layers.length; ++i) {
            this.layers[i] = new Dom('canvas').addClass('layer_' + i).attr({
                'width': this.width,
                'height': this.height
            }).css({
                'width': this.width + 'px',
                'height': this.height + 'px',
                'position': 'absolute',
                zIndex: i
            }).appendTo(this.target)[0].getContext(this.type);

            this.layers[i]['imageSmoothingEnabled'] = false;
        }

        this.fxCtx = new Dom('canvas').addClass('fx').attr({
            'width': this.width,
            'height': this.height
        }).css({
            'width': this.width + 'px',
            'height': this.height + 'px',
            'position': 'absolute',
            zIndex: i + 1
        }).appendTo(this.target)[0].getContext(this.type);

        this.fxCtx['imageSmoothingEnabled'] = false;
    }

    clearScreen(ctx) {
        if (0) {
            // setting canvas width resets imageSmoothingEnable to true
            ctx.canvas.width = ctx.canvas.width;

            ctx['imageSmoothingEnabled'] = false;
        } else {
            ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        }
    }

    clearAllScreens() {
        for (let i = 0; i < this.layers.length; ++i) {
            this.clearScreen(this.layers[i]);
        }

        this.clearScreen(this.fxCtx);
    }

    renderScene(scene) {
        this.clearScreen(this.fxCtx);

        // execute pre fx
        // TODO: here we have to make some hack to pre-render all buffers into a single one
        // then aply fx on this one, then render this one onto for-most layer
        this.executeFx(this.layers[0], null, scene, null, 'pre');

        // TODO: all CTX ?
        for (let i = 0; i < this.layers.length; ++i) {
            this.layers[i].canvas.style.opacity = scene.getOpacity();
        }

        this.clearScreen(this.layers[1]);

        scene.render(this.layers);

        if (scene.hudScene) {
            scene.hudScene.render(this.layers);
        }

        // TODO: here we have to make some hack to pre-render all buffers into a single one
        // then apply fx on this one, then render this one onto for-most layer
        /* HACK */
        if (Object.keys(this.fxQueue['post']).length) {
            this.clearScreen(this.fxCtx);
            // merge all canvas into fxCtx one
            for (let i = 0; i < this.layers.length; ++i) {
                this.fxCtx.drawImage(this.layers[i].canvas, 0, 0);
            }
        }
        /* HACK */
        // execute pre fx
        this.executeFx(this.fxCtx, this.fxCtx, scene, null, 'post');
    }

    prepareCanvas(resources) {
        let context = null,
            i = 0,
            oldStyle = '';

        for (i = 0; i < this.layers.length; ++i) {
            context = this.layers[i];

            oldStyle = context.canvas.style.display;
            context.canvas.style.display = "none";

            // NOTE: should we hide the canvas before?
            resources.forEach(function (resource) {
                if (resource.type === "image") {
                    // NOTE: maybe drawing only 1px is enough?
                    context.drawImage(resource.elt, 0, 0);
                }
            });

            this.clearScreen(context);

            context.canvas.style.display = oldStyle;
        }
    }

    animate(fxName, options, context) {
        console.log('animate');

        var fxClass = FX.getEffect(fxName),
            promise,
            easing = options.easing || 'linear',
            when = options.when || 'pre',
            fx,
            that = this;

        options.context = context || this;
        // console.log('animate', this.fxQueue);

        if (typeof this.fxQueue[when][fxName] !== 'undefined') {
            console.warn('Fx', fxName, 'already in progress, cannot execute twice');
            let def = new Deferred();
            def.resolve();
            promise = def.promise;

        } else if (!fxClass) {
            console.warn('Fx', fxName, 'unknown: did you spell it correctly ?');
        } else {
            fx = new fxClass(options, this);
            fx.setEasing(new FX.getEasing(easing));

            promise = fx.start().then(function () {
                console.log('effect ended, need to stop it', fxName);
                delete that.fxQueue[when][fxName];
            });
            this.fxQueue[when][fxName] = fx;
        }

        return promise;
    }

    stopAnimate(/*fxName*/) {
        console.log('TODO: need to stop animation');
    }

    executeFx(ctx, fxCtx, obj, time, when) {
        var fxObject;

        when = when || 'pre';

        for (var fxName in this.fxQueue[when]) {
            fxObject = this.fxQueue[when][fxName];
            // console.log('processing fx', fxName, fxObject);

            fxObject.process(ctx, fxCtx, obj, time);
        }
    }

    clearDisplay() {
        console.log('clearFX Queue');
        this.fxQueue.pre = {};
        this.fxQueue.post = {};

        this.clearAllScreens();
    }
};

export default Display;
<commit_msg>FIXED: typo for-most -> foremost<commit_after>import FX from 'FX/FX';
import Easing from 'FX/Easing/Easing';
import Deferred from 'Core/Deferred';
import Dom from 'Core/Dom';

/*jshint devel: true*/
/**
 *
 */
class Display {
    constructor(options, target) {
        console.log('[Display] Init()', options.name/*, options, target*/);

        let prefix = (function () {
            let styles = window.getComputedStyle(document.documentElement, ''),
                pre = (Array.prototype.slice
                    .call(styles)
                    .join('')
                    .match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o'])
                )[1],
                dom = ('WebKit|Moz|MS|O').match(new RegExp('(' + pre + ')', 'i'))[1];
            return {
                dom: dom,
                lowercase: pre,
                css: '-' + pre + '-',
                js: pre[0].toUpperCase() + pre.substr(1)
            };
        })();

        this.layers = new Array(options.numLayers);

        this.prefix = prefix.lowercase;

        this.target = target || new Dom('div').attr('id', 'display_' + options.name).appendTo('body');
        this.width = options.width;
        this.height = options.height;

        this.type = options.type || '2d';

        this.fxCtx = null;

        this._createLayers();

        this.fxQueue = {
            'pre': {},
            'post': {}
        };
    }

    getBuffer(w, h) {
        let ctx = new Dom('canvas').attr({
            width: w + 'px',
            height: h + 'px'
        })[0].getContext('2d');

        ctx['imageSmoothingEnabled'] = false;

        return ctx;
    }

    _createLayers() {
        let i;

        for (i = 0; i < this.layers.length; ++i) {
            this.layers[i] = new Dom('canvas').addClass('layer_' + i).attr({
                'width': this.width,
                'height': this.height
            }).css({
                'width': this.width + 'px',
                'height': this.height + 'px',
                'position': 'absolute',
                zIndex: i
            }).appendTo(this.target)[0].getContext(this.type);

            this.layers[i]['imageSmoothingEnabled'] = false;
        }

        this.fxCtx = new Dom('canvas').addClass('fx').attr({
            'width': this.width,
            'height': this.height
        }).css({
            'width': this.width + 'px',
            'height': this.height + 'px',
            'position': 'absolute',
            zIndex: i + 1
        }).appendTo(this.target)[0].getContext(this.type);

        this.fxCtx['imageSmoothingEnabled'] = false;
    }

    clearScreen(ctx) {
        if (0) {
            // setting canvas width resets imageSmoothingEnable to true
            ctx.canvas.width = ctx.canvas.width;

            ctx['imageSmoothingEnabled'] = false;
        } else {
            ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        }
    }

    clearAllScreens() {
        for (let i = 0; i < this.layers.length; ++i) {
            this.clearScreen(this.layers[i]);
        }

        this.clearScreen(this.fxCtx);
    }

    renderScene(scene) {
        this.clearScreen(this.fxCtx);

        // execute pre fx
        // TODO: here we have to make some hack to pre-render all buffers into a single one
        // then aply fx on this one, then render this one onto foremost layer
        this.executeFx(this.layers[0], null, scene, null, 'pre');

        // TODO: all CTX ?
        for (let i = 0; i < this.layers.length; ++i) {
            this.layers[i].canvas.style.opacity = scene.getOpacity();
        }

        this.clearScreen(this.layers[1]);

        scene.render(this.layers);

        if (scene.hudScene) {
            scene.hudScene.render(this.layers);
        }

        // TODO: here we have to make some hack to pre-render all buffers into a single one
        // then apply fx on this one, then render this one onto foremost layer
        /* HACK */
        if (Object.keys(this.fxQueue['post']).length) {
            this.clearScreen(this.fxCtx);
            // merge all canvas into fxCtx one
            for (let i = 0; i < this.layers.length; ++i) {
                this.fxCtx.drawImage(this.layers[i].canvas, 0, 0);
            }
        }
        /* HACK */
        // execute pre fx
        this.executeFx(this.fxCtx, this.fxCtx, scene, null, 'post');
    }

    prepareCanvas(resources) {
        let context = null,
            i = 0,
            oldStyle = '';

        for (i = 0; i < this.layers.length; ++i) {
            context = this.layers[i];

            oldStyle = context.canvas.style.display;
            context.canvas.style.display = "none";

            // NOTE: should we hide the canvas before?
            resources.forEach(function (resource) {
                if (resource.type === "image") {
                    // NOTE: maybe drawing only 1px is enough?
                    context.drawImage(resource.elt, 0, 0);
                }
            });

            this.clearScreen(context);

            context.canvas.style.display = oldStyle;
        }
    }

    animate(fxName, options, context) {
        console.log('animate');

        var fxClass = FX.getEffect(fxName),
            promise,
            easing = options.easing || 'linear',
            when = options.when || 'pre',
            fx,
            that = this;

        options.context = context || this;
        // console.log('animate', this.fxQueue);

        if (typeof this.fxQueue[when][fxName] !== 'undefined') {
            console.warn('Fx', fxName, 'already in progress, cannot execute twice');
            let def = new Deferred();
            def.resolve();
            promise = def.promise;

        } else if (!fxClass) {
            console.warn('Fx', fxName, 'unknown: did you spell it correctly ?');
        } else {
            fx = new fxClass(options, this);
            fx.setEasing(new FX.getEasing(easing));

            promise = fx.start().then(function () {
                console.log('effect ended, need to stop it', fxName);
                delete that.fxQueue[when][fxName];
            });
            this.fxQueue[when][fxName] = fx;
        }

        return promise;
    }

    stopAnimate(/*fxName*/) {
        console.log('TODO: need to stop animation');
    }

    executeFx(ctx, fxCtx, obj, time, when) {
        var fxObject;

        when = when || 'pre';

        for (var fxName in this.fxQueue[when]) {
            fxObject = this.fxQueue[when][fxName];
            // console.log('processing fx', fxName, fxObject);

            fxObject.process(ctx, fxCtx, obj, time);
        }
    }

    clearDisplay() {
        console.log('clearFX Queue');
        this.fxQueue.pre = {};
        this.fxQueue.post = {};

        this.clearAllScreens();
    }
};

export default Display;
<|endoftext|>


<commit_before>module.exports = {
	define: function (orm, Model, model, fields, colParams) {
		var idProperty = colParams && colParams.idProperty ? colParams.idProperty : "id";

		return {
			extend: function (associations) {
				var helper = this;

				Model.hasOne = function () {
					var model = this,
					    association = "association",
					    opts = {};

					for (var i = 0; i < arguments.length; i++) {
						switch (typeof arguments[i]) {
							case "string":
								association = arguments[i];
								break;
							case "function":
								model = arguments[i];
								break;
							case "object":
								opts = arguments[i];
								break;
						}
					}

					associations.push({
						"field" : association,
						"type"  : "one",
						"model" : model,	// this = circular reference
						"opts"  : opts
					});

					helper.create(this, association, model);
				};
			},
			create: function (instance, association, associationModel) {
				var camelCaseAssociation = association.substr(0, 1).toUpperCase() + association.substr(1);
				var collection = model;

				instance.prototype["get" + camelCaseAssociation] = function () {
					var cb = null, opts = {};

					for (var i = 0; i < arguments.length; i++) {
						switch (typeof arguments[i]) {
							case "object":
								opts = arguments[i];
								break;
							case "function":
								cb = arguments[i];
								break;
						}
					}

					if (this[association + "_id"] > 0) {
						if (this[association]) return cb(this[association]);

						var data = {}, conditions = {};
						data[model + "_id"] = this[idProperty];

						conditions[idProperty] = this[association + "_id"];

						orm._db.selectRecords(collection, {
							"conditions": conditions,
							"callback"	: function (err, data) {
								if (err || !data || data.length == 0) return cb(null);

								(new Model(data[0], opts)).ready(cb);
							}
						});
						return;
					}
					cb(null);
				};
				instance.prototype["unset" + camelCaseAssociation] = function (cb) {
					this["set" + camelCaseAssociation](null, cb);
				};
				instance.prototype["set" + camelCaseAssociation] = function (instance, cb) {
					var self = this;

					if (instance === null) {
						self[association + "_id"] = 0;
						delete self[association];

						return cb();
					}

					if (!instance.saved()) {
						instance.save(function (err, savedInstance) {
							if (err) return cb(err);

							self[association + "_id"] = savedInstance[idProperty];
							self[association] = savedInstance;
							cb();
						});
						return;
					}
					self[association + "_id"] = instance[idProperty];
					self[association] = instance;
					cb();
				};
			},
			fetch: function (instance, assoc, opts) {
				if (!(instance[assoc.field + "_id"] > 0
				   && assoc.opts && assoc.opts.hasOwnProperty("autoFetch")
				   && assoc.opts.autoFetch === true
				   && (!opts.hasOwnProperty("fetchDepth") || opts.fetchDepth > 0))) {
					return;
				}
				var camelCaseassoc = assoc.field.substr(0, 1).toUpperCase()
				                         + assoc.field.substr(1),
				    assocOpts = {};

				for (k in opts) {
					switch (k) {
						case "fetchDepth":
							assocOpts.fetchDepth = opts.fetchDepth - 1;
							break;
						default:
							assocOpts[k] = opts[k];
					}
				}

				instance._dataPending += 1;
				instance[assoc.field] = null;
				instance["get" + camelCaseassoc](assocOpts, function (result) {
					instance[assoc.field] = result;

					if (instance._dataPending-- == 1) {
						instance.emit("ready", instance);
					}
				});
			}
		}
	}
}
<commit_msg>Fix one associations selecting data from wrong collection<commit_after>module.exports = {
	define: function (orm, Model, model, fields, colParams) {
		var idProperty = colParams && colParams.idProperty ? colParams.idProperty : "id";

		return {
			extend: function (associations) {
				var helper = this;

				Model.hasOne = function () {
					var model = this,
					    association = "association",
					    opts = {};

					for (var i = 0; i < arguments.length; i++) {
						switch (typeof arguments[i]) {
							case "string":
								association = arguments[i];
								break;
							case "function":
								model = arguments[i];
								break;
							case "object":
								opts = arguments[i];
								break;
						}
					}

					associations.push({
						"field" : association,
						"type"  : "one",
						"model" : model,	// this = circular reference
						"opts"  : opts
					});

					helper.create(this, association, model);
				};
			},
			create: function (instance, association, associationModel) {
				var camelCaseAssociation = association.substr(0, 1).toUpperCase() + association.substr(1);

				instance.prototype["get" + camelCaseAssociation] = function () {
					var cb = null, opts = {};

					for (var i = 0; i < arguments.length; i++) {
						switch (typeof arguments[i]) {
							case "object":
								opts = arguments[i];
								break;
							case "function":
								cb = arguments[i];
								break;
						}
					}

					if (this[association + "_id"] > 0) {
						if (this[association]) return cb(this[association]);

						var data = {}, conditions = {};
						data[model + "_id"] = this[idProperty];

						conditions[idProperty] = this[association + "_id"];

						orm._db.selectRecords(associationModel._ORM.collection, {
							"conditions": conditions,
							"callback"	: function (err, data) {
								if (err || !data || data.length == 0) return cb(null);

								(new Model(data[0], opts)).ready(cb);
							}
						});
						return;
					}
					cb(null);
				};
				instance.prototype["unset" + camelCaseAssociation] = function (cb) {
					this["set" + camelCaseAssociation](null, cb);
				};
				instance.prototype["set" + camelCaseAssociation] = function (instance, cb) {
					var self = this;

					if (instance === null) {
						self[association + "_id"] = 0;
						delete self[association];

						return cb();
					}

					if (!instance.saved()) {
						instance.save(function (err, savedInstance) {
							if (err) return cb(err);

							self[association + "_id"] = savedInstance[idProperty];
							self[association] = savedInstance;
							cb();
						});
						return;
					}
					self[association + "_id"] = instance[idProperty];
					self[association] = instance;
					cb();
				};
			},
			fetch: function (instance, assoc, opts) {
				if (!(instance[assoc.field + "_id"] > 0
				   && assoc.opts && assoc.opts.hasOwnProperty("autoFetch")
				   && assoc.opts.autoFetch === true
				   && (!opts.hasOwnProperty("fetchDepth") || opts.fetchDepth > 0))) {
					return;
				}
				var camelCaseassoc = assoc.field.substr(0, 1).toUpperCase()
				                         + assoc.field.substr(1),
				    assocOpts = {};

				for (k in opts) {
					switch (k) {
						case "fetchDepth":
							assocOpts.fetchDepth = opts.fetchDepth - 1;
							break;
						default:
							assocOpts[k] = opts[k];
					}
				}

				instance._dataPending += 1;
				instance[assoc.field] = null;
				instance["get" + camelCaseassoc](assocOpts, function (result) {
					instance[assoc.field] = result;

					if (instance._dataPending-- == 1) {
						instance.emit("ready", instance);
					}
				});
			}
		}
	}
}
<|endoftext|>


<commit_before>StackedBarChart = function(m, div_id, x_label, id) {
	var div_id;
	var w = 500;
	var h = 200;
	var dataset;
	var xScale;
	var yScale;
	var colorScale;
	var xAxis;
	var yAxis;
	var bars;
	var svg;
	var chart;
	var active_group = 2;
	var margin = {
		top : 20,
		right : 20,
		bottom : 50,
		left : 60
	};
	var width = w - margin.left - margin.right;
	var height = h - margin.top - margin.bottom;
	var dataset = null;
	var svgbw = "";

	this.setLinearXScale = function(){
		xScale = d3.scale.linear().domain([ m.min , m.max ]).range([ 0, width ]);
		var bw = Math.floor(width / dataset.length -1);
		svgbw= "h"+bw+"V";
		return this;
	}

	this.setOrdinalXScale = function(){
		xScale = d3.scale.ordinal().domain(m.domain).rangeRoundBands([ 0, width ],0.01);
		var bw =xScale.rangeBand();
		svgbw= "h"+bw+"V";
		return this;
	}

	this.init = function() {
		// xScale = d3.scale.ordinal().rangeRoundBands([0, width], .1);
		// xScale = d3.scale.ordinal().rangeRoundBands([0, width], .1);

		//this.setLinearXScale();
		if (typeof m.domain == 'undefined'){
			this.setLinearXScale();
		} else {
			this.setOrdinalXScale();
		}

		var cols = [ "#ff8c00", "#7b6888", "#98abc5" ];
		var classes = [ [ "0", "selected", cols[0] ],
				[ "1", "unselected", cols[1] ], [ "2", "out", cols[2] ] ];

		colorScale = d3.scale.ordinal().range(cols);

		yScale = d3.scale.linear().domain([ 0, dataset.max[2] ]).range(
				[ height, 0 ]);

		colorScale.domain([ "selected", "unselected", "out" ]);
		xAxis = d3.svg.axis().scale(xScale).orient("bottom");

		yAxis = d3.svg.axis().scale(yScale).orient("left");

		// xScale.domain(this.dataset.map(function(d) {
		// return d.max-(d.max-d.min)/2; }));

		svg = d3.select("#" + div_id).append("svg").attr("width",
				width + margin.left + margin.right).attr("height",
				height + margin.top + margin.bottom).append("g").attr(
				"transform",
				"translate(" + margin.left + "," + margin.top + ")");

		chart = svg.select('.chart');
		svg.append("g").attr("class", "x axis").attr("transform",
				"translate(0," + height + ")").call(xAxis).append("text")
			    .attr("y", "3.5em").attr("x",
				width /2 ).style("text-anchor", "end").text(x_label);

		svg.append("g").attr("class", "y axis").call(yAxis).append("text")
				.attr("transform", "rotate(270)").attr("y", "-4.5em").attr("x",
						"-2em").style("text-anchor", "end").text("number of items [1000]");

		/*
		 * bars = svg.selectAll(".bars").data(dataset).enter()
		 * .append("g").attr("class", "g").attr("transform", function(d) {
		 * return "translate(" + (xScale(d.min)+xScale(d.max))/2 + ",0)"; });
		 */

		/* new bars */
		svg.append("clipPath").attr("id", "clip-" + div_id).append("rect")
				.attr("width", width).attr("height", height);

		bars = svg.selectAll(".bar").data([ "selected", "unselected", "out" ])
				.enter().append("path").attr("class", function(d) {
					return d + " foreground bar ";
				}).datum(dataset);

		svg.selectAll(".foreground.bar").attr("clip-path",
				"url(#clip-" + div_id + ")");

		// update(dataset);
		// svg.selectAll("selected bar").attr("d", barPathSelected);

		/* data */
		dataset.forEach(function(d) {
			var y0 = 0;
			d.levels = colorScale.domain().map(function(name) {
				return {
					name : name,
					y0 : y0,
					y1 : y0 += +d[name]
				};
			});
			d.total = 0;
		});

		/*
		 * bars.selectAll("path").data(function(m) { return m.levels;
		 * }).enter().append("rect").attr("y", function(d) { return
		 * yScale(d.y1); }).attr("width", bw).attr("height", function(d) {
		 * return yScale(d.y0) - yScale(d.y1); }).attr("fill", function(d) {
		 * return colorScale(d.name); }).attr("class", function(d){return
		 * div_id+d.name});
		 */

		var brush1 = d3.svg.multibrush().x(xScale).extentAdaption(resizeExtent)
				.on("brush", brush).on("brushend", function(d) {
					if (brush1.extent().length == 0) {
						brush();
					}

				});

		var brushNode = svg.append("g").attr("class", "brush").call(brush1)
				.selectAll("rect").attr("height", height);

		/**
		 * legend and scaling
		 */
		var legendRect = svg.append("g").attr("class", "l").selectAll('rect')
				.data(classes);

		legendRect.enter().append("rect").attr("id", function(d) {
			return div_id+ d[0];
		}).attr("x", w - 140).attr("y", function(d) {
			return (1 + d[0] * 15)
		}).attr("width", 12).attr("height", 12).attr("fill", function(d) {
			return d[2];
		}).on(
				"click",
				function(d) {
					var el = d3.select("#"+div_id + d[0])
						active_group = d[0];
						for (var i = 0; i < classes.length; i++) {
							calcBar();
						}

				});

		legendRect.enter().append("text").text(function(d) {
			return d[1];
		}).attr("x", w - 120).attr("y", function(d) {
			return (d[0] * 15 + 12)
		}).attr("width", 12).attr("height", 12).attr("stroke", "none");

		function resizeExtent(selection) {
			selection.attr("height", height);
		}

		function brush() {
			// console.log(brush1.extent());
			var f = brush1.extent();
			WGL.filterDim(id, f);

		}

	}

	// Create bars

	this.update = function(data) {
		if (dataset == null) {
			dataset = Array.prototype.slice.call(data);
			dataset.max = data.max;
			this.init();
		}
		dataset = Array.prototype.slice.call(data);

		/*
		 * dataset.forEach(function(d) { var y0 = 0; d.levels =
		 * colorScale.domain().map(function(name) { return { name : name, y0 :
		 * y0, y1 : y0 += +d[name] }; }); d.total = 0; });
		 */

		dataset.max = data.max;

		bars.datum(dataset);

		calcBar();
		// bars.data(dataset).transition().duration(10);
		/*
		 * bars.selectAll("rect").data(function(m) { return m.levels;
		 * }).transition().duration(10).attr("y", function(d) { return
		 * yScale(d.y1); }).attr("height", function(d) { return yScale(d.y0) -
		 * yScale(d.y1); });
		 */

		/*
		 * yAxis = d3.svg.axis().scale(yScale).orient("left");
		 * svg.selectAll('.y.axis').transition().duration(15).call(yAxis);
		 */
	}

	function calcBar(){
		yScale = d3.scale.linear().domain(
				[ 0, dataset.max[active_group] ]).range(
				[ height, 0 ]);
		yAxis = d3.svg.axis().scale(yScale).orient("left");
		svg.selectAll('.y.axis').transition().duration(30)
				.call(yAxis);

		svg.selectAll(".selected.bar").attr("d", barPathSelected);
		svg.selectAll(".unselected.bar").attr("d", barPathUnselected);
		svg.selectAll(".out.bar").attr("d", barPathOut);

	}
	function barPathSelected(groups) {
		var path = [], i = -1, n = groups.length, d;
		while (++i < n) {
			var d = groups[i];
			path.push("M", xScale(d.val), ",", height, "V", yScale(d.selected),
					svgbw, height);
		}
		return path.join("");
	}

	function barPathUnselected(groups) {
		var path = [], i = -1, n = groups.length, d;
		while (++i < n) {
			var d = groups[i];
			path.push("M", xScale(d.val), ",", yScale(d.selected), "V",
					yScale(d.selected) + yScale(d.unselected) - height, svgbw,
					yScale(d.selected));
		}
		return path.join("");
	}

	function barPathOut(groups) {
		var path = [], i = -1, n = groups.length, d;
		while (++i < n) {
			var d = groups[i];
			var start = yScale(d.selected) + yScale(d.unselected) - height;
			path.push("M", xScale(d.val), ",", start, "V", start
					+ yScale(d.out) - height, svgbw, start);
		}
		return path.join("");
	}
}<commit_msg>Small updates in ordinal filter<commit_after>StackedBarChart = function(m, div_id, x_label, id) {
	var div_id;
	var w = 500;
	var h = 200;
	var dataset;
	var xScale;
	var yScale;
	var colorScale;
	var xAxis;
	var yAxis;
	var bars;
	var svg;
	var chart;
	var active_group = 2;
	var margin = {
		top : 20,
		right : 20,
		bottom : 50,
		left : 60
	};
	var width = w - margin.left - margin.right;
	var height = h - margin.top - margin.bottom;
	var dataset = null;
	var svgbw = "";

	this.setLinearXScale = function(){
		xScale = d3.scale.linear().domain([ m.min , m.max ]).range([ 0, width ]);
		var bw = Math.floor(width / dataset.length -1);
		svgbw= "h"+bw+"V";
		return this;
	}

	this.setOrdinalXScale = function(){
		xScale = d3.scale.ordinal().domain(m.domain).rangeRoundBands([ 0, width ],0.01);
		var bw =xScale.rangeBand();
		svgbw= "h"+bw+"V";
		return this;
	}

	this.init = function() {
		// xScale = d3.scale.ordinal().rangeRoundBands([0, width], .1);
		// xScale = d3.scale.ordinal().rangeRoundBands([0, width], .1);

		//this.setLinearXScale();
		if (typeof m.domain == 'undefined'){
			this.setLinearXScale();
		} else {
			this.setOrdinalXScale();
		}

		var cols = [ "#ff8c00", "#7b6888", "#98abc5" ];
		var classes = [ [ "0", "selected", cols[0] ],
				[ "1", "unselected", cols[1] ], [ "2", "out", cols[2] ] ];

		colorScale = d3.scale.ordinal().range(cols);

		yScale = d3.scale.linear().domain([ 0, dataset.max[2] ]).range(
				[ height, 0 ]);

		colorScale.domain([ "selected", "unselected", "out" ]);
		xAxis = d3.svg.axis().scale(xScale).orient("bottom");

		yAxis = d3.svg.axis().scale(yScale).orient("left");

		// xScale.domain(this.dataset.map(function(d) {
		// return d.max-(d.max-d.min)/2; }));

		svg = d3.select("#" + div_id).append("svg").attr("width",
				width + margin.left + margin.right).attr("height",
				height + margin.top + margin.bottom).append("g").attr(
				"transform",
				"translate(" + margin.left + "," + margin.top + ")");

		chart = svg.select('.chart');
		svg.append("g").attr("class", "x axis").attr("transform",
				"translate(0," + height + ")").call(xAxis).append("text")
			    .attr("y", "3.5em").attr("x",
				width /2 ).style("text-anchor", "end").text(x_label);

		svg.append("g").attr("class", "y axis").call(yAxis).append("text")
				.attr("transform", "rotate(270)").attr("y", "-4.5em").attr("x",
						"-2em").style("text-anchor", "end").text("number of items [1000]");

		/*
		 * bars = svg.selectAll(".bars").data(dataset).enter()
		 * .append("g").attr("class", "g").attr("transform", function(d) {
		 * return "translate(" + (xScale(d.min)+xScale(d.max))/2 + ",0)"; });
		 */

		/* new bars */
		svg.append("clipPath").attr("id", "clip-" + div_id).append("rect")
				.attr("width", width).attr("height", height);

		bars = svg.selectAll(".bar").data([ "selected", "unselected", "out" ])
				.enter().append("path").attr("class", function(d) {
					return d + " foreground bar ";
				}).datum(dataset);

		//bars.on("click", function(d)
		//		{ d.selected = !d.selected;
		//			console.log(d);
		//		})

		svg.selectAll(".foreground.bar").attr("clip-path",
				"url(#clip-" + div_id + ")");

		// update(dataset);
		// svg.selectAll("selected bar").attr("d", barPathSelected);

		/* data */
		dataset.forEach(function(d) {
			var y0 = 0;
			d.levels = colorScale.domain().map(function(name) {
				return {
					name : name,
					y0 : y0,
					y1 : y0 += +d[name]
				};
			});
			d.total = 0;
		});

		/*
		 * bars.selectAll("path").data(function(m) { return m.levels;
		 * }).enter().append("rect").attr("y", function(d) { return
		 * yScale(d.y1); }).attr("width", bw).attr("height", function(d) {
		 * return yScale(d.y0) - yScale(d.y1); }).attr("fill", function(d) {
		 * return colorScale(d.name); }).attr("class", function(d){return
		 * div_id+d.name});
		 */

		var brush1 = d3.svg.multibrush().x(xScale).extentAdaption(resizeExtent)
				.on("brush", brush).on("brushend", function(d) {
					if (brush1.extent().length == 0) {
						brush();
					}

				});

		var brushNode = svg.append("g").attr("class", "brush").call(brush1)
				.selectAll("rect").attr("height", height);

		/**
		 * legend and scaling
		 */
		var legendRect = svg.append("g").attr("class", "l").selectAll('rect')
				.data(classes);

		legendRect.enter().append("rect").attr("id", function(d) {
			return div_id+ d[0];
		}).attr("x", w - 140).attr("y", function(d) {
			return (1 + d[0] * 15)
		}).attr("width", 12).attr("height", 12).attr("fill", function(d) {
			return d[2];
		}).on(
				"click",
				function(d) {
					var el = d3.select("#"+div_id + d[0])
						active_group = d[0];
						for (var i = 0; i < classes.length; i++) {
							calcBar();
						}

				});

		legendRect.enter().append("text").text(function(d) {
			return d[1];
		}).attr("x", w - 120).attr("y", function(d) {
			return (d[0] * 15 + 12)
		}).attr("width", 12).attr("height", 12).attr("stroke", "none");

		function resizeExtent(selection) {
			selection.attr("height", height);
		}

		function brush() {

			var f = brush1.extent();
			WGL.filterDim(id, f);
			console.log(brush1.extent()[0][0]+' '+brush1.extent()[0][1]);

		}

		function brushO() {

			var f = brush1.extent();
			var leftEdges = xScale.range();
        	var width = xScale.rangeBand();
        	var l;
        	var r;
        	var left = brush1.extent()[0][0];
        	var right = brush1.extent()[0][1]
        	for(l=0; left > (leftEdges[l] + width); l++) {}
        	for(r=0; right > (leftEdges[r] + width); r++) {}
            //do nothing, just increment j until case fails
        	console.log("Clicked on " + xScale.domain()[l]+ " "+xScale.domain()[r]);

        	var f = [];
        	f[0] = [ xScale.domain()[l],  xScale.domain()[r]];
			WGL.filterDim(id, f);
			//console.log(xScale.domain()[j]+' '+brush1.extent()[0][1]);

		}

	}

	// Create bars

	this.update = function(data) {
		if (dataset == null) {
			dataset = Array.prototype.slice.call(data);
			dataset.max = data.max;
			this.init();
		}
		dataset = Array.prototype.slice.call(data);

		/*
		 * dataset.forEach(function(d) { var y0 = 0; d.levels =
		 * colorScale.domain().map(function(name) { return { name : name, y0 :
		 * y0, y1 : y0 += +d[name] }; }); d.total = 0; });
		 */

		dataset.max = data.max;

		bars.datum(dataset);

		calcBar();
		// bars.data(dataset).transition().duration(10);
		/*
		 * bars.selectAll("rect").data(function(m) { return m.levels;
		 * }).transition().duration(10).attr("y", function(d) { return
		 * yScale(d.y1); }).attr("height", function(d) { return yScale(d.y0) -
		 * yScale(d.y1); });
		 */

		/*
		 * yAxis = d3.svg.axis().scale(yScale).orient("left");
		 * svg.selectAll('.y.axis').transition().duration(15).call(yAxis);
		 */
	}

	function calcBar(){
		yScale = d3.scale.linear().domain(
				[ 0, dataset.max[active_group] ]).range(
				[ height, 0 ]);
		yAxis = d3.svg.axis().scale(yScale).orient("left");
		svg.selectAll('.y.axis').transition().duration(30)
				.call(yAxis);

		svg.selectAll(".selected.bar").attr("d", barPathSelected);
		svg.selectAll(".unselected.bar").attr("d", barPathUnselected);
		svg.selectAll(".out.bar").attr("d", barPathOut);

	}
	function barPathSelected(groups) {
		var path = [], i = -1, n = groups.length, d;
		while (++i < n) {
			var d = groups[i];
			path.push("M", xScale(d.val), ",", height, "V", yScale(d.selected),
					svgbw, height);
		}
		return path.join("");
	}

	function barPathUnselected(groups) {
		var path = [], i = -1, n = groups.length, d;
		while (++i < n) {
			var d = groups[i];
			path.push("M", xScale(d.val), ",", yScale(d.selected), "V",
					yScale(d.selected) + yScale(d.unselected) - height, svgbw,
					yScale(d.selected));
		}
		return path.join("");
	}

	function barPathOut(groups) {
		var path = [], i = -1, n = groups.length, d;
		while (++i < n) {
			var d = groups[i];
			var start = yScale(d.selected) + yScale(d.unselected) - height;
			path.push("M", xScale(d.val), ",", start, "V", start
					+ yScale(d.out) - height, svgbw, start);
		}
		return path.join("");
	}
}<|endoftext|>


<commit_before>'use babel';
import { CompositeDisposable } from 'atom';

export var config = {
  accentColor: {
    type: 'string',
    default: 'Blue',
    enum: [ 'Blue', 'Purple', 'Green', 'Magenta' ],
    order: 1
  },
  treeViewColor: {
    description: 'Use Light Tree-View Background',
    type: 'boolean',
    default: false,
    order: 2
  }
};

var disposable;

export function activate() {
  disposable = new CompositeDisposable(
    atom.config.observe('atomic-design-ui.accentColor', updateAccentColor),
    atom.config.observe('atomic-design-ui.treeViewColor', updateTreeViewColor)
  );
}

export function deactivate() {
  disposable.dispose();
}

var workspaceView = atom.views.getView(atom.workspace);

function updateAccentColor(accentColor) {
  workspaceView.setAttribute('data-atomic-design-ui-accent-color', accentColor);
}

function updateTreeViewColor(treeViewColor) {
  workspaceView.setAttribute('data-atomic-design-ui-light-tree-view', treeViewColor);
}
<commit_msg>Add additional theme settings<commit_after>'use babel';
'use strict';
import {
	CompositeDisposable
} from 'atom';

export var config = {
	fontSize: {
		title: 'Font Size',
		description: 'Set the UI font size between 9 and 20',
		type: 'integer',
		minimum: 9,
		maximum: 20,
        default: 12,
		order: 1
	},
	accentColor: {
		type: 'string',
		default: 'Blue',
		enum: ['Blue', 'Purple', 'Green', 'Magenta'],
		order: 2
	},
	lightTreeView: {
		description: 'Use Light Tree-View Background',
		type: 'boolean',
		default: false,
		order: 3
	}
};

var disposable;

export function activate() {
	disposable = new CompositeDisposable(
		atom.config.observe('atomic-design-ui.fontSize', updateFontSize),
		atom.config.observe('atomic-design-ui.accentColor', updateAccentColor),
		atom.config.observe('atomic-design-ui.lightTreeView', updateTreeView)
	);
}

export function deactivate() {
	disposable.dispose();
}

var workspaceView = atom.views.getView(atom.workspace);

function updateFontSize(fontSize) {
	workspaceView.setAttribute('data-atomic-design-ui-font-size', fontSize);
}

function updateAccentColor(accentColor) {
	workspaceView.setAttribute('data-atomic-design-ui-accent-color', accentColor);
}

function updateTreeView(lightTreeView) {
	workspaceView.setAttribute('data-atomic-design-ui-light-tree-view', lightTreeView);
}
<|endoftext|>


<commit_before>const EosKnowledgePrivate = imports.gi.EosKnowledgePrivate;
const GObject = imports.gi.GObject;
const Lang = imports.lang;

const ContentObjectModel = imports.search.contentObjectModel;

/**
 * Class: HistoryItem
 *
 * An object to be used by a HistoryModel in order to keep track of the pages
 * that a user visits. Each HistoryItem contains the properties necessary
 * to recreate that page. This includes query parameters in the case of search
 * and article pages.
 *
 */
const HistoryItem = new Lang.Class({
    Name: 'HistoryItem',
    Extends: GObject.Object,
    Implements: [ EosKnowledgePrivate.HistoryItemModel ],
    Properties: {
        /**
         * Property: title
         *
         * FIXME: maybe remove from interface? never actually used.
         */
        'title': GObject.ParamSpec.string('title', 'override', 'override',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: page-type
         *
         * A string that stores the type of page that corresponds to a history item.
         * Supported page types are 'search', 'section', 'article', and 'home'.
         */
        'page-type': GObject.ParamSpec.string('page-type', 'Page Type',
            'The type of page of the history object. Either \'search\', \'section\', \'article\', or \'home\'',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: model
         * Content object model representing this page
         *
         * For 'article' pages, a <ArticleObjectModel> of the currently
         * displayed article. For 'section' pages, a <ContentObjectModel> of the
         * currently displayed set. Null for other pages.
         */
        'model': GObject.ParamSpec.object('model', 'Model',
            'Content object model representing this page',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ContentObjectModel.ContentObjectModel),
        /**
         * Property: query
         *
         * A query string entered by the user causing navigation to this history
         * item.
         */
        'query': GObject.ParamSpec.string('query', 'Query',
            'The search string entered when navigating to this page',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: empty
         *
         * A boolean value that stores whether or not a history item contains a
         * query that returns 0 results.
         */
        'empty': GObject.ParamSpec.boolean('empty', 'Empty',
            'True iff the query returned 0 results',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, false),
        /**
         * Property: from-global-search
         *
         * True if this history object was activated from global search,
         * currently only used for reader app standalone page, which shows a
         * different banner in that case.
         */
        'from-global-search': GObject.ParamSpec.boolean('from-global-search',
            'From Global Search', 'From Global Search',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, false),
    },

    equals: function (item) {
        return this.title === item.title &&
            this.page_type === item.page_type &&
            (this.model === null && item.model === null || this.model.ekn_id === item.model.ekn_id) &&
            this.query === item.query &&
            this.from_global_search === item.from_global_search;
    },
});

/**
 * Function: new_from_object
 */
HistoryItem.new_from_object = function (source) {
    let props = {};
    for (let prop in source) {
        if (source.hasOwnProperty(prop) && prop.substring(0, 1) !== '_')
            props[prop] = source[prop];
    }
    return new HistoryItem(props);
};
<commit_msg>historyItem: consider items with same model equal<commit_after>const EosKnowledgePrivate = imports.gi.EosKnowledgePrivate;
const GObject = imports.gi.GObject;
const Lang = imports.lang;

const ContentObjectModel = imports.search.contentObjectModel;

/**
 * Class: HistoryItem
 *
 * An object to be used by a HistoryModel in order to keep track of the pages
 * that a user visits. Each HistoryItem contains the properties necessary
 * to recreate that page. This includes query parameters in the case of search
 * and article pages.
 *
 */
const HistoryItem = new Lang.Class({
    Name: 'HistoryItem',
    Extends: GObject.Object,
    Implements: [ EosKnowledgePrivate.HistoryItemModel ],
    Properties: {
        /**
         * Property: title
         *
         * FIXME: maybe remove from interface? never actually used.
         */
        'title': GObject.ParamSpec.string('title', 'override', 'override',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: page-type
         *
         * A string that stores the type of page that corresponds to a history item.
         * Supported page types are 'search', 'section', 'article', and 'home'.
         */
        'page-type': GObject.ParamSpec.string('page-type', 'Page Type',
            'The type of page of the history object. Either \'search\', \'section\', \'article\', or \'home\'',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: model
         * Content object model representing this page
         *
         * For 'article' pages, a <ArticleObjectModel> of the currently
         * displayed article. For 'section' pages, a <ContentObjectModel> of the
         * currently displayed set. Null for other pages.
         */
        'model': GObject.ParamSpec.object('model', 'Model',
            'Content object model representing this page',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ContentObjectModel.ContentObjectModel),
        /**
         * Property: query
         *
         * A query string entered by the user causing navigation to this history
         * item.
         */
        'query': GObject.ParamSpec.string('query', 'Query',
            'The search string entered when navigating to this page',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: empty
         *
         * A boolean value that stores whether or not a history item contains a
         * query that returns 0 results.
         */
        'empty': GObject.ParamSpec.boolean('empty', 'Empty',
            'True iff the query returned 0 results',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, false),
        /**
         * Property: from-global-search
         *
         * True if this history object was activated from global search,
         * currently only used for reader app standalone page, which shows a
         * different banner in that case.
         */
        'from-global-search': GObject.ParamSpec.boolean('from-global-search',
            'From Global Search', 'From Global Search',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, false),
    },

    equals: function (item) {
        if (this.model)
            return this.page_type === item.page_type &&
            (this.model === null && item.model === null || this.model.ekn_id === item.model.ekn_id) &&
            this.from_global_search === item.from_global_search;
        return this.page_type === item.page_type &&
            this.query === item.query &&
            this.from_global_search === item.from_global_search;
    },
});

/**
 * Function: new_from_object
 */
HistoryItem.new_from_object = function (source) {
    let props = {};
    for (let prop in source) {
        if (source.hasOwnProperty(prop) && prop.substring(0, 1) !== '_')
            props[prop] = source[prop];
    }
    return new HistoryItem(props);
};
<|endoftext|>


<commit_before>/* ===========================================================
 * bootstrap-modal.js v2.1
 * ===========================================================
 * Copyright 2012 Jordan Schroter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function ($) {

	"use strict"; // jshint ;_;

	/* MODAL CLASS DEFINITION
	* ====================== */

	var Modal = function (element, options) {
		this.init(element, options);
	}

	Modal.prototype = {

		constructor: Modal,

		init: function (element, options) {
			this.options = options;

			this.$element = $(element)
				.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this));

			this.options.remote && this.$element.find('.modal-body').load(this.options.remote);

			var manager = typeof this.options.manager === 'function' ?
				this.options.manager.call(this) : this.options.manager;

			manager = manager.appendModal ?
				manager : $(manager).modalmanager().data('modalmanager');

			manager.appendModal(this);
		},

		toggle: function () {
			return this[!this.isShown ? 'show' : 'hide']();
		},

		show: function () {
			var that = this,
				e = $.Event('show');

			if (this.isShown) return;

			this.$element.triggerHandler(e);

			if (e.isDefaultPrevented()) return;

			this.escape();

			this.tab();

			this.options.loading && this.loading();
		},

		hide: function (e) {
			e && e.preventDefault();

			e = $.Event('hide');

			this.$element.triggerHandler(e);

			if (!this.isShown || e.isDefaultPrevented()) return (this.isShown = false);

			this.isShown = false;

			this.escape();

			this.tab();

			this.isLoading && this.loading();

			$(document).off('focusin.modal');

			this.$element
				.removeClass('in')
				.removeClass('animated')
				.removeClass(this.options.attentionAnimation)
				.removeClass('modal-overflow')
				.attr('aria-hidden', true);

			$.support.transition && this.$element.hasClass('fade') ?
				this.hideWithTransition() :
				this.hideModal();
		},

		layout: function () {
			var prop = this.options.height ? 'height' : 'max-height',
				value = this.options.height || this.options.maxHeight;

			if (this.options.width){
				this.$element.css('width', this.options.width);

				var that = this;
				this.$element.css('margin-left', function () {
					if (/%/ig.test(that.options.width)){
						return -(parseInt(that.options.width) / 2) + '%';
					} else {
						return -($(this).width() / 2) + 'px';
					}
				});
			} else {
				this.$element.css('width', '');
				this.$element.css('margin-left', '');
			}

			this.$element.find('.modal-body')
				.css('overflow', '')
				.css(prop, '');

			var modalOverflow = $(window).height() - 10 < this.$element.height();

			if (value){
				this.$element.find('.modal-body')
					.css('overflow', 'auto')
					.css(prop, value);
			}

			if (modalOverflow || this.options.modalOverflow) {
				this.$element
					.css('margin-top', 0)
					.addClass('modal-overflow');
			} else {
				this.$element
					.css('margin-top', 0 - this.$element.height() / 2)
					.removeClass('modal-overflow');
			}
		},

		tab: function () {
			var that = this;

			if (this.isShown && this.options.consumeTab) {
				this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) {
			    	if (e.keyCode && e.keyCode == 9){
						var $next = $(this),
							$rollover = $(this);

				       	that.$element.find('[data-tabindex]:enabled:not([readonly])').each(function (e) {
			         		if (!e.shiftKey){
			           	 		$next = $next.data('tabindex') < $(this).data('tabindex') ?
				              		$next = $(this) :
				              		$rollover = $(this);
				          	} else {
				            	$next = $next.data('tabindex') > $(this).data('tabindex') ?
				              		$next = $(this) :
				             		$rollover = $(this);
				          	}
				        });

				        $next[0] !== $(this)[0] ?
			          		$next.focus() : $rollover.focus();

						e.preventDefault();
			      	}
			    });
			} else if (!this.isShown) {
				this.$element.off('keydown.tabindex.modal');
			}
		},

		escape: function () {
			var that = this;
			if (this.isShown && this.options.keyboard) {
				if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1);

				this.$element.on('keyup.dismiss.modal', function (e) {
					e.which == 27 && that.hide();
				});
			} else if (!this.isShown) {
				this.$element.off('keyup.dismiss.modal')
			}
		},

		hideWithTransition: function () {
			var that = this
				, timeout = setTimeout(function () {
					that.$element.off($.support.transition.end)
					that.hideModal()
				}, 500);

			this.$element.one($.support.transition.end, function () {
				clearTimeout(timeout)
				that.hideModal()
			});
		},

		hideModal: function () {
			this.$element
				.hide()
				.triggerHandler('hidden');

			var prop = this.options.height ? 'height' : 'max-height';
			var value = this.options.height || this.options.maxHeight;

			if (value){
				this.$element.find('.modal-body')
					.css('overflow', '')
					.css(prop, '');
			}

		},

		removeLoading: function () {
			this.$loading.remove();
			this.$loading = null;
			this.isLoading = false;
		},

		loading: function (callback) {
			callback = callback || function () {};

			var animate = this.$element.hasClass('fade') ? 'fade' : '';

			if (!this.isLoading) {
				var doAnimate = $.support.transition && animate;

				this.$loading = $('
')
					.append(this.options.spinner)
					.appendTo(this.$element);

				if (doAnimate) this.$loading[0].offsetWidth // force reflow

				this.$loading.addClass('in')

				this.isLoading = true;

				doAnimate ?
					this.$loading.one($.support.transition.end, callback) :
					callback();

			} else if (this.isLoading && this.$loading) {
				this.$loading.removeClass('in');

				var that = this;
				$.support.transition && this.$element.hasClass('fade')?
					this.$loading.one($.support.transition.end, function () { that.removeLoading() }) :
					that.removeLoading();

			} else if (callback) {
				callback(this.isLoading);
			}
		},

		focus: function () {
			var $focusElem = this.$element.find(this.options.focusOn);

			$focusElem = $focusElem.length ? $focusElem : this.$element;

			$focusElem.focus();
		},

		attention: function (){
			// NOTE: transitionEnd with keyframes causes odd behaviour

			if (this.options.attentionAnimation){
				this.$element
					.removeClass('animated')
					.removeClass(this.options.attentionAnimation);

				var that = this;

				setTimeout(function () {
					that.$element
						.addClass('animated')
						.addClass(that.options.attentionAnimation);
				}, 0);
			}

			this.focus();
		},

		destroy: function () {
			var e = $.Event('destroy');
			this.$element.triggerHandler(e);
			if (e.isDefaultPrevented()) return;

			this.teardown();
		},

		teardown: function () {
			if (!this.$parent.length){
				this.$element.remove();
				this.$element = null;
				return;
			}

			if (this.$parent !== this.$element.parent()){
				this.$element.appendTo(this.$parent);
			}

			this.$element.off('.modal');
			this.$element.removeData('modal');
			this.$element
				.removeClass('in')
				.attr('aria-hidden', true);
		}
	}

	/* MODAL PLUGIN DEFINITION
	* ======================= */

	$.fn.modal = function (option, args) {
		return this.each(function () {
			var $this = $(this),
				data = $this.data('modal'),
				options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option);

			if (!data) $this.data('modal', (data = new Modal(this, options)))
			if (typeof option == 'string') data[option].apply(data, [].concat(args))
			else if (options.show) data.show()
		})
	}

	$.fn.modal.defaults = {
		keyboard: true,
		backdrop: true,
		loading: false,
		show: true,
		width: null,
		height: null,
		maxHeight: null,
		modalOverflow: false,
		consumeTab: true,
		focusOn: null,
		replace: false,
		resize: false,
		attentionAnimation: 'shake',
		manager: 'body',
		spinner: '

'
	}

	$.fn.modal.Constructor = Modal

	/* MODAL DATA-API
	* ============== */

	$(function () {
		$(document).off('.modal').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
			var $this = $(this),
				href = $this.attr('href'),
				$target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))), //strip for ie7
				option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());

			e.preventDefault();
			$target
				.modal(option)
				.one('hide', function () {
					$this.focus();
				})
		});
	});

}(window.jQuery);<commit_msg>Added missing semicolons<commit_after>/* ===========================================================
 * bootstrap-modal.js v2.1
 * ===========================================================
 * Copyright 2012 Jordan Schroter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function ($) {

	"use strict"; // jshint ;_;

	/* MODAL CLASS DEFINITION
	* ====================== */

	var Modal = function (element, options) {
		this.init(element, options);
	};

	Modal.prototype = {

		constructor: Modal,

		init: function (element, options) {
			this.options = options;

			this.$element = $(element)
				.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this));

			this.options.remote && this.$element.find('.modal-body').load(this.options.remote);

			var manager = typeof this.options.manager === 'function' ?
				this.options.manager.call(this) : this.options.manager;

			manager = manager.appendModal ?
				manager : $(manager).modalmanager().data('modalmanager');

			manager.appendModal(this);
		},

		toggle: function () {
			return this[!this.isShown ? 'show' : 'hide']();
		},

		show: function () {
			var that = this,
				e = $.Event('show');

			if (this.isShown) return;

			this.$element.triggerHandler(e);

			if (e.isDefaultPrevented()) return;

			this.escape();

			this.tab();

			this.options.loading && this.loading();
		},

		hide: function (e) {
			e && e.preventDefault();

			e = $.Event('hide');

			this.$element.triggerHandler(e);

			if (!this.isShown || e.isDefaultPrevented()) return (this.isShown = false);

			this.isShown = false;

			this.escape();

			this.tab();

			this.isLoading && this.loading();

			$(document).off('focusin.modal');

			this.$element
				.removeClass('in')
				.removeClass('animated')
				.removeClass(this.options.attentionAnimation)
				.removeClass('modal-overflow')
				.attr('aria-hidden', true);

			$.support.transition && this.$element.hasClass('fade') ?
				this.hideWithTransition() :
				this.hideModal();
		},

		layout: function () {
			var prop = this.options.height ? 'height' : 'max-height',
				value = this.options.height || this.options.maxHeight;

			if (this.options.width){
				this.$element.css('width', this.options.width);

				var that = this;
				this.$element.css('margin-left', function () {
					if (/%/ig.test(that.options.width)){
						return -(parseInt(that.options.width) / 2) + '%';
					} else {
						return -($(this).width() / 2) + 'px';
					}
				});
			} else {
				this.$element.css('width', '');
				this.$element.css('margin-left', '');
			}

			this.$element.find('.modal-body')
				.css('overflow', '')
				.css(prop, '');

			var modalOverflow = $(window).height() - 10 < this.$element.height();

			if (value){
				this.$element.find('.modal-body')
					.css('overflow', 'auto')
					.css(prop, value);
			}

			if (modalOverflow || this.options.modalOverflow) {
				this.$element
					.css('margin-top', 0)
					.addClass('modal-overflow');
			} else {
				this.$element
					.css('margin-top', 0 - this.$element.height() / 2)
					.removeClass('modal-overflow');
			}
		},

		tab: function () {
			var that = this;

			if (this.isShown && this.options.consumeTab) {
				this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) {
			    	if (e.keyCode && e.keyCode == 9){
						var $next = $(this),
							$rollover = $(this);

						that.$element.find('[data-tabindex]:enabled:not([readonly])').each(function (e) {
							if (!e.shiftKey){
						 		$next = $next.data('tabindex') < $(this).data('tabindex') ?
									$next = $(this) :
									$rollover = $(this);
							} else {
								$next = $next.data('tabindex') > $(this).data('tabindex') ?
									$next = $(this) :
									$rollover = $(this);
							}
						});

						$next[0] !== $(this)[0] ?
							$next.focus() : $rollover.focus();

						e.preventDefault();
					}
				});
			} else if (!this.isShown) {
				this.$element.off('keydown.tabindex.modal');
			}
		},

		escape: function () {
			var that = this;
			if (this.isShown && this.options.keyboard) {
				if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1);

				this.$element.on('keyup.dismiss.modal', function (e) {
					e.which == 27 && that.hide();
				});
			} else if (!this.isShown) {
				this.$element.off('keyup.dismiss.modal')
			}
		},

		hideWithTransition: function () {
			var that = this
				, timeout = setTimeout(function () {
					that.$element.off($.support.transition.end);
					that.hideModal();
				}, 500);

			this.$element.one($.support.transition.end, function () {
				clearTimeout(timeout);
				that.hideModal();
			});
		},

		hideModal: function () {
			this.$element
				.hide()
				.triggerHandler('hidden');

			var prop = this.options.height ? 'height' : 'max-height';
			var value = this.options.height || this.options.maxHeight;

			if (value){
				this.$element.find('.modal-body')
					.css('overflow', '')
					.css(prop, '');
			}

		},

		removeLoading: function () {
			this.$loading.remove();
			this.$loading = null;
			this.isLoading = false;
		},

		loading: function (callback) {
			callback = callback || function () {};

			var animate = this.$element.hasClass('fade') ? 'fade' : '';

			if (!this.isLoading) {
				var doAnimate = $.support.transition && animate;

				this.$loading = $('
')
					.append(this.options.spinner)
					.appendTo(this.$element);

				if (doAnimate) this.$loading[0].offsetWidth; // force reflow

				this.$loading.addClass('in');

				this.isLoading = true;

				doAnimate ?
					this.$loading.one($.support.transition.end, callback) :
					callback();

			} else if (this.isLoading && this.$loading) {
				this.$loading.removeClass('in');

				var that = this;
				$.support.transition && this.$element.hasClass('fade')?
					this.$loading.one($.support.transition.end, function () { that.removeLoading() }) :
					that.removeLoading();

			} else if (callback) {
				callback(this.isLoading);
			}
		},

		focus: function () {
			var $focusElem = this.$element.find(this.options.focusOn);

			$focusElem = $focusElem.length ? $focusElem : this.$element;

			$focusElem.focus();
		},

		attention: function (){
			// NOTE: transitionEnd with keyframes causes odd behaviour

			if (this.options.attentionAnimation){
				this.$element
					.removeClass('animated')
					.removeClass(this.options.attentionAnimation);

				var that = this;

				setTimeout(function () {
					that.$element
						.addClass('animated')
						.addClass(that.options.attentionAnimation);
				}, 0);
			}

			this.focus();
		},

		destroy: function () {
			var e = $.Event('destroy');
			this.$element.triggerHandler(e);
			if (e.isDefaultPrevented()) return;

			this.teardown();
		},

		teardown: function () {
			if (!this.$parent.length){
				this.$element.remove();
				this.$element = null;
				return;
			}

			if (this.$parent !== this.$element.parent()){
				this.$element.appendTo(this.$parent);
			}

			this.$element.off('.modal');
			this.$element.removeData('modal');
			this.$element
				.removeClass('in')
				.attr('aria-hidden', true);
		}
	};

	/* MODAL PLUGIN DEFINITION
	* ======================= */

	$.fn.modal = function (option, args) {
		return this.each(function () {
			var $this = $(this),
				data = $this.data('modal'),
				options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option);

			if (!data) $this.data('modal', (data = new Modal(this, options)));
			if (typeof option == 'string') data[option].apply(data, [].concat(args));
			else if (options.show) data.show()
		})
	};

	$.fn.modal.defaults = {
		keyboard: true,
		backdrop: true,
		loading: false,
		show: true,
		width: null,
		height: null,
		maxHeight: null,
		modalOverflow: false,
		consumeTab: true,
		focusOn: null,
		replace: false,
		resize: false,
		attentionAnimation: 'shake',
		manager: 'body',
		spinner: '

'
	};

	$.fn.modal.Constructor = Modal;

	/* MODAL DATA-API
	* ============== */

	$(function () {
		$(document).off('.modal').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
			var $this = $(this),
				href = $this.attr('href'),
				$target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))), //strip for ie7
				option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());

			e.preventDefault();
			$target
				.modal(option)
				.one('hide', function () {
					$this.focus();
				})
		});
	});

}(window.jQuery);
<|endoftext|>


<commit_before>'use babel'

const stimuli = [
  //
  // Movevent
  //
  {
    id: 'vim-mode:move-up',
    combo: 'k'
  },
  {
    id: 'vim-mode:move-down',
    combo: 'j'
  },
  {
    id: 'vim-mode:move-left',
    combo: 'h'
  },
  {
    id: 'vim-mode:move-right',
    combo: 'l'
  },
  //
  // Jump by word
  //
  {
    id: 'vim-mode:move-to-next-word',
    combo: 'w'
  },
  {
    id: 'vim-mode:move-to-next-whole-word',
    combo: 'W'
  },
  {
    id: 'vim-mode:move-to-end-of-word',
    combo: 'e'
  },
  {
    id: 'vim-mode:move-to-end-of-whole-word',
    combo: 'E'
  },
  {
    id: 'vim-mode:move-to-previous-word',
    combo: 'b'
  },
  {
    id: 'vim-mode:move-to-previous-whole-word',
    combo: 'B'
  },
  //
  // Scrolling
  //
  {
    id: 'vim-mode:scroll-cursor-to-top-leave',
    combo: 'zt'
  },
  {
    id: 'vim-mode:scroll-cursor-to-middle',
    combo: 'z.'
  },
  {
    id: 'vim-mode:scroll-cursor-to-middle-leave',
    combo: 'zz'
  },
  {
    id: 'vim-mode:scroll-cursor-to-bottom',
    combo: 'z-'
  },
  {
    id: 'vim-mode:scroll-cursor-to-bottom-leave',
    combo: 'zb'
  },
  {
    id: 'vim-mode:scroll-cursor-to-left',
    combo: 'zs'
  },
  {
    id: 'vim-mode:scroll-cursor-to-right',
    combo: 'ze'
  },
  {
    id: 'vim-mode:move-to-start-of-file',
    combo: 'gg'
  },
  {
    id: 'vim-mode:scroll-half-screen-down',
    combo: '^d'
  },
  {
    id: 'vim-mode:scroll-half-screen-up',
    combo: '^u'
  },
  //
  // Jumping
  //
  {
    id: 'vim-mode:till',
    combo: 't'
  },
  {
    id: 'vim-mode:till-backwards',
    combo: 'T'
  },
  {
    id: 'vim-mode:move-to-line',
    combo: 'g'
  },
  {
    id: 'vim-mode:move-to-end-of-line',
    combo: 'L'
  },
  {
    id: 'vim-mode:move-to-beginning-of-line',
    combo: 'H'
  },
  //
  // Inserting
  //
  {
    id: 'vim-mode:insert-after-end-of-line',
    combo: 'A'
  },
  {
    id: 'vim-mode:insert-after',
    combo: 'a'
  },
  {
    id: 'vim-mode:activate-insert-mode',
    combo: 'i'
  },
  {
    id: 'vim-mode:insert-at-beginning-of-line',
    combo: 'I'
  },
  {
    id: 'vim-mode:insert-below-with-newline',
    combo: 'o'
  },
  {
    id: 'vim-mode:insert-above-with-newline',
    combo: 'O'
  },
  //
  // Searching
  //
  {
    id: 'vim-mode:repeat-search',
    combo: 'n'
  },
  {
    id: 'vim-mode:repeat-search-backwards',
    combo: 'N'
  },
  //
  // Utility
  //
  {
    id: 'vim-mode:undo',
    combo: 'u'
  },
  {
    id: 'core:redo',
    combo: '^r'
  },
  {
    id: 'vim-mode:yank',
    combo: 'y'
  },
  {
    id: 'vim-mode:reset-normal-mode',
    combo: '^e'
  },
  {
    id: 'vim-mode:repeat',
    combo: '.'
  }
]

export default stimuli
<commit_msg>add points to stimuli<commit_after>'use babel'

class Stimulus {
  constructor({ id, combo, points }) {
    this.id           = id
    this.combo        = combo  || ''
    this.points       = points || 0

    const spl         = id.split(':')
    this.module       = spl[0]  || ''
    this.command      = spl[1] || ''
  }
}

const stimuli = [
  //
  // Movevent
  //
  new Stimulus({
    id: 'vim-mode:move-up',
    combo: 'k',
    points: -1,
  }),
  new Stimulus({
    id: 'vim-mode:move-down',
    combo: 'j',
    points: -1,
  }),
  new Stimulus({
    id: 'vim-mode:move-left',
    combo: 'h',
    points: -1,
  }),
  new Stimulus({
    id: 'vim-mode:move-right',
    combo: 'l',
    points: -1,
  }),
  //
  // Jump by word
  //
  new Stimulus({
    id: 'vim-mode:move-to-next-word',
    combo: 'w',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:move-to-next-whole-word',
    combo: 'W',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:move-to-end-of-word',
    combo: 'e',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:move-to-end-of-whole-word',
    combo: 'E',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:move-to-previous-word',
    combo: 'b',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:move-to-previous-whole-word',
    combo: 'B',
    points: 2,
  }),
  //
  // Scrolling
  //
  new Stimulus({
    id: 'vim-mode:scroll-cursor-to-top-leave',
    combo: 'zt',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:scroll-cursor-to-middle',
    combo: 'z.',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:scroll-cursor-to-middle-leave',
    combo: 'zz',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:scroll-cursor-to-bottom',
    combo: 'z-',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:scroll-cursor-to-bottom-leave',
    combo: 'zb',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:scroll-cursor-to-left',
    combo: 'zs',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:scroll-cursor-to-right',
    combo: 'ze',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:move-to-start-of-file',
    combo: 'gg',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:scroll-half-screen-down',
    combo: '^d',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:scroll-half-screen-up',
    combo: '^u',
    points: 2,
  }),
  //
  // Jumping
  //
  new Stimulus({
    id: 'vim-mode:till',
    combo: 't',
    points: 3,
  }),
  new Stimulus({
    id: 'vim-mode:till-backwards',
    combo: 'T',
    points: 3,
  }),
  new Stimulus({
    id: 'vim-mode:move-to-line',
    combo: 'g',
    points: 3,
  }),
  new Stimulus({
    id: 'vim-mode:move-to-end-of-line',
    combo: 'L',
    points: 3,
  }),
  new Stimulus({
    id: 'vim-mode:move-to-beginning-of-line',
    combo: 'H',
    points: 3,
  }),
  //
  // Inserting
  //
  new Stimulus({
    id: 'vim-mode:insert-after-end-of-line',
    combo: 'A',
    points: 1,
  }),
  new Stimulus({
    id: 'vim-mode:insert-after',
    combo: 'a',
    points: 1,
  }),
  new Stimulus({
    id: 'vim-mode:activate-insert-mode',
    combo: 'i',
    points: 1,
  }),
  new Stimulus({
    id: 'vim-mode:insert-at-beginning-of-line',
    combo: 'I',
    points: 1,
  }),
  new Stimulus({
    id: 'vim-mode:insert-below-with-newline',
    combo: 'o',
    points: 1,
  }),
  new Stimulus({
    id: 'vim-mode:insert-above-with-newline',
    combo: 'O',
    points: 1,
  }),
  //
  // Searching
  //
  new Stimulus({
    id: 'vim-mode:repeat-search',
    combo: 'n',
    points: 2,
  }),
  new Stimulus({
    id: 'vim-mode:repeat-search-backwards',
    combo: 'N',
    points: 2,
  }),
  //
  // Utility
  //
  new Stimulus({
    id: 'vim-mode:undo',
    combo: 'u',
    points: -2,
  }),
  new Stimulus({
    id: 'core:redo',
    combo: '^r',
    points: -2,
  }),
  new Stimulus({
    id: 'vim-mode:yank',
    combo: 'y',
    points: 1,
  }),
  new Stimulus({
    id: 'vim-mode:reset-normal-mode',
    combo: '^e',
    points: 1,
  }),
  new Stimulus({
    id: 'vim-mode:repeat',
    combo: '.',
    points: 1,
  })
]

export default stimuli
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var moment = require('moment');
var request = require('request');
var nconf = require('nconf');
nconf.argv();

var token = nconf.get('token') || process.env.OANDA_TOKEN;
var time = nconf.get('time')
	? nconf.get('time') + 'T22:00:00Z'
	: '';
if(time && moment().isAfter(moment(time))) {
	time = moment(time).utc().format();
} else {
	time = '';
}
var margin = parseFloat(nconf.get('margin')) || 0.00125;
var target = parseFloat(nconf.get('target')) || 0.0025;
var ranked = nconf.get('ranked') !== 'false';

var data = nconf.get('csv') || './report.csv';

// Create the parser
var parser = require('csv-parse')();

var results = {};
var wagers = {};
var rankBase = {};
var rankTotal = {usd:0, gbp:0, aud:0, eur:0, nzd:0, chf:0, cad:0, jpy:0};

// Use the writable stream api
parser.on('readable', function(){
	var cursor;
	var record;
	var chance;
	var odds;
	var meetsCriterion;
	var currency;
	var position;

  while(record = parser.read()){
	  currency = record[0].toLowerCase();
	  position = record[1];
		chance = parseFloat(record[2]) || 0.0;
		odds = parseFloat(record[3]) || 0.0;
		meetsCriterion = record[4] === 'true';

		if(!results[currency]) {
			results[currency] = {
				hold: {
					wager: 0.0,
					total: 0
				},
				long: {
					wager: 0.0,
					total: 0
				},
				short: {
					wager: 0.0,
					total: 0
				}
			};
		}

		if(chance > 0.0 && odds > 0.0) {
			if(meetsCriterion) {
				results[currency][position]['chance'] = (results[currency][position]['chance'] || 0.0) + chance;
				results[currency][position]['odds'] = (results[currency][position]['odds'] || 0.0) + odds;

				results[currency][position]['total'] = (results[currency][position]['total'] || 0) + 1.0;
			}
		}
  }
});
// Catch any error
parser.on('error', function(err){
  console.error(err.message);
});
// When we are done, test that the parsed output matched what expected
parser.on('finish', function(){
	var currencies = _.keys(results);
	var positions = ['hold', 'long', 'short'];
	var currency, position;
	var chance = 0.0;
	var odds = 0.0;
	var wager;
	var netWager;
	var total;
	var pair;
	var multiplier;

	// console.error('results:', JSON.stringify(results, null, '\t'));

	for(var i = 0; i< currencies.length; i++) {
		currency = currencies[i];
		// console.error('-------', currency,'-------');

		total = 0.0;
		for(var j=0; j < positions.length; j++) {
			position = positions[j];
			odds = 0.0;

			if(results[currency][position]['total']) {
				chance = results[currency][position]['chance'] / results[currency][position]['total'];
				odds = (results[currency][position]['odds'] / results[currency][position]['total']) - 1.0;
			}

			if(odds > 0.0) {
				wager = chance - ((1.0 - chance) / odds);
				results[currency][position]['wager'] = wager;

				// console.error(position, ':', (wager * 100.0) + '%');
			} else {
				results[currency][position]['wager'] = 0.0;
			}

			total = total + results[currency][position]['wager'];
		}

		netWager =  results[currency]['long']['wager'] - results[currency]['short']['wager'];
		multiplier = netWager > 0.0 ? 1.0 : -1.0;

		pair = getPair(currency);

		rankBase[pair.base] = (rankBase[pair.base] || 0.0) + netWager;
		rankBase[pair.other] = (rankBase[pair.other] || 0.0) - netWager;
		rankTotal[pair.base]++;
		rankTotal[pair.other]++;

		// if(results[currency]['hold']['wager'] < results[currency][netWager > 0.0 ? 'long' : 'short']['wager'])
		//wagers.push({currency: currency, wager: netWager});
		wagers[currency] = netWager;
	}

	var rankings = {};
	_.each(_.keys(rankBase), function(key) {
		rankings[key] = 100.0 * (rankBase[key] || 0.0) / rankTotal[key];
	});

	_.each(_.keys(results), function (currencyPair) {
		var newPair = getPair(currencyPair);

		var sum = ranked
			? rankings[newPair.base] - rankings[newPair.other]
			: wagers[currencyPair] * 100.0;

		switch(currencyPair) {
			case 'audjpy':
			case 'audusd':
			case 'euraud':
			case 'eurchf':
			case 'eurgbp':
			case 'eurjpy':
			case 'eurusd':
			case 'gbpchf':
			case 'gbpjpy':
			case 'gbpusd':
			case 'nzdusd':
			case 'usdcad':
			case 'usdchf':
			case 'usdjpy':
				fetchEntryOrders(currencyPair, time, function(orderEntryResult) {
					fetchStopOrders(currencyPair, time, orderEntryResult, function(orderStopResult) {
						fetchOpenPositions(currencyPair, time, function(openPositionsResult) {
							console.error('open positions:', openPositionsResult);
							console.error('orders (default):', orderEntryResult);
							console.error('orders (alt):', orderStopResult);

							var sl = sum > 0.0
								? orderStopResult.bid
								: orderStopResult.ask;
							var el = sum > 0.0
								? orderEntryResult.bid
								: orderEntryResult.ask;
							var risk = el - sl;
							var tp1 = el + risk;
							var tp2 = el + (2.0 * risk);
							var reward = tp2 - el;

							console.log(
								sum,
								currencyPair,
								'risk:'+(risk * 100.0 / openPositionsResult.rate),
								'sl:'+sl, 'el:'+el, 'tp1:'+tp1, 'tp2:'+tp2
							);
						});
					});
				});
				break;
			default:
		};
	});
});

var lineReader = require('readline').createInterface({
  input: require('fs').createReadStream(data)
});

var lineCount = 0;
lineReader.on('line', function (line) {
	if(lineCount) {
		parser.write(line + '\n');
	}

	lineCount++;
});

lineReader.on('close', function() {
	parser.end();
})

function getPair(currency) {
	var base = currency.substring(0, 3);
	var other = currency.substring(3, 6);

	var pair = {
		base: base,
		other: other
	};

	return pair;
}

var currencyPairMapping = {
	audjpy: 'AUD_JPY',
	audusd: 'AUD_USD',
	euraud: 'EUR_AUD',
	eurchf: 'EUR_CHF',
	eurgbp: 'EUR_GBP',
	eurjpy: 'EUR_JPY',
	eurusd: 'EUR_USD',
	gbpchf: 'GBP_CHF',
	gbpjpy: 'GBP_JPY',
	gbpusd: 'GBP_USD',
	nzdusd: 'NZD_USD',
	usdcad: 'USD_CAD',
	usdchf: 'USD_CHF',
	usdjpy: 'USD_JPY'
};

function fetchEntryOrders(currencyPair, time, done) {
	var instrument = currencyPairMapping[currencyPair];
	var requestUrl = 'https://api-fxpractice.oanda.com/v3/instruments/' + instrument + '/orderBook';

	if(time) {
		requestUrl = requestUrl + '?time=' + time;
	}

	var requestOpts = {
		url: requestUrl,
		gzip: true,
		headers: {
			'Authorization': 'Bearer ' + token
		}
	};

	var results = {};

	request(requestOpts, function(error, response, body) {
		var data = JSON.parse(body);
		if(error || _.has(data, 'errorMessage')) {
			return console.error('error:', error || data.errorMessage, requestUrl);
		}

		var rate = parseFloat(data.orderBook.price);
		var bid = rate;
		var ask = rate;
		var max = { bidPercent: 0.0, askPercent: 0.0 };

		_.each(_.sortBy(data.orderBook.buckets, 'price'), function(pricePoint) {
			pricePoint = _.reduce(_.keys(pricePoint), function(acc, key) {
				acc[key] = parseFloat(pricePoint[key]);

				return acc;
			}, {});

			var distOrig = pricePoint.price - rate;
			var dist = Math.abs(distOrig);
			var net = pricePoint.price > rate
				? pricePoint.shortCountPercent - pricePoint.longCountPercent
				: pricePoint.longCountPercent - pricePoint.shortCountPercent;

			if(dist < margin * rate) {
				if(distOrig < 0.0) {
					if(net > max.bidPercent) {
						max.bidPercent = net;
						bid = pricePoint.price;
					}
				} else {
					if(net > max.askPercent) {
						max.askPercent = net;
						ask = pricePoint.price;
					}
				}
			}
		});

		var average = (bid + ask) / 2.0;

		done({
			instrument: instrument,
			ask: _.isNaN(ask) ? 0.0 : ask,
			rate: rate,
			bid: _.isNaN(bid) ? 0.0 : bid,
			average: average
		});
	});
}

function fetchStopOrders(currencyPair, time, entryOrders, done) {
	var instrument = currencyPairMapping[currencyPair];
	var requestUrl = 'https://api-fxpractice.oanda.com/v3/instruments/' + instrument + '/orderBook';

	if(time) {
		requestUrl = requestUrl + '?time=' + time;
	}

	var requestOpts = {
		url: requestUrl,
		gzip: true,
		headers: {
			'Authorization': 'Bearer ' + token
		}
	};

	var results = {};

	request(requestOpts, function(error, response, body) {
		var data = JSON.parse(body);
		if(error || _.has(data, 'errorMessage')) {
			return console.error('error:', error || data.errorMessage, requestUrl);
		}

		var rate = parseFloat(data.orderBook.price);
		var bid = entryOrders.bid;
		var ask = entryOrders.ask;
		var max = { bidPercent: 0.0, askPercent: 0.0 };

		_.each(_.sortBy(data.orderBook.buckets, 'price'), function(pricePoint) {
			pricePoint = _.reduce(_.keys(pricePoint), function(acc, key) {
				acc[key] = parseFloat(pricePoint[key]);

				return acc;
			}, {});

			var distOrig = pricePoint.price - rate;
			var dist = Math.abs(distOrig);
			var net = pricePoint.price > rate
				? pricePoint.shortCountPercent - pricePoint.longCountPercent
				: pricePoint.longCountPercent - pricePoint.shortCountPercent;

			if(dist < (margin + target) * rate && (pricePoint.price < entryOrders.bid || pricePoint.price > entryOrders.ask)) {
				if(distOrig < 0.0) {
					if(net > max.bidPercent) {
						max.bidPercent = net;
						bid = pricePoint.price;
					}
				} else {
					if(net > max.askPercent) {
						max.askPercent = net;
						ask = pricePoint.price;
					}
				}
			}
		});

		var average = (bid + ask) / 2.0;

		done({
			instrument: instrument,
			ask: _.isNaN(ask) ? 0.0 : ask,
			rate: rate,
			bid: _.isNaN(bid) ? 0.0 : bid,
			average: average
		});
	});
}

function fetchOpenPositions(currencyPair, time, done) {
	var instrument = currencyPairMapping[currencyPair];
	var requestUrl = 'https://api-fxpractice.oanda.com/v3/instruments/' + instrument + '/positionBook';

	if(time) {
		requestUrl = requestUrl + '?time=' + time;
	}

	var requestOpts = {
		url: requestUrl,
		gzip: true,
		headers: {
			'Authorization': 'Bearer ' + token
		}
	};

	var results = {};

	request(requestOpts, function(error, response, body) {
		var data = JSON.parse(body);
		if(error || _.has(data, 'errorMessage')) {
			return console.error('error:', error || data.errorMessage, requestUrl);
		}

		var rate = parseFloat(data.positionBook.price);
		var sum = { bid: 0.0, ask: 0.0 };
		var total = { bid: 0, ask: 0 };

		_.each(_.sortBy(data.positionBook.buckets, 'price'), function(pricePoint) {
			pricePoint = _.reduce(_.keys(pricePoint), function(acc, key) {
				acc[key] = parseFloat(pricePoint[key]);

				return acc;
			}, {});

			var d = Math.abs(pricePoint.price - rate);

			if(d/rate <= margin) {
				if(pricePoint.longCountPercent) {
					sum.ask = sum.ask + (pricePoint.longCountPercent * pricePoint.price);
					total.ask = total.ask + pricePoint.longCountPercent;
				}

				if(pricePoint.shortCountPercent) {
					//console.error(pricePoint);
					sum.bid = sum.bid + (pricePoint.shortCountPercent * pricePoint.price);
					total.bid = total.bid + pricePoint.shortCountPercent;
				}
			}
		});

		var bid = sum.bid / total.bid;
		var ask = sum.ask / total.ask;
		var average = (bid + ask) / 2.0;

		done({
			instrument: instrument,
			ask: _.isNaN(ask) ? 0.0 : ask,
			rate: rate,
			bid: _.isNaN(bid) ? 0.0 : bid,
			average: average
		});
	});
}
<commit_msg>feat: add list of bids and offers<commit_after>'use strict';

var _ = require('lodash');
var moment = require('moment');
var request = require('request');
var nconf = require('nconf');
nconf.argv();

var token = nconf.get('token') || process.env.OANDA_TOKEN;
var time = nconf.get('time')
	? nconf.get('time') + 'T22:00:00Z'
	: '';
if(time && moment().isAfter(moment(time))) {
	time = moment(time).utc().format();
} else {
	time = '';
}
var margin = parseFloat(nconf.get('margin')) || 0.00125;
var target = parseFloat(nconf.get('target')) || 0.0025;
var ranked = nconf.get('ranked') !== 'false';

var data = nconf.get('csv') || './report.csv';

// Create the parser
var parser = require('csv-parse')();

var results = {};
var wagers = {};
var rankBase = {};
var rankTotal = {usd:0, gbp:0, aud:0, eur:0, nzd:0, chf:0, cad:0, jpy:0};

// Use the writable stream api
parser.on('readable', function(){
	var cursor;
	var record;
	var chance;
	var odds;
	var meetsCriterion;
	var currency;
	var position;

  while(record = parser.read()){
	  currency = record[0].toLowerCase();
	  position = record[1];
		chance = parseFloat(record[2]) || 0.0;
		odds = parseFloat(record[3]) || 0.0;
		meetsCriterion = record[4] === 'true';

		if(!results[currency]) {
			results[currency] = {
				hold: {
					wager: 0.0,
					total: 0
				},
				long: {
					wager: 0.0,
					total: 0
				},
				short: {
					wager: 0.0,
					total: 0
				}
			};
		}

		if(chance > 0.0 && odds > 0.0) {
			if(meetsCriterion) {
				results[currency][position]['chance'] = (results[currency][position]['chance'] || 0.0) + chance;
				results[currency][position]['odds'] = (results[currency][position]['odds'] || 0.0) + odds;

				results[currency][position]['total'] = (results[currency][position]['total'] || 0) + 1.0;
			}
		}
  }
});
// Catch any error
parser.on('error', function(err){
  console.error(err.message);
});
// When we are done, test that the parsed output matched what expected
parser.on('finish', function(){
	var currencies = _.keys(results);
	var positions = ['hold', 'long', 'short'];
	var currency, position;
	var chance = 0.0;
	var odds = 0.0;
	var wager;
	var netWager;
	var total;
	var pair;
	var multiplier;

	// console.error('results:', JSON.stringify(results, null, '\t'));

	for(var i = 0; i< currencies.length; i++) {
		currency = currencies[i];
		// console.error('-------', currency,'-------');

		total = 0.0;
		for(var j=0; j < positions.length; j++) {
			position = positions[j];
			odds = 0.0;

			if(results[currency][position]['total']) {
				chance = results[currency][position]['chance'] / results[currency][position]['total'];
				odds = (results[currency][position]['odds'] / results[currency][position]['total']) - 1.0;
			}

			if(odds > 0.0) {
				wager = chance - ((1.0 - chance) / odds);
				results[currency][position]['wager'] = wager;

				// console.error(position, ':', (wager * 100.0) + '%');
			} else {
				results[currency][position]['wager'] = 0.0;
			}

			total = total + results[currency][position]['wager'];
		}

		netWager =  results[currency]['long']['wager'] - results[currency]['short']['wager'];
		multiplier = netWager > 0.0 ? 1.0 : -1.0;

		pair = getPair(currency);

		rankBase[pair.base] = (rankBase[pair.base] || 0.0) + netWager;
		rankBase[pair.other] = (rankBase[pair.other] || 0.0) - netWager;
		rankTotal[pair.base]++;
		rankTotal[pair.other]++;

		// if(results[currency]['hold']['wager'] < results[currency][netWager > 0.0 ? 'long' : 'short']['wager'])
		//wagers.push({currency: currency, wager: netWager});
		wagers[currency] = netWager;
	}

	var rankings = {};
	_.each(_.keys(rankBase), function(key) {
		rankings[key] = 100.0 * (rankBase[key] || 0.0) / rankTotal[key];
	});

	_.each(_.keys(results), function (currencyPair) {
		var newPair = getPair(currencyPair);

		var sum = ranked
			? rankings[newPair.base] - rankings[newPair.other]
			: wagers[currencyPair] * 100.0;

		switch(currencyPair) {
			case 'audjpy':
			case 'audusd':
			case 'euraud':
			case 'eurchf':
			case 'eurgbp':
			case 'eurjpy':
			case 'eurusd':
			case 'gbpchf':
			case 'gbpjpy':
			case 'gbpusd':
			case 'nzdusd':
			case 'usdcad':
			case 'usdchf':
			case 'usdjpy':
				fetchEntryOrders(currencyPair, time, function(orderEntryResult) {
					fetchStopOrders(currencyPair, time, orderEntryResult, function(orderStopResult) {
						fetchOpenPositions(currencyPair, time, function(openPositionsResult) {
							console.error('open positions:', openPositionsResult);
							console.error('orders (default):', orderEntryResult);
							console.error('orders (alt):', orderStopResult);

							var sl = sum > 0.0
								? orderStopResult.bid
								: orderStopResult.ask;
							var el = sum > 0.0
								? orderEntryResult.bid
								: orderEntryResult.ask;
							var risk = el - sl;
							var tp1 = el + risk;
							var tp2 = el + (2.0 * risk);
							var reward = tp2 - el;

							console.log(
								sum,
								currencyPair,
								'risk:'+(risk * 100.0 / openPositionsResult.rate),
								'sl:'+sl, 'el:'+el, 'tp1:'+tp1, 'tp2:'+tp2
							);
						});
					});
				});
				break;
			default:
		};
	});
});

var lineReader = require('readline').createInterface({
  input: require('fs').createReadStream(data)
});

var lineCount = 0;
lineReader.on('line', function (line) {
	if(lineCount) {
		parser.write(line + '\n');
	}

	lineCount++;
});

lineReader.on('close', function() {
	parser.end();
})

function getPair(currency) {
	var base = currency.substring(0, 3);
	var other = currency.substring(3, 6);

	var pair = {
		base: base,
		other: other
	};

	return pair;
}

var currencyPairMapping = {
	audjpy: 'AUD_JPY',
	audusd: 'AUD_USD',
	euraud: 'EUR_AUD',
	eurchf: 'EUR_CHF',
	eurgbp: 'EUR_GBP',
	eurjpy: 'EUR_JPY',
	eurusd: 'EUR_USD',
	gbpchf: 'GBP_CHF',
	gbpjpy: 'GBP_JPY',
	gbpusd: 'GBP_USD',
	nzdusd: 'NZD_USD',
	usdcad: 'USD_CAD',
	usdchf: 'USD_CHF',
	usdjpy: 'USD_JPY'
};

function fetchEntryOrders(currencyPair, time, done) {
	var instrument = currencyPairMapping[currencyPair];
	var requestUrl = 'https://api-fxpractice.oanda.com/v3/instruments/' + instrument + '/orderBook';

	if(time) {
		requestUrl = requestUrl + '?time=' + time;
	}

	var requestOpts = {
		url: requestUrl,
		gzip: true,
		headers: {
			'Authorization': 'Bearer ' + token
		}
	};

	var results = {};

	request(requestOpts, function(error, response, body) {
		var data = JSON.parse(body);
		if(error || _.has(data, 'errorMessage')) {
			return console.error('error:', error || data.errorMessage, requestUrl);
		}

		var rate = parseFloat(data.orderBook.price);
		var bid = rate;
		var ask = rate;
		var max = { bidPercent: 0.0, askPercent: 0.0 };
		var bids = [];
		var asks = [];

		_.each(_.sortBy(data.orderBook.buckets, 'price'), function(pricePoint) {
			pricePoint = _.reduce(_.keys(pricePoint), function(acc, key) {
				acc[key] = parseFloat(pricePoint[key]);

				return acc;
			}, {});

			var distOrig = pricePoint.price - rate;
			var dist = Math.abs(distOrig);
			var net = pricePoint.price > rate
				? pricePoint.shortCountPercent - pricePoint.longCountPercent
				: pricePoint.longCountPercent - pricePoint.shortCountPercent;

			if(dist < margin * rate) {
				if(distOrig < 0.0) {
					if(net > max.bidPercent) {
						max.bidPercent = net;
						bid = pricePoint.price;
						bids.push(bid);
					}
				} else {
					if(net > max.askPercent) {
						max.askPercent = net;
						ask = pricePoint.price;
						asks.push(ask);
					}
				}
			}
		});

		var average = (bid + ask) / 2.0;

		done({
			instrument: instrument,
			asks: asks,
			ask: ask,
			rate: rate,
			bid: bid,
			bids: bids,
			average: average
		});
	});
}

function fetchStopOrders(currencyPair, time, entryOrders, done) {
	var instrument = currencyPairMapping[currencyPair];
	var requestUrl = 'https://api-fxpractice.oanda.com/v3/instruments/' + instrument + '/orderBook';

	if(time) {
		requestUrl = requestUrl + '?time=' + time;
	}

	var requestOpts = {
		url: requestUrl,
		gzip: true,
		headers: {
			'Authorization': 'Bearer ' + token
		}
	};

	var results = {};

	request(requestOpts, function(error, response, body) {
		var data = JSON.parse(body);
		if(error || _.has(data, 'errorMessage')) {
			return console.error('error:', error || data.errorMessage, requestUrl);
		}

		var rate = parseFloat(data.orderBook.price);
		var bid = entryOrders.bid;
		var ask = entryOrders.ask;
		var max = { bidPercent: 0.0, askPercent: 0.0 };

		_.each(_.sortBy(data.orderBook.buckets, 'price'), function(pricePoint) {
			pricePoint = _.reduce(_.keys(pricePoint), function(acc, key) {
				acc[key] = parseFloat(pricePoint[key]);

				return acc;
			}, {});

			var distOrig = pricePoint.price - rate;
			var dist = Math.abs(distOrig);
			var net = pricePoint.price > rate
				? pricePoint.shortCountPercent - pricePoint.longCountPercent
				: pricePoint.longCountPercent - pricePoint.shortCountPercent;

			if(dist < (margin + target) * rate && (pricePoint.price < entryOrders.bid || pricePoint.price > entryOrders.ask)) {
				if(distOrig < 0.0) {
					if(net > max.bidPercent) {
						max.bidPercent = net;
						bid = pricePoint.price;
					}
				} else {
					if(net > max.askPercent) {
						max.askPercent = net;
						ask = pricePoint.price;
					}
				}
			}
		});

		var average = (bid + ask) / 2.0;

		done({
			instrument: instrument,
			ask: _.isNaN(ask) ? 0.0 : ask,
			rate: rate,
			bid: _.isNaN(bid) ? 0.0 : bid,
			average: average
		});
	});
}

function fetchOpenPositions(currencyPair, time, done) {
	var instrument = currencyPairMapping[currencyPair];
	var requestUrl = 'https://api-fxpractice.oanda.com/v3/instruments/' + instrument + '/positionBook';

	if(time) {
		requestUrl = requestUrl + '?time=' + time;
	}

	var requestOpts = {
		url: requestUrl,
		gzip: true,
		headers: {
			'Authorization': 'Bearer ' + token
		}
	};

	var results = {};

	request(requestOpts, function(error, response, body) {
		var data = JSON.parse(body);
		if(error || _.has(data, 'errorMessage')) {
			return console.error('error:', error || data.errorMessage, requestUrl);
		}

		var rate = parseFloat(data.positionBook.price);
		var sum = { bid: 0.0, ask: 0.0 };
		var total = { bid: 0, ask: 0 };

		_.each(_.sortBy(data.positionBook.buckets, 'price'), function(pricePoint) {
			pricePoint = _.reduce(_.keys(pricePoint), function(acc, key) {
				acc[key] = parseFloat(pricePoint[key]);

				return acc;
			}, {});

			var d = Math.abs(pricePoint.price - rate);

			if(d/rate <= margin) {
				if(pricePoint.longCountPercent) {
					sum.ask = sum.ask + (pricePoint.longCountPercent * pricePoint.price);
					total.ask = total.ask + pricePoint.longCountPercent;
				}

				if(pricePoint.shortCountPercent) {
					//console.error(pricePoint);
					sum.bid = sum.bid + (pricePoint.shortCountPercent * pricePoint.price);
					total.bid = total.bid + pricePoint.shortCountPercent;
				}
			}
		});

		var bid = sum.bid / total.bid;
		var ask = sum.ask / total.ask;
		var average = (bid + ask) / 2.0;

		done({
			instrument: instrument,
			ask: _.isNaN(ask) ? 0.0 : ask,
			rate: rate,
			bid: _.isNaN(bid) ? 0.0 : bid,
			average: average
		});
	});
}
<|endoftext|>