<commit_before>/*
 *  Shout.js
 *
 *  A quick and dirty pub/sub messaging plugin
 *  inspired by the Backbone.js events framework.
 *
 *  Author: Stephen Murray
 *  Shout.js may be freely distributed under the MIT license.
 */

;(function(){

    "use strict";

    // Array of callbacks sorted by event keys
    var _callbacks,

    // Regex for the event string delimiter
    _delim = /\s+/;

    // Namespace our global and tack it on to `window`
    var Shout = this.Shout = {

        // Binds event(s) to a given callback
        listen: function(events, callback){
            var cbs, ev, sub;
            if (typeof events === 'undefined') {
                return false;
            }

            events = events.split(_delim);
            cbs = _callbacks || (_callbacks = {});

            while (ev = events.shift()) {
                sub = cbs[ev] || (cbs[ev] = []);
                sub.push(callback);
            }
        },

        // Unbinds event(s)
        deaf: function(events, handle){
            var cbs, ev, sub;
            if (typeof events === 'undefined') {
                return false;
            }

            events = events.split(_delim);

            while (ev = events.shift()) {
                if (typeof handle !== 'undefined' ) {
                    for (var i = _callbacks[ev].length - 1; i >= 0; i--) {
                        var cb = _callbacks[ev][i];
                        if (cb === handle) {
                            delete _callbacks[ev][i];
                        }
                    };
                } else {
                    delete _callbacks[ev];
                }
            }
        },

        // Triggers all callbacks associated with event(s)
        yell: function(events, context){
            var cbs, ev, sub;
            if (typeof events === 'undefined') {
                return false;
            }

            events = events.split(_delim);
            context = context || {};

            while (ev = events.shift()) {
                sub = _callbacks[ev];
                if (typeof sub !== 'undefined') {
                    for (var i = sub.length - 1; i >= 0; i--) {
                        if (typeof sub[i] !== 'undefined') {
                            sub[i].call(context);
                        }
                    }
                }
            }
        },

        // Registers custom namespaces to existing methods
        register: function(newNS, bindToNS){
            if (typeof Shout[bindToNS] !== 'undefined') {
                Shout[newNS] = Shout[bindToNS];
            }
        }

    };

    // Common pub/sub aliases
    Shout.on = Shout.bind = Shout.listen;
    Shout.off = Shout.unbind = Shout.deaf;
    Shout.trigger = Shout.shout = Shout.yell;

}).call(this);
<commit_msg>allow multiple handler arguments for listen() and deaf() methods<commit_after>/*
 *  Shout.js
 *
 *  A quick and dirty pub/sub messaging plugin
 *  inspired by the Backbone.js events framework.
 *
 *  Author: Stephen Murray
 *  Shout.js may be freely distributed under the MIT license.
 */

;(function(){

    "use strict";

    // Array of callbacks sorted by event keys
    var _callbacks,

    // Regex for the event string delimiter
    _delim = /\s+/;

    // Convenience function to get handlers from `arguments`
    function getHandlers(arrArgs) {
        return Array.prototype.slice.call(arrArgs, 1, arrArgs.length);
    }

    // Is `value` in the given `arr` array? Shallow comparison
    function inArray(value, arr) {
        for (var i = arr.length - 1; i >= 0; i--) {
            var val = arr[i];
            if (val === value) {
                return true;
            }
        };
    }

    // Namespace our global and tack it on to `window`
    var Shout = this.Shout = {

        // Binds event(s) to a given callback
        listen: function(events, callback){
            var cbs, ev, sub, handlers;
            if (typeof events === 'undefined') {
                return false;
            }

            handlers = getHandlers(arguments);

            events = events.split(_delim);
            cbs = _callbacks || (_callbacks = {});

            while (ev = events.shift()) {
                sub = cbs[ev] || (cbs[ev] = []);
                for (var i = 0; i < handlers.length; i++) {
                    sub.push(handlers[i]);
                }
            }
        },

        // Unbinds event(s)
        deaf: function(events, handle){
            var cbs, ev, sub, handlers;
            if (typeof events === 'undefined') {
                return false;
            }

            handlers = getHandlers(arguments);
            events = events.split(_delim);

            while (ev = events.shift()) {
                if (typeof handle !== 'undefined' ) {
                    for (var i = _callbacks[ev].length - 1; i >= 0; i--) {
                        var cb = _callbacks[ev][i];
                        if (inArray(cb, handlers)) {
                            delete _callbacks[ev][i];
                        }
                    };
                } else {
                    delete _callbacks[ev];
                }
            }
        },

        // Triggers all callbacks associated with event(s)
        yell: function(events, context){
            var cbs, ev, sub;
            if (typeof events === 'undefined') {
                return false;
            }

            events = events.split(_delim);
            context = context || {};

            while (ev = events.shift()) {
                sub = _callbacks[ev];
                if (typeof sub !== 'undefined') {
                    for (var i = sub.length - 1; i >= 0; i--) {
                        if (typeof sub[i] !== 'undefined') {
                            sub[i].call(context);
                        }
                    }
                }
            }
        },

        // Registers custom namespaces to existing methods
        register: function(newNS, bindToNS){
            if (typeof Shout[bindToNS] !== 'undefined') {
                Shout[newNS] = Shout[bindToNS];
            }
        }

    };

    // Common pub/sub aliases
    Shout.on = Shout.bind = Shout.listen;
    Shout.off = Shout.unbind = Shout.deaf;
    Shout.trigger = Shout.shout = Shout.yell;

}).call(this);
<|endoftext|>


<commit_before>/*#ifndef(UMD)*/
"use strict";
/*global _gpfFunc*/ // Create a new function using the source
/*global _gpfStringEscapeFor*/ // Make the string content compatible with lang
/*global _gpfA*/ // _gpfA
/*global _gpfANoSerial*/ // gpf.attributes.ClassNonSerializedAttribute
/*global _gpfI*/ // gpf.interfaces
// /*#endif*/

var
    _gpfJsonStringify,
    _gpfJsonParse;

function _gpfObject2Json (object) {
    var
        isArray,
        results,
        property,
        value;
    isArray = object instanceof Array;
    results = [];
    /*jshint -W089*/
    for (property in object) {
        if ("function" === typeof object[property]) {
            continue; // ignore
        }
        value = _gpfJsonStringify(object[property]);
        if (isArray) {
            results.push(value);
        } else {
            results.push(_gpfStringEscapeFor(property, "javascript")
                + ":" + value);
        }
    }
    if (isArray) {
        return "[" + results.join(",") + "]";
    } else {
        return "{" + results.join(",") + "}";
    }
    /*jshint +W089*/
}

// Need to use typeof as this is a global object
if("undefined" === typeof JSON) {

    _gpfJsonStringify = function (object) {
        var type = typeof object;
        if ("undefined" === type || "function" === type) {
            return;
        } else if ("number" === type || "boolean" === type) {
            return object.toString();
        } else if ("string" === type) {
            return _gpfStringEscapeFor(object, "javascript");
        }
        if (null === object) {
            return "null";
        } else {
            return _gpfObject2Json(object);
        }
    };

    _gpfJsonParse = function (test) {
        return _gpfFunc("return " + test)();
    };

} else {
    _gpfJsonStringify = JSON.stringify;
    _gpfJsonParse = JSON.parse;
}

gpf.json = {

    /**
     * The JSON.stringify() method converts a JavaScript value to a JSON string
     *
     * @param {*} value the value to convert to a JSON string
     * @return {String}
     */
    stringify: _gpfJsonStringify,

    /**
     * The JSON.parse() method parses a string as JSON
     *
     * @param {*} text The string to parse as JSON
     * @return {Object}
     */
    parse: _gpfJsonParse,

    /**
     * TODO there must be a way to make it less specific to JSON
     * TODO handle object sub members
     * TODO handle before/after load methods
     * TODO handle before/after save methods
     */

    /**
     * Load the object properties from the json representation.
     *
     * @param {Object} object
     * @param {Object|string} json
     * @return {Object}
     * @chainable
     */
    load: function (object, json) {
        var
            prototype = object.constructor.prototype,
            attributes = new _gpfA.Map(object),
            member,
            jsonMember;
        /*jshint -W089*/ // Actually, I want all properties
        for (member in prototype) {
            if ("function" === typeof prototype[member]
                || attributes.member(member).has(_gpfANoSerial)) {
                continue; // Ignore functions & unwanted members
            }
            /*
             * We have a member that must be serialized,
             * by default members with a starting _ will be initialized from
             * the corresponding member (without _) of the json object
             */
            if (0 === member.indexOf("_")) {
                jsonMember = member.substr(1);
            } else {
                jsonMember = member;
            }
            if (jsonMember in json) {
                object[member] = json[jsonMember];
            } else {
                // Reset the value coming from the prototype
                object[member] = prototype[member];
            }
        }
        return object;
    },
    /*jshint +W089*/

    /**
     * Save the object properties into a json representation.
     *
     * @param {Object} object
     * @return {Object}
     */
    save: function (object) {
        var
            result = {},
            prototype = object.constructor.prototype,
            attributes = new _gpfA.Map(object),
            member,
            jsonMember,
            value;
        /*jshint -W089*/ // Actually, I want all properties
        for (member in prototype) {
            if ("function" === typeof prototype[member]
                || attributes.member(member).has(_gpfANoSerial)) {
                continue; // Ignore functions & unwanted members
            }
            /*
             * We have a member that must be serialized,
             * by default members with a starting _ will be initialized from
             * the corresponding member (without _) of the json object
             */
            if (0 === member.indexOf("_")) {
                jsonMember = member.substr(1);
            } else {
                jsonMember = member;
            }
            value = object[member];
            if (value !== prototype[member]) {
                result[jsonMember] = value;
            }
        }
        return result;
    }
    /*jshint +W089*/

};

<commit_msg>JSON serialization<commit_after>/*#ifndef(UMD)*/
"use strict";
/*global _gpfFunc*/ // Create a new function using the source
/*global _gpfStringEscapeFor*/ // Make the string content compatible with lang
/*global _gpfA*/ // _gpfA
/*global _gpfANoSerial*/ // gpf.attributes.ClassNonSerializedAttribute
// /*#endif*/

var
    _gpfJsonStringify,
    _gpfJsonParse;

function _gpfObject2Json (object) {
    var
        isArray,
        results,
        property,
        value;
    isArray = object instanceof Array;
    results = [];
    /*jshint -W089*/
    for (property in object) {
        if ("function" === typeof object[property]) {
            continue; // ignore
        }
        value = _gpfJsonStringify(object[property]);
        if (isArray) {
            results.push(value);
        } else {
            results.push(_gpfStringEscapeFor(property, "javascript")
                + ":" + value);
        }
    }
    if (isArray) {
        return "[" + results.join(",") + "]";
    } else {
        return "{" + results.join(",") + "}";
    }
    /*jshint +W089*/
}

