<commit_before>/**
 * Copyright (c) 2015 Samsung Electronics, Inc.,
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";

const http = require('http');
const database = require("../util/database");
const log = require('../util/logging');
const mailing = require('../util/mailing');
const _ = require('lodash');

let serverList = [];
let serverListLastModifiedTime = new Date();
let checkingServerStatus;

exports.init = function(doNotStartChecking){

    mailing.init();

    loadServerList()
        .then(initServerStatusValues)
        .then(() => {
            if (!doNotStartChecking)
                startCheckingServerStatus();
        });
};

function loadServerList() {
    const sql =
        `SELECT pid, projectName, hostIP, portNumber,
                emailList, emailingWhenServerDead,
                projectType, groupName, administrator
        FROM ProjectInfo`;
    return database.exec(sql)
        .then((rows) => {
            serverList = rows;
        })
        .catch((err) => {
            log.error(err);
        });
}

function initServerStatusValues() {
    const date = new Date().getTime();
    serverList.forEach((server) => {
        const lastDigitOfHostIP = server.hostIP.split('.')[3];
        server.name = `${server.projectName}(${lastDigitOfHostIP}:${server.portNumber})`;
        server.rerunLastTryTime = date;
        server.rerunTimes = 0;
        server.heartbeat = `http://${server.hostIP}:${server.portNumber}/api/v1/isServerAlive`;
        server.heartbeatInDetail = `http://${server.hostIP}:${server.portNumber}/api/v2/server-detailed-status`;  // Not used yet
    });
}

function startCheckingServerStatus(){
    checkingServerStatus = setInterval(() => {
        checkServerStatusAndRunWhenItDown();
    }, global.config.serverStatusCheckInterval * 1000);
}

exports.startCheckingServerStatus = startCheckingServerStatus;
exports.stopServerChecking = stopCheckingServerStatus;  // TODO check

// TODO: detailedServerStatus

function checkServerStatusAndRunWhenItDown(){
    _.forEach(serverList, (server) => {
        http.get(server.heartbeat, (res) => {
            if(res.statusCode === 200) {
                setServerActiveStatus(server, true);
                return;
            }

            handleServerWhenDown(server, res);
        }).on('error', (error) => {
            handleServerWhenDown(server, error);
        });
    });
}

function setServerActiveStatus(server, serverStatus){
    if(server.active !== serverStatus){
        serverListLastModifiedTime = new Date();

        if(serverStatus === true){
            server.notifiedWhenItDown = false;
            log.info('server (' + server.name + ') is active now');
        } else {
            log.info('server (' + server.name + ') is not active now');
        }
    }

    server.active = serverStatus;
}

function handleServerWhenDown(server, error){
    if(error) log.error(error);

    setServerActiveStatus(server, false);
    emailWhenServerDown(server);
    //TODO runServerWhenTerminated(server);
}

function emailWhenServerDown(server) {
    if(server.emailingWhenServerDead === 'N' || server.notifiedWhenItDown) return;

    const params = {
        toList:server.emailList,
        ccList:["min.ho.kim@samsung.com"],
        title:"[Dexter Monitor] Server Failure: " + server.name,
        contents: createEmailContentsWhenServerDown(server)
    };

    mailing.sendEmail(params, (error) => {
        if(error)
            log.error("fail to email: " + JSON.stringify(params));
        else
            log.info('emailed because ' + server.name + ' is down');
    });

    server.notifiedWhenItDown = true;
}

function createEmailContentsWhenServerDown(server){
    return "Please check your server status.

"
        + ' - Server Name: ' + server.name + "
"
        + " - Server Type/Group: " + server.type + " / " + server.group + "
"
        + " - Server Administrator: " + server.serverAdministrator + "
"
        + " - Status: the heartbeat is not working. (the server may not be working)
"
        + " - heartbeat: " + server.heartbeat + "
"
        + " - Check Time: " + new Date();
}

function stopCheckingServerStatus(){
    clearInterval(checkingServerStatus);
}

exports.getConfig = function(req, res) {
    res.send(config);
};

exports.getServerListLastModifiedTime = function(req, res) {
    res.send(200, {"serverListLastModifiedTime": serverListLastModifiedTime});
};

exports.getServerList = function(req, res) {
    res.send(serverList);
};

exports.getServerListInternal = function() {
    return serverList;
};<commit_msg>[monitor] Add trim code to projectName<commit_after>/**
 * Copyright (c) 2015 Samsung Electronics, Inc.,
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";

const http = require('http');
const database = require("../util/database");
const log = require('../util/logging');
const mailing = require('../util/mailing');
const _ = require('lodash');

let serverList = [];
let serverListLastModifiedTime = new Date();
let checkingServerStatus;

exports.init = function(doNotStartChecking){

    mailing.init();

    loadServerList()
        .then(initServerStatusValues)
        .then(() => {
            if (!doNotStartChecking)
                startCheckingServerStatus();
        });
};

function loadServerList() {
    const sql =
        `SELECT pid, projectName, hostIP, portNumber,
                emailList, emailingWhenServerDead,
                projectType, groupName, administrator
        FROM ProjectInfo`;
    return database.exec(sql)
        .then((rows) => {
            serverList = rows;
        })
        .catch((err) => {
            log.error(err);
        });
}

function initServerStatusValues() {
    const date = new Date().getTime();
    serverList.forEach((server) => {
        server.projectName = _.trim(server.projectName);
        const lastDigitOfHostIP = server.hostIP.split('.')[3];
        server.name = `${server.projectName}(${lastDigitOfHostIP}:${server.portNumber})`;
        server.rerunLastTryTime = date;
        server.rerunTimes = 0;
        server.heartbeat = `http://${server.hostIP}:${server.portNumber}/api/v1/isServerAlive`;
        server.heartbeatInDetail = `http://${server.hostIP}:${server.portNumber}/api/v2/server-detailed-status`;  // Not used yet
    });
}

function startCheckingServerStatus(){
    checkingServerStatus = setInterval(() => {
        checkServerStatusAndRunWhenItDown();
    }, global.config.serverStatusCheckInterval * 1000);
}

exports.startCheckingServerStatus = startCheckingServerStatus;
exports.stopServerChecking = stopCheckingServerStatus;  // TODO check

// TODO: detailedServerStatus

function checkServerStatusAndRunWhenItDown(){
    _.forEach(serverList, (server) => {
        http.get(server.heartbeat, (res) => {
            if(res.statusCode === 200) {
                setServerActiveStatus(server, true);
                return;
            }

            handleServerWhenDown(server, res);
        }).on('error', (error) => {
            handleServerWhenDown(server, error);
        });
    });
}

function setServerActiveStatus(server, serverStatus){
    if(server.active !== serverStatus){
        serverListLastModifiedTime = new Date();

        if(serverStatus === true){
            server.notifiedWhenItDown = false;
            log.info('server (' + server.name + ') is active now');
        } else {
            log.info('server (' + server.name + ') is not active now');
        }
    }

    server.active = serverStatus;
}

function handleServerWhenDown(server, error){
    if(error) log.error(error);

    setServerActiveStatus(server, false);
    emailWhenServerDown(server);
    //TODO runServerWhenTerminated(server);
}

function emailWhenServerDown(server) {
    if(server.emailingWhenServerDead === 'N' || server.notifiedWhenItDown) return;

    const params = {
        toList:server.emailList,
        ccList:["min.ho.kim@samsung.com"],
        title:"[Dexter Monitor] Server Failure: " + server.name,
        contents: createEmailContentsWhenServerDown(server)
    };

    mailing.sendEmail(params, (error) => {
        if(error)
            log.error("fail to email: " + JSON.stringify(params));
        else
            log.info('emailed because ' + server.name + ' is down');
    });

    server.notifiedWhenItDown = true;
}

function createEmailContentsWhenServerDown(server){
    return "Please check your server status.

"
        + ' - Server Name: ' + server.name + "
"
        + " - Server Type/Group: " + server.type + " / " + server.group + "
"
        + " - Server Administrator: " + server.serverAdministrator + "
"
        + " - Status: the heartbeat is not working. (the server may not be working)
"
        + " - heartbeat: " + server.heartbeat + "
"
        + " - Check Time: " + new Date();
}

function stopCheckingServerStatus(){
    clearInterval(checkingServerStatus);
}

exports.getConfig = function(req, res) {
    res.send(config);
};

exports.getServerListLastModifiedTime = function(req, res) {
    res.send(200, {"serverListLastModifiedTime": serverListLastModifiedTime});
};

exports.getServerList = function(req, res) {
    res.send(serverList);
};

exports.getServerListInternal = function() {
    return serverList;
};<|endoftext|>


<commit_before>(function(){
	document.body.style.webkitTouchCallout = "none";
	document.body.style.webkitUserSelect = "none";
	document.body.style.webkitTextSizeAdjust = "none";
	document.body.style.webkitTapHighlightColor = "rgba(0,0,0,0)";

	var ns = FL.ns("billd");
	eval(FL.import("ns", "Player, Map, YellowBall, Spider, Fish, Floor, Bat, Spring, InstanceFactory"));
	eval(FL.import("FL", "Stage, LoadProgress, ImageLoader, Camera, Utils"));

	var getMapData = function(i){
		return JSON.parse(JSON.stringify(ns.allData[i||0]));
	}

	var lifeDom = document.querySelector("#life");
	var scoreDom = document.querySelector("#score");
	var	canvas = document.querySelector("canvas");
	var width = 600;
	var height = 300;
	var fps = 60;
	var mc;
	var life = 99;
	ns.score = 0;
	ns.allData = mapData;
	mapData = getMapData(FL.params.stage);

	var stage = ns.stage = new Stage(canvas, width, height, fps);
	stage.start();
	var isShake = false;

	var loadProgress = new LoadProgress(new ImageLoader());
	loadProgress.x = width>>1;loadProgress.y=height>>1;
	loadProgress.addEventListener("complete", function(){
		stage.removeChild(this);
		this.removeAllEventListener();
		loadProgress = null;
		R.images = this.loader.images;
		init();
	});
	loadProgress.load(R.images);
	stage.addChild(loadProgress);

	stage.initMouseEvent();
	stage.initKeyboardEvent();

	var map, player, camera;

	var snails = ns.snails = [];
	var spiders = ns.spiders = [];
	var fishs = ns.fishs = [];
	var floors = ns.floors = [];
	var springs = ns.springs = [];
	var yellowBalls = ns.yellowBalls = [];

	ns.setStage = function(i){
		snails.length = 0;
		spiders.length = 0;
		fishs.length = 0;
		springs.length = 0;
		floors.length = 0;
		stage.children.length = 0;
		mapData = getMapData(i);
		init();
	}

	setInterval(function(){
		stage.render();
	}, 1000/fps);

	function init(){
		map = ns.map = new Map();

		player = ns.player = Player.create();

		map.init(mapData.map.width, mapData.map.height);
		camera = new Camera(0, 0, width, height);

		player.pos.x = mapData.mc.player[0].x;
		player.pos.y = mapData.mc.player[0].y;
		player.y = player.pos.y + map.y;

		var bg = ns.bg = new FL.Bitmap();
		bg.setImg(R.images.bg);
		bg.visible = FL.params.bg!=0;

		bgSX = bg.width < map.width?(bg.width-width)/(map.width-width):1;
		bgSY = bg.height < map.height?(bg.height-height)/(map.height-height+420):1;
		bg.update = function(){
			bg.x = map.x * bgSX;
			bg.y = Math.min(map.y * bgSY, 0) ;
		}

		stage.addChild(bg);
		stage.addChild(map);
		stage.addChild(player);

		mapData.mc.floor = mapData.floor;
		for(var type in mapData.mc)
		{
			if(type == "yellow_ball") continue;
			var arr = mapData.mc[type]||[];
			for(var i = 0,l = arr.length;i < l;i ++)
			{
				var mc = InstanceFactory.create(type, arr[i]);
				mc && stage.addChild(mc);
			}
		}

		if(ns.door)stage.addChildAt(ns.door, 1);

		stage.update = update;
	}

	function update(){
		ns.fps ++;

		if(player.x >= Math.floor(width * .6) && map.x > width - map.width)
		{
			map.x = width * .6 - player.pos.x;
		}

		else if(player.x <= width * .4 && map.x < 0)
		{
			map.x = width * .4 - player.pos.x;
		}

		if(player.y <= Math.ceil(height * .3))
		{
			map.y = height * .3 - player.pos.y;
		}

		else if(player.y >= Math.floor(height * .7) && map.y > height - map.height)
		{
			map.y = height * .7 - player.pos.y;
		}

		if(player.pos.y > map.height && !isShake)
		{
			FL.Shake.shake(stage, .5, .03, "xy");
			isShake = true;
			setTimeout(function(){
				isShake = false;
				map.y = 200;
				map.x = 0;
				player.die();
				player.pos.x = player.x = mapData.mc.player[0].x;
				player.pos.y = player.y = mapData.mc.player[0].y;
			}, 1000);
		}

		if(player.pos.x < player.width*.5){
			player.pos.x = player.width*.5;
		}

		if(player.pos.x > map.width-player.width*.5){
			player.pos.x = map.width-player.width*.5;
		}

		for(var i = 0, l = spiders.length;i < l;i ++)
		{
			var spider = spiders[i];
			for(var j = 0, jl = yellowBalls.length;j < jl;j ++){
				var ball = yellowBalls[j];
				if(spider.alive && spider.isInStage && !ball.isDie && ball.isInStage && ball.hitTestObject(spider)){
					spider.v.y = -4;
					spider.v.x = 0;
					spider.scaleX = 1;
					spider.setCenter();
					spiders.splice(spiders.indexOf(spider), 1);
					TweenLite.to(spider, 2, {scaleX:.8, scaleY:.8, angle:10, onComplete:function(){
						stage.removeChild(spider);
					}})
					spider.alive = false;
					ns.score += 5;
					i--;
					l--;
					ball.destroy();
					break;
				}
			}

			if(	spider.alive && spider.isInStage && player.hitTestObject(spider))
			{
				if(player.v.y > 0){
					player.v.y = -5;
					spider.v.y = -4;
					spider.v.x = 0;
					spider.scaleX = 1;
					spider.setCenter();
					spiders.splice(spiders.indexOf(spider), 1);
					i--;
					l--;
					TweenLite.to(spider, 2, {scaleX:.8, scaleY:.8, angle:10, onComplete:function(){
						stage.removeChild(spider);
					}})
					spider.alive = false;
					ns.score += 5;
				}
				else{
					player.die();
					spider.attack();
					player.v.set(0, 0);
					player.a.x = spider.pos.x > player.pos.x ? -3:3;
					spider.v.x *= (spider.pos.x - player.pos.x) * spider.v.x < 0? 1:-1;
					life --;
					FL.Shake.shake(stage, .5, .02, "xy")
				}
				break;
			}
		}

		for(var i = 0, l = fishs.length;i < l;i ++)
		{
			var fish = fishs[i];
			if(player.hitTestObject(fish) && player.alive)
			{
				player.die();
				player.v.y = -4;
				player.a.x = player.v.x>0 ? -3:3;
				FL.Shake.shake(stage, .5, .02, "xy")
				break;
			}
		}

		lifeDom.innerHTML = "life:" + life;
		scoreDom.innerHTML = "score:" + ns.score;
	}

})();<commit_msg>add bullet<commit_after>(function(){
	document.body.style.webkitTouchCallout = "none";
	document.body.style.webkitUserSelect = "none";
	document.body.style.webkitTextSizeAdjust = "none";
	document.body.style.webkitTapHighlightColor = "rgba(0,0,0,0)";

	var ns = FL.ns("billd");
	eval(FL.import("ns", "Player, Map, YellowBall, Spider, Fish, Floor, Bat, Spring, InstanceFactory"));
	eval(FL.import("FL", "Stage, LoadProgress, ImageLoader, Camera, Utils"));

	var getMapData = function(i){
		return JSON.parse(JSON.stringify(ns.allData[i||0]));
	}

	var lifeDom = document.querySelector("#life");
	var scoreDom = document.querySelector("#score");
	var	canvas = document.querySelector("canvas");
	var width = 600;
	var height = 300;
	var fps = 60;
	var mc;
	var life = 99;
	ns.score = 0;
	ns.allData = mapData;
	mapData = getMapData(FL.params.stage);

	var stage = ns.stage = new Stage(canvas, width, height, fps);
	stage.start();
	var isShake = false;

	var loadProgress = new LoadProgress(new ImageLoader());
	loadProgress.x = width>>1;loadProgress.y=height>>1;
	loadProgress.addEventListener("complete", function(){
		stage.removeChild(this);
		this.removeAllEventListener();
		loadProgress = null;
		R.images = this.loader.images;
		init();
	});
	loadProgress.load(R.images);
	stage.addChild(loadProgress);

	stage.initMouseEvent();
	stage.initKeyboardEvent();

	var map, player, camera;

	var snails = ns.snails = [];
	var spiders = ns.spiders = [];
	var fishs = ns.fishs = [];
	var floors = ns.floors = [];
	var springs = ns.springs = [];
	var yellowBalls = ns.yellowBalls = [];

	ns.setStage = function(i){
		snails.length = 0;
		spiders.length = 0;
		fishs.length = 0;
		springs.length = 0;
		floors.length = 0;
		stage.children.length = 0;
		mapData = getMapData(i);
		init();
	}

	setInterval(function(){
		stage.render();
	}, 1000/fps);

	function init(){
		map = ns.map = new Map();

		player = ns.player = Player.create();

		map.init(mapData.map.width, mapData.map.height);
		camera = new Camera(0, 0, width, height);

		player.pos.x = mapData.mc.player[0].x;
		player.pos.y = mapData.mc.player[0].y;
		player.y = player.pos.y + map.y;

		var bg = ns.bg = new FL.Bitmap();
		bg.setImg(R.images.bg);
		bg.visible = FL.params.bg!=0;

		bgSX = bg.width < map.width?(bg.width-width)/(map.width-width):1;
		bgSY = bg.height < map.height?(bg.height-height)/(map.height-height+420):1;
		bg.update = function(){
			bg.x = map.x * bgSX;
			bg.y = Math.min(map.y * bgSY, 0) ;
		}

		stage.addChild(bg);
		stage.addChild(map);
		stage.addChild(player);

		mapData.mc.floor = mapData.floor;
		for(var type in mapData.mc)
		{
			if(type == "yellow_ball") continue;
			var arr = mapData.mc[type]||[];
			for(var i = 0,l = arr.length;i < l;i ++)
			{
				var mc = InstanceFactory.create(type, arr[i]);
				mc && stage.addChild(mc);
			}
		}

		if(ns.door)stage.addChildAt(ns.door, 1);

		stage.update = update;
	}

	function update(){
		ns.fps ++;

		if(player.x >= Math.floor(width * .6) && map.x > width - map.width)
		{
			map.x = width * .6 - player.pos.x;
		}

		else if(player.x <= width * .4 && map.x < 0)
		{
			map.x = width * .4 - player.pos.x;
		}

		if(player.y <= Math.ceil(height * .3))
		{
			map.y = height * .3 - player.pos.y;
		}

		else if(player.y >= Math.floor(height * .7) && map.y > height - map.height)
		{
			map.y = height * .7 - player.pos.y;
		}

		if(player.pos.y > map.height && !isShake)
		{
			FL.Shake.shake(stage, .5, .03, "xy");
			isShake = true;
			setTimeout(function(){
				isShake = false;
				map.y = 200;
				map.x = 0;
				player.die();
				player.pos.x = player.x = mapData.mc.player[0].x;
				player.pos.y = player.y = mapData.mc.player[0].y;
			}, 1000);
		}

		if(player.pos.x < player.width*.5){
			player.pos.x = player.width*.5;
		}

		if(player.pos.x > map.width-player.width*.5){
			player.pos.x = map.width-player.width*.5;
		}

		for(var i = 0, l = spiders.length;i < l;i ++)
		{
			var spider = spiders[i];
			for(var j = 0, jl = yellowBalls.length;j < jl;j ++){
				var ball = yellowBalls[j];
				if(spider.alive && spider.isInStage && !ball.isDie && ball.isInStage && ball.hitTestObject(spider)){
					spider.v.y = -4;
					spider.v.x = 0;
					spider.scaleX = 1;
					spider.setCenter();
					spiders.splice(spiders.indexOf(spider), 1);
					TweenLite.to(spider, 2, {scaleX:.8, scaleY:.8, angle:10, onComplete:function(){
						stage.removeChild(spider);
					}})
					spider.alive = false;
					ns.score += 5;
					i--;
					l--;
					ball.destroy();
					break;
				}
			}

			if(	spider.alive && spider.isInStage && player.alive && player.hitTestObject(spider))
			{
				if(player.v.y > 0){
					player.v.y = -5;
					spider.v.y = -4;
					spider.v.x = 0;
					spider.scaleX = 1;
					spider.setCenter();
					spiders.splice(spiders.indexOf(spider), 1);
					i--;
					l--;
					TweenLite.to(spider, 2, {scaleX:.8, scaleY:.8, angle:10, onComplete:function(){
						stage.removeChild(spider);
					}})
					spider.alive = false;
					ns.score += 5;
				}
				else{
					player.die();
					spider.attack();
					player.v.set(0, 0);
					player.a.x = spider.pos.x > player.pos.x ? -3:3;
					spider.v.x *= (spider.pos.x - player.pos.x) * spider.v.x < 0? 1:-1;
					life --;
					FL.Shake.shake(stage, .5, .02, "xy")
				}
				break;
			}
		}

		for(var i = 0, l = fishs.length;i < l;i ++)
		{
			var fish = fishs[i];
			if(player.hitTestObject(fish) && player.alive)
			{
				player.die();
				player.v.y = -4;
				player.a.x = player.v.x>0 ? -3:3;
				FL.Shake.shake(stage, .5, .02, "xy")
				break;
			}
		}

		lifeDom.innerHTML = "life:" + life;
		scoreDom.innerHTML = "score:" + ns.score;
	}

})();<|endoftext|>


<commit_before>

function Complex(real, imaginary) {
    this.r = real;
    this.i = imaginary;
    Object.freeze(this);
}
Complex.prototype.add =
    function(other) { return new Complex(this.r + other.r, this.i + other.i); };
Complex.prototype.sub =
    function(other) { return new Complex(this.r - other.r, this.i - other.i); };
Complex.prototype.scale =
    function(scalar){ return new Complex(this.r * scalar,  this.i * scalar ); };
Complex.prototype.mul =
    function(other) { var r = this.r; var i = this.i; var or = other.r; var oi = other.i;
        return new Complex(r * or - i * oi, r * oi + i * or); };
Complex.prototype.neg =
    function() { return new Complex(-this.r, -this.i); };
Complex.prototype.conj =
    function() { return new Complex(this.r, -this.i); };
Complex.prototype.isign =  // this * (0,1)
    function() { return new Complex(-this.i, this.r); };
Complex.prototype.mag =
    function() { var r = this.r; var i = this.i; return r*r+i*i; };
Complex.prototype.abs =
    function() { var r = this.r; var i = this.i; return Math.sqrt(r*r+i*i); };
Complex.prototype.arg =
    function() { return Math.atan2(this.i, this.r); };
Complex.prototype.toString =
    function() { return "(" + this.r.toString() + "," + this.i.toString() + ")"; };
Complex.ZERO =
    new Complex(0,0);
Complex.ONE =
    new Complex(1,0);
Complex.I =
    new Complex(0,1);

var ncoTable = (function() {

    var twopi = Math.PI * 2.0;
    var two16 = 65536;
    var delta = twopi / two16;

    var xs = new Array(two16);

    for (var idx = 0 ; idx < two16 ; idx++) {
        var angle = delta * idx;
        xs[idx] = { cos: Math.cos(angle), sin: Math.sin(angle) };
    }
    return xs;
})();

/**
 * A sine generator with a 32-bit accumulator and a 16-bit
 * lookup table.  Much faster than Math.whatever
 */
