<commit_before>const { describe, it } = require('mocha');

describe('Matcher', () => {

	it('exist', () => {

	});

});<commit_msg>Add unit tests<commit_after>const { describe, it } = require('mocha');
const { expect } = require('chai');
const statusClass = require('../src/matcher');

describe('Constants', () => {

	describe('INFORMATIONAL', () => {

		it('exist', () => {
			expect(statusClass.INFORMATIONAL).to.exist;
		});

		it('has expected value', () => {
			expect(statusClass.INFORMATIONAL).to.equal(1);
		});

	});

	describe('SUCCESS', () => {

		it('exist', () => {
			expect(statusClass.SUCCESS).to.exist;
		});

		it('has expected value', () => {
			expect(statusClass.SUCCESS).to.equal(2);
		});

	});

	describe('REDIRECTION', () => {

		it('exist', () => {
			expect(statusClass.REDIRECTION).to.exist;
		});

		it('has expected value', () => {
			expect(statusClass.REDIRECTION).to.equal(3);
		});

	});

	describe('CLIENT_ERROR', () => {

		it('exist', () => {
			expect(statusClass.CLIENT_ERROR).to.exist;
		});

		it('has expected value', () => {
			expect(statusClass.CLIENT_ERROR).to.equal(4);
		});

	});

	describe('SERVER_ERROR', () => {

		it('exist', () => {
			expect(statusClass.SERVER_ERROR).to.exist;
		});

		it('has expected value', () => {
			expect(statusClass.SERVER_ERROR).to.equal(5);
		});

	});

});

describe('Matcher', () => {

	it('exist', () => {
		expect(statusClass.match).to.exist;
	});

	it('is a function', () => {
		expect(statusClass.match).instanceOf(Function);
	});

	describe('when status code is 1**', () => {
		it('should return INFORMATIONAL', () => {
			const codes = statusClassSequence(statusClass.INFORMATIONAL);

			for (let code of codes) {
				expect(statusClass.match(code)).to.equal(statusClass.INFORMATIONAL);
			}
		})
	});

	describe('when status code is 2**', () => {
		it('should return SUCCESS', () => {
			const codes = statusClassSequence(statusClass.SUCCESS);

			for (let code of codes) {
				expect(statusClass.match(code)).to.equal(statusClass.SUCCESS);
			}
		})
	});

	describe('when status code is 3**', () => {
		it('should return REDIRECTION', () => {
			const codes = statusClassSequence(statusClass.REDIRECTION);

			for (let code of codes) {
				expect(statusClass.match(code)).to.equal(statusClass.REDIRECTION);
			}
		})
	});

	describe('when status code is 4**', () => {
		it('should return CLIENT_ERROR', () => {
			const codes = statusClassSequence(statusClass.CLIENT_ERROR);

			for (let code of codes) {
				expect(statusClass.match(code)).to.equal(statusClass.CLIENT_ERROR);
			}
		})
	});

	describe('when status code is 5**', () => {
		it('should return SERVER_ERROR', () => {
			const codes = statusClassSequence(statusClass.SERVER_ERROR);

			for (let code of codes) {
				expect(statusClass.match(code)).to.equal(statusClass.SERVER_ERROR);
			}
		})
	});

});

describe('Helpers', () => {

	describe('isInformational', () => {

		it('exist', () => {
			expect(statusClass.isInformational).to.exist
		});

		it('is a function', () => {
			expect(statusClass.isInformational).instanceOf(Function);
		});

		it('should return true if class is 1**', () => {
			const codes = statusClassSequence(statusClass.INFORMATIONAL);

			for (let code of codes) {
				expect(statusClass.isInformational(code)).to.be.true;
			}
		});

		it('should return false if class is not 1**', () => {
			expect(statusClass.isInformational(301)).to.be.false;
		});
	});

	describe('isSuccess', () => {

		it('exist', () => {
			expect(statusClass.isSuccess).to.exist
		});

		it('is a function', () => {
			expect(statusClass.isSuccess).instanceOf(Function);
		});

		it('should return true if class is 2**', () => {
			const codes = statusClassSequence(statusClass.SUCCESS);

			for (let code of codes) {
				expect(statusClass.isSuccess(code)).to.be.true;
			}
		});

		it('should return false if class is not 2**', () => {
			expect(statusClass.isSuccess(301)).to.be.false;
		});
	});

	describe('isRedirection', () => {

		it('exist', () => {
			expect(statusClass.isRedirection).to.exist
		});

		it('is a function', () => {
			expect(statusClass.isRedirection).instanceOf(Function);
		});

		it('should return true if class is 3**', () => {
			const codes = statusClassSequence(statusClass.REDIRECTION);

			for (let code of codes) {
				expect(statusClass.isRedirection(code)).to.be.true;
			}
		});

		it('should return false if class is not 3**', () => {
			expect(statusClass.isRedirection(200)).to.be.false;
		});
	});

	describe('isClientError', () => {

		it('exist', () => {
			expect(statusClass.isClientError).to.exist
		});

		it('is a function', () => {
			expect(statusClass.isClientError).instanceOf(Function);
		});

		it('should return true if class is 4**', () => {
			const codes = statusClassSequence(statusClass.CLIENT_ERROR);

			for (let code of codes) {
				expect(statusClass.isClientError(code)).to.be.true;
			}
		});

		it('should return false if class is not 4**', () => {
			expect(statusClass.isClientError(200)).to.be.false;
		});
	});

	describe('isServerError', () => {

		it('exist', () => {
			expect(statusClass.isServerError).to.exist
		});

		it('is a function', () => {
			expect(statusClass.isServerError).instanceOf(Function);
		});

		it('should return true if class is 5**', () => {
			const codes = statusClassSequence(statusClass.SERVER_ERROR);

			for (let code of codes) {
				expect(statusClass.isServerError(code)).to.be.true;
			}
		});

		it('should return false if class is not 5**', () => {
			expect(statusClass.isServerError(200)).to.be.false;
		});
	});

});

function* statusClassSequence(num) {
	const lengths = [3, 8, 8, 29, 11];
	const extras = [null, [226], null, [431, 444, 451, 499], [599]];

	for (let i=0; i<lengths[num-1]; i++) yield num * 100 + i;

	if (extras[num - 1]) yield* extras[num - 1];
}<|endoftext|>


<commit_before>/**
 *
 * Created by hakan on 01/04/2017.
 */
import completions from './completions';