// Need to use typeof as this is a global object
if("undefined" === typeof JSON) {

    _gpfJsonStringify = function (object) {
        var type = typeof object;
        if ("undefined" === type || "function" === type) {
            return;
        } else if ("number" === type || "boolean" === type) {
            return object.toString();
        } else if ("string" === type) {
            return _gpfStringEscapeFor(object, "javascript");
        }
        if (null === object) {
            return "null";
        } else {
            return _gpfObject2Json(object);
        }
    };

    _gpfJsonParse = function (test) {
        return _gpfFunc("return " + test)();
    };

} else {
    _gpfJsonStringify = JSON.stringify;
    _gpfJsonParse = JSON.parse;
}

gpf.json = {

    /**
     * The JSON.stringify() method converts a JavaScript value to a JSON string
     *
     * @param {*} value the value to convert to a JSON string
     * @return {String}
     */
    stringify: _gpfJsonStringify,

    /**
     * The JSON.parse() method parses a string as JSON
     *
     * @param {*} text The string to parse as JSON
     * @return {Object}
     */
    parse: _gpfJsonParse,

    /**
     * TODO there must be a way to make it less specific to JSON
     * TODO handle object sub members
     * TODO handle before/after load methods
     * TODO handle before/after save methods
     */

    /**
     * Load the object properties from the json representation.
     *
     * @param {Object} object
     * @param {Object|string} json
     * @return {Object}
     * @chainable
     */
    load: function (object, json) {
        var
            prototype = object.constructor.prototype,
            attributes = new _gpfA.Map(object),
            member,
            jsonMember;
        /*jshint -W089*/ // Actually, I want all properties
        for (member in prototype) {
            if ("function" === typeof prototype[member]
                || attributes.member(member).has(_gpfANoSerial)) {
                continue; // Ignore functions & unwanted members
            }
            /*
             * We have a member that must be serialized,
             * by default members with a starting _ will be initialized from
             * the corresponding member (without _) of the json object
             */
            if (0 === member.indexOf("_")) {
                jsonMember = member.substr(1);
            } else {
                jsonMember = member;
            }
            if (jsonMember in json) {
                object[member] = json[jsonMember];
            } else {
                // Reset the value coming from the prototype
                object[member] = prototype[member];
            }
        }
        return object;
    },
    /*jshint +W089*/

    /**
     * Save the object properties into a json representation.
     *
     * @param {Object} object
     * @return {Object}
     */
    save: function (object) {
        var
            result = {},
            prototype = object.constructor.prototype,
            attributes = new _gpfA.Map(object),
            member,
            jsonMember,
            value;
        /*jshint -W089*/ // Actually, I want all properties
        for (member in prototype) {
            if ("function" === typeof prototype[member]
                || attributes.member(member).has(_gpfANoSerial)) {
                continue; // Ignore functions & unwanted members
            }
            /*
             * We have a member that must be serialized,
             * by default members with a starting _ will be initialized from
             * the corresponding member (without _) of the json object
             */
            if (0 === member.indexOf("_")) {
                jsonMember = member.substr(1);
            } else {
                jsonMember = member;
            }
            value = object[member];
            if (value !== prototype[member]) {
                result[jsonMember] = value;
            }
        }
        return result;
    }
    /*jshint +W089*/

};

<|endoftext|>


<commit_before>var aacolor = d3.scale.ordinal()
	.range(['#CCFF00','#FFFF00','#FF0000','#FF0066','#00FF66','#FF9900','#0066FF',
		'#66FF00','#6600FF','#33FF00','#00FF00','#CC00FF','#FFCC00','#FF00CC',
		'#0000FF','#FF3300','#FF6600','#99FF00','#00CCFF','#00FFCC','#000000'])
	.domain(['A','C','D','E','F','G','H','I','K','L','M',
		'N','P','Q','R','S','T','V','W','Y','-']);
var barmargin = {top: 5, right: 10, bottom: 0, left: 10},
	barwidth = 200,
	barheight = 20,
	barpadding = .1;
var barchartmargin = {top: 5, right: 10, bottom: 10, left: 50},
	barchartwidth = 250,
	barchartheight = 70;

var plac_scale = d3.scale.linear()
	.range([0, barwidth]);
var vac_scale = d3.scale.linear()
	.range([0, barwidth]);

/** With data in hand, make the visualization */
function generateVis(){

	plac_scale.domain([0, numplac]);
	vac_scale.domain([0, numvac]);

	generateSiteSelector();
}

function generateSiteSelector() {
	var margin = {top: 20, right: 30, bottom: 30, left: 40},
	width = 500 - margin.left - margin.right,
	height = 200 - margin.top - margin.bottom;

	var xScale = d3.scale.ordinal()
		.domain(d3.range(vaccine.sequence.length))
		.rangeBands([0, width], 0.05);

	var yScale = d3.scale.linear()
		.domain([0, 1])
		.range([0.75*height, 0.25*height]);

	var xAxis = d3.svg.axis()
		.scale(xScale)
		.orient("bottom");

	var svg = d3.select("#overview").append("svg")
	    .attr("width", width)
	    .attr("height", height)
	  .append("g")
	  	.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
	    .call(d3.behavior.zoom().scaleExtent([0, 1000]).on("zoom", zoom));

	svg.append("rect")
	    .attr("class", "overlay")
	    .attr("width", width)
	    .attr("height", height);

	var sitebars = svg.selectAll(".sitebars")
	    .data(vaccine.sequence)
	  .enter().append("rect")
	    .attr("x", function (d,i) { return xScale(i); })
		.attr("y", yScale(1))
		.attr("width", xScale.rangeBand())
		.attr("height", height - yScale(1))
		.attr("fill", function (d) {
			if (d === '-') { return "black"; }
			else { return aacolor(d); }
		});

	svg.append("g")
		.attr("class", "x axis")
		.attr("transform", "translate(0," + yScale(0) + ")")
		.call(xAxis);

	function zoom() {
	  sitebars.attr("transform", "translate(" + d3.event.translate[0]+", 0)scale(" + d3.event.scale + ", 1)");
	  svg.select(".x.axis").attr("transform", "translate(" + d3.event.translate[0]+","+(yScale(0))+")")
       .call(xAxis.scale(xScale.rangeBands([0, width * d3.event.scale], 0.05)));
	}
}<commit_msg>Formatting updates<commit_after>var aacolor = d3.scale.ordinal()
	.range(['#CCFF00','#FFFF00','#FF0000','#FF0066','#00FF66','#FF9900','#0066FF',
		'#66FF00','#6600FF','#33FF00','#00FF00','#CC00FF','#FFCC00','#FF00CC',
		'#0000FF','#FF3300','#FF6600','#99FF00','#00CCFF','#00FFCC','#000000'])
	.domain(['A','C','D','E','F','G','H','I','K','L','M',
		'N','P','Q','R','S','T','V','W','Y','-']);
var barmargin = {top: 5, right: 10, bottom: 0, left: 10},
	barwidth = 200,
	barheight = 20,
	barpadding = .1;
var barchartmargin = {top: 5, right: 10, bottom: 10, left: 50},
	barchartwidth = 250,
	barchartheight = 70;

var plac_scale = d3.scale.linear()
	.range([0, barwidth]);
var vac_scale = d3.scale.linear()
	.range([0, barwidth]);

/** With data in hand, make the visualization */
function generateVis(){

	plac_scale.domain([0, numplac]);
	vac_scale.domain([0, numvac]);

	generateSiteSelector();
}

function generateSiteSelector() {
	var margin = {top: 100, right: 30, bottom: 30, left: 40},
	width = 500 - margin.left - margin.right,
	height = 200 - margin.top - margin.bottom;

	var xScale = d3.scale.ordinal()
		.domain(d3.range(vaccine.sequence.length))
		.rangeBands([0, width], 0.05);

	var yScale = d3.scale.linear()
		.domain([0, 1])
		.range([height, 0]);

	var xAxis = d3.svg.axis()
		.scale(xScale)
		.orient("bottom");

	var seqchart = d3.select("#overview").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 + ")")
	    .call(d3.behavior.zoom().scaleExtent([0, 1000]).on("zoom", zoom));

	seqchart.append("rect")
	    .attr("class", "overlay")
	    .attr("width", width)
	    .attr("height", height);

	var sitebars = seqchart.selectAll(".sitebars")
	    .data(vaccine.sequence)
	  .enter().append("rect")
	    .attr("x", function (d,i) { return xScale(i); })
		.attr("y", yScale(1))
		.attr("width", xScale.rangeBand())
		.attr("height", height - yScale(1))
		.attr("fill", function (d) {
			return aacolor(d);
		});

	seqchart.append("g")
		.attr("class", "x axis")
		.attr("transform", "translate(0," + (height + 5) + ")")
		.call(xAxis);

	function zoom() {
	  sitebars.attr("transform", "translate(" + d3.event.translate[0]+", 0)scale(" + d3.event.scale + ", 1)");
	  seqchart.select(".x.axis").attr("transform", "translate(" + d3.event.translate[0]+","+(height + 5)+")")
       .call(xAxis.scale(xScale.rangeBands([0, width * d3.event.scale], 0.05)));
	}
}<|endoftext|>


<commit_before>/*
json - a complete serializer and deserializer for JSON

json.load(datastring)
json.decode(datastring)
json.parse(datastring)
  returns a javascript object deserialized from the JSON string

json.dump(obj)
json.encode(obj)
  returns a string of JSON that represents the object
*/

/*global TJP*/
//context:browser
//context:console

var
  DOUBLE_QUOTE = 1,
  SINGLE_QUOTE = 2,
  OTHER = 8,
  BACKSLASH = 9,
  //////////////
  OPEN_BRACKET = 3,
  CLOSE_BRACKET = 4,
  OPEN_BRACE = 5,
  CLOSE_BRACE = 6,
  COMMA = 7,
  COLON = 10,
  //////////////
  STRING = 11,
  NUMBER = 12,
  TRUE = 13,
  FALSE = 14,
  NULL = 15,
  UNDEFINED = 16,
  INFINITY = 17,
  NEGATIVE_INFINITY = 18,
  IDENTIFIER = 19;