function Nco(frequency, sampleRate) {
    "use strict";
    var freq = 0|0;
    function setFrequency(frequency) {
        freq  = (4294967296.0 * frequency / sampleRate)|0;
		return freq;
    }
    this.setFrequency = setFrequency;
    setFrequency(frequency);

    var phase = 0|0;
    var table = ncoTable;

    this.next = function() {
        phase = (phase + freq) & 0xffffffff;
        return table[(phase >> 16) & 0xffff];
    };

    this.mixNext = function (v) {
        phase = (phase + freq) & 0xffffffff;
        var cs = table[(phase >> 16) & 0xffff];
        return new Complex(v*cs.cos, v*cs.sin);
    };

}

var Biquad = (function() {

    function Filter(b0, b1, b2, a1, a2) {

        var x1=0,  x2=0,  y1=0,  y2=0;
        var x1r=0, x2r=0, y1r=0, y2r=0;
        var x1i=0, x2i=0, y1i=0, y2i=0;

        this.update = function(x) {
            var y = b0*x + b1*x1 + b2*x2 - a1*y1 - a2*y2;
            x2 = x1; x1 = x;
            y2 = y1; y1 = y;
            return y;
        };

        this.updatex = function(x) {
            var r = x.r; var i = x.i;
            var yr = b0*r + b1*x1r + b2*x2r - a1*y1r - a2*y2r;
            var yi = b0*i + b1*x1i + b2*x2i - a1*y1i - a2*y2i;
            x2r = x1r; x1r = r;
            x2i = x1i; x1i = i;
            y2r = y1r; y1r = yr;
            y2i = y1i; y1i = yi;
            return new Complex(yr, yi);
        };
    }

    var cls = {
        lowPass : function(frequency, sampleRate, q) {
            q = typeof q !== 'undefined' ? q : 0.707;
            var freq = 2.0 * Math.PI * frequency / sampleRate;
            var alpha = Math.sin(freq) / (2.0 * q);
            var b0 = (1.0 - Math.cos(freq)) / 2.0;
            var b1 =  1.0 - Math.cos(freq);
            var b2 = (1.0 - Math.cos(freq)) / 2.0;
            var a0 = 1.0 + alpha;
            var a1 = -2.0 * Math.cos(freq);
            var a2 = 1.0 - alpha;
            return new Filter(b0/a0, b1/a0, b2/a0, a1/a0, a2/a0);
        },

        highPass : function(frequency, sampleRate, q) {
            q = typeof q !== 'undefined' ? q : 0.707;
            var freq = 2.0 * Math.PI * frequency / sampleRate;
            var alpha = Math.sin(freq) / (2.0 * q);
            var b0 =  (1.0 + Math.cos(freq)) / 2.0;
            var b1 = -(1.0 + Math.cos(freq));
            var b2 =  (1.0 + Math.cos(freq)) / 2.0;
            var a0 = 1.0 + alpha;
            var a1 = -2.0 * Math.cos(freq);
            var a2 = 1.0 - alpha;
            return new Filter(b0/a0, b1/a0, b2/a0, a1/a0, a2/a0);
        },

        bandPass : function(frequency, sampleRate, q) {
            q = typeof q !== 'undefined' ? q : 0.5;
            var freq = 2.0 * Math.PI * frequency / sampleRate;
            var alpha = Math.sin(freq) / (2.0 * q);
            var b0 = Math.sin(freq) / 2.0;   // = q*alpha
            var b1 = 0.0;
            var b2 = -Math.sin(freq) / 2.0;  // = -q*alpha
            var a0 = 1.0 + alpha;
            var a1 = -2.0 * Math.cos(freq);
            var a2 = 1.0 - alpha;
            return new Filter(b0/a0, b1/a0, b2/a0, a1/a0, a2/a0);
        },

        bandReject : function(frequency, sampleRate, q) {
            q = typeof q !== 'undefined' ? q : 0.5;
            var freq = 2.0 * Math.PI * frequency / sampleRate;
            var alpha = Math.sin(freq) / (2.0 * q);
            var b0 = 1.0;
            var b1 = -2.0 * Math.cos(freq);
            var b2 = 1.0;
            var a0 = 1.0 + alpha;
            var a1 = -2.0 * Math.cos(freq);
            var a2 = 1.0 - alpha;
            return new Filter(b0/a0, b1/a0, b2/a0, a1/a0, a2/a0);
        }
    };

    return cls;

})();