export const init = (ace) => {

    let langTools = ace.acequire("ace/ext/language_tools");
    let flowCompleter = {
        getCompletions: function (editor, session, pos, prefix, callback) {
            callback(null, completions.apikeys);
        }
    };
    langTools.addCompleter(flowCompleter);

    ace.define('ace/mode/docker_highlight_rules', function (require, exports, module) {
        let oop = require("ace/lib/oop");
        let JsonHighlightRules = require("ace/mode/json_highlight_rules").JsonHighlightRules;

        let DockerJsonHighlightRules = function () {
            // regexp must not have capturing parentheses. Use (?:) instead.
            // regexps are ordered -> the first match is used
            this.$rules = new JsonHighlightRules().getRules();

            this.$rules.start.unshift(
                {
                    token: "comment", // single line
                    regex: "#.*$"
                },
                {
                    token: "variable",
                    regex: " *(?:GET|POST|DELETE)[ |\t](images|containers|swarm|networks|volumes|_ping|system\\/df|version|info|auth|secrets|nodes|services|tasks|plugins)(?=\\/)?"
                },
                {
                    token: "variable",
                    regex: "(filters|all|size|limit|name|rename|ps_args|term|follow|stdout|stdin|stderr|since|logs|force|ling|digest|fromImage|fromSrc|repo|tag|noprune|comment|author|pause|changes|rotateWorkerToken|rotateManagerToken|rotateManagerUnlockKey|registryAuthFrom|remote|timeout|timestamps|tail|signal|json|create|top|stats|start|stop|restart|kill)(?=\\=|\\?)?"
                }
            );
        };
        oop.inherits(DockerJsonHighlightRules, JsonHighlightRules);
        module.exports.DockerJsonHighlightRules = DockerJsonHighlightRules;
    });

    ace.define("ace/snippets/docker", ["require", "exports", "module"], function (require, exports, module) {
        // eslint-disable-next-line
        exports.snippetText = 'snippet flt\n    filters={${1:filter-name}:{${2:true}:true}}';
        exports.scope = "docker"
    });

    ace.define('ace/mode/docker', function (require, exports, module) {
        let oop = require("ace/lib/oop");
        let JSONMode = require("ace/mode/json").Mode;

        let DockerJsonHighlightRules = require("ace/mode/docker_highlight_rules").DockerJsonHighlightRules;
        let MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
        let CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
        let CStyleFoldMode = require("./folding/cstyle").FoldMode;
        //let WorkerClient = require("../worker/worker_client").WorkerClient;

        let Mode = function () {
            this.HighlightRules = DockerJsonHighlightRules;
            this.$outdent = new MatchingBraceOutdent();
            this.$behaviour = new CstyleBehaviour();
            this.foldingRules = new CStyleFoldMode();
        };

        oop.inherits(Mode, JSONMode);

        (function () {

            this.getCompletions = function (editor, session, pos, prefix) {
                // autocomplete is done by the autocomplete module.
                return [];
            };

            this.getNextLineIndent = function (state, line, tab) {
                let indent = this.$getIndent(line);

                if (state === "start") {
                    let match = line.match(/^.*[{([]\s*$/);
                    if (match) {
                        indent += tab;
                    }
                }

                return indent;
            };

            this.checkOutdent = function (state, line, input) {
                return this.$outdent.checkOutdent(line, input);
            };

            this.autoOutdent = function (state, doc, row) {
                this.$outdent.autoOutdent(doc, row);
            };

            this.createWorker = function (session) {
            };

            this.$id = "ace/mode/docker";

        }).call(Mode.prototype);
        exports.Mode = Mode;
    });
};
<commit_msg>update docker syntax highlight<commit_after>/**
 *
 * Created by hakan on 01/04/2017.
 */
import completions from './completions';

export const init = (ace) => {

    let langTools = ace.acequire("ace/ext/language_tools");
    let flowCompleter = {
        getCompletions: function (editor, session, pos, prefix, callback) {
            callback(null, completions.apikeys);
        }
    };
    langTools.addCompleter(flowCompleter);

    ace.define('ace/mode/docker_highlight_rules', function (require, exports, module) {
        let oop = require("ace/lib/oop");
        let JsonHighlightRules = require("ace/mode/json_highlight_rules").JsonHighlightRules;

        let DockerJsonHighlightRules = function () {
            // regexp must not have capturing parentheses. Use (?:) instead.
            // regexps are ordered -> the first match is used
            this.$rules = new JsonHighlightRules().getRules();

            this.$rules.start.unshift(
                {
                    token: "comment", // single line
                    regex: "#.*$"
                },
                {
                    token: "variable",
                    regex: " *(?:GET|POST|DELETE)[ |\t](images|containers|swarm|networks|volumes|configs|distribution|_ping|system\\/df|version|info|auth|secrets|nodes|services|tasks|plugins)(?=\\/)?"
                },
                {
                    token: "variable",
                    regex: "(filters|all|size|limit|name|rename|ps_args|term|follow|stdout|stdin|stderr|since|logs|force|ling|digest|fromImage|fromSrc|repo|tag|noprune|comment|author|pause|changes|rotateWorkerToken|rotateManagerToken|rotateManagerUnlockKey|registryAuthFrom|remote|timeout|timestamps|tail|signal|json|create|top|stats|start|stop|restart|kill)(?=\\=|\\?)?"
                }
            );
        };
        oop.inherits(DockerJsonHighlightRules, JsonHighlightRules);
        module.exports.DockerJsonHighlightRules = DockerJsonHighlightRules;
    });

    ace.define("ace/snippets/docker", ["require", "exports", "module"], function (require, exports, module) {
        // eslint-disable-next-line
        exports.snippetText = 'snippet flt\n    filters={${1:filter-name}:{${2:true}:true}}';
        exports.scope = "docker"
    });

    ace.define('ace/mode/docker', function (require, exports, module) {
        let oop = require("ace/lib/oop");
        let JSONMode = require("ace/mode/json").Mode;

        let DockerJsonHighlightRules = require("ace/mode/docker_highlight_rules").DockerJsonHighlightRules;
        let MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
        let CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
        let CStyleFoldMode = require("./folding/cstyle").FoldMode;
        //let WorkerClient = require("../worker/worker_client").WorkerClient;

        let Mode = function () {
            this.HighlightRules = DockerJsonHighlightRules;
            this.$outdent = new MatchingBraceOutdent();
            this.$behaviour = new CstyleBehaviour();
            this.foldingRules = new CStyleFoldMode();
        };

        oop.inherits(Mode, JSONMode);

        (function () {

            this.getCompletions = function (editor, session, pos, prefix) {
                // autocomplete is done by the autocomplete module.
                return [];
            };

            this.getNextLineIndent = function (state, line, tab) {
                let indent = this.$getIndent(line);

                if (state === "start") {
                    let match = line.match(/^.*[{([]\s*$/);
                    if (match) {
                        indent += tab;
                    }
                }

                return indent;
            };

            this.checkOutdent = function (state, line, input) {
                return this.$outdent.checkOutdent(line, input);
            };

            this.autoOutdent = function (state, doc, row) {
                this.$outdent.autoOutdent(doc, row);
            };

            this.createWorker = function (session) {
            };

            this.$id = "ace/mode/docker";

        }).call(Mode.prototype);
        exports.Mode = Mode;
    });
};
<|endoftext|>


<commit_before>const get = function get(object, property) {
    if (typeof object !== 'object') {
        throw 'Invalid config object';
    }

    const [ key, propertyPart ] = property.split('.', 2);

    if (!object[key]) {
        throw `Config key "${key}" missing`;
    }

    if (!propertyPart) {
        return object[key];
    }

    return get(object[key], propertyPart);
};

class Config {

    constructor(file) {
        this.data = require(file);
    }

    get(key) {
        return get(this.data, key);
    }

}

export default Config;
<commit_msg>better config check<commit_after>const get = function get(object, property) {
    if (typeof object !== 'object') {
        throw 'Invalid config object';
    }

    const [ key, propertyPart ] = property.split('.', 2);

    if (!object.hasOwnProperty(key)) {
        throw `Config key "${key}" missing`;
    }

    if (!propertyPart) {
        return object[key];
    }

    return get(object[key], propertyPart);
};

class Config {

    constructor(file) {
        this.data = require(file);
    }

    get(key) {
        return get(this.data, key);
    }

}

export default Config;
<|endoftext|>


<commit_before>(function (root) {

    function Piklor(sel, colors, options) {
        var self = this;
        options = options || {};
        options.open = self.getElm(options.open);
        options.openEvent = options.openEvent || "click";
        options.style = Object(options.style);
        options.style.display = options.style.display || "block";
        options.template = options.template || "

";
        self.elm = self.getElm(sel);
        self.cbs = [];
        self.colors = colors;
        self.options = options;
        self.render();
        if (options.open) {
            options.open.addEventListener(options.openEvent, function (ev) {
                self.open();
            });
        }
        self.elm.addEventListener("click", function (ev) {
            var col = ev.target.getAttribute("data-col");
            if (!col) { return; }
            self.set(col);
            self.close();
        });
        self.close();
    }

    Piklor.prototype.getElm = function (el) {
        if (typeof el === "string") {
            return document.querySelector(el);
        }
        return el;
    };

    Piklor.prototype.render = function () {
        var self = this
          , html = ""
          ;

        self.colors.forEach(function (c) {
            html += self.options.template.replace(/\{color\}/g, c);
        });

        self.elm.innerHTML = html;
    };

    Piklor.prototype.close = function () {
        this.elm.style.display = "none";
    };

    Piklor.prototype.open = function () {
        this.elm.style.display = this.options.style.display;
    };

    Piklor.prototype.colorChosen = function (cb) {
        this.cbs.push(cb);
    };

    Piklor.prototype.set = function (c) {
        var self = this;
        self.color = c;
        self.cbs.forEach(function (cb) {
            cb.call(self, c);
        });
    };

    root.Piklor = Piklor;
})(this);
<commit_msg>Updated piklor.js in the example dir<commit_after>(function(root){function Piklor(sel,colors,options){var self=this;options=options||{};options.open=self.getElm(options.open);options.openEvent=options.openEvent||"click";options.style=Object(options.style);options.style.display=options.style.display||"block";options.template=options.template||'

';self.elm=self.getElm(sel);self.cbs=[];self.colors=colors;self.options=options;self.render();if(options.open){options.open.addEventListener(options.openEvent,function(ev){self.open()})}self.elm.addEventListener("click",function(ev){var col=ev.target.getAttribute("data-col");if(!col){return}self.set(col);self.close()});self.close()}Piklor.prototype.getElm=function(el){if(typeof el==="string"){return document.querySelector(el)}return el};Piklor.prototype.render=function(){var self=this,html="";self.colors.forEach(function(c){html+=self.options.template.replace(/\{color\}/g,c)});self.elm.innerHTML=html};Piklor.prototype.close=function(){this.elm.style.display="none"};Piklor.prototype.open=function(){this.elm.style.display=this.options.style.display};Piklor.prototype.colorChosen=function(cb){this.cbs.push(cb)};Piklor.prototype.set=function(c){var self=this;self.color=c;self.cbs.forEach(function(cb){cb.call(self,c)})};root.Piklor=Piklor})(this);<|endoftext|>


<commit_before>//Function for making player objects and adding them to the game
"use strict";
var game = game || {};

game.Player = function() {
  var Player = function(id, color, x, y, name) {
    this.pos = new Vec(x, y);
    this.velocity = new Vec(0, 0);
    this.acc = new Vec(0, 0);
    this.r = .05;
    this.color = color;
    this.dash_time = 0;
    this.dash_vec = new Vec(0, 0);
    this.resting = false;
  };

  var p = Player.prototype;

  p.update = function(dt) {
    //Some logic to be moved to helper functions
    if(this.dash_time > 0){
      this.dash_time -= dt;
      this.acc.y = 0;
    } else if(!this.resting){
      this.acc.y = .5;
    }

    if(this.pos.y > .95){
      this.acc.y = 0;
      this.pos.y = .95;
      this.velocity.scale(0);
      this.resting = true;
    }

    if(this.pos.x > 16/9 -.05) {
      this.pos.x = 16/9 -.05;
      this.velocity.x = 0;
    } else if(this.pos.x < .05) {
      this.pos.x = .05;
      this.velocity.x = 0;
    }
    //Fix this

    this.move(dt);
  };

  p.move = function(dt) {
    //Update velocity and position
    this.velocity.add({x: this.acc.x * dt, y: this.acc.y * dt});
    this.pos.add({x: this.velocity.x * dt, y: this.velocity.y * dt});
  };

  p.start_dash = function(x, y){
    //Get rid of aim

    //do dash
    this.dash_vec.x = -x;
    this.dash_vec.y = -y;
    this.dash_time = .1;
    this.acc.x = 0;
    this.acc.y = 0;
    this.velocity.x = -x;
    this.velocity.y = -y;
    this.resting = false;
  };

  p.render = function() {
    game.draw.circle(this.pos.x,
                     this.pos.y,
                     this.r,
                     'black');
    this.render_aim();
  };

  p.render_aim = function() {
    if(this.aiming){

    }
  };

  return Player;
}();<commit_msg>Players can no longer jump infinitly<commit_after>//Function for making player objects and adding them to the game
"use strict";
var game = game || {};

game.Player = function() {
  var Player = function(id, color, x, y, name) {
    this.pos = new Vec(x, y);
    this.velocity = new Vec(0, 0);
    this.acc = new Vec(0, 0);
    this.r = .05;
    this.color = color;
    this.dash_time = 0;
    this.dash_vec = new Vec(0, 0);
    this.resting = false;
    this.can_dash = true;
  };

  var p = Player.prototype;

  p.update = function(dt) {
    //Some logic to be moved to helper functions
    if(this.dash_time > 0){
      this.dash_time -= dt;
      this.acc.y = 0;
    } else if(!this.resting){
      this.acc.y = .5;
    }

    if(this.pos.y > .95){
      this.acc.y = 0;
      this.pos.y = .95;
      this.velocity.scale(0);
      this.resting = true;
      this.can_dash = true;
    }

    if(this.pos.x > 16/9 -.05) {
      this.pos.x = 16/9 -.05;
      this.velocity.x = 0;
      this.can_dash = true;
    } else if(this.pos.x < .05) {
      this.pos.x = .05;
      this.velocity.x = 0;
      this.can_dash = true;
    }
    //Fix this

    this.move(dt);
  };

  p.move = function(dt) {
    //Update velocity and position
    this.velocity.add({x: this.acc.x * dt, y: this.acc.y * dt});
    this.pos.add({x: this.velocity.x * dt, y: this.velocity.y * dt});
  };

  p.start_dash = function(x, y){
    //Get rid of aim
    if(!this.can_dash) return;
    //do dash
    this.dash_vec.x = -x;
    this.dash_vec.y = -y;
    this.dash_time = .1;
    this.acc.x = 0;
    this.acc.y = 0;
    this.velocity.x = -x;
    this.velocity.y = -y;
    this.resting = false;
    this.can_dash = false;
  };

  p.render = function() {
    game.draw.circle(this.pos.x,
                     this.pos.y,
                     this.r,
                     'black');
    this.render_aim();
  };

  p.render_aim = function() {
    if(this.aiming){

    }
  };

  return Player;
}();<|endoftext|>


<commit_before>///Model for graph visualization via vis.js

(function (app, $) {
  ko.components.register('juggler-graph', {
    viewModel: function (params) {
      params = params || {
        nodes: [1, 2, 3, 4, 5],
        edges: [
          [1, 2],
          [3, 4],
          [5, 2],
          [3, 5],
          [1, 4],
          [1, 3],
          [2, 3],
          [1, 5]
        ]
      };

      var nodes = params.nodes,
        edges = params.edges,
        orgraph = params.orgraph,
        labels = params.labels,
        colors = params.colors;

      this.nodes = ko.observable(nodes);
      this.edges = ko.observable(edges);
      this.orgraph = ko.observable(orgraph);
      this.labels = ko.observable(labels);
      this.colors = ko.observable(colors);
      this.network = ko.observable();
    },
    template: {
      fromUrl: 'graph.html',
      maxCacheAge: 60000
    }
  });

  function graphBinding(element, valueAccessor, allBindings, viewModel,
    bindingContext) {

    var params = ko.utils.unwrapObservable(valueAccessor());

    function nodesToObjects(nodes, labels, colors) {
      var colorsRaw = ['aqua', 'black', 'blue', 'fuchsia', 'gray', 'green',
        'lime', 'maroon', 'navy', 'olive', 'orange', 'purple', 'red',
        'silver', 'teal', 'white', 'yellow'];

      nodes = ko.utils.unwrapObservable(nodes);
      return _.map(nodes, function (node) {

        var nodeObj = {
          id: node,
          font: '18px verdana blue'
        };

        nodeObj.label = labels && labels[node] ? (node + '(' + labels[node] + ')') : node;
        var color;
        colors && colors[node] && (color = Math.floor((colors[node] / colors.length) * 255));
        colors && colors[node] && (nodeObj.color = 'rgba(' + color + ',' + color + ',' + 0 + ', 0.7)');
        return nodeObj;
      });
    }

    function edgesToObjects(edges, orgraph) {
      edges = ko.utils.unwrapObservable(edges);
      return _.map(edges, function (edge) {
        var edgeObj = {
          from: edge[0],
          to: edge[1]
        };

        if (orgraph) {
          edgeObj.arrows = 'to';
        }

        return edgeObj;
      });
    }

    var data = {};
    data = {
      nodes: nodesToObjects(params.nodes, ko.utils.unwrapObservable(params.labels), ko.utils.unwrapObservable(params.colors)),
      edges: edgesToObjects(params.edges, params.orgraph)
    };

    var options = {
      width: element.clientWidth + 'px',
      height: element.clientHeight + 'px',
      // manipulation: true,
      // interaction: {
      //   keyboard: true
      // }
    };

    if (params.network()) {
      params.network().destroy();
    }

    params.network(new vis.Network(element, data, options));
  }

  ko.bindingHandlers.graph = {
    // init: graphBinding,
    update: graphBinding
  };

})(window.juggler = window.juggler || {}, jQuery);
<commit_msg>Laypout<commit_after>///Model for graph visualization via vis.js

(function (app, $) {
  ko.components.register('juggler-graph', {
    viewModel: function (params) {
      params = params || {
        nodes: [1, 2, 3, 4, 5],
        edges: [
          [1, 2],
          [3, 4],
          [5, 2],
          [3, 5],
          [1, 4],
          [1, 3],
          [2, 3],
          [1, 5]
        ]
      };

      var nodes = params.nodes,
        edges = params.edges,
        orgraph = params.orgraph,
        labels = params.labels,
        colors = params.colors;

      this.nodes = ko.observable(nodes);
      this.edges = ko.observable(edges);
      this.orgraph = ko.observable(orgraph);
      this.labels = ko.observable(labels);
      this.colors = ko.observable(colors);
      this.network = ko.observable();
    },
    template: {
      fromUrl: 'graph.html',
      maxCacheAge: 60000
    }
  });

  function graphBinding(element, valueAccessor, allBindings, viewModel,
    bindingContext) {

    var params = ko.utils.unwrapObservable(valueAccessor());

    function nodesToObjects(nodes, labels, colors) {
      nodes = ko.utils.unwrapObservable(nodes);
      return _.map(nodes, function (node) {

        var nodeObj = {
          id: node,
          font: '18px verdana blue'
        };

        nodeObj.label = labels && labels[node] ? (node + '(' + labels[node] + ')') : node;
        var color;
        colors && colors[node] && (color = Math.floor((colors[node] / colors.length) * 255));
        colors && colors[node] && (nodeObj.color = 'rgba(' + color + ',' + color + ',' + 0 + ', 0.7)');
        return nodeObj;
      });
    }

    function edgesToObjects(edges, orgraph) {
      edges = ko.utils.unwrapObservable(edges);
      return _.map(edges, function (edge) {
        var edgeObj = {
          from: edge[0],
          to: edge[1]
        };

        if (orgraph) {
          edgeObj.arrows = 'to';
        }

        return edgeObj;
      });
    }

    var data = {};
    data = {
      nodes: nodesToObjects(params.nodes, ko.utils.unwrapObservable(params.labels), ko.utils.unwrapObservable(params.colors)),
      edges: edgesToObjects(params.edges, params.orgraph)
    };

    var options = {
      width: element.clientWidth + 'px',
      height: element.clientHeight + 'px',
      manipulation: true,
      interaction: {
        keyboard: true,
        navigationButtons:true
      }
    };

    if (params.network()) {
      params.network().destroy();
    }

    params.network(new vis.Network(element, data, options));
  }

  ko.bindingHandlers.graph = {
    // init: graphBinding,
    update: graphBinding
  };

})(window.juggler = window.juggler || {}, jQuery);
<|endoftext|>


<commit_before>var id3 = require('id3')
  , Parser = require('../lib/parser')

// Read an MPEG file from stdin
var f = process.stdin;
f.resume();

// Create a Parser instance
var parser = new Parser();

// pipe stdin to the parser
f.pipe(parser);

// emits 'header' events on each MPEG header (start of frame)
parser.on('header', function (b, meta) {
  console.error('header', meta);
  process.stdout.write(b);
});

// emits 'frame' event for the actual data from each frame
parser.on('frame', function (b) {
  console.error('frame');
  process.stdout.write(b);
});

// emits 'id3v2' when the ID3v2 section at the beginning has been parsed
parser.on('id3v2', function (b) {
  var tags = new id3(b);
  console.error(tags.getTags());
  console.error('id3v2. %d bytes', b.length);
  process.stdout.write(b);
});

// emits 'id3v1' event when the ID3v1 section at the end has been parsed
parser.on('id3v1', function (b) {
  var tags = new id3(b);
  console.error(tags.getTags());
  console.error('id3v1. %d bytes', b.length);
  process.stdout.write(b);
});
<commit_msg>Fix Parser test.<commit_after>var id3 = require('id3')
  , lame = require('../')

// Read an MPEG file from stdin
var f = process.stdin;
f.resume();

// Create a Parser instance
var parser = lame.createParser();

// pipe stdin to the parser
f.pipe(parser);

// emits 'header' events on each MPEG header (start of frame)
parser.on('header', function (b, meta) {
  console.error('header', meta);
  process.stdout.write(b);
});

// emits 'frame' event for the actual data from each frame
parser.on('frame', function (b) {
  console.error('frame');
  process.stdout.write(b);
});

// emits 'id3v2' when the ID3v2 section at the beginning has been parsed
parser.on('id3v2', function (b) {
  var tags = new id3(b);
  console.error(tags.getTags());
  console.error('id3v2. %d bytes', b.length);
  process.stdout.write(b);
});

// emits 'id3v1' event when the ID3v1 section at the end has been parsed
parser.on('id3v1', function (b) {
  var tags = new id3(b);
  console.error(tags.getTags());
  console.error('id3v1. %d bytes', b.length);
  process.stdout.write(b);
});
<|endoftext|>


<commit_before>/*
Connectivity Module
Keeps track of the user's socket connection and displays its status
*/

var Backbone = require('backbone');
var $ = Backbone.$ = require('jquery');
var _ = require('underscore');
var Handlebars = require('handlebars');
var templates = require('../../compiled/templates.js')( Handlebars );
var io = require('socket.io-client');

var STATES = ['connected','connecting','disconnected','connect_failed','reconnected','reconnecting','reconnect_failed'];

module.exports = Backbone.View.extend({
	el: '#connectivity',
	template: templates.connectivity,
	initialize: function(){
		_( this ).bindAll( 'bindState' );
		this.socket = io.connect( 'http://localhost' );
		_( STATES ).each( this.bindState );
		this.render();
	},
	render: function(){
		this.$el.html( this.template() );
		this.$body = $('body');
	},
	updateState: function( state ){
		if( !state ) return;
		this.$body.removeClass( STATES.join(' ') ).addClass( state );
	},
	bindState: function( state ){
		var event_name = state;
		if( state === 'connected' || state === 'disconnected' || state === 'reconnected' ){
			event_name = event_name.replace( /ed$/i, '' );
		}
		this.socket.on( event_name, _.bind( this.updateState, this, state ) );
	}
});<commit_msg>use window location for connectivity module connection<commit_after>/*
Connectivity Module
Keeps track of the user's socket connection and displays its status
*/

var Backbone = require('backbone');
var $ = Backbone.$ = require('jquery');
var _ = require('underscore');
var Handlebars = require('handlebars');
var templates = require('../../compiled/templates.js')( Handlebars );
var io = require('socket.io-client');

var STATES = ['connected','connecting','disconnected','connect_failed','reconnected','reconnecting','reconnect_failed'];

module.exports = Backbone.View.extend({
	el: '#connectivity',
	template: templates.connectivity,
	initialize: function(){
		_( this ).bindAll( 'bindState' );
		this.socket = io.connect( window.location.host );
		_( STATES ).each( this.bindState );
		this.render();
	},
	render: function(){
		this.$el.html( this.template() );
		this.$body = $('body');
	},
	updateState: function( state ){
		if( !state ) return;
		this.$body.removeClass( STATES.join(' ') ).addClass( state );
	},
	bindState: function( state ){
		var event_name = state;
		if( state === 'connected' || state === 'disconnected' || state === 'reconnected' ){
			event_name = event_name.replace( /ed$/i, '' );
		}
		this.socket.on( event_name, _.bind( this.updateState, this, state ) );
	}
});<|endoftext|>


<commit_before><commit_msg>added jquery.tmpl<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 DataTorrent, Inc. ALL Rights Reserved.
 *
 * 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.
 */

/**
 * <WIDGETNAME>
 *
 * <WIDGETDESCRIPTION>
 *
*/

var _ = require('underscore');
var kt = require('knights-templar');
var BaseView = DT.lib.WidgetView;

// class definition
var <WIDGETNAME> = BaseView.extend({

    initialize: function(options) {

        BaseView.prototype.initialize.call(this, options);

        // listeners, subviews, etc.

    },

    html: function() {

        var html = '';

        // generate markup here

        return html;
    },

    assignments: {

        // assign subviews here

    },

    template: kt.make(__dirname+'/<WIDGETNAME>.html','_')

});

exports = module.exports = <WIDGETNAME>;<commit_msg>updated widget template<commit_after>/*
 * Copyright (c) 2013 DataTorrent, Inc. ALL Rights Reserved.
 *
 * 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.
 */

var _ = require('underscore');
var kt = require('knights-templar');
var BaseView = DT.lib.WidgetView;

/**
 * <WIDGETNAME>
 *
 * <WIDGETDESCRIPTION>
 *
*/
var <WIDGETNAME> = BaseView.extend({

    initialize: function(options) {

        BaseView.prototype.initialize.call(this, options);

        // listeners, subviews, etc.

    },

    html: function() {

        var html = '';

        // generate markup here

        return html;
    },

    assignments: {

        // assign subviews here

    },

    template: kt.make(__dirname+'/<WIDGETNAME>.html','_')

});

exports = module.exports = <WIDGETNAME>;<|endoftext|>


<commit_before>

var InputElement = Backbone.Model.extend({
  initialize:function() {
    _.bindAll(this, 'markDirty');
    this.dirty = false;
    this.ui_options = {'element' : $('#input_element_'+this.get('id'))};
    this.bind('change:user_value', this.markDirty);
    this.bind('change:user_value', this.logUpdate);
  },

  set_min_value : function(result) {
    var factor = this.get('factor');
    this.set({'min_value' : result});
  },
  set_max_value : function(result) {
    var factor = this.get('factor');
    this.set({'max_value' : result});
  },
  set_label : function(label) {
    if(!_.isString(label)) return;
    this.set({'label' : label});
  },
  set_start_value : function(result) {
    this.set({'start_value' : result});
  },

  init_legacy_controller : function() {
    if (this.already_init != true) {
      App.input_elements.addInputElement(this);
      this.already_init = true;
    }
  },

  logUpdate : function() {
    App.etm_debug('Moved slider: #' + this.get('id') + ' - ' + this.get('key'));
    Tracker.track({
      slider: this.get('translated_name'),
      new_value: this.get('user_value')
    });
  },

  /**
   * Returns if this is dirty, meaning a attribute has changed.
   */
  isDirty:function() {
    if (this.get('fixed') == true) {
      return false;
    } else {
      return this.dirty;
    }
  },

  markDirty:function() {
    this.dirty = true;
  },

  setDirty:function(dirty) {
    this.dirty = dirty;
  }
});

var InputElementList = Backbone.Collection.extend({
  model : InputElement,

  initialize : function() {
    this.inputElements     = {};
    this.inputElementViews = {};

    this.shareGroups = {};
    this.balancers   = {};

    this.openInputElementInfoBox;
  },

  init_legacy_controller : function() {
    this.each(function(input_element) {
      input_element.init_legacy_controller();
    });
  },

  load_user_values : function() {
    _.bindAll(this, 'initialize_user_values');
    $.ajax({
      url: App.scenario.user_values_url(),
      success : this.initialize_user_values,
      timeout: 15000
    });
  },

  initialize_user_values : function(user_value_hash) {
    this.each(function(input_element) {
      var values = user_value_hash['' + input_element.get('input_id')];
      if (!values) {
        console.warn("Missing slider information! " + input_element.get('key'));
        return false;
      }
      input_element.set_min_value(values.min_value);
      input_element.set_max_value(values.max_value);
      input_element.set_start_value(values.start_value);
      input_element.set_label(values.full_label);

      // Disable if ET-Model *or* ET-Engine disable the input.
      input_element.set({
        disabled: input_element.get('disabled') || values.disabled
      });

      var user_value = values.user_value;
      var default_value = (_.isUndefined(user_value) || _.isNaN(user_value) || _.isNull(user_value)) ? values.start_value : user_value;
      input_element.set({user_value : default_value}, {silent : true});

      input_element.init_legacy_controller();
    });
    // UGLY: merit_order is enabled with the settings checkbox, that will trigger an API
    // request setting an input with id of 900. This will update the js settings object,
    // that will update the Current.setting ruby object.
    try {
      var merit_order_enabled = (user_value_hash[900].user_value == 1);
      App.settings.set({'use_merit_order' : merit_order_enabled});
    } catch(e) {
      console.log("Missing Merit order input");
    }
  },

  /**
   * Get the string which contains the update values for all dirty input elements.
   */
  api_update_params:function() {
    return _.map(this.dirty(), function(el) {
      return ("input["+el.get('input_id')+"]=" + el.get("user_value"));
    }).join("&");
  },

  dirty : function() {
    return this.select(function(el) { return el.isDirty(); });
  },

  reset_dirty : function() {
    _.each(this.dirty(), function(el) { el.setDirty(false); });
  },

  /**
   * Add a constraint to the constraints.
   * @param options - must contain an element item
   */
  addInputElement:function(inputElement, options) {
    var options = inputElement.ui_options;
    this.inputElements[inputElement.id] = inputElement;
    var inputElementView = new InputElementView({model : inputElement, el : options.element});

    this.inputElementViews[inputElement.id] = inputElementView;
    inputElementView.bind("change", $.proxy(this.handleUpdate, this));

    return true;
  },

  /**
   * Initialize a share group for an input element if it has one.
   */
  initShareGroup:function(inputElement) {
    var inputElementView = this.inputElementViews[inputElement.id];
    var shareGroupKey = inputElement.get("share_group");
    if(shareGroupKey && shareGroupKey.length) {
      var shareGroup = this.getOrCreateShareGroup(shareGroupKey);
      shareGroup.bind("slider_updated",$.proxy(function(){ inputElement.markDirty();},this)); //set all sliders from same sharegroup to dirty when one is touched
      shareGroup.addSlider(inputElementView.sliderView.sliderVO);

      var balancer = this.getOrCreateBalancer(shareGroupKey);
      balancer.add(inputElementView);
    }
  },

  /**
   * Finds or creates the share group.
   */
  getOrCreateShareGroup:function(shareGroup) {

    if(!this.shareGroups[shareGroup])
      this.shareGroups[shareGroup] = new SliderGroup({'total_value':100}); // add group if not created yet

    return this.shareGroups[shareGroup];
  },

  getOrCreateBalancer: function(name) {
    if (! this.balancers.hasOwnProperty(name)) {
      this.balancers[name] = new InputElementGroup({ max: 100 });
    }

    return this.balancers[name];
  },

  /**
   * Does a update request to update the values.
   */
  handleUpdate:function() {
    this.trigger("change");
  }
});
window.input_elements = new InputElementList();

<commit_msg>sliders: log slider id on failure<commit_after>

var InputElement = Backbone.Model.extend({
  initialize:function() {
    _.bindAll(this, 'markDirty');
    this.dirty = false;
    this.ui_options = {'element' : $('#input_element_'+this.get('id'))};
    this.bind('change:user_value', this.markDirty);
    this.bind('change:user_value', this.logUpdate);
  },

  set_min_value : function(result) {
    var factor = this.get('factor');
    this.set({'min_value' : result});
  },
  set_max_value : function(result) {
    var factor = this.get('factor');
    this.set({'max_value' : result});
  },
  set_label : function(label) {
    if(!_.isString(label)) return;
    this.set({'label' : label});
  },
  set_start_value : function(result) {
    this.set({'start_value' : result});
  },

  init_legacy_controller : function() {
    if (this.already_init != true) {
      App.input_elements.addInputElement(this);
      this.already_init = true;
    }
  },

  logUpdate : function() {
    App.etm_debug('Moved slider: #' + this.get('id') + ' - ' + this.get('key'));
    Tracker.track({
      slider: this.get('translated_name'),
      new_value: this.get('user_value')
    });
  },

  /**
   * Returns if this is dirty, meaning a attribute has changed.
   */
  isDirty:function() {
    if (this.get('fixed') == true) {
      return false;
    } else {
      return this.dirty;
    }
  },

  markDirty:function() {
    this.dirty = true;
  },

  setDirty:function(dirty) {
    this.dirty = dirty;
  }
});

var InputElementList = Backbone.Collection.extend({
  model : InputElement,

  initialize : function() {
    this.inputElements     = {};
    this.inputElementViews = {};

    this.shareGroups = {};
    this.balancers   = {};

    this.openInputElementInfoBox;
  },

  init_legacy_controller : function() {
    this.each(function(input_element) {
      input_element.init_legacy_controller();
    });
  },

  load_user_values : function() {
    _.bindAll(this, 'initialize_user_values');
    $.ajax({
      url: App.scenario.user_values_url(),
      success : this.initialize_user_values,
      timeout: 15000
    });
  },

  initialize_user_values : function(user_value_hash) {
    this.each(function(input_element) {
      var values = user_value_hash['' + input_element.get('input_id')];
      if (!values) {
        console.warn("Missing slider information! " + input_element.get('key') +
          " #" + input_element.get('id'));
        return false;
      }
      input_element.set_min_value(values.min_value);
      input_element.set_max_value(values.max_value);
      input_element.set_start_value(values.start_value);
      input_element.set_label(values.full_label);

      // Disable if ET-Model *or* ET-Engine disable the input.
      input_element.set({
        disabled: input_element.get('disabled') || values.disabled
      });

      var user_value = values.user_value;
      var default_value = (_.isUndefined(user_value) || _.isNaN(user_value) || _.isNull(user_value)) ? values.start_value : user_value;
      input_element.set({user_value : default_value}, {silent : true});

      input_element.init_legacy_controller();
    });
    // UGLY: merit_order is enabled with the settings checkbox, that will trigger an API
    // request setting an input with id of 900. This will update the js settings object,
    // that will update the Current.setting ruby object.
    try {
      var merit_order_enabled = (user_value_hash[900].user_value == 1);
      App.settings.set({'use_merit_order' : merit_order_enabled});
    } catch(e) {
      console.log("Missing Merit order input");
    }
  },

  /**
   * Get the string which contains the update values for all dirty input elements.
   */
  api_update_params:function() {
    return _.map(this.dirty(), function(el) {
      return ("input["+el.get('input_id')+"]=" + el.get("user_value"));
    }).join("&");
  },

  dirty : function() {
    return this.select(function(el) { return el.isDirty(); });
  },

  reset_dirty : function() {
    _.each(this.dirty(), function(el) { el.setDirty(false); });
  },

  /**
   * Add a constraint to the constraints.
   * @param options - must contain an element item
   */
  addInputElement:function(inputElement, options) {
    var options = inputElement.ui_options;
    this.inputElements[inputElement.id] = inputElement;
    var inputElementView = new InputElementView({model : inputElement, el : options.element});

    this.inputElementViews[inputElement.id] = inputElementView;
    inputElementView.bind("change", $.proxy(this.handleUpdate, this));

    return true;
  },

  /**
   * Initialize a share group for an input element if it has one.
   */
  initShareGroup:function(inputElement) {
    var inputElementView = this.inputElementViews[inputElement.id];
    var shareGroupKey = inputElement.get("share_group");
    if(shareGroupKey && shareGroupKey.length) {
      var shareGroup = this.getOrCreateShareGroup(shareGroupKey);
      shareGroup.bind("slider_updated",$.proxy(function(){ inputElement.markDirty();},this)); //set all sliders from same sharegroup to dirty when one is touched
      shareGroup.addSlider(inputElementView.sliderView.sliderVO);

      var balancer = this.getOrCreateBalancer(shareGroupKey);
      balancer.add(inputElementView);
    }
  },

  /**
   * Finds or creates the share group.
   */
  getOrCreateShareGroup:function(shareGroup) {

    if(!this.shareGroups[shareGroup])
      this.shareGroups[shareGroup] = new SliderGroup({'total_value':100}); // add group if not created yet

    return this.shareGroups[shareGroup];
  },

  getOrCreateBalancer: function(name) {
    if (! this.balancers.hasOwnProperty(name)) {
      this.balancers[name] = new InputElementGroup({ max: 100 });
    }

    return this.balancers[name];
  },

  /**
   * Does a update request to update the values.
   */
  handleUpdate:function() {
    this.trigger("change");
  }
});
window.input_elements = new InputElementList();

<|endoftext|>


<commit_before>module.exports = {

	//---------------------------------------------------------------------
	// Action Name
	//
	// This is the name of the action displayed in the editor.
	//---------------------------------------------------------------------

	name: "Weather",

	//---------------------------------------------------------------------
	// Action Section
	//
	// This is the section the action will fall into.
	//---------------------------------------------------------------------

	section: "Other Stuff",

	//---------------------------------------------------------------------
	// Action Subtitle
	//
	// This function generates the subtitle displayed next to the name.
	//---------------------------------------------------------------------

	subtitle: function (data) {
		const info = ['Temperature', 'Weather Text', 'Date', 'City', 'Country', 'Region', 'Wind Speed', 'Wind Chill', 'Wind Direction', 'Humidity', 'Pressure', 'Atmosphere Visibility', 'Sunrise Time', 'Sunset Time'];
		return `${info[parseInt(data.info)]}`;
	},

	//---------------------------------------------------------------------
	// DBM Mods Manager Variables (Optional but nice to have!)
	//
	// These are variables that DBM Mods Manager uses to show information
	// about the mods for people to see in the list.
	//---------------------------------------------------------------------

	// Who made the mod (If not set, defaults to "DBM Mods")
	author: "EGGSY",

	// The version of the mod (Defaults to 1.0.0)
	version: "1.8.7", //Added in 1.8.7

	// A short description to show on the mod line for this mod (Must be on a single line)
	short_description: "Stores weather informations with node module.",

	// If it depends on any other mods by name, ex: WrexMODS if the mod uses something from WrexMods

	//---------------------------------------------------------------------

	//---------------------------------------------------------------------
	// Action Storage Function
	//
	// Stores the relevant variable info for the editor.
	//---------------------------------------------------------------------

	variableStorage: function (data, varType) {
		const type = parseInt(data.storage);
		if (type !== varType) return;
		const info = parseInt(data.info);
		let dataType = 'Unknown Weather Type';
		switch (info) {
			case 0:
				dataType = "Temperature";
				break;
			case 1:
				dataType = "Weather - Text";
				break;
			case 2:
				dataType = "Date";
				break;
			case 3:
				dataType = "Weather - City";
				break;
			case 4:
				dataType = "Weather - Country";
				break;
			case 5:
				dataType = "Weather - Region";
				break;
			case 6:
				dataType = "Wind Speed";
				break;
			case 7:
				dataType = "Wind Chill";
				break;
			case 8:
				dataType = "Wind Direction";
				break;
			case 9:
				dataType = "Atmosphere Humidty";
				break;
			case 10:
				dataType = "Atmosphere Pressure";
				break;
			case 11:
				dataType = "Atmosphere Visibility";
				break;
			case 12:
				dataType = "Weather - Sunrise";
				break;
			case 13:
				dataType = "Weather - Sunset";
				break;
		}
		return ([data.varName, dataType]);
	},

	//---------------------------------------------------------------------
	// Action Fields
	//
	// These are the fields for the action. These fields are customized
	// by creating elements with corresponding IDs in the HTML. These
	// are also the names of the fields stored in the action's JSON data.
	//---------------------------------------------------------------------

	fields: ["city", "degreeType", "info", "storage", "varName"],

	//---------------------------------------------------------------------
	// Command HTML
	//
	// This function returns a string containing the HTML used for
	// editting actions.
	//
	// The "isEvent" parameter will be true if this action is being used
	// for an event. Due to their nature, events lack certain information,
	// so edit the HTML to reflect this.
	//
	// The "data" parameter stores constants for select elements to use.
	// Each is an array: index 0 for commands, index 1 for events.
	// The names are: sendTargets, members, roles, channels,
	//                messages, servers, variables
	//---------------------------------------------------------------------

	html: function (isEvent, data) {
		return `

				Mod Info:

				Created by EGGSY!

		Source City:

		<input id="city" class="round" type="text">

	 	Degree Type:

	 	<select id="degreeType" class="round">
			<option value="F">F</option>
			<option value="C">C</option>
		</select>

		Source Info:

		<select id="info" class="round">
			<option value="0">Temperature</option>
			<option value="1">Weather Text</option>
			<option value="2">Date</option>
			<option value="3">City</option>
			<option value="4">Country</option>
			<option value="5">Region</option>
			<option value="6">Wind Speed</option>
			<option value="7">Wind Chill</option>
			<option value="8">Wind Direction</option>
			<option value="9">Humidity</option>
			<option value="10">Pressure</option>
			<option value="11">Atmosphere Visibility</option>
			<option value="12">Sunrise Time</option>
			<option value="13">Sunset Time</option>
		</select>

			Store In:

			<select id="storage" class="round" onchange="glob.variableChange(this, 'varNameContainer')">
				${data.variables[0]}
			</select>

			Variable Name:

			<input id="varName" class="round" type="text">

`
	},

	//---------------------------------------------------------------------
	// Action Editor Init Code
	//
	// When the HTML is first applied to the action editor, this code
	// is also run. This helps add modifications or setup reactionary
	// functions for the DOM elements.
	//---------------------------------------------------------------------

	init: function () {
		const { glob, document } = this;
		glob.variableChange(document.getElementById('storage'), 'varNameContainer');
	},

	//---------------------------------------------------------------------
	// Action Bot Function
	//
	// This is the function for the action within the Bot's Action class.
	// Keep in mind event calls won't have access to the "msg" parameter,
	// so be sure to provide checks for variable existance.
	//---------------------------------------------------------------------

	action: function (cache) {
		const data = cache.actions[cache.index];
		const info = parseInt(data.info);
		const city = this.evalMessage(data.city, cache);
		const degreeType2 = this.evalMessage(data.degreeType, cache);

		// Check if everything is ok:
		if (!city) return console.log("Please specify a city to get weather informations.");

		// Main code:
		const WrexMODS = this.getWrexMods(); // as always.
		const weather = WrexMODS.require('yahoo-weather'); // WrexMODS'll automatically try to install the module if you run it with CMD/PowerShell.

		weather(`${city}`, `${degreeType2}`).then(response => {
			switch (info) {
				case 0:
					result = response.item.condition.temp;
					break;
				case 1:
					result = response.item.condition.text;
					break;
				case 2:
					result = response.item.condition.date;
					break;
				case 3:
					result = response.location.city;
					break;
				case 4:
					result = response.location.country;
					break;
				case 5:
					result = response.location.region;
					break;
				case 6:
					result = response.wind.speed;
					break;
				case 7:
					result = response.wind.chill;
					break;
				case 8:
					result = response.wind.direction;
					break;
				case 9:
					result = response.atmosphere.humidity;
					break;
				case 10:
					result = response.atmosphere.pressure;
					break;
				case 11:
					result = response.atmosphere.visibility;
					break;
				case 12:
					result = response.astronomy.sunrise;
					break;
				case 13:
					result = response.astronomy.sunset;
					break;
				default:
					break;
			}
			if (result !== undefined) {
				const storage = parseInt(data.storage);
				const varName2 = this.evalMessage(data.varName, cache);
				this.storeValue(result, storage, varName2, cache);
			}
			this.callNextAction(cache);
		}).catch(err => {
			console.log("ERROR:", err)
			this.callNextAction(cache)
		});
	},

	//---------------------------------------------------------------------
	// Action Bot Mod
	//
	// Upon initialization of the bot, this code is run. Using the bot's
	// DBM namespace, one can add/modify existing functions if necessary.
	// In order to reduce conflictions between mods, be sure to alias
	// functions you wish to overwrite.
	//---------------------------------------------------------------------

	mod: function (DBM) { }

}; // End of module
<commit_msg>Fixed Typo<commit_after>module.exports = {

	//---------------------------------------------------------------------
	// Action Name
	//
	// This is the name of the action displayed in the editor.
	//---------------------------------------------------------------------

	name: "Weather",

	//---------------------------------------------------------------------
	// Action Section
	//
	// This is the section the action will fall into.
	//---------------------------------------------------------------------

	section: "Other Stuff",

	//---------------------------------------------------------------------
	// Action Subtitle
	//
	// This function generates the subtitle displayed next to the name.
	//---------------------------------------------------------------------

	subtitle: function (data) {
		const info = ['Temperature', 'Weather Text', 'Date', 'City', 'Country', 'Region', 'Wind Speed', 'Wind Chill', 'Wind Direction', 'Humidity', 'Pressure', 'Atmosphere Visibility', 'Sunrise Time', 'Sunset Time'];
		return `${info[parseInt(data.info)]}`;
	},

	//---------------------------------------------------------------------
	// DBM Mods Manager Variables (Optional but nice to have!)
	//
	// These are variables that DBM Mods Manager uses to show information
	// about the mods for people to see in the list.
	//---------------------------------------------------------------------

	// Who made the mod (If not set, defaults to "DBM Mods")
	author: "EGGSY",

	// The version of the mod (Defaults to 1.0.0)
	version: "1.8.7", //Added in 1.8.7

	// A short description to show on the mod line for this mod (Must be on a single line)
	short_description: "Stores weather informations with node module.",

	// If it depends on any other mods by name, ex: WrexMODS if the mod uses something from WrexMods

	//---------------------------------------------------------------------

	//---------------------------------------------------------------------
	// Action Storage Function
	//
	// Stores the relevant variable info for the editor.
	//---------------------------------------------------------------------

	variableStorage: function (data, varType) {
		const type = parseInt(data.storage);
		if (type !== varType) return;
		const info = parseInt(data.info);
		let dataType = 'Unknown Weather Type';
		switch (info) {
			case 0:
				dataType = "Temperature";
				break;
			case 1:
				dataType = "Weather - Text";
				break;
			case 2:
				dataType = "Date";
				break;
			case 3:
				dataType = "Weather - City";
				break;
			case 4:
				dataType = "Weather - Country";
				break;
			case 5:
				dataType = "Weather - Region";
				break;
			case 6:
				dataType = "Wind Speed";
				break;
			case 7:
				dataType = "Wind Chill";
				break;
			case 8:
				dataType = "Wind Direction";
				break;
			case 9:
				dataType = "Atmosphere Humidity";
				break;
			case 10:
				dataType = "Atmosphere Pressure";
				break;
			case 11:
				dataType = "Atmosphere Visibility";
				break;
			case 12:
				dataType = "Weather - Sunrise";
				break;
			case 13:
				dataType = "Weather - Sunset";
				break;
		}
		return ([data.varName, dataType]);
	},

	//---------------------------------------------------------------------
	// Action Fields
	//
	// These are the fields for the action. These fields are customized
	// by creating elements with corresponding IDs in the HTML. These
	// are also the names of the fields stored in the action's JSON data.
	//---------------------------------------------------------------------

	fields: ["city", "degreeType", "info", "storage", "varName"],

	//---------------------------------------------------------------------
	// Command HTML
	//
	// This function returns a string containing the HTML used for
	// editting actions.
	//
	// The "isEvent" parameter will be true if this action is being used
	// for an event. Due to their nature, events lack certain information,
	// so edit the HTML to reflect this.
	//
	// The "data" parameter stores constants for select elements to use.
	// Each is an array: index 0 for commands, index 1 for events.
	// The names are: sendTargets, members, roles, channels,
	//                messages, servers, variables
	//---------------------------------------------------------------------

	html: function (isEvent, data) {
		return `

				Mod Info:

				Created by EGGSY!

		Source City:

		<input id="city" class="round" type="text">

	 	Degree Type:

	 	<select id="degreeType" class="round">
			<option value="F">F</option>
			<option value="C">C</option>
		</select>

		Source Info:

		<select id="info" class="round">
			<option value="0">Temperature</option>
			<option value="1">Weather Text</option>
			<option value="2">Date</option>
			<option value="3">City</option>
			<option value="4">Country</option>
			<option value="5">Region</option>
			<option value="6">Wind Speed</option>
			<option value="7">Wind Chill</option>
			<option value="8">Wind Direction</option>
			<option value="9">Humidity</option>
			<option value="10">Pressure</option>
			<option value="11">Atmosphere Visibility</option>
			<option value="12">Sunrise Time</option>
			<option value="13">Sunset Time</option>
		</select>

			Store In:

			<select id="storage" class="round" onchange="glob.variableChange(this, 'varNameContainer')">
				${data.variables[0]}
			</select>

			Variable Name:

			<input id="varName" class="round" type="text">

`
	},

	//---------------------------------------------------------------------
	// Action Editor Init Code
	//
	// When the HTML is first applied to the action editor, this code
	// is also run. This helps add modifications or setup reactionary
	// functions for the DOM elements.
	//---------------------------------------------------------------------

	init: function () {
		const { glob, document } = this;
		glob.variableChange(document.getElementById('storage'), 'varNameContainer');
	},

	//---------------------------------------------------------------------
	// Action Bot Function
	//
	// This is the function for the action within the Bot's Action class.
	// Keep in mind event calls won't have access to the "msg" parameter,
	// so be sure to provide checks for variable existance.
	//---------------------------------------------------------------------

	action: function (cache) {
		const data = cache.actions[cache.index];
		const info = parseInt(data.info);
		const city = this.evalMessage(data.city, cache);
		const degreeType2 = this.evalMessage(data.degreeType, cache);

		// Check if everything is ok:
		if (!city) return console.log("Please specify a city to get weather informations.");

		// Main code:
		const WrexMODS = this.getWrexMods(); // as always.
		const weather = WrexMODS.require('yahoo-weather'); // WrexMODS'll automatically try to install the module if you run it with CMD/PowerShell.

		weather(`${city}`, `${degreeType2}`).then(response => {
			switch (info) {
				case 0:
					result = response.item.condition.temp;
					break;
				case 1:
					result = response.item.condition.text;
					break;
				case 2:
					result = response.item.condition.date;
					break;
				case 3:
					result = response.location.city;
					break;
				case 4:
					result = response.location.country;
					break;
				case 5:
					result = response.location.region;
					break;
				case 6:
					result = response.wind.speed;
					break;
				case 7:
					result = response.wind.chill;
					break;
				case 8:
					result = response.wind.direction;
					break;
				case 9:
					result = response.atmosphere.humidity;
					break;
				case 10:
					result = response.atmosphere.pressure;
					break;
				case 11:
					result = response.atmosphere.visibility;
					break;
				case 12:
					result = response.astronomy.sunrise;
					break;
				case 13:
					result = response.astronomy.sunset;
					break;
				default:
					break;
			}
			if (result !== undefined) {
				const storage = parseInt(data.storage);
				const varName2 = this.evalMessage(data.varName, cache);
				this.storeValue(result, storage, varName2, cache);
			}
			this.callNextAction(cache);
		}).catch(err => {
			console.log("ERROR:", err)
			this.callNextAction(cache)
		});
	},

	//---------------------------------------------------------------------
	// Action Bot Mod
	//
	// Upon initialization of the bot, this code is run. Using the bot's
	// DBM namespace, one can add/modify existing functions if necessary.
	// In order to reduce conflictions between mods, be sure to alias
	// functions you wish to overwrite.
	//---------------------------------------------------------------------

	mod: function (DBM) { }

}; // End of module
<|endoftext|>


<commit_before>import React from 'react';
import { shallow, mount } from 'enzyme';
import TextInput from '../src/TextInput';
// import mocker from './helper/new-mocker';

describe('<TextInput />', () => {
  let wrapper;

  // const textareaAutoResizeMock = jest.fn();
  // const restore = mocker('textareaAutoResize', textareaAutoResizeMock);

  // afterAll(() => {
  // restore();
  // });

  test('handles layout classes', () => {
    wrapper = shallow(<TextInput s={4} m={6} />);

    expect(wrapper.hasClass('input-field')).toBeTruthy();
    expect(wrapper.hasClass('col')).toBeTruthy();
    expect(wrapper.hasClass('s4')).toBeTruthy();
    expect(wrapper.hasClass('m6')).toBeTruthy();
  });

  test('handles removing layout classes', () => {
    wrapper = shallow(<TextInput s={4} m={6} noLayout />);

    expect(wrapper.hasClass('input-field')).toBeTruthy();
    expect(wrapper.hasClass('col')).toBeFalsy();
    expect(wrapper.hasClass('s4')).toBeFalsy();
    expect(wrapper.hasClass('m6')).toBeFalsy();
  });

  test('renders placeholder', () => {
    wrapper = shallow(<TextInput placeholder="Name" />);
    expect(wrapper.find('input').prop('placeholder')).toEqual('Name');
  });

  test('renders label', () => {
    wrapper = shallow(<TextInput label="Name" />);
    expect(wrapper.find('label').text()).toEqual('Name');
  });

  test('handles validate', () => {
    wrapper = shallow(<TextInput validate />);
    expect(wrapper.find('input.validate')).toHaveLength(1);
  });

  test('handles inputClassName', () => {
    wrapper = shallow(<TextInput validate inputClassName={'hello red'} />);
    expect(wrapper.find('input.hello.red.validate')).toHaveLength(1);
  });

  test('handles other types', () => {
    wrapper = shallow(<TextInput type="password" />);
    expect(wrapper.find('input').prop('type')).toEqual('password');
  });

  test('calls onChange if provided', () => {
    wrapper = shallow(<TextInput />);
    wrapper.setState({ value: 'hello' });
    expect(wrapper.find('input').prop('value')).toEqual('hello');
  });

  test('with icon', () => {
    wrapper = shallow(<TextInput icon="cloud" />);
    expect(wrapper.find('i.material-icons.prefix')).toHaveLength(1);
  });
});
<commit_msg>lint TextInput spec<commit_after>import React from 'react';
import { shallow } from 'enzyme';
import TextInput from '../src/TextInput';

describe('<TextInput />', () => {
  let wrapper;

  test('handles layout classes', () => {
    wrapper = shallow(<TextInput s={4} m={6} />);

    expect(wrapper.hasClass('input-field')).toBeTruthy();
    expect(wrapper.hasClass('col')).toBeTruthy();
    expect(wrapper.hasClass('s4')).toBeTruthy();
    expect(wrapper.hasClass('m6')).toBeTruthy();
  });

  test('handles removing layout classes', () => {
    wrapper = shallow(<TextInput s={4} m={6} noLayout />);

    expect(wrapper.hasClass('input-field')).toBeTruthy();
    expect(wrapper.hasClass('col')).toBeFalsy();
    expect(wrapper.hasClass('s4')).toBeFalsy();
    expect(wrapper.hasClass('m6')).toBeFalsy();
  });

  test('renders placeholder', () => {
    wrapper = shallow(<TextInput placeholder="Name" />);
    expect(wrapper.find('input').prop('placeholder')).toEqual('Name');
  });

  test('renders label', () => {
    wrapper = shallow(<TextInput label="Name" />);
    expect(wrapper.find('label').text()).toEqual('Name');
  });

  test('handles validate', () => {
    wrapper = shallow(<TextInput validate />);
    expect(wrapper.find('input.validate')).toHaveLength(1);
  });

  test('handles inputClassName', () => {
    wrapper = shallow(<TextInput validate inputClassName={'hello red'} />);
    expect(wrapper.find('input.hello.red.validate')).toHaveLength(1);
  });

  test('handles other types', () => {
    wrapper = shallow(<TextInput type="password" />);
    expect(wrapper.find('input').prop('type')).toEqual('password');
  });

  test('calls onChange if provided', () => {
    wrapper = shallow(<TextInput />);
    wrapper.setState({ value: 'hello' });
    expect(wrapper.find('input').prop('value')).toEqual('hello');
  });

  test('with icon', () => {
    wrapper = shallow(<TextInput icon="cloud" />);
    expect(wrapper.find('i.material-icons.prefix')).toHaveLength(1);
  });
});
<|endoftext|>


<commit_before>/**
 * Filename: Login.js
 * Purpose: This file creates the login page.
 * Created By: John Nolcox
 * Last Update: 6:01PM 15FEB17 by John Nolcox
**/

import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  Image,
  Text,
  KeyboardAvoidingView
} from 'react-native';

import LoginForm from './loginForm';

export default class login extends Component {
    render() {
        return (
          // The following line of code allows everything on screen to move up for the keyboard to appear
          // instead of the keyboard covering whatever was there.
            <KeyboardAvoidingView behavior="padding" style={styles.container}>
              <View style={styles.logoContainer}>
              <Image
                style={styles.logo}
                source={require('../../images/wallet.png')}
                />

                <Text style={styles.logoTitle}>An app made for budgeting with rewards!</Text>
              </View>
              <View style={styles.formContainer}>
                <LoginForm />
              </View>
            </KeyboardAvoidingView>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#3498db'
    },
    logoContainer: {
      alignItems: 'center',
      flexGrow: 1,
      justifyContent: 'center'
    },
    logo: {
      width: 100,
      height: 100
    },
    logoTitle: {
      color: '#FFF',
      marginTop: 10,
      width: 160,
      textAlign: 'center',
      opacity: 0.9
    }
});
<commit_msg>add title component<commit_after>/**
 * Filename: Login.js
 * Purpose: This file creates the login page.
 * Created By: John Nolcox
 * Last Update: 6:01PM 15FEB17 by John Nolcox
**/

import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  Image,
  Text,
  KeyboardAvoidingView
} from 'react-native';

import LoginForm from './loginForm';

export default class login extends Component {
    render() {
        return (
          // The following line of code allows everything on screen to move up for the keyboard to appear
          // instead of the keyboard covering whatever was there.
            <KeyboardAvoidingView behavior="padding" style={styles.container}>
              <Text style={styles.appTitle}>Hoola</Text>
              <View style={styles.logoContainer}>
                <Image
                  style={styles.logo}
                  source={require('../../images/wallet.png')}
                />
                <Text style={styles.logoTitle}>An app made for budgeting with rewards!</Text>
              </View>
              <View style={styles.formContainer}>
                <LoginForm />
              </View>
            </KeyboardAvoidingView>
        );
    }
}

const styles = StyleSheet.create({
    container: {
      flex: 1,
      backgroundColor: '#3498db'
    },
    logoContainer: {
      alignItems: 'center',
      flexGrow: 1,
      justifyContent: 'center'
    },
    logo: {
      width: 100,
      height: 100
    },
    logoTitle: {
      color: '#FFF',
      marginTop: 10,
      width: 160,
      textAlign: 'center',
      opacity: 0.9
    },
    appTitle: {
      color: "#2BE189",
      marginTop: 200,
      fontFamily: 'Marker Felt',
      fontSize: 80,
      textAlign: 'center',
    }
});
<|endoftext|>


<commit_before>const uuidGenerator = Components.classes["@mozilla.org/uuid-generator;1"]
                      .getService(Components.interfaces.nsIUUIDGenerator);

function makeUuid() {
  var uuid = uuidGenerator.generateUUID();
  uuid = uuid.toString();
  // Strips off {}:
  return uuid.substr(1, uuid.length-2);
}

function getDocument() {
  return content.document;
}

let tabUuid = makeUuid();

let MIN_IMAGE_WIDTH = 200;
let MIN_IMAGE_HEIGHT = 100;

function getData() {
  let pageId = content._hashroomId;
  if (! pageId) {
    pageId = content._hashroomId = makeUuid();
  }
  let props = {
    title: content.document.title,
    url: content.location.href,
    tabId: tabUuid,
    pageId: content._hashroomId,
    time: Date.now(),
    images: []
  };
  let els = content.document.getElementsByTagName("img");
  let bestWidth = 0;
  for (let i=0; i<els.length; i++) {
    let el = els[i];
    if (el.width < MIN_IMAGE_WIDTH || el.height < MIN_IMAGE_HEIGHT) {
      continue;
    }
    props.images.push(packImage(el));
    if (el.width > bestWidth) {
      bestWidth = el.width;
      props.image = packImage(el);
    }
  }
  props.openGraph = getOpenGraph();
  props.twitterCard = getTwitterCard();
  return props;
}

function packImage(element) {
  return {
    src: element.src,
    title: element.getAttribute("title"),
    alt: element.getAttribute("alt"),
    height: element.height,
    width: element.width
  };
}

function getOpenGraph() {
  let openGraph = {};
  // If you update this, also update _OPENGRAPH_PROPERTIES in shot.js:
  let openGraphProperties = "title type url image audio description determiner locale site_name video image:secure_url image:type image:width image:height video:secure_url video:type video:width image:height audio:secure_url audio:type article:published_time article:modified_tim article:expiration_time article:author article:section article:tag book:author book:isbn book:release_date book:tag profile:first_name profile:last_name profile:username profile:gender".split(/\s+/g);
  for (let i=0; i<openGraphProperties.length; i++) {
    let prop = openGraphProperties[i];
    let elems = getDocument().querySelectorAll("meta[property='og:" + prop + "']");
    let value;
    if (elems.length > 1) {
      value = [];
      for (let i=0; i<elems.length; i++) {
        let v = elems[i].getAttribute("content");
        if (v) {
          value.push(v);
        }
      }
      if (! value.length) {
        value = null;
      }
    } else if (elems.length === 1) {
      value = elems[0].getAttribute("content");
    }
    if (value) {
      openGraph[prop] = value;
    }
  }
  return openGraph;
}

function getTwitterCard() {
  let twitterCard = {};
  // If you update this, also update _TWITTERCARD_PROPERTIES in shot.js:
  let properties = "card site title description image player player:width player:height player:stream player:stream:content_type".split(/\s+/g);
  for (let i=0; i<properties.length; i++) {
    let prop = properties[i];
    let elem = getDocument().querySelector("meta[name='twitter:" + prop + "']");
    if (elem) {
      let value = elem.getAttribute("content");
      if (value) {
        twitterCard[prop] = value;
      }
    }
  }
  return twitterCard;
}

// framescripter infrastructure:
let isDisabled = false;
addMessageListener("hashroom@get-data:call", function handler(event) {
  if (isDisabled) {
    return;
  }
  var result;
  try {
    result = getData();
  } catch (e) {
    console.error("Error getting data:", e);
    console.trace();
    result = {
      error: {
        name: e.name,
        description: e+""
      }
    };
  }
  result.callId = event.data.callId;
  sendAsyncMessage("hashroom@get-data:return", result);
});

addMessageListener("pageshot@disable", function (event) {
  isDisabled = true;
});
<commit_msg>Don't pick up hidden images<commit_after>const uuidGenerator = Components.classes["@mozilla.org/uuid-generator;1"]
                      .getService(Components.interfaces.nsIUUIDGenerator);

function makeUuid() {
  var uuid = uuidGenerator.generateUUID();
  uuid = uuid.toString();
  // Strips off {}:
  return uuid.substr(1, uuid.length-2);
}

function getDocument() {
  return content.document;
}

let tabUuid = makeUuid();

let MIN_IMAGE_WIDTH = 200;
let MIN_IMAGE_HEIGHT = 100;

function getData() {
  let pageId = content._hashroomId;
  if (! pageId) {
    pageId = content._hashroomId = makeUuid();
  }
  let props = {
    title: content.document.title,
    url: content.location.href,
    tabId: tabUuid,
    pageId: content._hashroomId,
    time: Date.now(),
    images: []
  };
  let els = content.document.getElementsByTagName("img");
  let bestWidth = 0;
  for (let i=0; i<els.length; i++) {
    let el = els[i];
    if (! isVisible(el)) {
      console.log("skipping image", el.src);
      continue;
    }
    if (el.width < MIN_IMAGE_WIDTH || el.height < MIN_IMAGE_HEIGHT) {
      continue;
    }
    props.images.push(packImage(el));
    if (el.width > bestWidth) {
      bestWidth = el.width;
      props.image = packImage(el);
    }
  }
  props.openGraph = getOpenGraph();
  props.twitterCard = getTwitterCard();
  return props;
}

function isVisible(element) {
  while (element && element.tagName != "BODY") {
    let style;
    try {
      style = content.getComputedStyle(element);
    } catch (e) {
      console.log("bad element:", element, e+"");
    }
    if (style && style.display == "none") {
      return false;
    }
    element = element.parentNode;
  }
  return true;
}

function packImage(element) {
  return {
    src: element.src,
    title: element.getAttribute("title"),
    alt: element.getAttribute("alt"),
    height: element.height,
    width: element.width
  };
}

function getOpenGraph() {
  let openGraph = {};
  // If you update this, also update _OPENGRAPH_PROPERTIES in shot.js:
  let openGraphProperties = "title type url image audio description determiner locale site_name video image:secure_url image:type image:width image:height video:secure_url video:type video:width image:height audio:secure_url audio:type article:published_time article:modified_tim article:expiration_time article:author article:section article:tag book:author book:isbn book:release_date book:tag profile:first_name profile:last_name profile:username profile:gender".split(/\s+/g);
  for (let i=0; i<openGraphProperties.length; i++) {
    let prop = openGraphProperties[i];
    let elems = getDocument().querySelectorAll("meta[property='og:" + prop + "']");
    let value;
    if (elems.length > 1) {
      value = [];
      for (let i=0; i<elems.length; i++) {
        let v = elems[i].getAttribute("content");
        if (v) {
          value.push(v);
        }
      }
      if (! value.length) {
        value = null;
      }
    } else if (elems.length === 1) {
      value = elems[0].getAttribute("content");
    }
    if (value) {
      openGraph[prop] = value;
    }
  }
  return openGraph;
}

function getTwitterCard() {
  let twitterCard = {};
  // If you update this, also update _TWITTERCARD_PROPERTIES in shot.js:
  let properties = "card site title description image player player:width player:height player:stream player:stream:content_type".split(/\s+/g);
  for (let i=0; i<properties.length; i++) {
    let prop = properties[i];
    let elem = getDocument().querySelector("meta[name='twitter:" + prop + "']");
    if (elem) {
      let value = elem.getAttribute("content");
      if (value) {
        twitterCard[prop] = value;
      }
    }
  }
  return twitterCard;
}

// framescripter infrastructure:
let isDisabled = false;
addMessageListener("hashroom@get-data:call", function handler(event) {
  if (isDisabled) {
    return;
  }
  var result;
  try {
    result = getData();
  } catch (e) {
    console.error("Error getting data:", e);
    console.trace();
    result = {
      error: {
        name: e.name,
        description: e+""
      }
    };
  }
  result.callId = event.data.callId;
  sendAsyncMessage("hashroom@get-data:return", result);
});

addMessageListener("pageshot@disable", function (event) {
  isDisabled = true;
});
<|endoftext|>


<commit_before>// TODO make it a module
require(['jquery', 'knockout', 'websocket-json-events'],
        function($, _, websocket_json_events) {

  var status = {
    unknown: 'unknown',
    connecting: 'connecting',
    connected: 'connected',
    disconnected: 'disconnected'
  };

  var statusLabels = {
    unknown: '<<unknown>>',
    connecting: 'Connecting...',
    connected: 'Connected',
    disconnected: 'Disconnected'
  };

  // TODO put it into the model
  socket = null;

  function ConversationsModel() {
    var self = this;

    self.connectionStatus = ko.observable(status.disconnected);
    self.connectionStatusText = ko.computed(function() {
      return statusLabels[self.connectionStatus];
    });
    self.isConnected = ko.computed(function() {
      return self.connectionStatus() == status.connected;
    });

    self.username = ko.observable("");
    self.channels = ko.observableArray([]);
    self.channel = ko.observable("");
    self.channelSelected = ko.computed(function() {
      return (self.channel().length > 0);
    });
    self.users = ko.observableArray([]);
    self.usersReceived = ko.observable(false);
    self.conversations = ko.observableArray([]);
    self.conversationsReceived = ko.observable(false);
    self.conversation = ko.observable({topic: "", messages: []});
    self.conversationSelected = ko.computed(function() {
      return (typeof self.conversation().tag !== "undefined");
    });

    self.conversationsDict = ko.computed(function() {
      return objectArrayToDict(self.conversations(), 'tag');
    });

    self.connect = function() {
      connectInternal();
    };

    self.disconnect = function() {
      disconnectInternal();
    };

    self.channelClicked = function(channelName) {
      browseChannelInternal(channelName);
    }

    self.conversationClicked = function(conversation) {
      conversationClickedInternal(conversation.tag);
    }
  }

  function connectInternal() {
    console.log("Connecting as " + conversationsModel.username());
    conversationsModel.connectionStatus(status.connecting);

    socket = new websocket_json_events.FancyWebSocket('ws://localhost:9999/echo');

    socket.bind(
      'open',
      function(_) {
        console.log('socket open');
        socket.send('connect', { user: conversationsModel.username() });
      });

    socket.bind(
      'close',
      function(_) {
        console.log('socket closed');
        conversationsModel.connectionStatus(status.disconnected);
      });

    socket.bindDefault(function(event, data) {
      console.error("Warning: Received unexpected message: " + event + "(" + data + ")");
    });

    socket.bindMethod(
      'connect',
      function(_) {
        console.log("connected ok");
        conversationsModel.connectionStatus(status.connected);
        socket.send('list_channels', {});
      },
      function(err) {
        console.log("failed to connect: ", err);
      });

    socket.bindMethod(
      'list_channels',
      function(data) {
        conversationsModel.channels(data['channels']);
      },
      function(err) {
        console.log("failed to get channels: ", err);
      });
  }

  function disconnectInternal() {
    socket.bindMethod(
      'disconnect',
      function(_) {
        console.log("Socket disconnected");
        socket.close();
      },
      function(_) {
        /* whoosh */
      });

    conversationsModel.conversation({topic: "", messages: []});
    conversationsModel.conversationsReceived(false);
    conversationsModel.conversations([]);
    conversationsModel.usersReceived(false);
    conversationsModel.users([]);
    conversationsModel.channel("");
    conversationsModel.channels([]);

    socket.send('disconnect', {});
  }

  function browseChannelInternal(channel) {
    console.log("Channel clicked: " + channel);
    conversationsModel.channel(channel);
    socket.bindMethod(
      'list_users',
      function(usersEvent) {
        console.log("Users on ", conversationsModel.channel(),
                    " are ", usersEvent.users);
        conversationsModel.users(usersEvent.users);
        conversationsModel.usersReceived(true);
      },
      function(err) {
        console.log("failed to get users: ", err);
      });

    socket.bindMethod(
      'list_conversations',
      function(conversationsEvent) {
        var conversationsArray = conversationsEvent.conversations;

        console.log("Conversations in ", conversationsModel.channel(),
                    " are ", conversationsArray);

        conversationsModel.conversations(conversationsArray);
        conversationsModel.conversationsReceived(true);
      },
      function(err) {
        console.log("failed to get conversations: ", err);
      });

    socket.send('list_users',
                {"channel": conversationsModel.channel()});
    socket.send('list_conversations',
                {"channel": conversationsModel.channel()});
  }

  function conversationClickedInternal(tag) {
    console.log("Conversation clicked: ", tag);

    var conv = conversationsModel.conversationsDict()[tag];
    if (!conv || !conv.tag)
      console.error("Warning: Could not find conversation for tag '"
                    + tag + "' in conversation dict: ", conversationsDict());
    else
      conversationsModel.conversation(conv);
  }

  $(function() {
    console.log("hello logorrhea");

    var conversationsModel = new ConversationsModel();
    window.conversationsModel = conversationsModel;
    ko.applyBindings(conversationsModel);

    $("#usernameInput").focus();
  });

  /* Turns an array of object into a "dictionary" for fast access,
     using the given member of each object as the key.
     Example:

        objectArrayToDict([{ user: 'nh2', age: 20 }], 'user')
        ==
        { 'nh2': { user: 'nh2', age: 20 } }
  */
  function objectArrayToDict(array, keyMemberName) {
    var dict = {};
    ko.utils.arrayForEach(array, function(obj) {
      dict[obj[keyMemberName]] = obj;
    });
    return dict;
  }
});
<commit_msg>Client: Attach socket to window<commit_after>// TODO make it a module
require(['jquery', 'knockout', 'websocket-json-events'],
        function($, _, websocket_json_events) {

  var status = {
    unknown: 'unknown',
    connecting: 'connecting',
    connected: 'connected',
    disconnected: 'disconnected'
  };

  var statusLabels = {
    unknown: '<<unknown>>',
    connecting: 'Connecting...',
    connected: 'Connected',
    disconnected: 'Disconnected'
  };

  // TODO put it into the model
  socket = null;

  function ConversationsModel() {
    var self = this;

    self.connectionStatus = ko.observable(status.disconnected);
    self.connectionStatusText = ko.computed(function() {
      return statusLabels[self.connectionStatus];
    });
    self.isConnected = ko.computed(function() {
      return self.connectionStatus() == status.connected;
    });

    self.username = ko.observable("");
    self.channels = ko.observableArray([]);
    self.channel = ko.observable("");
    self.channelSelected = ko.computed(function() {
      return (self.channel().length > 0);
    });
    self.users = ko.observableArray([]);
    self.usersReceived = ko.observable(false);
    self.conversations = ko.observableArray([]);
    self.conversationsReceived = ko.observable(false);
    self.conversation = ko.observable({topic: "", messages: []});
    self.conversationSelected = ko.computed(function() {
      return (typeof self.conversation().tag !== "undefined");
    });

    self.conversationsDict = ko.computed(function() {
      return objectArrayToDict(self.conversations(), 'tag');
    });

    self.connect = function() {
      connectInternal();
    };

    self.disconnect = function() {
      disconnectInternal();
    };

    self.channelClicked = function(channelName) {
      browseChannelInternal(channelName);
    }

    self.conversationClicked = function(conversation) {
      conversationClickedInternal(conversation.tag);
    }
  }

  function connectInternal() {
    console.log("Connecting as " + conversationsModel.username());
    conversationsModel.connectionStatus(status.connecting);

    socket = new websocket_json_events.FancyWebSocket('ws://localhost:9999/echo');
    // For debuging / event injection
    window.socket = socket;

    socket.bind(
      'open',
      function(_) {
        console.log('socket open');
        socket.send('connect', { user: conversationsModel.username() });
      });

    socket.bind(
      'close',
      function(_) {
        console.log('socket closed');
        conversationsModel.connectionStatus(status.disconnected);
      });

    socket.bindDefault(function(event, data) {
      console.error("Warning: Received unexpected message: " + event + "(" + data + ")");
    });

    socket.bindMethod(
      'connect',
      function(_) {
        console.log("connected ok");
        conversationsModel.connectionStatus(status.connected);
        socket.send('list_channels', {});
      },
      function(err) {
        console.log("failed to connect: ", err);
      });

    socket.bindMethod(
      'list_channels',
      function(data) {
        conversationsModel.channels(data['channels']);
      },
      function(err) {
        console.log("failed to get channels: ", err);
      });
  }

  function disconnectInternal() {
    socket.bindMethod(
      'disconnect',
      function(_) {
        console.log("Socket disconnected");
        socket.close();
      },
      function(_) {
        /* whoosh */
      });

    conversationsModel.conversation({topic: "", messages: []});
    conversationsModel.conversationsReceived(false);
    conversationsModel.conversations([]);
    conversationsModel.usersReceived(false);
    conversationsModel.users([]);
    conversationsModel.channel("");
    conversationsModel.channels([]);

    socket.send('disconnect', {});
  }

  function browseChannelInternal(channel) {
    console.log("Channel clicked: " + channel);
    conversationsModel.channel(channel);
    socket.bindMethod(
      'list_users',
      function(usersEvent) {
        console.log("Users on ", conversationsModel.channel(),
                    " are ", usersEvent.users);
        conversationsModel.users(usersEvent.users);
        conversationsModel.usersReceived(true);
      },
      function(err) {
        console.log("failed to get users: ", err);
      });

    socket.bindMethod(
      'list_conversations',
      function(conversationsEvent) {
        var conversationsArray = conversationsEvent.conversations;

        console.log("Conversations in ", conversationsModel.channel(),
                    " are ", conversationsArray);

        conversationsModel.conversations(conversationsArray);
        conversationsModel.conversationsReceived(true);
      },
      function(err) {
        console.log("failed to get conversations: ", err);
      });

    socket.send('list_users',
                {"channel": conversationsModel.channel()});
    socket.send('list_conversations',
                {"channel": conversationsModel.channel()});
  }

  function conversationClickedInternal(tag) {
    console.log("Conversation clicked: ", tag);

    var conv = conversationsModel.conversationsDict()[tag];
    if (!conv || !conv.tag)
      console.error("Warning: Could not find conversation for tag '"
                    + tag + "' in conversation dict: ", conversationsDict());
    else
      conversationsModel.conversation(conv);
  }

  $(function() {
    console.log("hello logorrhea");

    var conversationsModel = new ConversationsModel();
    window.conversationsModel = conversationsModel;
    ko.applyBindings(conversationsModel);

    $("#usernameInput").focus();
  });

  /* Turns an array of object into a "dictionary" for fast access,
     using the given member of each object as the key.
     Example:

        objectArrayToDict([{ user: 'nh2', age: 20 }], 'user')
        ==
        { 'nh2': { user: 'nh2', age: 20 } }
  */
  function objectArrayToDict(array, keyMemberName) {
    var dict = {};
    ko.utils.arrayForEach(array, function(obj) {
      dict[obj[keyMemberName]] = obj;
    });
    return dict;
  }
});
<|endoftext|>


<commit_before>/* eslint-disable max-len, no-unused-expressions */

import { expect } from 'chai';
import Router from '../src/router';

describe('Router', () => {
    it('should invoke callback for matching path', () => {
        const router = new Router();
        const spy = sinon.spy();
        router.route('/foo/bar', spy);
        router.dispatch('/foo/bar');
        expect(spy.called).to.equal(true);
    });

    it('should pass parameters to the callback for matching path', () => {
        const router = Router();
        const spy = sinon.spy();
        router.route('/foo/:bar/baz/:qux', spy);
        router.dispatch('/foo/123/baz/abc');
        expect(spy.called).to.equal(true);
        expect(spy.calledWith('123', 'abc')).to.equal(true);
    });

    it('should support special characters as defined by RFC 3986', () => {
        const spy = sinon.spy();
        const router = Router({
            '/foo/:bar': spy
        });
        router.dispatch('/foo/-._~:?#[]@!$&\'()*+,;=');
        expect(spy.called).to.equal(true);
        expect(spy.calledWith('-._~:?#[]@!$&\'()*+,;=')).to.equal(true);
    });

    it('should stop matching after finding the first successful match', () => {
        const spy1 = sinon.spy();
        const spy2 = sinon.spy();
        const spy3 = sinon.spy();
        Router()
            .route('/foo', spy1)
            .route('/bar', spy2)
            .route('/baz', spy3)
            .dispatch('/foo');
        expect(spy1.called).to.equal(true);
        expect(spy2.called).to.equal(false);
        expect(spy3.called).to.equal(false);
    });

});<commit_msg>Fix linting errors<commit_after>/* eslint-disable max-len, no-unused-expressions */

import { expect } from 'chai';
import sinon from 'sinon';
import Router from '../src/router';

describe('Router', () => {
    it('should invoke callback for matching path', () => {
        const router = new Router();
        const spy = sinon.spy();
        router.route('/foo/bar', spy);
        router.dispatch('/foo/bar');
        expect(spy.called).to.equal(true);
    });

    it('should pass parameters to the callback for matching path', () => {
        const router = Router();
        const spy = sinon.spy();
        router.route('/foo/:bar/baz/:qux', spy);
        router.dispatch('/foo/123/baz/abc');
        expect(spy.called).to.equal(true);
        expect(spy.calledWith('123', 'abc')).to.equal(true);
    });

    it('should support special characters as defined by RFC 3986', () => {
        const spy = sinon.spy();
        const router = Router({
            '/foo/:bar': spy
        });
        router.dispatch('/foo/-._~:?#[]@!$&\'()*+,;=');
        expect(spy.called).to.equal(true);
        expect(spy.calledWith('-._~:?#[]@!$&\'()*+,;=')).to.equal(true);
    });

    it('should stop matching after finding the first successful match', () => {
        const spy1 = sinon.spy();
        const spy2 = sinon.spy();
        const spy3 = sinon.spy();
        Router()
            .route('/foo', spy1)
            .route('/bar', spy2)
            .route('/baz', spy3)
            .dispatch('/foo');
        expect(spy1.called).to.equal(true);
        expect(spy2.called).to.equal(false);
        expect(spy3.called).to.equal(false);
    });
});
<|endoftext|>


<commit_before>'use strict';

import { h, Component } from 'preact';
import Client from '../lib/client.js';
import { bind } from 'decko';
import * as numbers from '../lib/numbers.js';

class Realtime extends Component {

  constructor(props) {
    super(props)

    this.state = {
      count: 0
    }
  }

  componentDidMount() {
      this.fetchData();
      this.interval = window.setInterval(this.fetchData, 15000);
  }

  componentWillUnmount() {
      clearInterval(this.interval);
  }

  componentWillReceiveProps(newProps, newState) {
    if(!this.paramsChanged(this.props, newProps)) {
      return;
    }

    this.fetchData()
  }

  paramsChanged(o, n) {
    return o.siteId != n.siteId || o.before != n.before && o.after != n.after;
  }

  @bind
  setDocumentTitle() {
    // update document title
    let visitorText = this.state.count == 1 ? 'visitor' : 'visitors';
    document.title = ( this.state.count > 0 ? `${numbers.formatPretty(this.state.count)} current ${visitorText} — Fathom` : 'Fathom' );
  }

  @bind
  fetchData() {
    let url = `/sites/${this.props.siteId}/stats/site/realtime`
    Client.request(url)
      .then((d) => {
        this.setState({ count: d })
        this.setDocumentTitle();
      })
  }

  render(props, state) {
    let visitorText = state.count == 1 ? 'visitor' : 'visitors';
    return (
        {numbers.formatPretty(state.count)} current {visitorText}
    )
  }
}

export default Realtime
<commit_msg>fix paramsChanged func in realtime component<commit_after>'use strict';

import { h, Component } from 'preact';
import Client from '../lib/client.js';
import { bind } from 'decko';
import * as numbers from '../lib/numbers.js';

class Realtime extends Component {

  constructor(props) {
    super(props)

    this.state = {
      count: 0
    }
  }

  componentDidMount() {
      this.fetchData();
      this.interval = window.setInterval(this.fetchData, 15000);
  }

  componentWillUnmount() {
      clearInterval(this.interval);
  }

  componentWillReceiveProps(newProps, newState) {
    if(!this.paramsChanged(this.props, newProps)) {
      return;
    }

    this.fetchData()
  }

  paramsChanged(o, n) {

    return o.siteId != n.siteId || o.before != n.before || o.after != n.after;
  }

  @bind
  setDocumentTitle() {
    // update document title
    let visitorText = this.state.count == 1 ? 'visitor' : 'visitors';
    document.title = ( this.state.count > 0 ? `${numbers.formatPretty(this.state.count)} current ${visitorText} — Fathom` : 'Fathom' );
  }

  @bind
  fetchData() {
    let url = `/sites/${this.props.siteId}/stats/site/realtime`
    Client.request(url)
      .then((d) => {
        this.setState({ count: d })
        this.setDocumentTitle();
      })
  }

  render(props, state) {
    let visitorText = state.count == 1 ? 'visitor' : 'visitors';
    return (
        {numbers.formatPretty(state.count)} current {visitorText}
    )
  }
}

export default Realtime
<|endoftext|>