/* comment this out for production
var ltrim_regex = RegExp('^\\s\\s*'),
    space_regex = RegExp('\\s');
var TJP = TJP || {
  base: {
    trim: function(str) {
      var i;
      str = str.replace(ltrim_regex, '');
      i = str.length;
      while (space_regex.test(str.charAt(--i)));
      return str.slice(0, i + 1);
    }
  }
};

var rev = {};
rev[DOUBLE_QUOTE] = 'DOUBLE_QUOTE';
rev[SINGLE_QUOTE] = 'SINGLE_QUOTE';
rev[OPEN_BRACKET] = 'OPEN_BRACKET';
rev[CLOSE_BRACKET] = 'CLOSE_BRACKET';
rev[OPEN_BRACE] = 'OPEN_BRACE';
rev[CLOSE_BRACE] = 'CLOSE_BRACE';
rev[COMMA] = 'COMMA';
rev[OTHER] = 'OTHER';
rev[BACKSLASH] = 'BACKSLASH';
rev[COLON] = 'COLON';
rev[STRING] = 'STRING';
rev[NUMBER] = 'NUMBER';
rev[TRUE] = 'TRUE';
rev[FALSE] = 'FALSE';
rev[NULL] = 'NULL';
rev[UNDEFINED] = 'UNDEFINED';
rev[INFINITY] = 'INFINITY';
rev[NEGATIVE_INFINITY] = 'NEGATIVE_INFINITY';
rev[IDENTIFIER] = 'IDENTIFIER';

function show(tokens) {
  var i, j, token, spaces;
  for (i = 0; i < tokens.length; i++) {
    token = tokens[i];
    for (spaces = [], j = rev[token[0]].length; j <= 17; j++) spaces.push(' ');
    print(rev[token[0]] + spaces.join('') + token[1]);
  }
};
*/

TJP.json = TJP.json || {};

var CHAR_TOKENS = {
  '"': DOUBLE_QUOTE,
  "'": SINGLE_QUOTE,
  '[': OPEN_BRACKET,
  ']': CLOSE_BRACKET,
  '{': OPEN_BRACE,
  '}': CLOSE_BRACE,
  ',': COMMA,
  '\\': BACKSLASH,
  ':': COLON
};

var REMOVE_SLASHES = {
  'n': '\n',
  'r': '\r',
  't': '\t',
  'b': '\b',
  'f': '\f'
};

function tokenize(data) {
  var i, ch, tokens = [], buffer = [], token;

  for (i = 0; i < data.length; i++) {
    ch = data[i];
    token = CHAR_TOKENS[ch];
    if (token) {
      if (buffer.length) {
        tokens.push([OTHER, buffer.join('')]);
        buffer = [];
      }
      tokens.push([token, ch]);
    } else buffer.push(ch);
  }
  if (buffer.length) tokens.push([OTHER, buffer.join('')]);

  return tokens;
};

var number_regex = /^-?((\d+(\.(\d+)?)?)|(\.\d+))([eE]-?\d+)?$/;

function reduce_tokens(tokens) {
  var i, token, next, replacement, buffer, instr, val, strtype;

  // scan for BACKSLASHes and replace as necessary
  for (i = 0; i < tokens.length; i++) {
    token = tokens[i];
    if (token[0] === BACKSLASH) {
      next = tokens[i + 1];
      switch(next[0]) {
        case BACKSLASH:
          tokens.splice(i, 2, [OTHER, '\\\\']);
          break;
        case OTHER:
          replacement = REMOVE_SLASHES[next[1].slice(0, 1)];
          if (replacement)
            tokens.splice(i, 2, [OTHER, replacement + next[1].slice(1)]);
          else tokens.splice(i--, 1);
          break;
        case SINGLE_QUOTE:
        case DOUBLE_QUOTE:
          // this is the only case in which we keep the BACKSLASH token
          break;
        default:
          throw new Error("Bad context for a \\");
      }
    }
  }

  // combine adjacent OTHER tokens
  for (i = 0; i < tokens.length; i++) {
    if (tokens[i][0] === OTHER && tokens[i + 1] &&
        tokens[i + 1][0] === OTHER)
      tokens.splice(i, 2, [OTHER, tokens[i][1] + tokens[i + 1][1]]);
  }

  // find STRINGs
  for (i = 0, buffer = [], instr = false; i < tokens.length; i++) {
    token = tokens[i];
    if (token[0] === SINGLE_QUOTE || token[0] === DOUBLE_QUOTE) {
      if (instr) {
        if (tokens[i - 1] && tokens[i - 1][0] === BACKSLASH) {
          buffer.push(token[1]);
          tokens.splice(--i, 2);
          continue;
        } else if (token[0] !== strtype) {
          buffer.push(token[1]);
          tokens.splice(i--, 1);
          continue;
        }
        else {
          tokens.splice(i, 1, [STRING, buffer.join('')]);
          buffer = [];
        }
      }  else {
        strtype = token[0];
        tokens.splice(i--, 1);
      }
      instr = !instr;
    } else if (instr) {
      buffer.push(token[1]);
      tokens.splice(i--, 1);
    }
  }

  // trim whitespace and identify the OTHERs
  for (i = 0; i < tokens.length; i++) {
    token = tokens[i];
    if (token[0] === OTHER) {
      val = TJP.base.trim(token[1]);
      if (!val) tokens.splice(i, 1);
      else {
        token[1] = val;
        if (val === "true") token[0] = TRUE;
        else if (val === "false") token[0] = FALSE;
        else if (val === "null") token[0] = NULL;
        else if (val === "undefined") token[0] = UNDEFINED;
        else if (val === "Infinity") token[0] = INFINITY;
        else if (val === "-Infinity") token[0] = NEGATIVE_INFINITY;
        else if (number_regex.test(val))
          token[0] = NUMBER;
        else token[0] = IDENTIFIER;
      }
    }
  }
};

function apply_value(stack, value) {
  var stacktop = stack[stack.length - 1];
  if (stacktop.type === OPEN_BRACE) {
    if (stacktop.postcolon) {
      stacktop.obj[stacktop.key] = value;
      stacktop.postcolon = false;
    } else throw new Error("Bad syntax");
  } else if (stacktop.type === OPEN_BRACKET) {
    if (stacktop.postcomma || stacktop.juststarted) {
      stacktop.obj.push(value);
      stacktop.postcomma = stacktop.juststarted = false;
    } else throw new Error("Bad syntax");
  } else throw new Error("Parser Error");
};

function find_matching(opener, closer, tokens) {
  var i, token, count = 1;
  for (i = 0; i < tokens.length; i++) {
    token = tokens[i][0];
    if (token === opener) count++;
    else if (token === closer) count--;
    if (!count) return i;
  }
  throw new Error("No matching '" + closer + "' found");
};

function parse_open_straight(stack, token) {
  stack.push({
    type: OPEN_BRACKET,
    obj: [],
    postcomma: false,
    juststarted: true
  });
};

function parse_close_straight(stack, token) {
  var stacktop = stack[stack.length - 1], arr;
  if (stacktop.type !== OPEN_BRACKET) throw new Error("mismatched ']'");
  arr = stack.pop().obj;
  stacktop = stack[stack.length - 1];
  switch(stacktop.type) {
    case OPEN_BRACE:
      stacktop.obj[stacktop.key] = arr;
      break;
    case OPEN_BRACKET:
      stacktop.obj.push(arr);
      break;
    default:
      throw new Error("bad context for an array");
  }
};

function parse_open_curly(stack, token) {
  stack.push({
    type: OPEN_BRACE,
    obj: {},
    key: '',
    postcomma: false,
    postcolon: false,
    juststarted: true
  });
};

function parse_close_curly(stack, token) {
  var stacktop = stack[stack.length - 1], arr, obj;
  if (stacktop.type !== OPEN_BRACE) throw new Error("mismatched ']'");
  obj = stack.pop().obj;
  stacktop = stack[stack.length - 1];
  switch(stacktop.type) {
    case OPEN_BRACE:
      stacktop.obj[stacktop.key] = obj;
      break;
    case OPEN_BRACKET:
      stacktop.obj.push(obj);
      break;
    default:
      throw new Error("bad context for an array");
  }
};

function parse_identifier(stack, token) {
  var stacktop = stack[stack.length - 1];
  if (stacktop.type === OPEN_BRACE &&
      (stacktop.postcomma || stacktop.juststarted)) {
    stacktop.key = token[1];
    stacktop.postcomma = stacktop.juststarted = false;
  } else throw new Error("Bad syntax");
};

function parse_comma(stack, token) {
  var stacktop = stack[stack.length - 1];
  stacktop.postcomma = true;
};

function parse_colon(stack, token) {
  var stacktop = stack[stack.length - 1];
  if (stacktop.type !== OPEN_BRACE) throw new Error("bad context for a COLON");
  stacktop.postcolon = true;
};

function parse_string(stack, token) {
  var stacktop = stack[stack.length - 1];
  if (stacktop.type === OPEN_BRACE &&
      (stacktop.postcomma || stacktop.juststarted)) {
    stacktop.key = token[1];
    stacktop.postcomma = stacktop.juststarted = false;
  } else apply_value(stack, token[1]);
};

function parse_number(stack, token) {
  apply_value(stack, eval(token[1]));
};

var simple_values = {};
simple_values[TRUE] = true;
simple_values[FALSE] = false;
simple_values[UNDEFINED] = undefined;
simple_values[NULL] = null;
simple_values[INFINITY] = Infinity;
simple_values[NEGATIVE_INFINITY] = -Infinity;

function parse_simple_value(stack, token) {
  apply_value(stack, simple_values[token[0]]);
};

var parsers = {};
parsers[OPEN_BRACKET] = parse_open_straight;
parsers[CLOSE_BRACKET] = parse_close_straight;
parsers[OPEN_BRACE] = parse_open_curly;
parsers[CLOSE_BRACE] = parse_close_curly;
parsers[COMMA] = parse_comma;
parsers[COLON] = parse_colon;
parsers[STRING] = parse_string;
parsers[NUMBER] = parse_number;
parsers[NEGATIVE_INFINITY] = parsers[NULL] = parse_simple_value;
parsers[UNDEFINED] = parsers[INFINITY] = parse_simple_value;
parsers[TRUE] = parsers[FALSE] = parse_simple_value;
parsers[IDENTIFIER] = parse_identifier;

function parse_tokens(tokens) {
  var stack = [{
    type: OPEN_BRACKET,
    obj: [],
    postcomma: false,
    juststarted: true
  }], token;
  while (tokens.length) {
    token = tokens.shift();
    parsers[token[0]](stack, token);
  }
  return stack[0].obj[0];
};

TJP.json.load = TJP.json.decode = TJP.json.parse = function(data) {
  var tokens = tokenize(data);
  reduce_tokens(tokens);
  return parse_tokens(tokens);
};

function gettype(obj) {
  var dumbtype = typeof obj;
  switch(dumbtype) {
    case "number":
      if (isNaN(obj)) return "NaN";
    case "string":
    case "boolean":
    case "undefined":
      return dumbtype;
    case "object":
      if (obj instanceof Number) return "number";
      if (obj instanceof String) return "string";
      if (obj instanceof Boolean) return "boolean";
      if (obj instanceof Array) return "array";
      if (obj instanceof Date) return "date";
      if (obj instanceof RegExp) return "regexp";
      if (obj === null) return "null";
      return "object";
  }
};

function dump_array(arr) {
  var dumped = [], i;
  for (i = 0; i < arr.length; i++) {
    dumped.push(TJP.json.dump(arr[i]));
  }
  return dumped.join('');
};