var cossinTable = (function() {

    var twopi = Math.PI * 2.0;
    var two16 = 65536;
    var delta = twopi / two16;

    var xs = new Array(two16);

    for (var idx = 0 ; idx < two16 ; idx++) {
        var angle = delta * idx;
        xs[idx] = { cos: Math.cos(angle), sin: Math.sin(angle) };
    }
    return xs;
})();

/**
 * This version uses Biquad filters for the arms
 * http://www.trondeau.com/blog/2011/8/13/control-loop-gain-values.html
 */
function Costas(frequency, dataRate, sampleRate, plotter) {
    "use strict";

    var err   = 0;
    var alpha = 0;
    var beta  = 0;
    var damp  = 0.707;
    var freq  = 0;
    var phase = 0|0;
    var counter = 0;

    var table = cossinTable;
    var ilp, qlp, dlp;
    var agcint1=0, agcint2=0;
    var agcgain=0.001;

    function setFrequency(frequency) {
        freq  = (4294967296.0 * frequency / sampleRate)|0;
    }
    this.setFrequency = setFrequency;
    setFrequency(frequency);
    var maxErr = 4294967296.0 * 20.0 / sampleRate;
    console.log("maxerr: " + maxErr);
    var minErr = -maxErr;

    function setDataRate(rate) {
        ilp = Biquad.lowPass(rate*0.5, sampleRate);
        qlp = Biquad.lowPass(rate*0.5, sampleRate);
        dlp = Biquad.lowPass(rate*4.0, sampleRate);
    }
    this.setDataRate = setDataRate;
    setDataRate(dataRate);

    this.update = function(v) {
        v = v * agcint1;
        var agcerr = 1.0 - Math.abs(v);
        agcint2 = agcint1;
        agcint1 = agcint2 + agcgain * agcerr;

        var adjFreq = (freq + err) | 0;
        phase = (phase + adjFreq) & 0xffffffff;
        var cs = table[(phase >> 16) & 0xffff];
        var i = v * cs.cos;
        var q = v * cs.sin;
        var iz = ilp.update(i);
        var qz = qlp.update(q);
        //console.log("qz: " + qz);
        var angle = -Math.atan2(qz, iz);
        err += dlp.update(angle) * 5000.0; // adjust this
        if (err < minErr)
            err = minErr;
        else if (err > maxErr)
            err = maxErr;
        //console.log("" + iz + " " + qz + " " + angle + " " + err);
        if (++counter % 20 === 0)
            plotter.update([iz, qz, angle, err, minErr, maxErr]);
        //console.log("iq: " + iz + ", " + qz);
        return new Complex(iz,qz);
    };

}

function Plotter(canvas, lines) {
    var size = lines.length;
    var ctx = canvas.getContext("2d");
    var width = canvas.width;
    var height = canvas.height;

    function reset() {
        for (var i=0 ; i<size ; i++) {
            lines[i].data = [];
        }
    }
    var y0 = canvas.height / 2;

    reset();

    this.update = function(values) {
       var len = values.length;
       if (len>size) {
           len = size;
       }
       for (var i=0 ; i<len ; i++) {
           var data = lines[i].data;
           data[data.length] = values[i];
       }
    }

    function redraw() {
        ctx.strokeStyle = "black";
        ctx.rect(0,0, width, height);
        ctx.fill();

        for (var i=0 ; i < size ; i++) {
            var line = lines[i];
            ctx.strokeStyle = line.style;
            ctx.beginPath();
            ctx.moveTo(0, y0);
            var data = line.data;
            var ll = data.length;
            for (var x=0 ; x<ll ; x++) {
                var y = data[x];
                var sgn = (y>0) ? 1 : -1;
                var v = Math.log(Math.abs(y)+1) * sgn * 10.0;
                ctx.lineTo(x, y0 - v);
            }
            ctx.stroke();
        }
    }
    this.redraw = redraw;

}

function testme() {
    var canvas = document.getElementById("mycanvas");
    var lines = [
        {style:"red"},
        {style:"green"},
        {style:"blue"},
        {style:"cyan"},
        {style:"white"},
        {style:"white"}
    ];
    var plotter = new Plotter(canvas, lines);
    var frequency = 100;
    var dataRate = 2;
    var sampleRate = 1000;
    var nco = new Nco(frequency - 0.5, sampleRate);
    var costas = new Costas(frequency, dataRate, sampleRate, plotter);
    for (var i=0 ; i < 15000 ; i++) {
        var cs = nco.next();
        costas.update(cs.cos);
    }
    plotter.redraw();
 }

<commit_msg>good start<commit_after>

function Complex(real, imaginary) {
    this.r = real;
    this.i = imaginary;
    Object.freeze(this);
}
Complex.prototype.add =
    function(other) { return new Complex(this.r + other.r, this.i + other.i); };
Complex.prototype.sub =
    function(other) { return new Complex(this.r - other.r, this.i - other.i); };
Complex.prototype.scale =
    function(scalar){ return new Complex(this.r * scalar,  this.i * scalar ); };
Complex.prototype.mul =
    function(other) { var r = this.r; var i = this.i; var or = other.r; var oi = other.i;
        return new Complex(r * or - i * oi, r * oi + i * or); };
Complex.prototype.neg =
    function() { return new Complex(-this.r, -this.i); };
Complex.prototype.conj =
    function() { return new Complex(this.r, -this.i); };
Complex.prototype.isign =  // this * (0,1)
    function() { return new Complex(-this.i, this.r); };
Complex.prototype.mag =
    function() { var r = this.r; var i = this.i; return r*r+i*i; };
Complex.prototype.abs =
    function() { var r = this.r; var i = this.i; return Math.sqrt(r*r+i*i); };
Complex.prototype.arg =
    function() { return Math.atan2(this.i, this.r); };
Complex.prototype.toString =
    function() { return "(" + this.r.toString() + "," + this.i.toString() + ")"; };
Complex.ZERO =
    new Complex(0,0);
Complex.ONE =
    new Complex(1,0);
Complex.I =
    new Complex(0,1);

var ncoTable = (function() {

    var twopi = Math.PI * 2.0;
    var two16 = 65536;
    var delta = twopi / two16;

    var xs = new Array(two16);

    for (var idx = 0 ; idx < two16 ; idx++) {
        var angle = delta * idx;
        xs[idx] = { cos: Math.cos(angle), sin: Math.sin(angle) };
    }
    return xs;
})();

/**
 * A sine generator with a 32-bit accumulator and a 16-bit
 * lookup table.  Much faster than Math.whatever
 */
function Nco(frequency, sampleRate) {
    "use strict";
    var freq = 0|0;
    function setFrequency(frequency) {
        freq  = (4294967296.0 * frequency / sampleRate)|0;
		return freq;
    }
    this.setFrequency = setFrequency;
    setFrequency(frequency);

    var phase = 0|0;
    var table = ncoTable;

    this.next = function() {
        phase = (phase + freq) & 0xffffffff;
        return table[(phase >> 16) & 0xffff];
    };

    this.mixNext = function (v) {
        phase = (phase + freq) & 0xffffffff;
        var cs = table[(phase >> 16) & 0xffff];
        return new Complex(v*cs.cos, v*cs.sin);
    };

}

var Biquad = (function() {

    function Filter(b0, b1, b2, a1, a2) {

        var x1=0,  x2=0,  y1=0,  y2=0;
        var x1r=0, x2r=0, y1r=0, y2r=0;
        var x1i=0, x2i=0, y1i=0, y2i=0;

        this.update = function(x) {
            var y = b0*x + b1*x1 + b2*x2 - a1*y1 - a2*y2;
            x2 = x1; x1 = x;
            y2 = y1; y1 = y;
            return y;
        };

        this.updatex = function(x) {
            var r = x.r; var i = x.i;
            var yr = b0*r + b1*x1r + b2*x2r - a1*y1r - a2*y2r;
            var yi = b0*i + b1*x1i + b2*x2i - a1*y1i - a2*y2i;
            x2r = x1r; x1r = r;
            x2i = x1i; x1i = i;
            y2r = y1r; y1r = yr;
            y2i = y1i; y1i = yi;
            return new Complex(yr, yi);
        };
    }

    var cls = {
        lowPass : function(frequency, sampleRate, q) {
            q = typeof q !== 'undefined' ? q : 0.707;
            var freq = 2.0 * Math.PI * frequency / sampleRate;
            var alpha = Math.sin(freq) / (2.0 * q);
            var b0 = (1.0 - Math.cos(freq)) / 2.0;
            var b1 =  1.0 - Math.cos(freq);
            var b2 = (1.0 - Math.cos(freq)) / 2.0;
            var a0 = 1.0 + alpha;
            var a1 = -2.0 * Math.cos(freq);
            var a2 = 1.0 - alpha;
            return new Filter(b0/a0, b1/a0, b2/a0, a1/a0, a2/a0);
        },

        highPass : function(frequency, sampleRate, q) {
            q = typeof q !== 'undefined' ? q : 0.707;
            var freq = 2.0 * Math.PI * frequency / sampleRate;
            var alpha = Math.sin(freq) / (2.0 * q);
            var b0 =  (1.0 + Math.cos(freq)) / 2.0;
            var b1 = -(1.0 + Math.cos(freq));
            var b2 =  (1.0 + Math.cos(freq)) / 2.0;
            var a0 = 1.0 + alpha;
            var a1 = -2.0 * Math.cos(freq);
            var a2 = 1.0 - alpha;
            return new Filter(b0/a0, b1/a0, b2/a0, a1/a0, a2/a0);
        },

        bandPass : function(frequency, sampleRate, q) {
            q = typeof q !== 'undefined' ? q : 0.5;
            var freq = 2.0 * Math.PI * frequency / sampleRate;
            var alpha = Math.sin(freq) / (2.0 * q);
            var b0 = Math.sin(freq) / 2.0;   // = q*alpha
            var b1 = 0.0;
            var b2 = -Math.sin(freq) / 2.0;  // = -q*alpha
            var a0 = 1.0 + alpha;
            var a1 = -2.0 * Math.cos(freq);
            var a2 = 1.0 - alpha;
            return new Filter(b0/a0, b1/a0, b2/a0, a1/a0, a2/a0);
        },

        bandReject : function(frequency, sampleRate, q) {
            q = typeof q !== 'undefined' ? q : 0.5;
            var freq = 2.0 * Math.PI * frequency / sampleRate;
            var alpha = Math.sin(freq) / (2.0 * q);
            var b0 = 1.0;
            var b1 = -2.0 * Math.cos(freq);
            var b2 = 1.0;
            var a0 = 1.0 + alpha;
            var a1 = -2.0 * Math.cos(freq);
            var a2 = 1.0 - alpha;
            return new Filter(b0/a0, b1/a0, b2/a0, a1/a0, a2/a0);
        }
    };

    return cls;

})();

var cossinTable = (function() {

    var twopi = Math.PI * 2.0;
    var two16 = 65536;
    var delta = twopi / two16;

    var xs = new Array(two16);

    for (var idx = 0 ; idx < two16 ; idx++) {
        var angle = delta * idx;
        xs[idx] = { cos: Math.cos(angle), sin: Math.sin(angle) };
    }
    return xs;
})();

/**
 * This version uses Biquad filters for the arms
 * http://www.trondeau.com/blog/2011/8/13/control-loop-gain-values.html
 */
function Costas(frequency, dataRate, sampleRate, plotter) {
    "use strict";

    var err   = 0;
    var alpha = 0;
    var beta  = 0;
    var damp  = 0.707;
    var freq  = 0;
    var phase = 0|0;
    var counter = 0;

    var table = cossinTable;
    var ilp, qlp, dlp;
    var agcint1=0, agcint2=0;
    var agcgain=0.001;

    function setFrequency(frequency) {
        freq  = (4294967296.0 * frequency / sampleRate)|0;
    }
    this.setFrequency = setFrequency;
    setFrequency(frequency);
    var maxErr = 4294967296.0 * 20.0 / sampleRate;
    console.log("maxerr: " + maxErr);
    var minErr = -maxErr;

    function setDataRate(rate) {
        ilp = Biquad.lowPass(rate*0.5, sampleRate);
        qlp = Biquad.lowPass(rate*0.5, sampleRate);
        dlp = Biquad.lowPass(rate*4.0, sampleRate);
    }
    this.setDataRate = setDataRate;
    setDataRate(dataRate);

    this.update = function(v) {
        v = v * agcint1;
        var agcerr = 1.0 - Math.abs(v);
        agcint2 = agcint1;
        agcint1 = agcint2 + agcgain * agcerr;

        var adjFreq = (freq + err) | 0;
        phase = (phase + adjFreq) & 0xffffffff;
        var cs = table[(phase >> 16) & 0xffff];
        var i = v * cs.cos;
        var q = v * cs.sin;
        var iz = ilp.update(i);
        var qz = qlp.update(q);
        //console.log("qz: " + qz);
        var angle = -Math.atan2(qz, iz);
        err += dlp.update(angle) * 5000.0; // adjust this
        if (err < minErr)
            err = minErr;
        else if (err > maxErr)
            err = maxErr;
        //console.log("" + iz + " " + qz + " " + angle + " " + err);
        if (++counter % 30 === 0)
            plotter.update([iz, qz, angle, err, minErr, maxErr]);
        //console.log("iq: " + iz + ", " + qz);
        return new Complex(iz,qz);
    };

}

function Plotter(canvas, lines) {
    var size = lines.length;
    var ctx = canvas.getContext("2d");
    var width = canvas.width;
    var height = canvas.height;

    function reset() {
        for (var i=0 ; i<size ; i++) {
            lines[i].data = [];
        }
    }
    var y0 = canvas.height / 2;

    reset();

    this.update = function(values) {
       var len = values.length;
       if (len>size) {
           len = size;
       }
       for (var i=0 ; i<len ; i++) {
           var data = lines[i].data;
           data[data.length] = values[i];
       }
    }

    function scaledY(y) {
        var sgn = (y>0) ? 1 : -1;
        var v = Math.log(Math.abs(y)+1) * sgn * 10.0;
        return v;
    }

    function redraw() {
        ctx.strokeStyle = "black";
        ctx.rect(0,0, width, height);
        ctx.fill();

        var pwr = 1;
        ctx.strokeStyle = "orange";
        while (pwr < 100000000) {
            var y = scaledY(pwr);
            ctx.beginPath();
            ctx.moveTo(0, y0-y);
            ctx.lineTo(width, y0-y);
            ctx.stroke();
            ctx.beginPath();
            ctx.moveTo(0, y0+y);
            ctx.lineTo(width, y0+y);
            ctx.stroke();
            pwr *= 10;
            console.log("ok");
        }

        for (var i=0 ; i < size ; i++) {
            var line = lines[i];
            ctx.strokeStyle = line.style;
            ctx.beginPath();
            ctx.moveTo(0, y0);
            var data = line.data;
            var ll = data.length;
            for (var x=0 ; x<ll ; x++) {
                var y = data[x];
                ctx.lineTo(x, y0 - scaledY(y));
            }
            ctx.stroke();
        }
    }
    this.redraw = redraw;

}

function testme() {
    var canvas = document.getElementById("mycanvas");
    var lines = [
        {style:"red"},
        {style:"green"},
        {style:"blue"},
        {style:"cyan"},
        {style:"white"},
        {style:"white"}
    ];
    var plotter = new Plotter(canvas, lines);
    var frequency = 100;
    var dataRate = 2;
    var sampleRate = 1000;
    var nco = new Nco(frequency - 0.5, sampleRate);
    var costas = new Costas(frequency, dataRate, sampleRate, plotter);

    for (var i=0 ; i < 24000 ; i++) {
        var cs = nco.next();
        costas.update(cs.cos);
    }
    plotter.redraw();
 }

<|endoftext|>


<commit_before>var env = process.env.GOP_ENV || 'dev'
  , config = {}
  ;

// Common options
config.env = env;
config.serverPort = 5000;
config.disconnectTimeout = 2000;

// Environment specific options
switch (env) {
  case 'prod':
    config.host = 'http://lmt.io:5000';
    break;

  case 'dev':
  default:
    config.loginNotRequired = false;   // Set to true to avoid having to log upon every reload
    config.host = 'http://localhost:5000';
    break;
}