function dump_object(obj) {
  var dumped = [], name;
  for (name in obj) {
    dumped.push(name + ":" + TJP.json.dump(obj[name]));
  }
  return "{" + dumped.join(',') + "}";
};

var ADD_SLASHES = {
  "\n": "\\n",
  "\r": "\\r",
  "\t": "\\t",
  "\b": "\\b",
  "\f": "\\f",
  '"': '\\"'
};

function dump_string(str) {
  var from;
  str = str.replace('\\', '\\\\');
  for (from in ADD_SLASHES) str = str.replace(from, ADD_SLASHES[from], 'g');
  return '"' + str + '"';
};

TJP.json.dump = TJP.json.encode = function(data) {
  var type = gettype(data);
  switch(type) {
    case "number":
    case "boolean":
      return data.toString();
    case "string":
      return dump_string(data);
    case "undefined":
    case "NaN":
    case "null":
      return type;
    case "array":
      return dump_array(data);
    case "object":
      return dump_object(data);
    case "date":
    case "regexp":
      throw new Error("can't serialize a " + type);
  }
};
<commit_msg>fix to backslash escaping in serialization<commit_after>/*
json - a complete serializer and deserializer for JSON

json.load(datastring)
json.decode(datastring)
json.parse(datastring)
  returns a javascript object deserialized from the JSON string

json.dump(obj)
json.encode(obj)
  returns a string of JSON that represents the object
*/

/*global TJP*/
//context:browser
//context:console

var
  DOUBLE_QUOTE = 1,
  SINGLE_QUOTE = 2,
  OTHER = 8,
  BACKSLASH = 9,
  //////////////
  OPEN_BRACKET = 3,
  CLOSE_BRACKET = 4,
  OPEN_BRACE = 5,
  CLOSE_BRACE = 6,
  COMMA = 7,
  COLON = 10,
  //////////////
  STRING = 11,
  NUMBER = 12,
  TRUE = 13,
  FALSE = 14,
  NULL = 15,
  UNDEFINED = 16,
  INFINITY = 17,
  NEGATIVE_INFINITY = 18,
  IDENTIFIER = 19;

/* comment this out for production
var ltrim_regex = RegExp('^\\s\\s*'),
    space_regex = RegExp('\\s');
var TJP = TJP || {
  base: {
    trim: function(str) {
      var i;
      str = str.replace(ltrim_regex, '');
      i = str.length;
      while (space_regex.test(str.charAt(--i)));
      return str.slice(0, i + 1);
    }
  }
};

var rev = {};
rev[DOUBLE_QUOTE] = 'DOUBLE_QUOTE';
rev[SINGLE_QUOTE] = 'SINGLE_QUOTE';
rev[OPEN_BRACKET] = 'OPEN_BRACKET';
rev[CLOSE_BRACKET] = 'CLOSE_BRACKET';
rev[OPEN_BRACE] = 'OPEN_BRACE';
rev[CLOSE_BRACE] = 'CLOSE_BRACE';
rev[COMMA] = 'COMMA';
rev[OTHER] = 'OTHER';
rev[BACKSLASH] = 'BACKSLASH';
rev[COLON] = 'COLON';
rev[STRING] = 'STRING';
rev[NUMBER] = 'NUMBER';
rev[TRUE] = 'TRUE';
rev[FALSE] = 'FALSE';
rev[NULL] = 'NULL';
rev[UNDEFINED] = 'UNDEFINED';
rev[INFINITY] = 'INFINITY';
rev[NEGATIVE_INFINITY] = 'NEGATIVE_INFINITY';
rev[IDENTIFIER] = 'IDENTIFIER';

function show(tokens) {
  var i, j, token, spaces;
  for (i = 0; i < tokens.length; i++) {
    token = tokens[i];
    for (spaces = [], j = rev[token[0]].length; j <= 17; j++) spaces.push(' ');
    print(rev[token[0]] + spaces.join('') + token[1]);
  }
};
*/

TJP.json = TJP.json || {};

var CHAR_TOKENS = {
  '"': DOUBLE_QUOTE,
  "'": SINGLE_QUOTE,
  '[': OPEN_BRACKET,
  ']': CLOSE_BRACKET,
  '{': OPEN_BRACE,
  '}': CLOSE_BRACE,
  ',': COMMA,
  '\\': BACKSLASH,
  ':': COLON
};

var REMOVE_SLASHES = {
  'n': '\n',
  'r': '\r',
  't': '\t',
  'b': '\b',
  'f': '\f'
};

function tokenize(data) {
  var i, ch, tokens = [], buffer = [], token;

  for (i = 0; i < data.length; i++) {
    ch = data[i];
    token = CHAR_TOKENS[ch];
    if (token) {
      if (buffer.length) {
        tokens.push([OTHER, buffer.join('')]);
        buffer = [];
      }
      tokens.push([token, ch]);
    } else buffer.push(ch);
  }
  if (buffer.length) tokens.push([OTHER, buffer.join('')]);

  return tokens;
};

var number_regex = /^-?((\d+(\.(\d+)?)?)|(\.\d+))([eE]-?\d+)?$/;

function reduce_tokens(tokens) {
  var i, token, next, replacement, buffer, instr, val, strtype;

  // scan for BACKSLASHes and replace as necessary
  for (i = 0; i < tokens.length; i++) {
    token = tokens[i];
    if (token[0] === BACKSLASH) {
      next = tokens[i + 1];
      switch(next[0]) {
        case BACKSLASH:
          tokens.splice(i, 2, [OTHER, '\\\\']);
          break;
        case OTHER:
          replacement = REMOVE_SLASHES[next[1].slice(0, 1)];
          if (replacement)
            tokens.splice(i, 2, [OTHER, replacement + next[1].slice(1)]);
          else tokens.splice(i--, 1);
          break;
        case SINGLE_QUOTE:
        case DOUBLE_QUOTE:
          // this is the only case in which we keep the BACKSLASH token
          break;
        default:
          throw new Error("Bad context for a \\");
      }
    }
  }

  // combine adjacent OTHER tokens
  for (i = 0; i < tokens.length; i++) {
    if (tokens[i][0] === OTHER && tokens[i + 1] &&
        tokens[i + 1][0] === OTHER)
      tokens.splice(i, 2, [OTHER, tokens[i][1] + tokens[i + 1][1]]);
  }

  // find STRINGs
  for (i = 0, buffer = [], instr = false; i < tokens.length; i++) {
    token = tokens[i];
    if (token[0] === SINGLE_QUOTE || token[0] === DOUBLE_QUOTE) {
      if (instr) {
        if (tokens[i - 1] && tokens[i - 1][0] === BACKSLASH) {
          buffer.push(token[1]);
          tokens.splice(--i, 2);
          continue;
        } else if (token[0] !== strtype) {
          buffer.push(token[1]);
          tokens.splice(i--, 1);
          continue;
        }
        else {
          tokens.splice(i, 1, [STRING, buffer.join('')]);
          buffer = [];
        }
      }  else {
        strtype = token[0];
        tokens.splice(i--, 1);
      }
      instr = !instr;
    } else if (instr) {
      buffer.push(token[1]);
      tokens.splice(i--, 1);
    }
  }

  // trim whitespace and identify the OTHERs
  for (i = 0; i < tokens.length; i++) {
    token = tokens[i];
    if (token[0] === OTHER) {
      val = TJP.base.trim(token[1]);
      if (!val) tokens.splice(i, 1);
      else {
        token[1] = val;
        if (val === "true") token[0] = TRUE;
        else if (val === "false") token[0] = FALSE;
        else if (val === "null") token[0] = NULL;
        else if (val === "undefined") token[0] = UNDEFINED;
        else if (val === "Infinity") token[0] = INFINITY;
        else if (val === "-Infinity") token[0] = NEGATIVE_INFINITY;
        else if (number_regex.test(val))
          token[0] = NUMBER;
        else token[0] = IDENTIFIER;
      }
    }
  }
};

function apply_value(stack, value) {
  var stacktop = stack[stack.length - 1];
  if (stacktop.type === OPEN_BRACE) {
    if (stacktop.postcolon) {
      stacktop.obj[stacktop.key] = value;
      stacktop.postcolon = false;
    } else throw new Error("Bad syntax");
  } else if (stacktop.type === OPEN_BRACKET) {
    if (stacktop.postcomma || stacktop.juststarted) {
      stacktop.obj.push(value);
      stacktop.postcomma = stacktop.juststarted = false;
    } else throw new Error("Bad syntax");
  } else throw new Error("Parser Error");
};

function find_matching(opener, closer, tokens) {
  var i, token, count = 1;
  for (i = 0; i < tokens.length; i++) {
    token = tokens[i][0];
    if (token === opener) count++;
    else if (token === closer) count--;
    if (!count) return i;
  }
  throw new Error("No matching '" + closer + "' found");
};

function parse_open_straight(stack, token) {
  stack.push({
    type: OPEN_BRACKET,
    obj: [],
    postcomma: false,
    juststarted: true
  });
};

function parse_close_straight(stack, token) {
  var stacktop = stack[stack.length - 1], arr;
  if (stacktop.type !== OPEN_BRACKET) throw new Error("mismatched ']'");
  arr = stack.pop().obj;
  stacktop = stack[stack.length - 1];
  switch(stacktop.type) {
    case OPEN_BRACE:
      stacktop.obj[stacktop.key] = arr;
      break;
    case OPEN_BRACKET:
      stacktop.obj.push(arr);
      break;
    default:
      throw new Error("bad context for an array");
  }
};

function parse_open_curly(stack, token) {
  stack.push({
    type: OPEN_BRACE,
    obj: {},
    key: '',
    postcomma: false,
    postcolon: false,
    juststarted: true
  });
};

function parse_close_curly(stack, token) {
  var stacktop = stack[stack.length - 1], arr, obj;
  if (stacktop.type !== OPEN_BRACE) throw new Error("mismatched ']'");
  obj = stack.pop().obj;
  stacktop = stack[stack.length - 1];
  switch(stacktop.type) {
    case OPEN_BRACE:
      stacktop.obj[stacktop.key] = obj;
      break;
    case OPEN_BRACKET:
      stacktop.obj.push(obj);
      break;
    default:
      throw new Error("bad context for an array");
  }
};

function parse_identifier(stack, token) {
  var stacktop = stack[stack.length - 1];
  if (stacktop.type === OPEN_BRACE &&
      (stacktop.postcomma || stacktop.juststarted)) {
    stacktop.key = token[1];
    stacktop.postcomma = stacktop.juststarted = false;
  } else throw new Error("Bad syntax");
};

function parse_comma(stack, token) {
  var stacktop = stack[stack.length - 1];
  stacktop.postcomma = true;
};

function parse_colon(stack, token) {
  var stacktop = stack[stack.length - 1];
  if (stacktop.type !== OPEN_BRACE) throw new Error("bad context for a COLON");
  stacktop.postcolon = true;
};

function parse_string(stack, token) {
  var stacktop = stack[stack.length - 1];
  if (stacktop.type === OPEN_BRACE &&
      (stacktop.postcomma || stacktop.juststarted)) {
    stacktop.key = token[1];
    stacktop.postcomma = stacktop.juststarted = false;
  } else apply_value(stack, token[1]);
};

function parse_number(stack, token) {
  apply_value(stack, eval(token[1]));
};

var simple_values = {};
simple_values[TRUE] = true;
simple_values[FALSE] = false;
simple_values[UNDEFINED] = undefined;
simple_values[NULL] = null;
simple_values[INFINITY] = Infinity;
simple_values[NEGATIVE_INFINITY] = -Infinity;

function parse_simple_value(stack, token) {
  apply_value(stack, simple_values[token[0]]);
};

var parsers = {};
parsers[OPEN_BRACKET] = parse_open_straight;
parsers[CLOSE_BRACKET] = parse_close_straight;
parsers[OPEN_BRACE] = parse_open_curly;
parsers[CLOSE_BRACE] = parse_close_curly;
parsers[COMMA] = parse_comma;
parsers[COLON] = parse_colon;
parsers[STRING] = parse_string;
parsers[NUMBER] = parse_number;
parsers[NEGATIVE_INFINITY] = parsers[NULL] = parse_simple_value;
parsers[UNDEFINED] = parsers[INFINITY] = parse_simple_value;
parsers[TRUE] = parsers[FALSE] = parse_simple_value;
parsers[IDENTIFIER] = parse_identifier;

function parse_tokens(tokens) {
  var stack = [{
    type: OPEN_BRACKET,
    obj: [],
    postcomma: false,
    juststarted: true
  }], token;
  while (tokens.length) {
    token = tokens.shift();
    parsers[token[0]](stack, token);
  }
  return stack[0].obj[0];
};

TJP.json.load = TJP.json.decode = TJP.json.parse = function(data) {
  var tokens = tokenize(data);
  reduce_tokens(tokens);
  return parse_tokens(tokens);
};

function gettype(obj) {
  var dumbtype = typeof obj;
  switch(dumbtype) {
    case "number":
      if (isNaN(obj)) return "NaN";
    case "string":
    case "boolean":
    case "undefined":
      return dumbtype;
    case "object":
      if (obj instanceof Number) return "number";
      if (obj instanceof String) return "string";
      if (obj instanceof Boolean) return "boolean";
      if (obj instanceof Array) return "array";
      if (obj instanceof Date) return "date";
      if (obj instanceof RegExp) return "regexp";
      if (obj === null) return "null";
      return "object";
  }
};

function dump_array(arr) {
  var dumped = [], i;
  for (i = 0; i < arr.length; i++) {
    dumped.push(TJP.json.dump(arr[i]));
  }
  return dumped.join('');
};

function dump_object(obj) {
  var dumped = [], name;
  for (name in obj) {
    dumped.push(name + ":" + TJP.json.dump(obj[name]));
  }
  return "{" + dumped.join(',') + "}";
};

var ADD_SLASHES = {
  "\n": "\\n",
  "\r": "\\r",
  "\t": "\\t",
  "\b": "\\b",
  "\f": "\\f",
  '"': '\\"'
};

function dump_string(str) {
  var from;
  str = str.replace('\\', '\\\\', 'g');
  for (from in ADD_SLASHES) str = str.replace(from, ADD_SLASHES[from], 'g');
  return '"' + str + '"';
};

TJP.json.dump = TJP.json.encode = function(data) {
  var type = gettype(data);
  switch(type) {
    case "number":
    case "boolean":
      return data.toString();
    case "string":
      return dump_string(data);
    case "undefined":
    case "NaN":
    case "null":
      return type;
    case "array":
      return dump_array(data);
    case "object":
      return dump_object(data);
    case "date":
    case "regexp":
      throw new Error("can't serialize a " + type);
  }
};
<|endoftext|>


<commit_before>/** @license
 * RequireJS plugin for loading JSON files
 * - depends on Text plugin and it was HEAVILY "inspired" by it as well.
 * Author: Miller Medeiros
 * Version: 0.4.0 (2014/04/10)
 * Released under the MIT license
 */
define(['text'], function(text){

    var CACHE_BUST_QUERY_PARAM = 'bust',
        CACHE_BUST_FLAG = '!bust',
        jsonParse = (typeof JSON !== 'undefined' && typeof JSON.parse === 'function')? JSON.parse : function(val){
            return eval('('+ val +')'); //quick and dirty
        },
        buildMap = {};

    function cacheBust(url){
        url = url.replace(CACHE_BUST_FLAG, '');
        url += (url.indexOf('?') < 0)? '?' : '&';
        return url + CACHE_BUST_QUERY_PARAM +'='+ Math.round(2147483647 * Math.random());
    }

    //API
    return {

        load : function(name, req, onLoad, config) {
            if (( config.isBuild && (config.inlineJSON === false || name.indexOf(CACHE_BUST_QUERY_PARAM +'=') !== -1)) || (req.toUrl(name).indexOf('empty:') === 0)) {
                //avoid inlining cache busted JSON or if inlineJSON:false
                //and don't inline files marked as empty!
                onLoad(null);
            } else {
                text.get(req.toUrl(name), function(data){
                    if (config.isBuild) {
                        buildMap[name] = data;
                        onLoad(data);
                    } else {
                        console.log(data);
                        onLoad(jsonParse(data));
                    }
                },
                    onLoad.error, {
                        accept: 'application/json'
                    }
                );
            }
        },

        normalize : function (name, normalize) {
            // used normalize to avoid caching references to a "cache busted" request
            if (name.indexOf(CACHE_BUST_FLAG) !== -1) {
                name = cacheBust(name);
            }
            // resolve any relative paths
            return normalize(name);
        },

        //write method based on RequireJS official text plugin by James Burke
        //https://github.com/jrburke/requirejs/blob/master/text.js
        write : function(pluginName, moduleName, write){
            if(moduleName in buildMap){
                var content = buildMap[moduleName];
                write('define("'+ pluginName +'!'+ moduleName +'", function(){ return '+ content +';});\n');
            }
        }

    };
});
<commit_msg>Debugging bamboo issues<commit_after>/** @license
 * RequireJS plugin for loading JSON files
 * - depends on Text plugin and it was HEAVILY "inspired" by it as well.
 * Author: Miller Medeiros
 * Version: 0.4.0 (2014/04/10)
 * Released under the MIT license
 */
define(['text'], function(text){

    var CACHE_BUST_QUERY_PARAM = 'bust',
        CACHE_BUST_FLAG = '!bust',
        jsonParse = (typeof JSON !== 'undefined' && typeof JSON.parse === 'function')? JSON.parse : function(val){
            return eval('('+ val +')'); //quick and dirty
        },
        buildMap = {};

    function cacheBust(url){
        url = url.replace(CACHE_BUST_FLAG, '');
        url += (url.indexOf('?') < 0)? '?' : '&';
        return url + CACHE_BUST_QUERY_PARAM +'='+ Math.round(2147483647 * Math.random());
    }

    //API
    return {

        load : function(name, req, onLoad, config) {
            if (( config.isBuild && (config.inlineJSON === false || name.indexOf(CACHE_BUST_QUERY_PARAM +'=') !== -1)) || (req.toUrl(name).indexOf('empty:') === 0)) {
                //avoid inlining cache busted JSON or if inlineJSON:false
                //and don't inline files marked as empty!
                onLoad(null);
            } else {
                text.get(req.toUrl(name), function(data){
                    if (config.isBuild) {
                        buildMap[name] = data;
                        onLoad(data);
                    } else {
                        console.log(req.toUrl(name), data);
                        onLoad(jsonParse(data));
                    }
                },
                    onLoad.error, {
                        accept: 'application/json'
                    }
                );
            }
        },

        normalize : function (name, normalize) {
            // used normalize to avoid caching references to a "cache busted" request
            if (name.indexOf(CACHE_BUST_FLAG) !== -1) {
                name = cacheBust(name);
            }
            // resolve any relative paths
            return normalize(name);
        },

        //write method based on RequireJS official text plugin by James Burke
        //https://github.com/jrburke/requirejs/blob/master/text.js
        write : function(pluginName, moduleName, write){
            if(moduleName in buildMap){
                var content = buildMap[moduleName];
                write('define("'+ pluginName +'!'+ moduleName +'", function(){ return '+ content +';});\n');
            }
        }

    };
});
<|endoftext|>


<commit_before>// Based on https://gist.github.com/gfreezy/6060661

slate.config("windowHintsShowIcons", true);
slate.config("windowHintsIgnoreHiddenWindows", false);
slate.config("windowHintsSpread", true);
slate.config("windowHintsSpreadSearchWidth", 60);
slate.config("secondsBeforeRepeat", 0.2);
slate.config("secondsBetweenRepeat", 0.0);
slate.config("gridBackgroundColor", [75, 77, 81, 0.6]);
slate.config("gridCellBackgroundColor", [75, 77, 81, 0.6]);

var pushRight = slate.operation("push", {
    "direction": "right",
    "style": "bar-resize:screenSizeX/2"
});

var pushLeft = slate.operation("push", {
    "direction": "left",
    "style": "bar-resize:screenSizeX/2"
});

var throwNextLeft = slate.operation("throw", {
    "width": "screenSizeX/2",
    "height": "screenSizeY",
    "screen": "next"
});

var throwNextRight = slate.operation("throw", {
    "x": "screenOriginX+(screenSizeX)/2",
    "y": "screenOriginY",
    "width": "screenSizeX/2",
    "height": "screenSizeY",
    "screen": "next"
});

var fullscreen = slate.operation("move", {
    "x": "screenOriginX",
    "y": "screenOriginY",
    "width": "screenSizeX",
    "height": "screenSizeY"
});

var throwNextFullscreen = slate.operation("throw", {
    "x": "screenOriginX",
    "y": "screenOriginY",
    "width": "screenSizeX",
    "height": "screenSizeY",
    "screen": "next"
});

var grid = slate.operation("grid", {
    "grids": {
        "1440x900": {
            "width": 8,
            "height": 6
        },
        "1920x1080": {
            "width": 8,
            "height": 6
        },
        "1920x1200": {
            "width": 8,
            "height": 6
        }
    },
    "padding": 5
});

var growRight = slate.operation("resize", {
    "width" : "+10%",
    "height" : "+0"
});

var shrinkRight = slate.operation("resize", {
    "width" : "-10%",
    "height" : "+0"
});

var moveTopLeft = slate.operation("corner", {
    "direction": "top-left"
});

var moveTopRight = slate.operation("corner", {
    "direction": "top-right"
});

var moveBottomRight = slate.operation("corner", {
    "direction": "bottom-right"
});

var switcher = slate.operation("hint");