// Interface
module.exports = config;
<commit_msg>Good hostname<commit_after>var env = process.env.GOP_ENV || 'dev'
  , config = {}
  ;

// Common options
config.env = env;
config.serverPort = 5000;
config.disconnectTimeout = 2000;

// Environment specific options
switch (env) {
  case 'prod':
    config.host = 'http://lmt.io';
    break;

  case 'dev':
  default:
    config.loginNotRequired = false;   // Set to true to avoid having to log upon every reload
    config.host = 'http://localhost:5000';
    break;
}

// Interface
module.exports = config;
<|endoftext|>


<commit_before>(function(root, factory) {
    if (typeof exports === 'object') { // Node.js
        module.exports = factory(
            require('../functional.js'),
            require('../reactive.js')
        );
    } else if (typeof define === 'function' && define.amd) { // Require.JS
        define(['jef/functional', 'jef/reactive'], factory);
    } else {  // Browser globals
        root.jef = root.jef || {};
        root.jef.mathematical = factory(
            root.jef.functional,
            root.jef.reactive
        );
    }
})(this, function(f, r){
    'use strict';

    function display(value) {
        return function() {
            console.log('Triggered on change; {c} value is: ' + value());
        }
    }

    function sum(a, b) {
        return function() {
            return a() + b();
        }
    }

    function replace(string) {
        return function() {
            var args = f.slice(arguments);
            return string.replace(/{([^}]+)}/gm, function(key) {
                return args.shift()();
            });
        }
    }

    var a, b, c, message;

    message = replace('Current result of {a} + {b} = {c}');

    a = r.value(1);
    b = r.value(1);
    c = sum(a, b);

    message = message.bind(message, a, b, c);
    console.log(message());

    a = r.observable(a, display(c));
    b = r.observable(b, display(c));

    a(2);
    console.log(message());
    a(3);
    console.log(message());
    b(4);
    console.log(message());

});
<commit_msg>demo namespace<commit_after>(function(root, factory) {
    if (typeof exports === 'object') { // Node.js
        module.exports = factory(
            require('../functional.js'),
            require('../reactive.js')
        );
    } else if (typeof define === 'function' && define.amd) { // Require.JS
        define(['jef/functional', 'jef/reactive'], factory);
    } else {  // Browser globals
        root.jefdemo = root.jefdemo || {};
        root.jefdemo.reactive_demo = factory(
            root.jef.functional,
            root.jef.reactive
        );
    }
})(this, function(f, r){
    'use strict';

    function display(value) {
        return function() {
            console.log('Triggered on change; {c} value is: ' + value());
        }
    }

    function sum(a, b) {
        return function() {
            return a() + b();
        }
    }

    function replace(string) {
        return function() {
            var args = f.slice(arguments);
            return string.replace(/{([^}]+)}/gm, function(key) {
                return args.shift()();
            });
        }
    }

    var a, b, c, message;

    message = replace('Current result of {a} + {b} = {c}');

    a = r.value(1);
    b = r.value(1);
    c = sum(a, b);

    message = message.bind(message, a, b, c);
    console.log(message());

    a = r.observable(a, display(c));
    b = r.observable(b, display(c));

    a(2);
    console.log(message());
    a(3);
    console.log(message());
    b(4);
    console.log(message());

});
<|endoftext|>


<commit_before>'use strict';

const path = require('path');

module.exports = {

    // -------- app configuration --------

    // 端口号
    'app.port': 3010,

    // -------- log configuration --------

    // 启用日志
    'log.enable': true,

    // 启用接口日志
    'log.api.enable': false,

    // 日志文件夹路径
    'log.path': './logs',

    // 单个日志文件大小
    'log.maxsize': 1024 * 1024 * 100
};<commit_msg>remove dependency<commit_after>'use strict';

module.exports = {

    // -------- app configuration --------

    // 端口号
    'app.port': 3010,

    // -------- log configuration --------

    // 启用日志
    'log.enable': true,

    // 启用接口日志
    'log.api.enable': false,

    // 日志文件夹路径
    'log.path': './logs',

    // 单个日志文件大小
    'log.maxsize': 1024 * 1024 * 100
};<|endoftext|>


<commit_before><commit_msg>:boom: added month total days function<commit_after><|endoftext|>


<commit_before>var hamming = (n) => {
  if(n === 1){return 1;}
  let sequences = [1];
  let lastIndex = 0;
  let smallestIndex = 0;
  while( sequences[sequences.length - 1] < 30 && sequences.length < n){
    let lastNum = sequences[sequences.length - 1];
    let candidates = [];
    let appliedLastIndex = false;
    for(let i = lastIndex; i < sequences.length; ++i){
      let two = sequences[i] * 2;
      let three = sequences[i] * 3;
      let five = sequences[i] * 5;
      if(two > lastNum){
        candidates.push(two);
        if(appliedLastIndex === false){
          if(smallestIndex > i){
            smallestIndex = i;
          }
          appliedLastIndex = true;
        }
      }
      if(three > lastNum){
        candidates.push(three);
        if(appliedLastIndex === false){
          if(smallestIndex > i){
            smallestIndex = i;
          }
          appliedLastIndex = true;
        }
      }
      if(five > lastNum){
        candidates.push(five);
        if(appliedLastIndex === false){
          if(smallestIndex > i){
            smallestIndex = i;
          }
          appliedLastIndex = true;
        }
      }
    }
    lastIndex = smallestIndex;
    let smallest = Math.min.apply(Math, candidates);
    sequences.push(smallest);
  }

  if(n > sequences.length){
    let num = 31;
    while(sequences.length < n){
      let newNum = num;
      while(newNum !== 0 || newNum !== 1){
        if(newNum % 2 === 0){
          newNum = newNum / 2;
        } else if(newNum % 3 === 0){
          newNum = newNum / 3;
        } else if(newNum % 5 === 0){
          newNum = newNum / 5;
        } else {
          newNum = 0;
        }
      }
      if(newNum === 1){
        sequences.push(num);
      }
      ++num;
    }
  }
  return sequences.pop();

};

module.exports = hamming;
<commit_msg>hamming refactor still no pass<commit_after>var hamming = (n) => {
  console.log(n);
  if(n === 1){return 1;}
  let sequences = [1];
  let lastIndex = 0;
  let smallestIndex = 0;
  while( sequences[sequences.length - 1] < 30 && sequences.length < n){
    let lastNum = sequences[sequences.length - 1];
    let candidates = [];
    let appliedLastIndex = false;
    for(let i = lastIndex; i < sequences.length; ++i){
      let two = sequences[i] * 2;
      let three = sequences[i] * 3;
      let five = sequences[i] * 5;
      if(two > lastNum){
        candidates.push(two);
        if(appliedLastIndex === false){
          if(smallestIndex > i){
            smallestIndex = i;
          }
          appliedLastIndex = true;
        }
      }
      if(three > lastNum){
        candidates.push(three);
        if(appliedLastIndex === false){
          if(smallestIndex > i){
            smallestIndex = i;
          }
          appliedLastIndex = true;
        }
      }
      if(five > lastNum){
        candidates.push(five);
        if(appliedLastIndex === false){
          if(smallestIndex > i){
            smallestIndex = i;
          }
          appliedLastIndex = true;
        }
      }
    }
    lastIndex = smallestIndex;
    let smallest = Math.min.apply(Math, candidates);
    sequences.push(smallest);
  }

  if(n > sequences.length){
    let num = 31;
    while(sequences.length < n){
      let newNum = num;
      while(newNum !== 0){
        if(newNum % 2 === 0){
          newNum = newNum / 2;
        } else if(newNum % 3 === 0){
          newNum = newNum / 3;
        } else if(newNum % 5 === 0){
          newNum = newNum / 5;
        } else {
          newNum = 0;
        }
        if(newNum === 1){break;}
      }
      if(newNum === 1){
        sequences.push(num);
      }
      ++num;
    }
  }
  return sequences.pop();

};

module.exports = hamming;
<|endoftext|>


<commit_before>import fs from 'fs';
import chalk from 'chalk';

const print = ({
  color,
  message,
}) => {
  //eslint-disable-next-line
  console.log(chalk.bold[color](message));
};

const error = message => print({
  color: 'red',
  message,
});

const success = message => print({
  color: 'green',
  message,
});

//eslint-disable-next-line
export const exit = ({ code = 0, message = '' } = {}) => {
  if (message) {
    const text = `\n\t${message}\n`;
    if (code === 0) {
      success(text);
    } else {
      error(text);
    }
  }
  process.exit(code);
};

export const copy = (src, dest) => new Promise((resolve, reject) => {
  const readStream = fs.createReadStream(src);
  readStream.once('error', reject);
  readStream.once('end', resolve);
  readStream.pipe(fs.createWriteStream(dest));
});
<commit_msg>linting<commit_after>import fs from 'fs';
import chalk from 'chalk';

const print = ({
  color,
  message,
}) => {
  //eslint-disable-next-line
  console.log(chalk.bold[color](message));
};

const error = message => print({
  color: 'red',
  message,
});

const success = message => print({
  color: 'green',
  message,
});

export const exit = ({ code = 0, message = '' } = {}) => {
  if (message) {
    const text = `\n\t${message}\n`;
    if (code === 0) {
      success(text);
    } else {
      error(text);
    }
  }
  process.exit(code);
};

export const copy = (src, dest) => new Promise((resolve, reject) => {
  const readStream = fs.createReadStream(src);
  readStream.once('error', reject);
  readStream.once('end', resolve);
  readStream.pipe(fs.createWriteStream(dest));
});
<|endoftext|>


<commit_before>const fs = require('fs-extra');
const path = require('path');
var readline = require('readline');
const constants = require('./constants.js');
const displayCheckbox = require('./functions/displayCheckbox.js');
const createFile = require('./functions/createFile.js');

const configFilepath = path.join(constants.GLOBAL_DIR, constants.GLOBAL_CONFIG);

/**
 * Create a config file based on the values provided
 *
 * @returns {void}
 */
function createConfigFile(config) {
    createFile({
        name: configFilepath,
        source: config
    });
}

/**
 * Configure the tool with some settings
 *
 * @param {string} options - Extra options.
 * @returns {void}
 */
module.exports = (optionalPath, options) => {
    // gas config -r
    if (options.remove) {
        process.stdout.write('Removing your config completely');
        fs.removeSync(configFilepath);
        displayCheckbox('green');
        process.exit(0);
    }

    // gas config -i
    if (options.import) {
        process.stdout.write(`Importing your config from '${optionalPath}'`);

        let config = fs.readFileSync(optionalPath, 'utf8');
        if (!config) {
            config = {};
        }

        // Overwrite current config
        createConfigFile(config);
        displayCheckbox('green');
        process.exit(0);
    }

    // gas config -e
    if (options.export) {
        // Read content of the global config file
        let config = fs.readFileSync(configFilepath, 'utf8');

        if (!config) {
            config = '{}';
        }

        // Create file or print output
        if (optionalPath) {
            process.stdout.write(`Exporting your config to '${optionalPath}'`);

            // Create a file in the specified location
            const file = {
                name: path.join(optionalPath, 'google-apps-script-config.json'),
                source: config,
            };
            createFile(file);
            displayCheckbox('green');
        } else {
            console.log(config);
        }
    }

    // gas config
    const config = {};
    var rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    rl.question('Q1: ', function (input) {
        config.test = input;
        rl.question('Q2: ', function (input) {
            config.derp = input;
            rl.question('Q3: ', function (input) {
                config.wa = input;
                console.log(config);
                rl.close();
            });
        });
    });

    //console.log('dialog');
    //createConfigFile();
};
<commit_msg>Some work on config entry<commit_after>const fs = require('fs-extra');
const path = require('path');
var readline = require('readline');
const constants = require('./constants.js');
const displayCheckbox = require('./functions/displayCheckbox.js');
const createFile = require('./functions/createFile.js');