var throwNext = function(win) {
    if (!win) {
        return;
    }
    var winRect = win.rect();
    var screen = win.screen().visibleRect();

    var newX = (winRect.x - screen.x) / screen.width + "*screenSizeX+screenOriginX";
    var newY = (winRect.y - screen.y) / screen.height + "*screenSizeY+screenOriginY";
    var newWidth = winRect.width / screen.width + "*screenSizeX";
    var newHeight = winRect.height / screen.height + "*screenSizeY";
    var throwNext = slate.operation("throw", {
        "x": newX,
        "y": newY,
        "width": newWidth,
        "height": newHeight,
        "screen": "next"
    });
    win.doOperation(throwNext);
};

var pushedLeft = function(win) {
    if (!win) {
        return false;
    }
    var winRect = win.rect();
    var screen = win.screen().visibleRect();

    if (winRect.x === screen.x &&
        winRect.y === screen.y &&
        winRect.width === screen.width / 2 &&
        winRect.height === screen.height
    ) {
        return true;
    }
    return false;
};

var pushedRight = function(win) {
    if (!win) {
        return false;
    }
    var winRect = win.rect();
    var screen = win.screen().visibleRect();

    if (winRect.x === screen.x + screen.width / 2 &&
        winRect.y === screen.y &&
        winRect.width === screen.width / 2 &&
        winRect.height === screen.height
    ) {
        return true;
    }
    return false;
};

var isFullscreen = function(win) {
    if (!win) {
        return false;
    }
    var winRect = win.rect();
    var screen = win.screen().visibleRect();
    if (winRect.width === screen.width &&
        winRect.height === screen.height
    ) {
        return true;
    }
    return false;
};

slate.bind("left:alt,cmd", function(win) {
    if (!win) {
        return false;
    }
    if (pushedLeft(win)) {
        win.doOperation(throwNextLeft);
    } else {
        win.doOperation(pushLeft);
    }
});

slate.bind("right:alt,cmd", function(win) {
    if (!win) {
        return false;
    }

    if (pushedRight(win)) {
        win.doOperation(throwNextRight);
    } else {
        win.doOperation(pushRight);
    }
});

slate.bind("up:alt,cmd", function(win) {
    if (!win) {
        return false;
    }

    if (isFullscreen(win)) {
        win.doOperation(throwNextFullscreen);
    } else {
        win.doOperation(fullscreen);
    }
});

slate.bind("down:alt,cmd", function(win) {
    if (!win) {
        return false;
    }

    if (pushedLeft(win)) {
        win.doOperation(throwNextLeft);
    } else if (pushedRight(win)) {
        win.doOperation(throwNextRight);
    } else if (isFullscreen(win)) {
        win.doOperation(throwNextFullscreen);
    } else {
        throwNext(win);
    }
});

slate.bind("left:ctrl,alt,cmd", shrinkRight);
slate.bind("right:ctrl,alt,cmd", growRight);

slate.bind("up:ctrl,alt", throwNext);
slate.bind("down:ctrl,alt", moveBottomRight);
slate.bind("left:ctrl,alt", moveTopLeft);
slate.bind("right:ctrl,alt", moveTopRight);

slate.bind("g:alt,cmd", grid);
slate.bind("h:alt,cmd", switcher);

slate.source(".slate.js.local")
<commit_msg>add ability to resize vertically to slate config<commit_after>// Based on https://gist.github.com/gfreezy/6060661

slate.config("windowHintsShowIcons", true);
slate.config("windowHintsIgnoreHiddenWindows", false);
slate.config("windowHintsSpread", true);
slate.config("windowHintsSpreadSearchWidth", 60);
slate.config("secondsBeforeRepeat", 0.2);
slate.config("secondsBetweenRepeat", 0.0);
slate.config("gridBackgroundColor", [75, 77, 81, 0.6]);
slate.config("gridCellBackgroundColor", [75, 77, 81, 0.6]);

var pushRight = slate.operation("push", {
    "direction": "right",
    "style": "bar-resize:screenSizeX/2"
});

var pushLeft = slate.operation("push", {
    "direction": "left",
    "style": "bar-resize:screenSizeX/2"
});

var throwNextLeft = slate.operation("throw", {
    "width": "screenSizeX/2",
    "height": "screenSizeY",
    "screen": "next"
});

var throwNextRight = slate.operation("throw", {
    "x": "screenOriginX+(screenSizeX)/2",
    "y": "screenOriginY",
    "width": "screenSizeX/2",
    "height": "screenSizeY",
    "screen": "next"
});

var fullscreen = slate.operation("move", {
    "x": "screenOriginX",
    "y": "screenOriginY",
    "width": "screenSizeX",
    "height": "screenSizeY"
});

var throwNextFullscreen = slate.operation("throw", {
    "x": "screenOriginX",
    "y": "screenOriginY",
    "width": "screenSizeX",
    "height": "screenSizeY",
    "screen": "next"
});

var grid = slate.operation("grid", {
    "grids": {
        "1440x900": {
            "width": 8,
            "height": 6
        },
        "1920x1080": {
            "width": 8,
            "height": 6
        },
        "1920x1200": {
            "width": 8,
            "height": 6
        }
    },
    "padding": 5
});

var growRight = slate.operation("resize", {
    "width" : "+10%",
    "height" : "+0"
});

var shrinkRight = slate.operation("resize", {
    "width" : "-10%",
    "height" : "+0"
});

var moveTopLeft = slate.operation("corner", {
    "direction": "top-left"
});

var growDown = slate.operation("resize", {
    "width" : "+0",
    "height" : "+10%"
});

var shrinkDown = slate.operation("resize", {
    "width" : "+0",
    "height" : "-10%"
});

var moveTopRight = slate.operation("corner", {
    "direction": "top-right"
});

var moveBottomRight = slate.operation("corner", {
    "direction": "bottom-right"
});

var switcher = slate.operation("hint");

var throwNext = function(win) {
    if (!win) {
        return;
    }
    var winRect = win.rect();
    var screen = win.screen().visibleRect();

    var newX = (winRect.x - screen.x) / screen.width + "*screenSizeX+screenOriginX";
    var newY = (winRect.y - screen.y) / screen.height + "*screenSizeY+screenOriginY";
    var newWidth = winRect.width / screen.width + "*screenSizeX";
    var newHeight = winRect.height / screen.height + "*screenSizeY";
    var throwNext = slate.operation("throw", {
        "x": newX,
        "y": newY,
        "width": newWidth,
        "height": newHeight,
        "screen": "next"
    });
    win.doOperation(throwNext);
};

var pushedLeft = function(win) {
    if (!win) {
        return false;
    }
    var winRect = win.rect();
    var screen = win.screen().visibleRect();

    if (winRect.x === screen.x &&
        winRect.y === screen.y &&
        winRect.width === screen.width / 2 &&
        winRect.height === screen.height
    ) {
        return true;
    }
    return false;
};

var pushedRight = function(win) {
    if (!win) {
        return false;
    }
    var winRect = win.rect();
    var screen = win.screen().visibleRect();

    if (winRect.x === screen.x + screen.width / 2 &&
        winRect.y === screen.y &&
        winRect.width === screen.width / 2 &&
        winRect.height === screen.height
    ) {
        return true;
    }
    return false;
};

var isFullscreen = function(win) {
    if (!win) {
        return false;
    }
    var winRect = win.rect();
    var screen = win.screen().visibleRect();
    if (winRect.width === screen.width &&
        winRect.height === screen.height
    ) {
        return true;
    }
    return false;
};

slate.bind("left:alt,cmd", function(win) {
    if (!win) {
        return false;
    }
    if (pushedLeft(win)) {
        win.doOperation(throwNextLeft);
    } else {
        win.doOperation(pushLeft);
    }
});

slate.bind("right:alt,cmd", function(win) {
    if (!win) {
        return false;
    }

    if (pushedRight(win)) {
        win.doOperation(throwNextRight);
    } else {
        win.doOperation(pushRight);
    }
});

slate.bind("up:alt,cmd", function(win) {
    if (!win) {
        return false;
    }

    if (isFullscreen(win)) {
        win.doOperation(throwNextFullscreen);
    } else {
        win.doOperation(fullscreen);
    }
});

slate.bind("down:alt,cmd", function(win) {
    if (!win) {
        return false;
    }

    if (pushedLeft(win)) {
        win.doOperation(throwNextLeft);
    } else if (pushedRight(win)) {
        win.doOperation(throwNextRight);
    } else if (isFullscreen(win)) {
        win.doOperation(throwNextFullscreen);
    } else {
        throwNext(win);
    }
});

slate.bind("left:ctrl,alt,cmd", shrinkRight);
slate.bind("right:ctrl,alt,cmd", growRight);
slate.bind("up:ctrl,alt,cmd", shrinkDown);
slate.bind("down:ctrl,alt,cmd", growDown);

slate.bind("up:ctrl,alt", throwNext);
slate.bind("down:ctrl,alt", moveBottomRight);
slate.bind("left:ctrl,alt", moveTopLeft);
slate.bind("right:ctrl,alt", moveTopRight);

slate.bind("g:alt,cmd", grid);
slate.bind("h:alt,cmd", switcher);

slate.source(".slate.js.local")
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////////
//// cron jobs for updating/fetching data
/////////////////////////////////////////////////////////////////////

const CronJob = require('cron').CronJob;
const blockchainApi = require('./../lib/blockchain-info-api');
const BitcoinValue = require('./../model/BitcoinValue.js');
const BitcoinValueHourlyAvg = require('./../model/BitcoinValueHourlyAvg.js');
const BitcoinValueDailyAvg = require('./../model/BitcoinValueDailyAvg.js');
const BitcoinValueMonthlyAvg = require('./../model/BitcoinValueMonthlyAvg.js');
const tools = require('./../lib/tools');

var mongoCallback = function(error, data) {
  if(error)
    console.log(error);
  // else
  //   console.log(data);
}

var updateHourlyAvgValue = function(error, data) {
    // current timestamp in UTC
    var UTCtimestamp = parseInt(new Date().getTime() / 1000);
    // current rouned hour timestamp in UTC
    var roundHourUTCtimestamp = UTCtimestamp - (UTCtimestamp % 3600);

    // get all values for from start of current hour up to now
    // if it's 14:30, then get values between 14:00 and 14:30
    BitcoinValue.find({
        timestamp: {
            $gte: roundHourUTCtimestamp,
            $lte: UTCtimestamp
        }
    }, function(error, data) {
        // error check
        if(error) {
          console.log(error);
          return false;
        }

        var hourAvg = tools.getDataAverage(data, 'value');

        // skip update if avarage is null
        if (hourAvg === null) return;

        // check if there is an hourly avg value with this timestamp
        // update/create accordingly
        BitcoinValueHourlyAvg.update({
            timestamp: roundHourUTCtimestamp
        },
        { value: hourAvg},
        function (err, raw) {
            if(err) {
              console.log(err);
            }

            // if not matching object exist,
            // then create new with these values
            if (raw.n == 0) {
                BitcoinValueHourlyAvg.create({
                    value: hourAvg,
                    timestamp: roundHourUTCtimestamp
                }, mongoCallback);
            }
        });
    });
}