const configFilepath = path.join(constants.GLOBAL_DIR, constants.GLOBAL_CONFIG);

/**
 * Create a config file based on the values provided
 *
 * @param {object} config - The config to create
 * @returns {void}
 */
function createConfigFile(config) {
    createFile({
        name: configFilepath,
        source: config
    });
}

/**
 * Create a config file based on the values provided
 *
 * @param {string} success - Whether or not the dialog completed succesfully
 * @param {string} config - The config we created trough the dialog
 * @returns {void}
 */
function endDialog(success, config) {
    if (success) {
        // console.log(config);
        createConfigFile(config);
        console.log();
        process.stdout.write('Succesfully configured gas.');
        displayCheckbox('green');
    } else {
        console.log(`Only 'y' and 'n' are accepted inputs.`);
        process.stdout.write('Failed to configure gas.');
        displayCheckbox('red');
        process.exit(1);
    }
}

/**
 * Configure the tool with some settings
 *
 * @param {string} optionalPath - Either the path the a config file to import or the location to which we need to export the config
 * @param {string} options - Extra options.
 * @returns {void}
 */
module.exports = (optionalPath, options) => {
    // gas config -r
    if (options.remove) {
        process.stdout.write('Removing your config completely');
        fs.removeSync(configFilepath);
        displayCheckbox('green');
        process.exit(0);
    }

    // gas config -i
    if (options.import) {
        process.stdout.write(`Importing your config from '${optionalPath}'`);

        let config = fs.readFileSync(optionalPath, 'utf8');
        if (!config) {
            config = {};
        }

        // Overwrite current config
        createConfigFile(config);
        displayCheckbox('green');
        process.exit(0);
    }

    // gas config -e
    if (options.export) {
        // Read content of the global config file
        let config = fs.readFileSync(configFilepath, 'utf8');

        if (!config) {
            config = '{}';
        }

        // Create file or print output
        if (optionalPath) {
            process.stdout.write(`Exporting your config to '${optionalPath}'`);

            // Create a file in the specified location
            const file = {
                name: path.join(optionalPath, 'google-apps-script-config.json'),
                source: config,
            };
            createFile(file);
            displayCheckbox('green');
        } else {
            console.log(config);
        }
    }

    // gas config
    const config = {};
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    rl.question(`Do you want to use .gs as extension for your local code files instead of .js? [${'y'.green}/${'n'.red}]\n > `, function (input) {
        if (input === 'y') {
            config.extension = '.gs';
        } else if (input !== 'n') {
            endDialog(false);
            rl.close();
        }

        rl.question(`Do you want to use a custom OAuth 2.0 client to authenticate with Google Drive? [${'y'.green}/${'n'.red}]\n > `, function (input) {
            if (input === 'y') {
                config.client = {};
                console.log();
                rl.question(`Enter the 'Client ID' of your client \n > `, function (input) {
                    config.client.id = input;
                    rl.question(`Enter your 'Client secret' of your client\n > `, function (input) {
                        config.client.secret = input;
                        endDialog(true, config);
                        rl.close();
                    });
                });
            } else if (input === 'n') {
                endDialog(true, config);
                rl.close();
            } else {
                endDialog(false);
                rl.close();
            }
        });
    });
};
<|endoftext|>


<commit_before>(function(){
/**
@namespace mi2JS(core)

*/

/** Very basic wrapper used for scripting(similar to JQuery and alike). Contains some useful
   methods to allow manipulation, and can be extended further if needed. For more advanced
   functionalities check {@link mi2JS.comp..Base} component and it's descendants in {@link mi2JS.comp.}.
@class NodeWrapper
@memberof mi2JS(core)
*/

/**
@name mi2JS
*/
var $ = window.mi2JS = window.mi2JS || function NodeWrapper(node, root){
	if( this instanceof $){ // called as "new mi2JS(node);"
		this.el = node instanceof String ? $.find(node, root) : node;
		if(this.el === null) throw new Error('null node or not found '+node);
	}else
		return new $(node, root);
};

/**  /^[A-Za-z]+[\w-_]*/ - defines allowed tag names when sent as parameter to find/findAll
@constant tagNameReg
@memberof mi2JS(core)
*/
$.tagNameReg = /^[A-Za-z]+[\w-_]*/;

/** return first node matching the search criteria
@function find
@memberof mi2JS(core)
@param {String} search Search pattern
@param {Element} root root node
*/
$.find = function(search, root){
	// $.nn('find',{search:search});//ASSERT

	root = root || document.body;
	if(root instanceof $) root = root.el;

	if(search.charAt(0) == '#') return root.getElementById(search.substring(1));

	if($.tagNameReg.test(search)) return root.getElementsByTagName(search)[0];

	return root.querySelector(search);
}

/** return all nodes matching the search criteria
@function findAll
@memberof mi2JS(core)
@param {String} search Search pattern
@param {Element} root root node
*/
$.findAll = function(search, root){
	// $.nn('find',{search:search});//ASSERT

	root = root || document.body;
	if(root instanceof $) root = root.el;

	if($.tagNameReg.test(search)) return root.getElementsByTagName(search);

	return root.querySelectorAll(search);
}

/** use the object as scope for the function (popular)
@function bind
@memberof mi2JS(core)
@param {Object} object scope for the function
@param {Element} func function
*/
$.bind = function(object, func){
	// dynamic
	if(typeof func == 'string')
		return function() { object[func].apply(object, arguments); };

	// native implementation
	if(func.bind) return func.bind(object);

	// closure when native implementation not present
	return function() { func.apply(object, arguments); };
};

/**

utility for classes  -
Extends destination class with source class.

Taken over from Oliver Caldwell's blog:  Prototypical inheritance done right

{@link http://oli.me.uk/2013/06/01/prototypical-inheritance-done-right/}

@function extend
@memberof mi2JS(core)

@param {class} destination The class that should be inheriting things.
@param {class} source The parent class that should be inherited from.
@return {object} The prototype of the parent.

 */
$.extend = function(destination, source) {
	destination.prototype = Object.create(source.prototype);
	destination.prototype.constructor = destination;
	destination.superClass = source.prototype;
	return source.prototype;
};

/**
utility for classes  -
Takes prototype of the source(mixin) class and copies properties to prototype of destination class.

@function mixin
@memberof mi2JS(core)

@param {class} destination - The class that is being enhanced with the mixin
@param {class} source - The mixin class
@param {boolean} overwrite - should the existing properties be overwritten
*/
$.mixin = function(dest, source, overwrite) {
	var proto = dest.prototype, ext = source.prototype;
	for(var p in ext) if(!proto[p])	proto[p] = ext[p];
};

/** Update dest object by adding properties from another object. Copied aro only own properties
of the other object (checked by hasOwnProperty).

@function update
@memberof mi2JS(core)

@param {Object} destination - The object that is being updated
@param {Object} update - Object from which the properties are copied
*/
$.update = function(dest, update){
	if(dest && update ){
		for (var prop in update)
			if(update.hasOwnProperty(prop)) dest[prop] = update[prop];
	}
	return dest;
};

/** Check if the passed parameter is an array
@function isArray
@memberof mi2JS(core)
@param {Object} object
*/
$.isArray = Array.isArray ||  function (xs) {
    return {}.toString.call(xs) === '[object Array]';
};

/** Make a shallow copy of an object.

@function copy
@memberof mi2JS(core)

@param {Object} obj - objec to copy
*/
$.copy = function(obj){
    if ($.isArray(obj)) {
        var len = obj.length;
        copy = Array(len);
        for (var i = 0; i < len; i++) {
            copy[i] = obj[i];
        }
        return copy;
    }
	return $.update({},obj);
};

/** Parse number using parseFloat, but return zero if not a number.

@function num
@memberof mi2JS(core)

@param obj - string or anything else (if parseFloat fails, zero is returned)
*/
$.num = function(str){
	var n = parseFloat(str);
	if(isNaN(n)) return 0;
	return n;
};

/** Check if passed value is empty.

null

undefined

 === 0

empty string

empty array

empty object (without any iterable properties)

@function isEmpty
@memberof mi2JS(core)

@param obj
*/
$.isEmpty = function(obj){
	if(obj === void 0 || obj === null || obj === 0) return true;
	if(obj instanceof Array || typeof obj == 'string') return obj.length == 0;
	if(typeof obj == 'object'){
		for(var p in obj) return false;
		return true;
	}
	return false;
};

/** Uses {@link mi2JS(core).fixEvent}. Listen for event on an object. Any object that has either
addEventListener or attachEvent.

@function listen
@memberof mi2JS(core)
@param {Object} obj object that will generate the event
@param {String} evt event name
@param {Function} fnc callback
@param {Object} self callback function scope ( bind will be performed )
@param {boolean|object} options options parameter for addEventListener
*/
$.listen = function ( obj, evt, fnc, self, options ){

//	$.nn('$.listen', {obj:obj, evt:evt, fnc:fnc} );

	var listener = function(evt){
		if(typeof(fnc) == 'string') fnc = self[fnc];
		fnc.call(self || obj, $.fixEvent(evt));
	};

	if (obj.addEventListener){
		obj.addEventListener(evt,listener,options);
		return true;
	}
	else
		return obj.attachEvent("on"+evt,listener);
};

/** Used by {@link mi2JS(core).listen}. Do some cleaning on the event object provided by the browser, for easier handling of browser differences.
This is likely more extensive in other libraries. Override it if you need more.

@function fixEvent
@memberof mi2JS(core)
@param {Event} evt Browser  event
*/
$.fixEvent = function(evt){
	evt = evt || window.event;
	evt.stop = function() {
		if(this.preventDefault){
			this.preventDefault();
			this.stopPropagation();
		} else {
			this.returnValue = false;
		}
	};

	evt.target = evt.target || evt.srcElement;

	evt.pointerX = function() {
		return this.pageX || (this.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
	};

	evt.pointerY = function() {
		return this.pageY || (this.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
	};

	return evt;
};

}());
<commit_msg>change memberof<commit_after>(function(){
/**
@namespace mi2JS(core)

*/

/** Very basic wrapper used for scripting(similar to JQuery and alike). Contains some useful
   methods to allow manipulation, and can be extended further if needed. For more advanced
   functionalities check {@link mi2JS.comp..Base} component and it's descendants in {@link mi2JS.comp.}.
@class NodeWrapper
@memberof mi2JS(core)
*/

/**
@name mi2JS
@memberof mi2JS(core)
*/
var $ = window.mi2JS = window.mi2JS || function NodeWrapper(node, root){
	if( this instanceof $){ // called as "new mi2JS(node);"
		this.el = node instanceof String ? $.find(node, root) : node;
		if(this.el === null) throw new Error('null node or not found '+node);
	}else
		return new $(node, root);
};

/**  /^[A-Za-z]+[\w-_]*/ - defines allowed tag names when sent as parameter to find/findAll
@constant tagNameReg
@memberof mi2JS(core)
*/
$.tagNameReg = /^[A-Za-z]+[\w-_]*/;

/** return first node matching the search criteria
@function find
@memberof mi2JS(core)
@param {String} search Search pattern
@param {Element} root root node
*/
$.find = function(search, root){
	// $.nn('find',{search:search});//ASSERT

	root = root || document.body;
	if(root instanceof $) root = root.el;

	if(search.charAt(0) == '#') return root.getElementById(search.substring(1));

	if($.tagNameReg.test(search)) return root.getElementsByTagName(search)[0];

	return root.querySelector(search);
}

/** return all nodes matching the search criteria
@function findAll
@memberof mi2JS(core)
@param {String} search Search pattern
@param {Element} root root node
*/
$.findAll = function(search, root){
	// $.nn('find',{search:search});//ASSERT

	root = root || document.body;
	if(root instanceof $) root = root.el;

	if($.tagNameReg.test(search)) return root.getElementsByTagName(search);

	return root.querySelectorAll(search);
}

/** use the object as scope for the function (popular)
@function bind
@memberof mi2JS(core)
@param {Object} object scope for the function
@param {Element} func function
*/
$.bind = function(object, func){
	// dynamic
	if(typeof func == 'string')
		return function() { object[func].apply(object, arguments); };

	// native implementation
	if(func.bind) return func.bind(object);

	// closure when native implementation not present
	return function() { func.apply(object, arguments); };
};

/**

utility for classes  -
Extends destination class with source class.

Taken over from Oliver Caldwell's blog:  Prototypical inheritance done right

{@link http://oli.me.uk/2013/06/01/prototypical-inheritance-done-right/}

@function extend
@memberof mi2JS(core)

@param {class} destination The class that should be inheriting things.
@param {class} source The parent class that should be inherited from.
@return {object} The prototype of the parent.

 */
$.extend = function(destination, source) {
	destination.prototype = Object.create(source.prototype);
	destination.prototype.constructor = destination;
	destination.superClass = source.prototype;
	return source.prototype;
};

/**
utility for classes  -
Takes prototype of the source(mixin) class and copies properties to prototype of destination class.

@function mixin
@memberof mi2JS(core)

@param {class} destination - The class that is being enhanced with the mixin
@param {class} source - The mixin class
@param {boolean} overwrite - should the existing properties be overwritten
*/
$.mixin = function(dest, source, overwrite) {
	var proto = dest.prototype, ext = source.prototype;
	for(var p in ext) if(!proto[p])	proto[p] = ext[p];
};

/** Update dest object by adding properties from another object. Copied aro only own properties
of the other object (checked by hasOwnProperty).

@function update
@memberof mi2JS(core)

@param {Object} destination - The object that is being updated
@param {Object} update - Object from which the properties are copied
*/
$.update = function(dest, update){
	if(dest && update ){
		for (var prop in update)
			if(update.hasOwnProperty(prop)) dest[prop] = update[prop];
	}
	return dest;
};

/** Check if the passed parameter is an array
@function isArray
@memberof mi2JS(core)
@param {Object} object
*/
$.isArray = Array.isArray ||  function (xs) {
    return {}.toString.call(xs) === '[object Array]';
};

/** Make a shallow copy of an object.

@function copy
@memberof mi2JS(core)

@param {Object} obj - objec to copy
*/
$.copy = function(obj){
    if ($.isArray(obj)) {
        var len = obj.length;
        copy = Array(len);
        for (var i = 0; i < len; i++) {
            copy[i] = obj[i];
        }
        return copy;
    }
	return $.update({},obj);
};

/** Parse number using parseFloat, but return zero if not a number.

@function num
@memberof mi2JS(core)

@param obj - string or anything else (if parseFloat fails, zero is returned)
*/
$.num = function(str){
	var n = parseFloat(str);
	if(isNaN(n)) return 0;
	return n;
};

/** Check if passed value is empty.

null

undefined

 === 0

empty string

empty array

empty object (without any iterable properties)

@function isEmpty
@memberof mi2JS(core)

@param obj
*/
$.isEmpty = function(obj){
	if(obj === void 0 || obj === null || obj === 0) return true;
	if(obj instanceof Array || typeof obj == 'string') return obj.length == 0;
	if(typeof obj == 'object'){
		for(var p in obj) return false;
		return true;
	}
	return false;
};

/** Uses {@link mi2JS(core).fixEvent}. Listen for event on an object. Any object that has either
addEventListener or attachEvent.

@function listen
@memberof mi2JS(core)
@param {Object} obj object that will generate the event
@param {String} evt event name
@param {Function} fnc callback
@param {Object} self callback function scope ( bind will be performed )
@param {boolean|object} options options parameter for addEventListener
*/
$.listen = function ( obj, evt, fnc, self, options ){

//	$.nn('$.listen', {obj:obj, evt:evt, fnc:fnc} );

	var listener = function(evt){
		if(typeof(fnc) == 'string') fnc = self[fnc];
		fnc.call(self || obj, $.fixEvent(evt));
	};

	if (obj.addEventListener){
		obj.addEventListener(evt,listener,options);
		return true;
	}
	else
		return obj.attachEvent("on"+evt,listener);
};

/** Used by {@link mi2JS(core).listen}. Do some cleaning on the event object provided by the browser, for easier handling of browser differences.
This is likely more extensive in other libraries. Override it if you need more.

@function fixEvent
@memberof mi2JS(core)
@param {Event} evt Browser  event
*/
$.fixEvent = function(evt){
	evt = evt || window.event;
	evt.stop = function() {
		if(this.preventDefault){
			this.preventDefault();
			this.stopPropagation();
		} else {
			this.returnValue = false;
		}
	};

	evt.target = evt.target || evt.srcElement;

	evt.pointerX = function() {
		return this.pageX || (this.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
	};

	evt.pointerY = function() {
		return this.pageY || (this.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
	};

	return evt;
};

}());
<|endoftext|>


<commit_before>// Defaults:
var PORT = process.env.PORT || 3000
  , SESSION_SECRET = process.env.PORT || "8L8BudMkqBUqrz"
  , SERVER_NAME = process.env.SERVER_NAME || "http://localhost:3000"
  , GITHUB_APP_ID = process.env.GITHUB_APP_ID || "a3af4568e9d8ca4165fe"
  , GITHUB_APP_SECRET = process.env.GITHUB_APP_SECRET || "18651128b57787a3336094e2ba1af240dfe44f6c"
  , GITHUB_HOSTNAME =  process.env.GITHUB_HOSTNAME || SERVER_NAME

var everypaas = require('everypaas')

// Config object encapsulates strider configured state from ENV variables etc.
module.exports = {
    db_uri : everypaas.getMongodbUrl()
  , server_port: PORT
  , session_secret: SESSION_SECRET
  , github : {
      appId : GITHUB_APP_ID
    , appSecret : GITHUB_APP_SECRET
    , myHostname : GITHUB_HOSTNAME
  }
}

// Logging configuration
module.exports.logging = {
  exitOnError: true,
  loggly_enabled: false,
  file_enabled: false,
  console: {
    // Log everything
    level: 0,
    colorize: true,
    timestamp: true
  },
  console_enabled: true
}
<commit_msg>default db uri<commit_after>// Defaults:
var PORT = process.env.PORT || 3000
  , SESSION_SECRET = process.env.PORT || "8L8BudMkqBUqrz"
  , SERVER_NAME = process.env.SERVER_NAME || "http://localhost:3000"
  , GITHUB_APP_ID = process.env.GITHUB_APP_ID || "a3af4568e9d8ca4165fe"
  , GITHUB_APP_SECRET = process.env.GITHUB_APP_SECRET || "18651128b57787a3336094e2ba1af240dfe44f6c"
  , GITHUB_HOSTNAME =  process.env.GITHUB_HOSTNAME || SERVER_NAME

var everypaas = require('everypaas')

// Config object encapsulates strider configured state from ENV variables etc.
module.exports = {
    db_uri : process.env.DB_URI || everypaas.getMongodbUrl() || "mongodb://localhost/strider-foss"
  , server_port: PORT
  , session_secret: SESSION_SECRET
  , github : {
      appId : GITHUB_APP_ID
    , appSecret : GITHUB_APP_SECRET
    , myHostname : GITHUB_HOSTNAME
  }
}

// Logging configuration
module.exports.logging = {
  exitOnError: true,
  loggly_enabled: false,
  file_enabled: false,
  console: {
    // Log everything
    level: 0,
    colorize: true,
    timestamp: true
  },
  console_enabled: true
}
<|endoftext|>


<commit_before>import Game from './gameModel';
import Q from 'q';
import helpers from '../config/helpers';

var findGame = Q.nbind(Game.findOne, Game);
var createGame = Q.nbind(Game.create, Game);

export default {
  // Create new multiplayer match
  makeGame: function (req, res, next) {
    var user1 = req.body.user1;
    var user2 = req.body.user2;
    createGame({
      player1: user1,
      player2: user2,
      active: true
    })
    .then(function (newGame) {
      console.log(newGame);
      res.send(201, newGame._id);
    });
  },

  // Delete specified game from database
  cancelGame: function (gameId, res) {
    findGame({_id : "ObjectId(" + gameId + ")"})
      .then(function (targetGame) {
        console.log(targetGame);
        targetGame.active = false;
        res.send(201, targetGame);
      })
      .catch(function (err) {
        console.error(err);
      });
  }
};<commit_msg>Fully refactor gameController.js using ES6 syntax<commit_after>import Game from './gameModel';
import Q from 'q';

const findGame = Q.nbind(Game.findOne, Game);
const createGame = Q.nbind(Game.create, Game);

export default {
  // Create new multiplayer match
  makeGame(req, res, next) {
    const user1 = req.body.user1;
    const user2 = req.body.user2;
    createGame({
      player1: user1,
      player2: user2,
      active: true,
    })
    .then((newGame) => {
      console.log(newGame);
      res.send(201, newGame._id);
    });
  },

  // Delete specified game from database
  cancelGame(gameId, res) {
    findGame({ _id: `ObjectId(${gameId})` })
      .then((targetGame) => {
        console.log(targetGame);
        targetGame.active = false;
        res.send(201, targetGame);
      })
      .catch((err) => {
        console.error(err);
      });
  },
};
<|endoftext|>


<commit_before>const os = require('os');
const interfaces = os.networkInterfaces();
const _ = require('underscore');
const socketio = require('socket.io');
const jwt = require('jsonwebtoken');
const raven = require('raven');

const config = require('./nodeconfig.js');
const logger = require('../log.js');
const ZmqSocket = require('./zmqsocket.js');
const Game = require('../game/game.js');
const Socket = require('../socket.js');

var ravenClient = new raven.Client(config.sentryDsn);
ravenClient.patchGlobal();

class GameServer {
    constructor() {
        this.listenAddress = this.getNetworkAddress();
        this.games = {};
        this.sockets = {};

        this.socket = new ZmqSocket(this.listenAddress);
        this.socket.on('onStartGame', this.onStartGame.bind(this));
        this.socket.on('onSpectator', this.onSpectator.bind(this));

        this.io = socketio();
        this.io.listen(process.env.PORT || config.socketioPort);
        this.io.set('heartbeat timeout', 30000);
        this.io.use(this.handshake.bind(this));
        this.io.on('connection', this.onConnection.bind(this));
    }

    getNetworkAddress() {
        var firstAddress = undefined;

        _.each(interfaces, addresses => {
            _.each(addresses, address => {
                if(address.family !== 'IPv4' || address.internal || firstAddress) {
                    return;
                }

                firstAddress = address.address;
            });
        });

        return firstAddress;
    }

    handleError(game, e) {
        logger.error(e);

        var debugData = {};

        debugData.game = game.getState();

        _.each(game.getPlayers(), player => {
            debugData[player.name] = player.getState(player.name);
        });

        ravenClient.captureException(e, { extra: debugData });

        if(game) {
            game.addMessage('A Server error has occured processing your game state, apologies.  Your game may now be in an inconsistent state, or you may be able to continue.  The error has been logged.');
        }
    }

    runAndCatchErrors(game, func) {
        try {
            func();
        } catch(e) {
            this.handleError(game, e);

            this.sendGameState(game);
        }
    }

    findGameForUser(username) {
        return _.find(this.games, game => {
            return game.playersAndSpectators[username];
        });
    }

    sendGameState(game) {
        _.each(game.getPlayersAndSpectators(), player => {
            if(this.sockets[player.id]) {
                this.sockets[player.id].send('gamestate', game.getState(player.name));
            }
        });
    }

    handshake(socket, next) {
        if(socket.handshake.query.token) {
            jwt.verify(socket.handshake.query.token, config.secret, function(err, user) {
                if(err) {
                    logger.info(err);
                    return;
                }

                socket.request.user = user;
            });
        }

        next();
    }

    gameWon(game, reason, winner) {
        this.socket.send('GAMEWIN', { game: game.getSaveState(), winner: winner.name, reason: reason });
    }

    onStartGame(pendingGame) {
        var game = new Game(pendingGame, { router: this });
        this.games[pendingGame.id] = game;

        game.started = true;
        _.each(pendingGame.players, player => {
            game.selectDeck(player.name, player.deck);
        });

        game.initialise();

        logger.info('Starting new game', game.id);
    }

    onSpectator(pendingGame, username) {
        var game = this.games[pendingGame.id];
        if(!game) {
            return;
        }

        game.watch('TBA', { username: username });

        this.sendGameState(game);
    }

    onConnection(ioSocket) {
        if(!ioSocket.request.user) {
            ioSocket.disconnect();
            return;
        }

        var game = this.findGameForUser(ioSocket.request.user.username);
        if(!game) {
            ioSocket.disconnect();
            return;
        }

        var socket = new Socket(ioSocket);

        var player = game.playersAndSpectators[socket.user.username];
        if(!player) {
            return;
        }

        player.id = socket.id;
        if(player.disconnected) {
            game.reconnect(socket.id, player.name);
        }

        socket.joinChannel(game.id);

        this.sockets[socket.id] = socket;

        this.sendGameState(game);

        socket.registerEvent('game', this.onGameMessage.bind(this));
        socket.on('disconnect', this.onSocketDisconnected.bind(this));

        this.sockets[ioSocket.id] = socket;
    }

    onSocketDisconnected(socket) {
        var game = this.findGameForUser(socket.user.username);
        if(!game) {
            return;
        }

        game.disconnect(socket.user.username);

        if(game.isEmpty()) {
            delete this.games[game.id];

            this.socket.send('GAMECLOSED', { game: game.id });
        } else if(game.isSpectator(game.playersAndSpectators[socket.user.username])) {
            this.socket.send('PLAYERLEFT', { gameId: game.id, game: game.getSaveState(), player: socket.user.username, spectator: true });
        }

        this.sendGameState(game);
    }

    onLeaveGame(socket) {
        var game = this.findGameForUser(socket.user.username);
        if(!game) {
            return;
        }

        this.socket.send('PLAYERLEFT', {
            gameId: game.id,
            game: game.getSaveState(),
            player: socket.user.username,
            spectator: game.isSpectator(game.playersAndSpectators[socket.user.username])
        });

        game.leave(socket.user.username);

        socket.send('gamestate', game.getState(socket.user.username));

        socket.leaveChannel(game.id);

        if(game.isEmpty()) {
            delete this.games[game.id];

            this.socket.send('GAMECLOSED', { game: game.id });
        }

        this.sendGameState(game);
    }

    onGameMessage(socket, command, ...args) {
        var game = this.findGameForUser(socket.user.username);

        if(!game) {
            return;
        }

        if(command === 'leavegame') {
            return this.onLeaveGame(socket);
        }

        if(!game[command] || !_.isFunction(game[command])) {
            return;
        }

        this.runAndCatchErrors(game, () => {
            game[command](socket.user.username, ...args);

            game.continue();

            this.sendGameState(game);
        });
    }
}

module.exports = GameServer;
<commit_msg>spectator check needs to be doen before the call to game<commit_after>const os = require('os');
const interfaces = os.networkInterfaces();
const _ = require('underscore');
const socketio = require('socket.io');
const jwt = require('jsonwebtoken');
const raven = require('raven');

const config = require('./nodeconfig.js');
const logger = require('../log.js');
const ZmqSocket = require('./zmqsocket.js');
const Game = require('../game/game.js');
const Socket = require('../socket.js');

var ravenClient = new raven.Client(config.sentryDsn);
ravenClient.patchGlobal();

class GameServer {
    constructor() {
        this.listenAddress = this.getNetworkAddress();
        this.games = {};
        this.sockets = {};

        this.socket = new ZmqSocket(this.listenAddress);
        this.socket.on('onStartGame', this.onStartGame.bind(this));
        this.socket.on('onSpectator', this.onSpectator.bind(this));

        this.io = socketio();
        this.io.listen(process.env.PORT || config.socketioPort);
        this.io.set('heartbeat timeout', 30000);
        this.io.use(this.handshake.bind(this));
        this.io.on('connection', this.onConnection.bind(this));
    }

    getNetworkAddress() {
        var firstAddress = undefined;

        _.each(interfaces, addresses => {
            _.each(addresses, address => {
                if(address.family !== 'IPv4' || address.internal || firstAddress) {
                    return;
                }

                firstAddress = address.address;
            });
        });

        return firstAddress;
    }

    handleError(game, e) {
        logger.error(e);

        var debugData = {};

        debugData.game = game.getState();

        _.each(game.getPlayers(), player => {
            debugData[player.name] = player.getState(player.name);
        });

        ravenClient.captureException(e, { extra: debugData });

        if(game) {
            game.addMessage('A Server error has occured processing your game state, apologies.  Your game may now be in an inconsistent state, or you may be able to continue.  The error has been logged.');
        }
    }

    runAndCatchErrors(game, func) {
        try {
            func();
        } catch(e) {
            this.handleError(game, e);

            this.sendGameState(game);
        }
    }

    findGameForUser(username) {
        return _.find(this.games, game => {
            return game.playersAndSpectators[username];
        });
    }

    sendGameState(game) {
        _.each(game.getPlayersAndSpectators(), player => {
            if(this.sockets[player.id]) {
                this.sockets[player.id].send('gamestate', game.getState(player.name));
            }
        });
    }

    handshake(socket, next) {
        if(socket.handshake.query.token) {
            jwt.verify(socket.handshake.query.token, config.secret, function(err, user) {
                if(err) {
                    logger.info(err);
                    return;
                }

                socket.request.user = user;
            });
        }

        next();
    }

    gameWon(game, reason, winner) {
        this.socket.send('GAMEWIN', { game: game.getSaveState(), winner: winner.name, reason: reason });
    }

    onStartGame(pendingGame) {
        var game = new Game(pendingGame, { router: this });
        this.games[pendingGame.id] = game;

        game.started = true;
        _.each(pendingGame.players, player => {
            game.selectDeck(player.name, player.deck);
        });

        game.initialise();

        logger.info('Starting new game', game.id);
    }

    onSpectator(pendingGame, username) {
        var game = this.games[pendingGame.id];
        if(!game) {
            return;
        }

        game.watch('TBA', { username: username });

        this.sendGameState(game);
    }

    onConnection(ioSocket) {
        if(!ioSocket.request.user) {
            ioSocket.disconnect();
            return;
        }

        var game = this.findGameForUser(ioSocket.request.user.username);
        if(!game) {
            ioSocket.disconnect();
            return;
        }

        var socket = new Socket(ioSocket);

        var player = game.playersAndSpectators[socket.user.username];
        if(!player) {
            return;
        }

        player.id = socket.id;
        if(player.disconnected) {
            game.reconnect(socket.id, player.name);
        }

        socket.joinChannel(game.id);

        this.sockets[socket.id] = socket;

        this.sendGameState(game);

        socket.registerEvent('game', this.onGameMessage.bind(this));
        socket.on('disconnect', this.onSocketDisconnected.bind(this));

        this.sockets[ioSocket.id] = socket;
    }

    onSocketDisconnected(socket) {
        var game = this.findGameForUser(socket.user.username);
        if(!game) {
            return;
        }

        var isSpectator = game.isSpectator(game.playersAndSpectators[socket.user.username]);

        game.disconnect(socket.user.username);

        if(game.isEmpty()) {
            delete this.games[game.id];

            this.socket.send('GAMECLOSED', { game: game.id });
        } else if(isSpectator) {
            this.socket.send('PLAYERLEFT', { gameId: game.id, game: game.getSaveState(), player: socket.user.username, spectator: true });
        }

        this.sendGameState(game);
    }

    onLeaveGame(socket) {
        var game = this.findGameForUser(socket.user.username);
        if(!game) {
            return;
        }

        this.socket.send('PLAYERLEFT', {
            gameId: game.id,
            game: game.getSaveState(),
            player: socket.user.username,
            spectator: game.isSpectator(game.playersAndSpectators[socket.user.username])
        });

        game.leave(socket.user.username);

        socket.send('gamestate', game.getState(socket.user.username));

        socket.leaveChannel(game.id);

        if(game.isEmpty()) {
            delete this.games[game.id];

            this.socket.send('GAMECLOSED', { game: game.id });
        }

        this.sendGameState(game);
    }

    onGameMessage(socket, command, ...args) {
        var game = this.findGameForUser(socket.user.username);

        if(!game) {
            return;
        }

        if(command === 'leavegame') {
            return this.onLeaveGame(socket);
        }

        if(!game[command] || !_.isFunction(game[command])) {
            return;
        }

        this.runAndCatchErrors(game, () => {
            game[command](socket.user.username, ...args);

            game.continue();

            this.sendGameState(game);
        });
    }
}

module.exports = GameServer;
<|endoftext|>