// cron job every 15 minutes
// var job1 = new CronJob('00 */5 * * * *', function() {
var job1 = new CronJob('00 00,15,30,45 * * * *', function() {
    blockchainApi.fetchCurrentPrice(function (body) {
        BitcoinValue.create({
            value: body.USD.last,
            timestamp: tools.getCurrentTimestamp()
        }, updateHourlyAvgValue);
    });
}, null, true, 'UTC');

// // cron job every hour at :05 minutes
// // calc and write avg bitcoin value for previous hour
// var job2 = new CronJob('00 05 * * * *', function() {
//     // current timestamp in UTC
//     var UTCtimestamp = parseInt(new Date().getTime() / 1000);
//     // current rouned hour timestamp in UTC
//     var roundHourUTCtimestamp = UTCtimestamp - (UTCtimestamp % 3600);
//     // previous rouned hour timestamp in UTC
//     var prevHourUTCtimestamp = roundHourUTCtimestamp - 3600;
//
//     // get all values for past hour
//     // if it's 14:05, then get values between 13:00 and 14:00 (UTC)
//     BitcoinValue.find({
//         timestamp: {
//             $gte: prevHourUTCtimestamp,
//             $lte: roundHourUTCtimestamp
//         }
//     }, function(error, data) {
//         // error check
//         if(error) {
//           console.log(error);
//           return false;
//         }
//
//         var hourAvg = tools.getDataAverage(data, 'value');
//
//         // skip update if avarage is null
//         if (hourAvg === null) return;
//
//         // write hourly avg value to db
//         BitcoinValueHourlyAvg.create({
//             value: hourAvg,
//             timestamp: prevHourUTCtimestamp
//         }, mongoCallback);
//     });
//
// }, null, true, 'UTC');

// cron job every hour at :59 minutes
// calc and write avg bitcoin value for current day up to this moment
var job3 = new CronJob('00 59 * * * *', function() {

    // // proceed only if it's 0 Hours UTC (12 AM)
    // if (new Date().getUTCHours() != 0) {
    //     return;
    // }

    // current timestamp in UTC
    var UTCtimestamp = parseInt(new Date().getTime() / 1000);
    // current rouned day timestamp in UTC
    var roundDayUTCtimestamp = UTCtimestamp - (UTCtimestamp % (24 * 3600));

    // // previous rouned day timestamp in UTC
    // var prevDayUTCtimestamp = roundDayUTCtimestamp - (24 * 3600);

    // get all hourly average values for past day
    // and calc the average value
    BitcoinValueHourlyAvg.find({
        timestamp: {
            $gte: roundDayUTCtimestamp,
            $lte: UTCtimestamp
        }
    }, function(error, data) {
        // error check
        if(error) {
          console.log(error);
          return false;
        }

        var dailyAvg = tools.getDataAverage(data, 'value');

        // skip update if avarage is null
        if (dailyAvg === null) return;

        // check if there is a daily avg value with this timestamp
        // update/create accordingly
        BitcoinValueDailyAvg.update({
            timestamp: roundDayUTCtimestamp
        },
        { value: dailyAvg},
        function (err, raw) {
            if(err) {
              console.log(err);
            }

            // if not matching object exist,
            // then create new with these values
            if (raw.n == 0) {
                BitcoinValueDailyAvg.create({
                    value: dailyAvg,
                    timestamp: roundDayUTCtimestamp
                }, mongoCallback);
            }
        });
    });

}, null, true, 'UTC');

// cron job every day at 23:55 minutes
// calc and write avg bitcoin value for current month up to this moment
var job4 = new CronJob('00 55 23 * * *', function() {
    // get current year and month
    // build monthly string like '2017-07-01' and convert it to timestamp
    var year = new Date().getUTCFullYear();
    var monthString = tools.monthIntToString(new Date().getUTCMonth());
    var monthlyTimestamp = new Date(
        year + '-' + monthString + '-01'
    ).getTime() / 1000;

    // get all daily average values for past month
    BitcoinValueDailyAvg.find({
        timestamp: {
            $gte: monthlyTimestamp,
        }
    }, function(error, data) {
        // error check
        if(error) {
          console.log(error);
          return false;
        }

        var monthlyAvg = tools.getDataAverage(data, 'value');

        // skip update if avarage is null
        if (monthlyAvg === null) return;

        // check if there is a monthly avg value with this timestamp
        // update/create accordingly
        BitcoinValueMonthlyAvg.update({
            timestamp: monthlyTimestamp
        },
        { value: monthlyAvg},
        function (error, raw) {
            if(error) {
              console.log(error);
              return false;
            }

            // if not matching object exist,
            // then create new with these values
            if (raw.n == 0) {
                BitcoinValueMonthlyAvg.create({
                    value: monthlyAvg,
                    timestamp: monthlyTimestamp
                }, mongoCallback);
            }
        });
    });

}, null, true, 'UTC');

// exports
module.exports = {
    fetchCurrentValue: job1,
    // updateHourlyValue: job2,
    updateDailyValue: job3,
    updateMonthlyValue: job4
};
<commit_msg>Add parseFloat value logic to fetchCurrentPrice update method<commit_after>/////////////////////////////////////////////////////////////////////
//// cron jobs for updating/fetching data
/////////////////////////////////////////////////////////////////////

const CronJob = require('cron').CronJob;
const blockchainApi = require('./../lib/blockchain-info-api');
const BitcoinValue = require('./../model/BitcoinValue.js');
const BitcoinValueHourlyAvg = require('./../model/BitcoinValueHourlyAvg.js');
const BitcoinValueDailyAvg = require('./../model/BitcoinValueDailyAvg.js');
const BitcoinValueMonthlyAvg = require('./../model/BitcoinValueMonthlyAvg.js');
const tools = require('./../lib/tools');

var mongoCallback = function(error, data) {
  if(error)
    console.log(error);
  // else
  //   console.log(data);
}

var updateHourlyAvgValue = function(error, data) {
    // current timestamp in UTC
    var UTCtimestamp = parseInt(new Date().getTime() / 1000);
    // current rouned hour timestamp in UTC
    var roundHourUTCtimestamp = UTCtimestamp - (UTCtimestamp % 3600);

    // get all values for from start of current hour up to now
    // if it's 14:30, then get values between 14:00 and 14:30
    BitcoinValue.find({
        timestamp: {
            $gte: roundHourUTCtimestamp,
            $lte: UTCtimestamp
        }
    }, function(error, data) {
        // error check
        if(error) {
          console.log(error);
          return false;
        }

        var hourAvg = tools.getDataAverage(data, 'value');

        // skip update if avarage is null
        if (hourAvg === null) return;

        // check if there is an hourly avg value with this timestamp
        // update/create accordingly
        BitcoinValueHourlyAvg.update({
            timestamp: roundHourUTCtimestamp
        },
        { value: hourAvg},
        function (err, raw) {
            if(err) {
              console.log(err);
            }

            // if not matching object exist,
            // then create new with these values
            if (raw.n == 0) {
                BitcoinValueHourlyAvg.create({
                    value: hourAvg,
                    timestamp: roundHourUTCtimestamp
                }, mongoCallback);
            }
        });
    });
}

// cron job every 15 minutes
// var job1 = new CronJob('00 */5 * * * *', function() {
var job1 = new CronJob('00 00,15,30,45 * * * *', function() {
    blockchainApi.fetchCurrentPrice(function (body) {
        BitcoinValue.create({
            value: parseFloat((body.USD.last).toFixed(2)),
            timestamp: tools.getCurrentTimestamp()
        }, updateHourlyAvgValue);
    });
}, null, true, 'UTC');

// // cron job every hour at :05 minutes
// // calc and write avg bitcoin value for previous hour
// var job2 = new CronJob('00 05 * * * *', function() {
//     // current timestamp in UTC
//     var UTCtimestamp = parseInt(new Date().getTime() / 1000);
//     // current rouned hour timestamp in UTC
//     var roundHourUTCtimestamp = UTCtimestamp - (UTCtimestamp % 3600);
//     // previous rouned hour timestamp in UTC
//     var prevHourUTCtimestamp = roundHourUTCtimestamp - 3600;
//
//     // get all values for past hour
//     // if it's 14:05, then get values between 13:00 and 14:00 (UTC)
//     BitcoinValue.find({
//         timestamp: {
//             $gte: prevHourUTCtimestamp,
//             $lte: roundHourUTCtimestamp
//         }
//     }, function(error, data) {
//         // error check
//         if(error) {
//           console.log(error);
//           return false;
//         }
//
//         var hourAvg = tools.getDataAverage(data, 'value');
//
//         // skip update if avarage is null
//         if (hourAvg === null) return;
//
//         // write hourly avg value to db
//         BitcoinValueHourlyAvg.create({
//             value: hourAvg,
//             timestamp: prevHourUTCtimestamp
//         }, mongoCallback);
//     });
//
// }, null, true, 'UTC');

// cron job every hour at :59 minutes
// calc and write avg bitcoin value for current day up to this moment
var job3 = new CronJob('00 59 * * * *', function() {

    // // proceed only if it's 0 Hours UTC (12 AM)
    // if (new Date().getUTCHours() != 0) {
    //     return;
    // }

    // current timestamp in UTC
    var UTCtimestamp = parseInt(new Date().getTime() / 1000);
    // current rouned day timestamp in UTC
    var roundDayUTCtimestamp = UTCtimestamp - (UTCtimestamp % (24 * 3600));

    // // previous rouned day timestamp in UTC
    // var prevDayUTCtimestamp = roundDayUTCtimestamp - (24 * 3600);

    // get all hourly average values for past day
    // and calc the average value
    BitcoinValueHourlyAvg.find({
        timestamp: {
            $gte: roundDayUTCtimestamp,
            $lte: UTCtimestamp
        }
    }, function(error, data) {
        // error check
        if(error) {
          console.log(error);
          return false;
        }

        var dailyAvg = tools.getDataAverage(data, 'value');

        // skip update if avarage is null
        if (dailyAvg === null) return;

        // check if there is a daily avg value with this timestamp
        // update/create accordingly
        BitcoinValueDailyAvg.update({
            timestamp: roundDayUTCtimestamp
        },
        { value: dailyAvg},
        function (err, raw) {
            if(err) {
              console.log(err);
            }

            // if not matching object exist,
            // then create new with these values
            if (raw.n == 0) {
                BitcoinValueDailyAvg.create({
                    value: dailyAvg,
                    timestamp: roundDayUTCtimestamp
                }, mongoCallback);
            }
        });
    });

}, null, true, 'UTC');

// cron job every day at 23:55 minutes
// calc and write avg bitcoin value for current month up to this moment
var job4 = new CronJob('00 55 23 * * *', function() {
    // get current year and month
    // build monthly string like '2017-07-01' and convert it to timestamp
    var year = new Date().getUTCFullYear();
    var monthString = tools.monthIntToString(new Date().getUTCMonth());
    var monthlyTimestamp = new Date(
        year + '-' + monthString + '-01'
    ).getTime() / 1000;

    // get all daily average values for past month
    BitcoinValueDailyAvg.find({
        timestamp: {
            $gte: monthlyTimestamp,
        }
    }, function(error, data) {
        // error check
        if(error) {
          console.log(error);
          return false;
        }

        var monthlyAvg = tools.getDataAverage(data, 'value');

        // skip update if avarage is null
        if (monthlyAvg === null) return;

        // check if there is a monthly avg value with this timestamp
        // update/create accordingly
        BitcoinValueMonthlyAvg.update({
            timestamp: monthlyTimestamp
        },
        { value: monthlyAvg},
        function (error, raw) {
            if(error) {
              console.log(error);
              return false;
            }

            // if not matching object exist,
            // then create new with these values
            if (raw.n == 0) {
                BitcoinValueMonthlyAvg.create({
                    value: monthlyAvg,
                    timestamp: monthlyTimestamp
                }, mongoCallback);
            }
        });
    });

}, null, true, 'UTC');

// exports
module.exports = {
    fetchCurrentValue: job1,
    // updateHourlyValue: job2,
    updateDailyValue: job3,
    updateMonthlyValue: job4
};
<|endoftext|>


<commit_before>/**
 * The lightbox widget
 *
 * Copyright (C) 2009-2011 Nikolay Nemshilov
 */
var Lightbox = new Widget({

  extend: {
    version: '2.2.0',

    EVENTS: $w('show hide load'),

    Options: {
      fxName:          'fade',
      fxDuration:      300,

      group:           null, // a group marker

      hideOnEsc:       true,
      hideOnOutClick:  true,
      showCloseButton: true,

      cssRule:         "a[data-lightbox]", // all lightbox links css-rule

      // video links default size
      mediaWidth:      425,
      mediaHeight:     350
    },

    i18n: {
      Close: 'Close',
      Prev:  'Previous Image',
      Next:  'Next Image'
    },

    // the supported image-urls regexp
    Images: /\.(jpg|jpeg|gif|png|bmp)/,

    // media content sources
    Medias: [
      [/(http:\/\/.*?youtube\.[a-z]+)\/watch\?v=([^&]+)/,       '$1/v/$2',                      'swf'],
      [/(http:\/\/video.google.com)\/videoplay\?docid=([^&]+)/, '$1/googleplayer.swf?docId=$2', 'swf'],
      [/(http:\/\/vimeo\.[a-z]+)\/([0-9]+).*?/,                 '$1/moogaloop.swf?clip_id=$2',  'swf']
    ]
  },

  /**
   * basic constructor
   *
   * @param Object options override
   * @param Element optional options holder
   * @return void
   */
  initialize: function(options, context) {
    this
      .$super('lightbox', {})
      .setOptions(options, context)
      .insert([
        this.locker = new Locker(this.options),
        this.dialog = new Dialog(this.options)
      ])
      .on({
        close: this._close,
        next:  this._next,
        prev:  this._prev
      });
  },

  /**
   * Extracting the rel="lightboux[groupname]" attributes
   *
   * @param Object options
   * @param Element link with options
   * @return Dialog this
   */
  setOptions: function(options, context) {
    this.$super(options, context);

    if (context) {
      var rel = context.get('rel');
      if (rel && (rel = rel.match(/lightbox\[(.+?)\]/))) {
        this.options.group = rel[1];
      }
    }

    return this;
  },

  /**
   * Sets the popup's title
   *
   * @param mixed string or element or somethin'
   * @return Lighbox self
   */
  setTitle: function(text) {
    this.dialog.setTitle(text);

    return this;
  },

  /**
   * Shows the lightbox
   *
   * @param String/Array... content
   * @return Lightbox this
   */
  show: function(content) {
    return this._showAnd(function() {
      this.dialog.show(content, !content);
    });
  },

  /**
   * Hides the lightbox
   *
   * @return Lightbox this
   */
  hide: function() {
    Lightbox.current = null;

    return this.$super(this.options.fxName, {
      duration: this.options.fxDuration/3,
      onFinish: R(function() {
        this.fire('hide');
        this.remove();
      }).bind(this)
    });
  },

  /**
   * Loads up the data from url or a link
   *
   * @param String address or a link element
   * @param Object Xhr options
   * @return Lightbox this
   */
  load: function(link, options) {
    return this._showAnd(function() {
      this.dialog.load(link, options);
    });
  },

  /**
   * Resizes the content block to the given size
   *
   * @param Hash size
   * @return Lightbox this
   */
  resize: function(size) {
    this.dialog.resize(size);
    return this;
  },

// protected

  // handles the 'close' event
  _close: function(event) {
    event.stop();
    this.hide();
  },

  // handles the 'prev' event
  _prev: function(event) {
    event.stop();
    Pager.prev();
  },

  // handles the 'next' event
  _next: function(event) {
    event.stop();
    Pager.next();
  },

  // shows the lightbox element and then calls back
  _showAnd: function(callback) {
    if (Lightbox.current !== this) {
      Lightbox.current = this;

      // hidding all the hanging around lightboxes
      $$('div.rui-lightbox').each('remove');

      this.insertTo(document.body);
      this.dialog.show('', true);

      if (Browser.OLD) { // IE's get screwed by the transparency tricks
        this.reposition();
        Element.prototype.show.call(this);
        callback.call(this);
      } else {
        this.setStyle('display:none');
        Element.prototype.show.call(this, this.options.fxName, {
          duration: this.options.fxDuration/2,
          onFinish: R(function() {
            callback.call(this);
            this.fire('show');
          }).bind(this)
        });
      }
    } else {
      callback.call(this);
    }

    return this;
  },

  // manually repositioning under IE6 browser
  reposition: function() {
    if (Browser.IE6) {
      var win = $(window);

      this.setStyle({
        top:      win.scrolls().y + 'px',
        width:    win.size().x    + 'px',
        height:   win.size().y    + 'px',
        position: "absolute"
      });
    }
  }
});
<commit_msg>Lightbox bumping up the version<commit_after>/**
 * The lightbox widget
 *
 * Copyright (C) 2009-2011 Nikolay Nemshilov
 */
var Lightbox = new Widget({

  extend: {
    version: '2.2.1',

    EVENTS: $w('show hide load'),

    Options: {
      fxName:          'fade',
      fxDuration:      300,

      group:           null, // a group marker

      hideOnEsc:       true,
      hideOnOutClick:  true,
      showCloseButton: true,

      cssRule:         "a[data-lightbox]", // all lightbox links css-rule

      // video links default size
      mediaWidth:      425,
      mediaHeight:     350
    },

    i18n: {
      Close: 'Close',
      Prev:  'Previous Image',
      Next:  'Next Image'
    },

    // the supported image-urls regexp
    Images: /\.(jpg|jpeg|gif|png|bmp)/,

    // media content sources
    Medias: [
      [/(http:\/\/.*?youtube\.[a-z]+)\/watch\?v=([^&]+)/,       '$1/v/$2',                      'swf'],
      [/(http:\/\/video.google.com)\/videoplay\?docid=([^&]+)/, '$1/googleplayer.swf?docId=$2', 'swf'],
      [/(http:\/\/vimeo\.[a-z]+)\/([0-9]+).*?/,                 '$1/moogaloop.swf?clip_id=$2',  'swf']
    ]
  },

  /**
   * basic constructor
   *
   * @param Object options override
   * @param Element optional options holder
   * @return void
   */
  initialize: function(options, context) {
    this
      .$super('lightbox', {})
      .setOptions(options, context)
      .insert([
        this.locker = new Locker(this.options),
        this.dialog = new Dialog(this.options)
      ])
      .on({
        close: this._close,
        next:  this._next,
        prev:  this._prev
      });
  },

  /**
   * Extracting the rel="lightboux[groupname]" attributes
   *
   * @param Object options
   * @param Element link with options
   * @return Dialog this
   */
  setOptions: function(options, context) {
    this.$super(options, context);

    if (context) {
      var rel = context.get('rel');
      if (rel && (rel = rel.match(/lightbox\[(.+?)\]/))) {
        this.options.group = rel[1];
      }
    }

    return this;
  },

  /**
   * Sets the popup's title
   *
   * @param mixed string or element or somethin'
   * @return Lighbox self
   */
  setTitle: function(text) {
    this.dialog.setTitle(text);

    return this;
  },

  /**
   * Shows the lightbox
   *
   * @param String/Array... content
   * @return Lightbox this
   */
  show: function(content) {
    return this._showAnd(function() {
      this.dialog.show(content, !content);
    });
  },

  /**
   * Hides the lightbox
   *
   * @return Lightbox this
   */
  hide: function() {
    Lightbox.current = null;

    return this.$super(this.options.fxName, {
      duration: this.options.fxDuration/3,
      onFinish: R(function() {
        this.fire('hide');
        this.remove();
      }).bind(this)
    });
  },

  /**
   * Loads up the data from url or a link
   *
   * @param String address or a link element
   * @param Object Xhr options
   * @return Lightbox this
   */
  load: function(link, options) {
    return this._showAnd(function() {
      this.dialog.load(link, options);
    });
  },

  /**
   * Resizes the content block to the given size
   *
   * @param Hash size
   * @return Lightbox this
   */
  resize: function(size) {
    this.dialog.resize(size);
    return this;
  },

// protected

  // handles the 'close' event
  _close: function(event) {
    event.stop();
    this.hide();
  },

  // handles the 'prev' event
  _prev: function(event) {
    event.stop();
    Pager.prev();
  },

  // handles the 'next' event
  _next: function(event) {
    event.stop();
    Pager.next();
  },

  // shows the lightbox element and then calls back
  _showAnd: function(callback) {
    if (Lightbox.current !== this) {
      Lightbox.current = this;

      // hidding all the hanging around lightboxes
      $$('div.rui-lightbox').each('remove');

      this.insertTo(document.body);
      this.dialog.show('', true);

      if (Browser.OLD) { // IE's get screwed by the transparency tricks
        this.reposition();
        Element.prototype.show.call(this);
        callback.call(this);
      } else {
        this.setStyle('display:none');
        Element.prototype.show.call(this, this.options.fxName, {
          duration: this.options.fxDuration/2,
          onFinish: R(function() {
            callback.call(this);
            this.fire('show');
          }).bind(this)
        });
      }
    } else {
      callback.call(this);
    }

    return this;
  },

  // manually repositioning under IE6 browser
  reposition: function() {
    if (Browser.IE6) {
      var win = $(window);

      this.setStyle({
        top:      win.scrolls().y + 'px',
        width:    win.size().x    + 'px',
        height:   win.size().y    + 'px',
        position: "absolute"
      });
    }
  }
});
<|endoftext|>