<commit_before>'use strict';

var hideAnswer = function() {
    $('#answer-box').removeClass('in');
    $('#answer-box').addClass('out');
};

var pierreProcessor = function(w) {
    var wl = w.toLowerCase();

    // Is it Lua?
    if(w === 'Lua') {
        // It's Lua! Pierre likes this.
        return 'Yes!';
    }

    // Lua is not LUA...
    else if(wl === 'lua') {
        return 'n00b! It\'s "Lua".';
    }

    else if(wl === 'fsonrpc') {
        return 'Yes! But not FSON.';
    }

    else if(wl === 'environment variables') {
        return 'Yes!';
    }

    else if(wl === 'valgrind') {
        return 'It Does Rubbish!';
    }

    else
    {
        return 'No.';
    }
};

$(document).ready(function() {
    $('#submit').click(function(){
        $('#query').blur();

        var query = $('#query')[0].value;

        var answer = pierreProcessor(query);

        $('#answer-box').removeClass('out');
        $('#answer-box').addClass('in');
        $('#answer').html(answer);
    });

    $('#query').focus(hideAnswer);
    $('#query').change(hideAnswer);
  });
<commit_msg>fix: avoid 'ENTER' to reload pages<commit_after>'use strict';

var hideAnswer = function() {
    $('#answer-box').removeClass('in');
    $('#answer-box').addClass('out');
};

var pierreProcessor = function(w) {
    var wl = w.toLowerCase();

    // Is it Lua?
    if(w === 'Lua') {
        // It's Lua! Pierre likes this.
        return 'Yes!';
    }

    // Lua is not LUA...
    else if(wl === 'lua') {
        return 'n00b! It\'s "Lua".';
    }

    else if(wl === 'fsonrpc') {
        return 'Yes! But not FSON.';
    }

    else if(wl === 'environment variables') {
        return 'Yes!';
    }

    else if(wl === 'valgrind') {
        return 'It Does Rubbish!';
    }

    else
    {
        return 'No.';
    }
};

var query = function()
{
    $('#query').blur();

    var query = $('#query')[0].value;

    var answer = pierreProcessor(query);

    $('#answer-box').removeClass('out');
    $('#answer-box').addClass('in');
    $('#answer').html(answer);
}

$(document).ready(function() {
    $('#submit').click(query);
    $('#query').keypress(function(e) {
        if (e.which == 13) {
            query();
        }
    });

    $('#query').focus(hideAnswer);
    $('#query').change(hideAnswer);
  });
<|endoftext|>


<commit_before>function drawField()
{
	var c = document.getElementById("myCanvas");
	var ctx = c.getContext("2d");

	for (var i = 0; i < 3; i++)
	{
		var positionX = 100 + (100 * i);
		ctx.moveTo(positionX,0);
		ctx.lineTo(positionX,400);
		ctx.strokeStyle="green";
		ctx.lineWidth = "8";
		ctx.stroke();
	}

	for (var j = 0; j < 3; j++)
	{
		var positionY = 100 + (100 * j);
		ctx.moveTo(0,positionY);
		ctx.lineTo(400, positionY);
		ctx.strokeStyle="green";
		ctx.lineWidth = "8";
		ctx.stroke();
	}

}
function pickRandomItem(){
        var randomItem = Math.floor(Math.random()* arrayOfEmptyBlocks.length);
        return randomItem;
}

// pickRandomItem() goes through the arrayOfEmptyBlocks and picks randomly an item. The return value is stored in the variable randomItem

function callRun2(){
        var randomProperty = pickRandomItem();
        drawBlock(arrayOfEmptyBlocks[randomProperty]);

        deleteNumFromArray(randomProperty);
}
function deleteNumFromArray(randomProperty){
    var blockRemovedArray = arrayOfEmptyBlocks.splice(randomProperty,1);
    if (blockRemovedArray !== null && blockRemovedArray.length != 0) {
        arrayOfFullBlocks.push(blockRemovedArray[0]);
    }

    if(arrayOfEmptyBlocks.length === 0){
        document.getElementById("myBtn").disabled = true;
    }
}

function drawBlock(block){

	var c2 = document.getElementById("myCanvas");
    var ctx7 = c2.getContext("2d");

	ctx7.fillStyle = "#41f341";
	ctx7.fillRect(block.xPos,block.yPos,block.xFill,block.yFill);

	ctx7.font = "50px Arial";
	ctx7.fillStyle = "green";
	ctx7.fillText(block.num,block.numXPos,block.numYPos);
}

function block(name, xPos, yPos, xFill, yFill, num, numXPos, numYPos) {
    this.name = name;
    this.xPos = xPos;
    this.yPos = yPos;
    this.xFill = xFill;
	this.yFill = yFill;
	this.num = num;
	this.numXPos = numXPos;
    this.numYPos = numYPos;

    this.blockLeft = null;
    this.blockRight = null;
    this.blockUp = null;
    this.blockDown = null;

    this.setBlockNeighbors = function(left, right, up, down)
    {
        this.blockLeft = left;
        this.blockRight = right;
        this.blockUp = up;
        this.blockDown = down;
    };
}

var arrayOfEmptyBlocks = [];
var arrayOfFullBlocks = [];
//console.log("*********",arrayOfFullBlocks);
function createBlocks()
{
    var block1 = new block("block1",0,0,96,96,2,35,65);
    var block2 = new block("block2",104,0,92,96,2,135,65);
    var block3 = new block("block3",204,0,92,96,2,235,65);
    var block4 = new block("block4",304,0,96,96,2,335,65);

    var block5 = new block("block5",0,104,96,92,2,35,165);
    var block6 = new block("block6",104,104,92,92,2,135,165);
    var block7 = new block("block7",204,104,92,92,2,235,165);
    var block8 = new block("block8",304,104,96,92,2,335,165);

    var block9 = new block("block9",0,204,96,92,2,35,265);
    var block10 = new block("block10",104,204,92,92,2,135,265);
    var block11 = new block("block11",204,204,92,92,2,235,265);
    var block12 = new block("block12",304,204,96,92,2,335,265);

    var block13 = new block("block13",0,304,96,96,2,35,365);
    var block14 = new block("block14",104,304,92,96,2,135,365);
    var block15 = new block("block15",204,304,92,96,2,235,365);
    var block16 = new block("block16",304,304,96,96,2,335,365);

    block1.setBlockNeighbors(null, block2,null,block5);
    block2.setBlockNeighbors(block1,block3,null,block6);
    block3.setBlockNeighbors(block2,block4,null,block7);
    block4.setBlockNeighbors(block3,null,null,block8);
    block5.setBlockNeighbors(null,block6,block1,block9);
    block6.setBlockNeighbors(block5,block7,block2,block10);
    block7.setBlockNeighbors(block6,block8,block3,block11);
    block8.setBlockNeighbors(block7,null,block4,block12);
    block9.setBlockNeighbors(null,block10,block5,block13);
    block10.setBlockNeighbors(block9,block11,block6,block14);
    block11.setBlockNeighbors(block10,block12,block7,block15);
    block12.setBlockNeighbors(block11,null,block8,block16);
    block13.setBlockNeighbors(null,block14,block9,null);
    block14.setBlockNeighbors(block13,block15,block10,null);
    block15.setBlockNeighbors(block14,block16,block11,null);
    block16.setBlockNeighbors(block15,null,block12,null);

    arrayOfEmptyBlocks.push(block1,block2,block3,block4,block5,block6,
            block7,block8,block9,block10,block11,block12,block13,
            block14,block15,block16);
}

createBlocks();

// following is a test functions for the above data

function checkNeighbors()
{
    var test = "";

    for (var i = 0; i < arrayOfEmptyBlocks.length; i++)
        {
            currBlock = arrayOfEmptyBlocks[i];
            left = "";
            right = "";
            up = "";
            down = "";

            if (currBlock.blockLeft !== null)
            {
                left = currBlock.blockLeft.name;
            }

            if (currBlock.blockRight !== null)
            {
                right = currBlock.blockRight.name;
            }

            if (currBlock.blockUp !== null)
            {
                up = currBlock.blockUp.name;
            }

            if (currBlock.blockDown !== null)
            {
                down = currBlock.blockDown.name;
            }

            test += currBlock.name + ": (left: " + left + ")"
                            + ", (right: " + right + ")"
                            + ", (up: " + up + ")"
                            + ", (down: " + down + ")"
                            + "\n";
        }

    document.getElementById("neighborCheck").innerText = test;
}

document.onkeydown = function(e) {
    e = e || window.event;
    switch(e.which || e.keyCode) {

        case 37: // left
        move("left");
        clearField();
        redrawField();
        callRun2();
        break;

        case 38: // up
        move("up");
        clearField();
        redrawField();
        callRun2();
        break;

        case 39: // right
        move("right");
        clearField();
        redrawField();
        callRun2();
        break;

        case 40: // down
        move("down");
        clearField();
        redrawField();
        callRun2();
        break;

        default: return; // exit this handler for other keys
}
};

function move(direction){

    var movement = false;

    do {
        movement = false;
        for (var i=0; i<arrayOfFullBlocks.length; i++){
        currentBlock = arrayOfFullBlocks[i];
        var currentBlockMove;
        switch (direction){
            case "left":
                currentBlockMove = currentBlock.blockLeft;
                break;
            case "right":
                currentBlockMove = currentBlock.blockRight;
                break;
            case "up":
                currentBlockMove = currentBlock.blockUp;
                break;
            case "down":
                currentBlockMove = currentBlock.blockDown;
                break;
        }

        // if the block cannot move right, either because there is a NULL or because the space is already full, meaning the block is in the arrayOfFullBlocks

        if (currentBlockMove === null || (arrayOfFullBlocks.indexOf(currentBlockMove) !== -1 && currentBlockMove.num !== currentBlock.num)){
            //if it is null, or it is in the arrayOfFullBlocks and the number of currentBlockMove is not the same a in currentBlock.num
            continue;
        }else if (arrayOfFullBlocks.indexOf(currentBlockMove) !== -1 && currentBlockMove.num == currentBlock.num){
                currentBlockMove.num = currentBlockMove.num * 2;
                var justOneBlockArray =  arrayOfFullBlocks.splice(i,1);
                // we splice the item of the arrayOfEmptyBlocks, but push it to a variable, since otherwise it is stored as an array withing the arrayOfEmptyBlocks.
                if (justOneBlockArray !== null && justOneBlockArray.length != 0) {
                    arrayOfEmptyBlocks.push(justOneBlockArray[0]);
                }
                movement = true;
               break;
        }
        currentBlockMove.num = currentBlock.num;
        currentBlock.num = 2;
        arrayOfFullBlocks[i] = currentBlockMove;
        arrayOfEmptyBlocks[arrayOfEmptyBlocks.indexOf(currentBlockMove)] = currentBlock;
        // we swapped two positions. We put currentBlockRight (it was in the "empty" array) into the arrayOfFullBlocks. We put currentBlock, which was in the arrayOfFullBlocks into the arrayOfEmptyBlocks (where all empty arrays are.
        movement = true;
        }
    }
    while (movement);
}

function clearField(){
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
    for(var i = 0; i < arrayOfEmptyBlocks.length; i++){
        currentBlock = arrayOfEmptyBlocks[i];
        ctx.clearRect(currentBlock.xPos,currentBlock.yPos,currentBlock.xFill,currentBlock.yFill);
    }
}

function redrawField()
{
    for (var i = 0; i < arrayOfFullBlocks.length; i++) {
        currBlock = arrayOfFullBlocks[i];
        drawBlock(currBlock);
    }
}

drawField();

<commit_msg>Add property upDated to blocks<commit_after>function drawField()
{
	var c = document.getElementById("myCanvas");
	var ctx = c.getContext("2d");

	for (var i = 0; i < 3; i++)
	{
		var positionX = 100 + (100 * i);
		ctx.moveTo(positionX,0);
		ctx.lineTo(positionX,400);
		ctx.strokeStyle="green";
		ctx.lineWidth = "8";
		ctx.stroke();
	}

	for (var j = 0; j < 3; j++)
	{
		var positionY = 100 + (100 * j);
		ctx.moveTo(0,positionY);
		ctx.lineTo(400, positionY);
		ctx.strokeStyle="green";
		ctx.lineWidth = "8";
		ctx.stroke();
	}

}
function pickRandomItem(){
        var randomItem = Math.floor(Math.random()* arrayOfEmptyBlocks.length);
        return randomItem;
}

// pickRandomItem() goes through the arrayOfEmptyBlocks and picks randomly an item. The return value is stored in the variable randomItem

function callRun2(){
        var randomProperty = pickRandomItem();
        drawBlock(arrayOfEmptyBlocks[randomProperty]);

        deleteNumFromArray(randomProperty);
}
function deleteNumFromArray(randomProperty){
    var blockRemovedArray = arrayOfEmptyBlocks.splice(randomProperty,1);
    if (blockRemovedArray !== null && blockRemovedArray.length != 0) {
        arrayOfFullBlocks.push(blockRemovedArray[0]);
    }

    if(arrayOfEmptyBlocks.length === 0){
        document.getElementById("myBtn").disabled = true;
    }
}

function drawBlock(block){

	var c2 = document.getElementById("myCanvas");
    var ctx7 = c2.getContext("2d");

	ctx7.fillStyle = "#41f341";
	ctx7.fillRect(block.xPos,block.yPos,block.xFill,block.yFill);

	ctx7.font = "50px Arial";
	ctx7.fillStyle = "green";
	ctx7.fillText(block.num,block.numXPos,block.numYPos);
}

function block(name, xPos, yPos, xFill, yFill, num, numXPos, numYPos) {
    this.name = name;
    this.xPos = xPos;
    this.yPos = yPos;
    this.xFill = xFill;
	this.yFill = yFill;
	this.num = num;
	this.numXPos = numXPos;
    this.numYPos = numYPos;
    this.upDated = false;

    this.blockLeft = null;
    this.blockRight = null;
    this.blockUp = null;
    this.blockDown = null;

    this.setBlockNeighbors = function(left, right, up, down)
    {
        this.blockLeft = left;
        this.blockRight = right;
        this.blockUp = up;
        this.blockDown = down;
    };
}

var arrayOfEmptyBlocks = [];
var arrayOfFullBlocks = [];
//console.log("*********",arrayOfFullBlocks);
function createBlocks()
{
    var block1 = new block("block1",0,0,96,96,2,35,65);
    var block2 = new block("block2",104,0,92,96,2,135,65);
    var block3 = new block("block3",204,0,92,96,2,235,65);
    var block4 = new block("block4",304,0,96,96,2,335,65);

    var block5 = new block("block5",0,104,96,92,2,35,165);
    var block6 = new block("block6",104,104,92,92,2,135,165);
    var block7 = new block("block7",204,104,92,92,2,235,165);
    var block8 = new block("block8",304,104,96,92,2,335,165);

    var block9 = new block("block9",0,204,96,92,2,35,265);
    var block10 = new block("block10",104,204,92,92,2,135,265);
    var block11 = new block("block11",204,204,92,92,2,235,265);
    var block12 = new block("block12",304,204,96,92,2,335,265);

    var block13 = new block("block13",0,304,96,96,2,35,365);
    var block14 = new block("block14",104,304,92,96,2,135,365);
    var block15 = new block("block15",204,304,92,96,2,235,365);
    var block16 = new block("block16",304,304,96,96,2,335,365);

    block1.setBlockNeighbors(null, block2,null,block5);
    block2.setBlockNeighbors(block1,block3,null,block6);
    block3.setBlockNeighbors(block2,block4,null,block7);
    block4.setBlockNeighbors(block3,null,null,block8);
    block5.setBlockNeighbors(null,block6,block1,block9);
    block6.setBlockNeighbors(block5,block7,block2,block10);
    block7.setBlockNeighbors(block6,block8,block3,block11);
    block8.setBlockNeighbors(block7,null,block4,block12);
    block9.setBlockNeighbors(null,block10,block5,block13);
    block10.setBlockNeighbors(block9,block11,block6,block14);
    block11.setBlockNeighbors(block10,block12,block7,block15);
    block12.setBlockNeighbors(block11,null,block8,block16);
    block13.setBlockNeighbors(null,block14,block9,null);
    block14.setBlockNeighbors(block13,block15,block10,null);
    block15.setBlockNeighbors(block14,block16,block11,null);
    block16.setBlockNeighbors(block15,null,block12,null);

    arrayOfEmptyBlocks.push(block1,block2,block3,block4,block5,block6,
            block7,block8,block9,block10,block11,block12,block13,
            block14,block15,block16);
}

createBlocks();

// following is a test functions for the above data

function checkNeighbors()
{
    var test = "";

    for (var i = 0; i < arrayOfEmptyBlocks.length; i++)
        {
            currBlock = arrayOfEmptyBlocks[i];
            left = "";
            right = "";
            up = "";
            down = "";

            if (currBlock.blockLeft !== null)
            {
                left = currBlock.blockLeft.name;
            }

            if (currBlock.blockRight !== null)
            {
                right = currBlock.blockRight.name;
            }

            if (currBlock.blockUp !== null)
            {
                up = currBlock.blockUp.name;
            }

            if (currBlock.blockDown !== null)
            {
                down = currBlock.blockDown.name;
            }

            test += currBlock.name + ": (left: " + left + ")"
                            + ", (right: " + right + ")"
                            + ", (up: " + up + ")"
                            + ", (down: " + down + ")"
                            + "\n";
        }

    document.getElementById("neighborCheck").innerText = test;
}

document.onkeydown = function(e) {
    e = e || window.event;
    switch(e.which || e.keyCode) {

        case 37: // left
        move("left");
        clearField();
        redrawField();
        callRun2();
        break;

        case 38: // up
        move("up");
        clearField();
        redrawField();
        callRun2();
        break;

        case 39: // right
        move("right");
        clearField();
        redrawField();
        callRun2();
        break;

        case 40: // down
        move("down");
        clearField();
        redrawField();
        callRun2();
        break;

        default: return; // exit this handler for other keys
}
};

function move(direction){

    var movement = false;

    do {
        movement = false;
        for (var i=0; i<arrayOfFullBlocks.length; i++){
        currentBlock = arrayOfFullBlocks[i];
        var currentBlockMove;
        switch (direction){
            case "left":
                currentBlockMove = currentBlock.blockLeft;
                break;
            case "right":
                currentBlockMove = currentBlock.blockRight;
                break;
            case "up":
                currentBlockMove = currentBlock.blockUp;
                break;
            case "down":
                currentBlockMove = currentBlock.blockDown;
                break;
        }

        // if the block cannot move right, either because there is a NULL or because the space is already full, meaning the block is in the arrayOfFullBlocks

        if (currentBlockMove === null || (arrayOfFullBlocks.indexOf(currentBlockMove) !== -1 && currentBlockMove.num !== currentBlock.num)){
            //if it is null, or it is in the arrayOfFullBlocks and the number of currentBlockMove is not the same a in currentBlock.num
            continue;
        }else if (arrayOfFullBlocks.indexOf(currentBlockMove) !== -1 && currentBlockMove.num == currentBlock.num){
                if (currentBlockMove.upDated || currentBlock.upDated){
                    continue;
                }
                currentBlockMove.upDated = true;
                currentBlockMove.num = currentBlockMove.num * 2;
                var justOneBlockArray =  arrayOfFullBlocks.splice(i,1);
                // we splice the item of the arrayOfEmptyBlocks, but push it to a variable, since otherwise it is stored as an array withing the arrayOfEmptyBlocks.
                if (justOneBlockArray !== null && justOneBlockArray.length != 0) {
                    arrayOfEmptyBlocks.push(justOneBlockArray[0]);
                }
                movement = true;
               break;
        }
        currentBlockMove.num = currentBlock.num;
        currentBlock.num = 2;
        arrayOfFullBlocks[i] = currentBlockMove;
        arrayOfEmptyBlocks[arrayOfEmptyBlocks.indexOf(currentBlockMove)] = currentBlock;
        // we swapped two positions. We put currentBlockRight (it was in the "empty" array) into the arrayOfFullBlocks. We put currentBlock, which was in the arrayOfFullBlocks into the arrayOfEmptyBlocks (where all empty arrays are.
        movement = true;
        }
    }
    while (movement);
}

function clearField(){
        var c = document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
    for(var i = 0; i < arrayOfEmptyBlocks.length; i++){
        currentBlock = arrayOfEmptyBlocks[i];
        ctx.clearRect(currentBlock.xPos,currentBlock.yPos,currentBlock.xFill,currentBlock.yFill);
    }
}

function redrawField()
{
    for (var i = 0; i < arrayOfFullBlocks.length; i++) {
        currBlock = arrayOfFullBlocks[i];
        drawBlock(currBlock);
        currBlock.upDated = false;
    }
}

drawField();

<|endoftext|>


<commit_before>/*
 * tests requiring DOM manipulation for punchcards.DateCircle from dist/punchcards.js
 */

/*global describe, beforeEach, fixture, crossfilter, afterEach, it, expect, punchcards*/

describe('punchcards DateCircle class...', function () {

    'use strict';

    var fixtures, cf;

    beforeEach(function () {

        var data;

        // set the base directory for loading of fixtures
        fixture.setBase('test');

        // load the html and json fixtures
        fixtures = fixture.load('date-circle.fixture.html',
            'cityofchicago-police-data.fixture.json');

        data = fixtures[1];
        cf = crossfilter(data);

    });

    afterEach(function () {
        // clean up the DOM
        fixture.cleanup();
        cf = undefined;
    });

    it('...html fixture should have loaded correctly', function () {
        var actual, expected;
        actual = fixtures[0][0].outerHTML;
        expected = '

';
        expect(actual).toEqual(expected);
    });

    it('...json fixture should have loaded correctly', function () {
        var actual, expected;
        actual = Object.keys(fixtures[1][0]).sort();
        expected = ["casenumber", "datestr", "description", "latitude", "longitude", "primary"];
        expect(actual).toEqual(expected);
    });

    it('...json fixture should have 5000 records', function () {
        var actual, expected;
        actual = cf.size();
        expected = 5000;
        expect(actual).toEqual(expected);
    });

    it('...constructor should return an instance of punchcards.DateCircle when called with valid arguments', function () {
        var actual, datecircle;
        datecircle = new punchcards.DateCircle(cf, 'punchcard-date-circle');
        actual = datecircle instanceof punchcards.DateCircle;
        expect(actual).toBe(true);
    });

    it('...after calling .drawSymbols(), the chart should have an ' +
        'SVG g element of class "symbol" attached to it', function () {
            var actual, datecircle;
            datecircle = new punchcards.DateCircle(cf, 'punchcard-date-circle');
            datecircle.defineDimensions();
            datecircle.drawSvg();
            datecircle.drawHorizontalAxis();
            datecircle.drawVerticalAxis();
            datecircle.drawSymbols();
            actual = datecircle.svg.select('g.symbol')[0][0];
            expect(actual).not.toBe(null);
        });

    it('...after calling .drawSymbols(), the chart should have an ' +
        'SVG g element of class "symbol" with 139 SVG circles of class ' +
        '"symbol" attached to it', function () {
            var actual, datecircle, symbols;
            datecircle = new punchcards.DateCircle(cf, 'punchcard-date-circle');
            datecircle.defineDimensions();
            datecircle.drawSvg();
            datecircle.drawHorizontalAxis();
            datecircle.drawVerticalAxis();
            datecircle.drawSymbols();
            symbols = datecircle.svg.select('g.symbol').selectAll('circle.symbol')[0];
            actual = symbols.length;
            expect(actual).toEqual(139);
        });

});

<commit_msg>added more unit tests for DateCircle when combined with small data sets (n=1 or n=3; issue#62)<commit_after>/*
 * tests requiring DOM manipulation for punchcards.DateCircle from dist/punchcards.js
 */

/*global describe, beforeEach, fixture, crossfilter, afterEach, it, expect, punchcards*/

describe('punchcards DateCircle class with cityofchicago-police-data.fixture.json...', function () {

    'use strict';

    var fixtures, cf;

    beforeEach(function () {

        var data;

        // set the base directory for loading of fixtures
        fixture.setBase('test');

        // load the html and json fixtures
        fixtures = fixture.load('date-circle.fixture.html',
            'cityofchicago-police-data.fixture.json');

        data = fixtures[1];
        cf = crossfilter(data);

    });

    afterEach(function () {
        // clean up the DOM
        fixture.cleanup();
        cf = undefined;
    });

    it('...html fixture should have loaded correctly', function () {
        var actual, expected;
        actual = fixtures[0][0].outerHTML;
        expected = '

';
        expect(actual).toEqual(expected);
    });

    it('...json fixture should have loaded correctly', function () {
        var actual, expected;
        actual = Object.keys(fixtures[1][0]).sort();
        expected = ["casenumber", "datestr", "description", "latitude", "longitude", "primary"];
        expect(actual).toEqual(expected);
    });

    it('...json fixture should have 5000 records', function () {
        var actual, expected;
        actual = cf.size();
        expected = 5000;
        expect(actual).toEqual(expected);
    });

    it('...constructor should return an instance of punchcards.DateCircle when called with valid arguments', function () {
        var actual, datecircle;
        datecircle = new punchcards.DateCircle(cf, 'punchcard-date-circle');
        actual = datecircle instanceof punchcards.DateCircle;
        expect(actual).toBe(true);
    });

    it('...after calling .drawSymbols(), the chart should have an ' +
        'SVG g element of class "symbol" attached to it', function () {
            var actual, datecircle;
            datecircle = new punchcards.DateCircle(cf, 'punchcard-date-circle');
            datecircle.defineDimensions();
            datecircle.drawSvg();
            datecircle.drawHorizontalAxis();
            datecircle.drawVerticalAxis();
            datecircle.drawSymbols();
            actual = datecircle.svg.select('g.symbol')[0][0];
            expect(actual).not.toBe(null);
        });

    it('...after calling .drawSymbols(), the chart should have an ' +
        'SVG g element of class "symbol" with 139 SVG circles of class ' +
        '"symbol" attached to it', function () {
            var actual, datecircle, symbols;
            datecircle = new punchcards.DateCircle(cf, 'punchcard-date-circle');
            datecircle.defineDimensions();
            datecircle.drawSvg();
            datecircle.drawHorizontalAxis();
            datecircle.drawVerticalAxis();
            datecircle.drawSymbols();
            symbols = datecircle.svg.select('g.symbol').selectAll('circle.symbol')[0];
            actual = symbols.length;
            expect(actual).toEqual(139);
        });

});

describe('punchcards DateCircle class with test/simple-n3.fixture.json...', function () {

    'use strict';

    var fixtures, cf;

    beforeEach(function () {

        var data;

        // set the base directory for loading of fixtures
        fixture.setBase('test');

        // load the html and json fixtures
        fixtures = fixture.load('date-circle.fixture.html',
            'simple-n3.fixture.json');

        data = fixtures[1];
        cf = crossfilter(data);

    });

    afterEach(function () {
        // clean up the DOM
        fixture.cleanup();
        cf = undefined;
    });

    it('...html fixture should have loaded correctly', function () {
        var actual, expected;
        actual = fixtures[0][0].outerHTML;
        expected = '

';
        expect(actual).toEqual(expected);
    });

    it('...json fixture should have loaded correctly', function () {
        var actual, expected;
        actual = Object.keys(fixtures[1][0]).sort();
        expected = ["datestr"];
        expect(actual).toEqual(expected);
    });

    it('...json fixture should have 3 records', function () {
        var actual, expected;
        actual = cf.size();
        expected = 3;
        expect(actual).toEqual(expected);
    });

    it('...after calling .drawSymbols(), the chart should have an ' +
        'SVG g element of class "symbol" with 2 SVG circle elements of class ' +
        '"symbol" attached to it', function () {
            var actual, datecircle, symbols;
            datecircle = new punchcards.DateCircle(cf, 'punchcard-date-circle');
            datecircle.defineDimensions();
            datecircle.drawSvg();
            datecircle.drawHorizontalAxis();
            datecircle.drawVerticalAxis();
            datecircle.drawSymbols();
            symbols = datecircle.svg.select('g.symbol').selectAll('circle.symbol')[0];
            actual = symbols.length;
            expect(actual).toEqual(2);
        });

});

describe('punchcards DateCircle class with test/simple-n1.fixture.json...', function () {

    'use strict';

    var fixtures, cf;

    beforeEach(function () {

        var data;

        // set the base directory for loading of fixtures
        fixture.setBase('test');

        // load the html and json fixtures
        fixtures = fixture.load('date-circle.fixture.html',
            'simple-n1.fixture.json');

        data = fixtures[1];
        cf = crossfilter(data);

    });

    afterEach(function () {
        // clean up the DOM
        fixture.cleanup();
        cf = undefined;
    });

    it('...html fixture should have loaded correctly', function () {
        var actual, expected;
        actual = fixtures[0][0].outerHTML;
        expected = '

';
        expect(actual).toEqual(expected);
    });

    it('...json fixture should have loaded correctly', function () {
        var actual, expected;
        actual = Object.keys(fixtures[1][0]).sort();
        expected = ["datestr"];
        expect(actual).toEqual(expected);
    });

    it('...json fixture should have just 1 record', function () {
        var actual, expected;
        actual = cf.size();
        expected = 1;
        expect(actual).toEqual(expected);
    });

    it('...after calling .drawSymbols(), the chart should have an ' +
        'SVG g element of class "symbol" with 1 SVG circle of class ' +
        '"symbol" attached to it', function () {
            var actual, datecircle, symbols;
            datecircle = new punchcards.DateCircle(cf, 'punchcard-date-circle');
            datecircle.defineDimensions();
            datecircle.drawSvg();
            datecircle.drawHorizontalAxis();
            datecircle.drawVerticalAxis();
            datecircle.drawSymbols();
            symbols = datecircle.svg.select('g.symbol').selectAll('circle.symbol')[0];
            actual = symbols.length;
            expect(actual).toEqual(1);
        });

    it('...after calling .drawSymbols(), the chart should have an ' +
        'SVG g element of class "symbol" with 1 SVG circle of class ' +
        '"symbol" attached to it, whose radius should be a positive number', function () {

            // matches the following
            //
            // <circle class="symbol" cx="104" cy="-125.66666666666667" r="0" fill="rgb(0,127,255)"></circle>
            // <circle class="symbol" cx="104" cy="-125.66666666666667" r="120" fill="rgb(0,127,255)"></circle>
            // <circle class="symbol" cx="104" cy="-125.66666666666667" r="0" fill="rgb(0,127,255)"></circle>
            // <circle class="symbol" cx="104" cy="-125.66666666666667" r="120.43" fill="rgb(0,127,255)"></circle>
            // <circle class="symbol" cx="104" cy="-125.66666666666667" r=".4" fill="rgb(0,127,255)"></circle>
            // <circle class="symbol" cx="104" cy="-125.66666666666667" r=".48982" fill="rgb(0,127,255)"></circle>
            //
            // but not
            //
            // <circle class="symbol" cx="104" cy="-125.66666666666667" r="NaN" fill="rgb(0,127,255)"></circle>

            var actual, datecircle, symbols, re;
            datecircle = new punchcards.DateCircle(cf, 'punchcard-date-circle');
            datecircle.defineDimensions();
            datecircle.drawSvg();
            datecircle.drawHorizontalAxis();
            datecircle.drawVerticalAxis();
            datecircle.drawSymbols();
            symbols = datecircle.svg.select('g.symbol').selectAll('circle.symbol')[0];
            re = new RegExp('^<circle.*r="(\d{1,}|\d{0,}\.\d{1,})".*><\/circle>$');
            actual = re.test(symbols[0]);
            expect(actual).toEqual(true);
        });

});

<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var deviceScreen = require('Dimensions').get('window');
var styles = require('./styles');
var queueAnimation = require('./animations');

var {
  PanResponder,
  View,
} = React;

/**
 * Default open menu offset. Describes a size of the amount you can
 * move content view from the left and release without opening it
 * @type {Number}
 */
var openMenuOffset = deviceScreen.width * 2 / 3;

/**
 * Content view offset in the `hidden` state
 * @type {Number}
 */
var hiddenMenuOffset = 0;

/**
 * Size of the amount you can move content view in the opened menu state and
 * release without menu closing
 * @type {Number}
 */
var barrierForward = deviceScreen.width / 4;

/**
 * Check if the current gesture offset bigger than allowed one
 * before opening menu
 * @param  {Number} dx Gesture offset from the left side of the window
 * @return {Boolean}
 */
function shouldOpenMenu(dx: Number) {
    return dx > barrierForward;
}

/**
 * no operation function. does nothing.
 */
function noop() {}

var SideMenu = React.createClass({

  /**
   * Current state of the menu, whether it is open or not
   * @type {Boolean}
   */
  isOpen: false,

  /**
   * Current style `left` attribute
   * @todo Check if it's possible to avoid using `left`
   * @type {Number}
   */
  left: 0,

  /**
   * Default left offset for content view
   * @todo Check if it's possible to avoid using `prevLeft`
   * @type {Number}
   */
  prevLeft: 0,

  /**
   * Creates PanResponders and links to appropriate functions
   * @return {Void}
   */
  createResponders: function(disableGestures) {
    if (disableGestures || false) {
      this.responder = PanResponder.create({});
      return;
    }

    this.responder = PanResponder.create({
        onMoveShouldSetPanResponder: this.handleMoveShouldSetPanResponder,
        onPanResponderMove: this.handlePanResponderMove,
        onPanResponderRelease: this.handlePanResponderEnd,
    });
  },

  /**
   * Set the initial responders
   * @return {Void}
   */
  componentWillMount: function () {
    this.createResponders(this.props.disableGestures);
  },

  /**
   * Update responders on new props whenever possible
   * @return {Void}
   */
  componentWillReceiveProps: function (nextProps) {
    this.createResponders(nextProps.disableGestures);
  },

  /**
   * Change `left` style attribute
   * Works only if `sideMenu` is a ref to React.Component
   * @return {Void}
   */
  updatePosition: function() {
    this.sideMenu.setNativeProps({ left: this.left });
  },

  /**
   * Permission to use responder
   * @return {Boolean} true
   */
  handleMoveShouldSetPanResponder: function(e: Object, gestureState: Object) {
    var x = Math.round(Math.abs(gestureState.dx));
    var y = Math.round(Math.abs(gestureState.dy));

    return x > this.props.toleranceX && y < this.props.toleranceY;
  },

  /**
   * Handler on responder move
   * @param  {Synthetic Event} e
   * @param  {Object} gestureState
   * @return {Void}
   */
  handlePanResponderMove: function(e: Object, gestureState: Object) {
    this.left = this.prevLeft + gestureState.dx;

    if ((this.menuPositionMultiplier() * this.left) > 0) {
      this.updatePosition();
    }
  },

  /**
   * Returns 1 or -1 depending on the menuPosition
   * @return {Number}
   */
  menuPositionMultiplier: function() {
    return this.props.menuPosition === "right" ? -1 : 1;
  },

  /**
   * Open menu
   * @return {Void}
   */
  openMenu: function() {
    queueAnimation(this.props.animation);

    this.left = this.menuPositionMultiplier() *
      (this.props.openMenuOffset || openMenuOffset);

    this.updatePosition();
    this.prevLeft = this.left;

    if (!this.isOpen) {
      this.props.onChange();
    }

    this.isOpen = true;
  },

  /**
   * Close menu
   * @return {Void}
   */
  closeMenu: function() {
    queueAnimation(this.props.animation);
    this.left = this.menuPositionMultiplier() *
      (this.props.hiddenMenuOffset || hiddenMenuOffset);

    this.updatePosition();
    this.prevLeft = this.left;

    if (this.isOpen) {
      this.props.onChange();
    }

    this.isOpen = false;
  },

  /**
   * Toggle menu
   * @return {Void}
   */
  toggleMenu: function() {
    if (this.isOpen) {
      this.closeMenu();
    } else {
      this.openMenu();
    }
  },

  /**
   * Handler on responder move ending
   * @param  {Synthetic Event} e
   * @param  {Object} gestureState
   * @return {Void}
   */
  handlePanResponderEnd: function(e: Object, gestureState: Object) {
    var shouldOpen = this.menuPositionMultiplier() *
      (this.left + gestureState.dx);

    if (shouldOpenMenu(shouldMenuOpen)) {
      this.openMenu();
    } else {
      this.closeMenu();
    }

    this.updatePosition();
    this.prevLeft = this.left;
  },

  /**
   * Get content view. This view will be rendered over menu
   * @return {React.Component}
   */
  getContentView: function() {
    var getMenuActions = this.getMenuActions();
    return (
      <View
        style={styles.frontView}
        ref={(sideMenu) => this.sideMenu = sideMenu}
        {...this.responder.panHandlers}>

        {React.Children.map(this.props.children, function(child) {
          return React.cloneElement(child, {
            menuActions: getMenuActions
          });
        })}
      </View>
    );
  },

  /**
   * Get menu actions to expose it to
   * menu and children components
   * @return {Object} Public API methods
   */
  getMenuActions: function() {
    return {
      close: this.closeMenu,
      toggle: this.toggleMenu,
      open: this.openMenu
    };
  },

  /**
   * Get menu view. This view will be rendered under
   * content view. Also, this function will decorate
   * passed `menu` component with side menu API
   * @return {React.Component}
   */
  getMenuView: function() {
    var menuActions = this.getMenuActions();

    return (
      <View style={styles.menu}>
        {React.addons.cloneWithProps(this.props.menu, { menuActions })}
      </View>
    );
  },

  /**
   * Compose and render menu and content view
   * @return {React.Component}
   */
  render: function() {
    return (
      <View style={styles.container}>
        {this.getMenuView()}
        {this.getContentView()}
      </View>
    );
  }
});

SideMenu.propTypes = {
  toleranceX: React.PropTypes.number,
  toleranceY: React.PropTypes.number,
  onChange: React.PropTypes.func
}

SideMenu.defaultProps = {
  toleranceY: 10,
  toleranceX: 10,
  onChange: noop
};

module.exports = SideMenu;
<commit_msg>Fixing typo<commit_after>'use strict';

var React = require('react-native');
var deviceScreen = require('Dimensions').get('window');
var styles = require('./styles');
var queueAnimation = require('./animations');

var {
  PanResponder,
  View,
} = React;

/**
 * Default open menu offset. Describes a size of the amount you can
 * move content view from the left and release without opening it
 * @type {Number}
 */
var openMenuOffset = deviceScreen.width * 2 / 3;

/**
 * Content view offset in the `hidden` state
 * @type {Number}
 */
var hiddenMenuOffset = 0;

/**
 * Size of the amount you can move content view in the opened menu state and
 * release without menu closing
 * @type {Number}
 */
var barrierForward = deviceScreen.width / 4;

/**
 * Check if the current gesture offset bigger than allowed one
 * before opening menu
 * @param  {Number} dx Gesture offset from the left side of the window
 * @return {Boolean}
 */
function shouldOpenMenu(dx: Number) {
    return dx > barrierForward;
}

/**
 * no operation function. does nothing.
 */
function noop() {}

var SideMenu = React.createClass({

  /**
   * Current state of the menu, whether it is open or not
   * @type {Boolean}
   */
  isOpen: false,

  /**
   * Current style `left` attribute
   * @todo Check if it's possible to avoid using `left`
   * @type {Number}
   */
  left: 0,

  /**
   * Default left offset for content view
   * @todo Check if it's possible to avoid using `prevLeft`
   * @type {Number}
   */
  prevLeft: 0,

  /**
   * Creates PanResponders and links to appropriate functions
   * @return {Void}
   */
  createResponders: function(disableGestures) {
    if (disableGestures || false) {
      this.responder = PanResponder.create({});
      return;
    }

    this.responder = PanResponder.create({
        onMoveShouldSetPanResponder: this.handleMoveShouldSetPanResponder,
        onPanResponderMove: this.handlePanResponderMove,
        onPanResponderRelease: this.handlePanResponderEnd,
    });
  },

  /**
   * Set the initial responders
   * @return {Void}
   */
  componentWillMount: function () {
    this.createResponders(this.props.disableGestures);
  },

  /**
   * Update responders on new props whenever possible
   * @return {Void}
   */
  componentWillReceiveProps: function (nextProps) {
    this.createResponders(nextProps.disableGestures);
  },

  /**
   * Change `left` style attribute
   * Works only if `sideMenu` is a ref to React.Component
   * @return {Void}
   */
  updatePosition: function() {
    this.sideMenu.setNativeProps({ left: this.left });
  },

  /**
   * Permission to use responder
   * @return {Boolean} true
   */
  handleMoveShouldSetPanResponder: function(e: Object, gestureState: Object) {
    var x = Math.round(Math.abs(gestureState.dx));
    var y = Math.round(Math.abs(gestureState.dy));

    return x > this.props.toleranceX && y < this.props.toleranceY;
  },

  /**
   * Handler on responder move
   * @param  {Synthetic Event} e
   * @param  {Object} gestureState
   * @return {Void}
   */
  handlePanResponderMove: function(e: Object, gestureState: Object) {
    this.left = this.prevLeft + gestureState.dx;

    if ((this.menuPositionMultiplier() * this.left) > 0) {
      this.updatePosition();
    }
  },

  /**
   * Returns 1 or -1 depending on the menuPosition
   * @return {Number}
   */
  menuPositionMultiplier: function() {
    return this.props.menuPosition === "right" ? -1 : 1;
  },

  /**
   * Open menu
   * @return {Void}
   */
  openMenu: function() {
    queueAnimation(this.props.animation);

    this.left = this.menuPositionMultiplier() *
      (this.props.openMenuOffset || openMenuOffset);

    this.updatePosition();
    this.prevLeft = this.left;

    if (!this.isOpen) {
      this.props.onChange();
    }

    this.isOpen = true;
  },

  /**
   * Close menu
   * @return {Void}
   */
  closeMenu: function() {
    queueAnimation(this.props.animation);
    this.left = this.menuPositionMultiplier() *
      (this.props.hiddenMenuOffset || hiddenMenuOffset);

    this.updatePosition();
    this.prevLeft = this.left;

    if (this.isOpen) {
      this.props.onChange();
    }

    this.isOpen = false;
  },

  /**
   * Toggle menu
   * @return {Void}
   */
  toggleMenu: function() {
    if (this.isOpen) {
      this.closeMenu();
    } else {
      this.openMenu();
    }
  },

  /**
   * Handler on responder move ending
   * @param  {Synthetic Event} e
   * @param  {Object} gestureState
   * @return {Void}
   */
  handlePanResponderEnd: function(e: Object, gestureState: Object) {
    var shouldOpen = this.menuPositionMultiplier() *
      (this.left + gestureState.dx);

    if (shouldOpenMenu(shouldOpen)) {
      this.openMenu();
    } else {
      this.closeMenu();
    }

    this.updatePosition();
    this.prevLeft = this.left;
  },

  /**
   * Get content view. This view will be rendered over menu
   * @return {React.Component}
   */
  getContentView: function() {
    var getMenuActions = this.getMenuActions();
    return (
      <View
        style={styles.frontView}
        ref={(sideMenu) => this.sideMenu = sideMenu}
        {...this.responder.panHandlers}>

        {React.Children.map(this.props.children, function(child) {
          return React.cloneElement(child, {
            menuActions: getMenuActions
          });
        })}
      </View>
    );
  },

  /**
   * Get menu actions to expose it to
   * menu and children components
   * @return {Object} Public API methods
   */
  getMenuActions: function() {
    return {
      close: this.closeMenu,
      toggle: this.toggleMenu,
      open: this.openMenu
    };
  },

  /**
   * Get menu view. This view will be rendered under
   * content view. Also, this function will decorate
   * passed `menu` component with side menu API
   * @return {React.Component}
   */
  getMenuView: function() {
    var menuActions = this.getMenuActions();

    return (
      <View style={styles.menu}>
        {React.addons.cloneWithProps(this.props.menu, { menuActions })}
      </View>
    );
  },

  /**
   * Compose and render menu and content view
   * @return {React.Component}
   */
  render: function() {
    return (
      <View style={styles.container}>
        {this.getMenuView()}
        {this.getContentView()}
      </View>
    );
  }
});

SideMenu.propTypes = {
  toleranceX: React.PropTypes.number,
  toleranceY: React.PropTypes.number,
  onChange: React.PropTypes.func
}

SideMenu.defaultProps = {
  toleranceY: 10,
  toleranceX: 10,
  onChange: noop
};

module.exports = SideMenu;
<|endoftext|>


<commit_before>/* Global variables */
var last_sms_id = -1;
var httpServer = new HTTPServer(8080);

/* Logging the result from messages */
function logMsg(msg){
	var r = "";
	['type', 'id', 'threadId', 'body', 'delivery', 'deliveryStatus', 'read', 'receiver', 'sender', 'timestamp', 'messageClass'].forEach(function (key){
		r += '
 ' + key + ': ' + msg[key];
	});
	console.log(r);
}

/* Not very beautiful, but for now, it is OK */
function update_loc(){
	$('[data-l10n-id]').each(function(index){
		$(this).html(navigator.mozL10n.get($(this).attr('data-l10n-id')));
	});
}

/* Loading the page */
function load_page(requested_page){
	console.log('Loading page ' + requested_page);
	if (requested_page == "about"){
		$("#main-container").load("../content/about_content.html", function() {
			console.log('Loading of the HTML performed');
			update_loc();
		});
	} else if (requested_page == "server"){
		$("#main-container").load("../content/server_content.html", function() {
			console.log('Loading of the HTML performed');
			update_loc();

			/* Getting the elements */
			var sstatus = document.getElementById('server-status');
			var ip     = document.getElementById('ip-address');
			var port   = document.getElementById('listening-port');
			var start_b  = document.getElementById('start-server');
			var stop_b   = document.getElementById('stop-server');

			/* Displaying */
			IPUtils.getAddresses(function(ipAddress) {
				ip.textContent = ip.textContent || ipAddress;
			});

			port.textContent = httpServer.port;

			if (httpServer.running){
				sstatus.textContent = navigator.mozL10n.get('running');
			} else {
				sstatus.textContent = navigator.mozL10n.get('stopped');
			}

			/* Adding listeners in the buttons */
			start_b.addEventListener('click', function() {
				console.log('Clicked on start');
			  	httpServer.start();
				sstatus.textContent = navigator.mozL10n.get('running');
			});

			stop_b.addEventListener('click', function() {
				console.log('Clicked on stop');
			  	httpServer.stop();
				sstatus.textContent = navigator.mozL10n.get('stopped');
			});

			$('#testing-server').on('click', function(e){
				console.log('Clicked on testing');

				e.preventDefault();
				var activity = new MozActivity({
					name: "view",
					data: {
						type: "url",
						url: 'http://' + ip.textContent + ':' + port.textContent
					}
				});
				//window.location.href = 'http://' + ip.textContent + ':' + port.textContent;
			});
		});
	} else if (requested_page == "settings"){
		$("#main-container").load("../content/settings_content.html", function() {
			console.log('Loading of the HTML performed');
			update_loc();

			/* Initializing the selects */
			$('select').material_select();

			/* Modifying the app language */
			$("#select-language").change(function() {
				var l = $("#select-language").val();
				console.log('New selected language: ' + l);
				navigator.mozL10n.language.code = l;
			});
		});
	} else {
		$("#main-container").load("../content/index_content.html", function() {
			console.log('Loading of the HTML performed');
			update_loc();

			last_sms_id = -1;

			/* Settings the behavior on click : sending SMS */
			$('#sms-submit').on("click", function (ev){
				console.log('Submitting SMS form...');

				/* Creating the response div, if not existing */
				var resp = document.getElementById('response');
				if (resp == null) {
					$("#main-container").append('

');
				}

				$("#response").html(navigator.mozL10n.get('submitting_sms') + '...');

				var msg = document.getElementById('message').value;
				var phone = document.getElementById('contacts').value;
				console.log('Submitted message : ' + msg + ' Phone nb: ' + phone);

				var request;
				request = navigator.mozMobileMessage.send(phone, msg);

				/* When the message was successfully sent */
				request.onsuccess = function (){
					window.thing = this;
					console.log(this.result);
					console.log('Sent to: ' + this.result);
					last_sms_id = this.result['id'];
					logMsg(this.result);
					$("#response").html('' + navigator.mozL10n.get('successfully_sent') + ' ✓
');

					/* Check if the last sms was well delivered (receipt) */
					var checking_last_sms = window.setInterval(function(){
						if (last_sms_id != -1){
							var request = navigator.mozMobileMessage.getMessage(last_sms_id);
							request.onsuccess = function (){
								window.thing = this;
								console.error(this.result);

								if (this.result['deliveryStatus'] == 'success'){
									clearInterval(checking_last_sms);
									$("#response").append('' + navigator.mozL10n.get('successfully_received') + ' ✓');
								}

								logMsg(this.result);
							}

							request.onerror = function (){
								$("#response").html('Couldn\'t retrieve last sent SMS...');
								clearInterval(checking_last_sms);
							}
						}
					}, 5000);
				};

				/* When the message wasn't sent correctly */
				request.onerror = function (){
					window.thing = this;
					console.error(this.error.name);
					console.error(this.error.message);
					$("#response").html('' + navigator.mozL10n.get('error_sending_message') + ' ✗');
					$("#response").append('' + this.error.name + ':' + this.error.message + '');
				};
			});

			var allContacts = navigator.mozContacts.getAll();

			allContacts.onsuccess = function(event) {
				var cursor = event.target;
				var gn, fn, tl;
				if (cursor.result) {
					gn = (cursor.result.givenName == null) ? "" : cursor.result.givenName[0]
					fn = (cursor.result.familyName == null) ? "" : cursor.result.familyName[0]
					tl = (cursor.result.tel == null) ? "" : cursor.result.tel[0].value
					console.log('Found one contact... Given name : ' + gn + ', Family name : ' + fn + ', Tel : ' + tl);

					/* Append new contact to the select */
					$('#contacts').append('<option value="' + tl + '">' + gn + ' ' + fn + '</option>');

					/* Go to the next contact */
					cursor.continue();
				} else {
					console.log('No more contacts, creating the Materialize select...');
					/* Once the contacts are all retrieved, we create the Materialize select */
					$('select').material_select();
				}
			};

			allContacts.onerror = function() {
				console.warn('Something went terribly wrong while retrieving the contacts!');
			};
		});
	}
}

/* DOMContentLoaded is fired once the document has been loaded and parsed,
but without waiting for other external resources to load (css/images/etc)
That makes the app more responsive and perceived as faster.
https://developer.mozilla.org/Web/Reference/Events/DOMContentLoaded */
window.addEventListener('DOMContentLoaded', function() {

	/* We'll ask the browser to use strict code to help us catch errors earlier.
	https://developer.mozilla.org/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode */
	'use strict';

	/* Adding listener to the server (when the server is getting a request) */
	httpServer.addEventListener('request', function(evt) {
		var request  = evt.request;
		var response = evt.response;

		console.log(request);

		if (request.path === 'image.jpg') {
		    response.headers['Content-Type'] = 'image/png';
		    response.sendFile('../img/icons/fox128x128.png');
		    return;
		}

		var paramsString = JSON.stringify(request.params, null, 2);
		var bodyString   = JSON.stringify(request.body, null, 2);

		var firstName = (request.body && request.body.first_name) || '';
		var lastName  = (request.body && request.body.last_name)  || '';

		var body = '<!DOCTYPE html><title>Firefox OS Web Server</title>
Hello World!

If you can read this, the Firefox OS Web Server is operational!

The path you requested is: ' + request.path + '

URL Parameters:

' + paramsString + '

POST Data:

' + bodyString + '

Sample Form
<form method="POST" action=".">
First Name:<input type="text" name="first_name" value="' + firstName + '">

Last Name:<input type="text" name="last_name" value="' + lastName + '">
<input type="submit" value="Submit"></form>
To see something really scary, click here :-)
';

		response.send(body);
	});

	/* Loading the side nav */
	var e = document.getElementById('nav-slide');
	if (e != null){
		console.log('Successfully retrieved nav-slide');
		$("#nav-slide").load('../slide.html', function() {
			$('.button-collapse').sideNav({
				menuWidth: 200, /* Default is 240 */
				edge: 'left', /* Choose the horizontal origin */
				closeOnClick: true /* Closes side-nav on  clicks, useful for Angular/Meteor */
			});

			$('#home').on("click", function(ev){
				console.log("Clicked home");
				load_page("home");
			});
			$('#objects').on("click", function(ev){
				console.log("Clicked objects");
				// load_page("objects");
			});
			$('#server').on("click", function(ev){
				console.log("Clicked server");
				load_page("server");
			});
			$('#settings').on("click", function(ev){
				console.log("Clicked settings");
				load_page("settings");
			});
			$('#about').on("click", function(ev){
				console.log("Clicked about");
				load_page("about");
			});

			load_page("home");

		});
	} else {
		console.log('Error while retrieving nav-slide');
	}

	/* We want to wait until the localisations library has loaded all the strings.
	So we'll tell it to let us know once it's ready. */
	navigator.mozL10n.once(start);

	function start() {
		// var message = document.getElementById('message');
		// message.textContent = translate('message');
		$('select').material_select();
	}

});

/* Stopping the server when unload */
window.addEventListener('beforeunload', function() {
	httpServer.stop();
});

<commit_msg>Adding toast to the objects tab<commit_after>/* Global variables */
var last_sms_id = -1;
var httpServer = new HTTPServer(8080);

/* Logging the result from messages */
function logMsg(msg){
	var r = "";
	['type', 'id', 'threadId', 'body', 'delivery', 'deliveryStatus', 'read', 'receiver', 'sender', 'timestamp', 'messageClass'].forEach(function (key){
		r += '
 ' + key + ': ' + msg[key];
	});
	console.log(r);
}

/* Not very beautiful, but for now, it is OK */
function update_loc(){
	$('[data-l10n-id]').each(function(index){
		$(this).html(navigator.mozL10n.get($(this).attr('data-l10n-id')));
	});
}

/* Loading the page */
function load_page(requested_page){
	console.log('Loading page ' + requested_page);
	if (requested_page == "about"){
		$("#main-container").load("../content/about_content.html", function() {
			console.log('Loading of the HTML performed');
			update_loc();
		});
	} else if (requested_page == "server"){
		$("#main-container").load("../content/server_content.html", function() {
			console.log('Loading of the HTML performed');
			update_loc();

			/* Getting the elements */
			var sstatus = document.getElementById('server-status');
			var ip     = document.getElementById('ip-address');
			var port   = document.getElementById('listening-port');
			var start_b  = document.getElementById('start-server');
			var stop_b   = document.getElementById('stop-server');

			/* Displaying */
			IPUtils.getAddresses(function(ipAddress) {
				ip.textContent = ip.textContent || ipAddress;
			});

			port.textContent = httpServer.port;

			if (httpServer.running){
				sstatus.textContent = navigator.mozL10n.get('running');
			} else {
				sstatus.textContent = navigator.mozL10n.get('stopped');
			}

			/* Adding listeners in the buttons */
			start_b.addEventListener('click', function() {
				console.log('Clicked on start');
			  	httpServer.start();
				sstatus.textContent = navigator.mozL10n.get('running');
			});

			stop_b.addEventListener('click', function() {
				console.log('Clicked on stop');
			  	httpServer.stop();
				sstatus.textContent = navigator.mozL10n.get('stopped');
			});

			$('#testing-server').on('click', function(e){
				console.log('Clicked on testing');

				e.preventDefault();
				var activity = new MozActivity({
					name: "view",
					data: {
						type: "url",
						url: 'http://' + ip.textContent + ':' + port.textContent
					}
				});
				//window.location.href = 'http://' + ip.textContent + ':' + port.textContent;
			});
		});
	} else if (requested_page == "settings"){
		$("#main-container").load("../content/settings_content.html", function() {
			console.log('Loading of the HTML performed');
			update_loc();

			/* Initializing the selects */
			$('select').material_select();

			/* Modifying the app language */
			$("#select-language").change(function() {
				var l = $("#select-language").val();
				console.log('New selected language: ' + l);
				navigator.mozL10n.language.code = l;
			});
		});
	} else {
		$("#main-container").load("../content/index_content.html", function() {
			console.log('Loading of the HTML performed');
			update_loc();

			last_sms_id = -1;

			/* Settings the behavior on click : sending SMS */
			$('#sms-submit').on("click", function (ev){
				console.log('Submitting SMS form...');

				/* Creating the response div, if not existing */
				var resp = document.getElementById('response');
				if (resp == null) {
					$("#main-container").append('

');
				}

				$("#response").html(navigator.mozL10n.get('submitting_sms') + '...');

				var msg = document.getElementById('message').value;
				var phone = document.getElementById('contacts').value;
				console.log('Submitted message : ' + msg + ' Phone nb: ' + phone);

				var request;
				request = navigator.mozMobileMessage.send(phone, msg);

				/* When the message was successfully sent */
				request.onsuccess = function (){
					window.thing = this;
					console.log(this.result);
					console.log('Sent to: ' + this.result);
					last_sms_id = this.result['id'];
					logMsg(this.result);
					$("#response").html('' + navigator.mozL10n.get('successfully_sent') + ' ✓
');

					/* Check if the last sms was well delivered (receipt) */
					var checking_last_sms = window.setInterval(function(){
						if (last_sms_id != -1){
							var request = navigator.mozMobileMessage.getMessage(last_sms_id);
							request.onsuccess = function (){
								window.thing = this;
								console.error(this.result);

								if (this.result['deliveryStatus'] == 'success'){
									clearInterval(checking_last_sms);
									$("#response").append('' + navigator.mozL10n.get('successfully_received') + ' ✓');
								}

								logMsg(this.result);
							}

							request.onerror = function (){
								$("#response").html('Couldn\'t retrieve last sent SMS...');
								clearInterval(checking_last_sms);
							}
						}
					}, 5000);
				};

				/* When the message wasn't sent correctly */
				request.onerror = function (){
					window.thing = this;
					console.error(this.error.name);
					console.error(this.error.message);
					$("#response").html('' + navigator.mozL10n.get('error_sending_message') + ' ✗');
					$("#response").append('' + this.error.name + ':' + this.error.message + '');
				};
			});

			var allContacts = navigator.mozContacts.getAll();

			allContacts.onsuccess = function(event) {
				var cursor = event.target;
				var gn, fn, tl;
				if (cursor.result) {
					gn = (cursor.result.givenName == null) ? "" : cursor.result.givenName[0]
					fn = (cursor.result.familyName == null) ? "" : cursor.result.familyName[0]
					tl = (cursor.result.tel == null) ? "" : cursor.result.tel[0].value
					console.log('Found one contact... Given name : ' + gn + ', Family name : ' + fn + ', Tel : ' + tl);

					/* Append new contact to the select */
					$('#contacts').append('<option value="' + tl + '">' + gn + ' ' + fn + '</option>');

					/* Go to the next contact */
					cursor.continue();
				} else {
					console.log('No more contacts, creating the Materialize select...');
					/* Once the contacts are all retrieved, we create the Materialize select */
					$('select').material_select();
				}
			};

			allContacts.onerror = function() {
				console.warn('Something went terribly wrong while retrieving the contacts!');
			};
		});
	}
}

/* DOMContentLoaded is fired once the document has been loaded and parsed,
but without waiting for other external resources to load (css/images/etc)
That makes the app more responsive and perceived as faster.
https://developer.mozilla.org/Web/Reference/Events/DOMContentLoaded */
window.addEventListener('DOMContentLoaded', function() {

	/* We'll ask the browser to use strict code to help us catch errors earlier.
	https://developer.mozilla.org/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode */
	'use strict';

	/* Adding listener to the server (when the server is getting a request) */
	httpServer.addEventListener('request', function(evt) {
		var request  = evt.request;
		var response = evt.response;

		console.log(request);

		if (request.path === 'image.jpg') {
		    response.headers['Content-Type'] = 'image/png';
		    response.sendFile('../img/icons/fox128x128.png');
		    return;
		}

		var paramsString = JSON.stringify(request.params, null, 2);
		var bodyString   = JSON.stringify(request.body, null, 2);

		var firstName = (request.body && request.body.first_name) || '';
		var lastName  = (request.body && request.body.last_name)  || '';

		var body = '<!DOCTYPE html><title>Firefox OS Web Server</title>
Hello World!

If you can read this, the Firefox OS Web Server is operational!

The path you requested is: ' + request.path + '

URL Parameters:

' + paramsString + '

POST Data:

' + bodyString + '

Sample Form
<form method="POST" action=".">
First Name:<input type="text" name="first_name" value="' + firstName + '">

Last Name:<input type="text" name="last_name" value="' + lastName + '">
<input type="submit" value="Submit"></form>
To see something really scary, click here :-)
';

		response.send(body);
	});

	/* Loading the side nav */
	var e = document.getElementById('nav-slide');
	if (e != null){
		console.log('Successfully retrieved nav-slide');
		$("#nav-slide").load('../slide.html', function() {
			$('.button-collapse').sideNav({
				menuWidth: 200, /* Default is 240 */
				edge: 'left', /* Choose the horizontal origin */
				closeOnClick: true /* Closes side-nav on  clicks, useful for Angular/Meteor */
			});

			$('#home').on("click", function(ev){
				console.log("Clicked home");
				load_page("home");
			});
			$('#objects').on("click", function(ev){
				console.log("Clicked objects");
				Materialize.toast('Work in progress', 4000);
			});
			$('#server').on("click", function(ev){
				console.log("Clicked server");
				load_page("server");
			});
			$('#settings').on("click", function(ev){
				console.log("Clicked settings");
				load_page("settings");
			});
			$('#about').on("click", function(ev){
				console.log("Clicked about");
				load_page("about");
			});

			load_page("home");

		});
	} else {
		console.log('Error while retrieving nav-slide');
	}

	/* We want to wait until the localisations library has loaded all the strings.
	So we'll tell it to let us know once it's ready. */
	navigator.mozL10n.once(start);

	function start() {
		// var message = document.getElementById('message');
		// message.textContent = translate('message');
		$('select').material_select();
	}

});

/* Stopping the server when unload */
window.addEventListener('beforeunload', function() {
	httpServer.stop();
});

<|endoftext|>


<commit_before>/*!
 * defaults-deep <https://github.com/jonschlinkert/defaults-deep>
 *
 * Copyright (c) 2014-2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var isObject = require('is-plain-object');
var forOwn = require('for-own');

function defaultsDeep(o, objects) {
  if (!isObject(o)) return {};
  if (!isObject(objects)) return o;

  function copy(o, current) {
    forOwn(current, function (value, key) {
      var val = o[key];
      // add the missing property, or allow a null property to be updated
      if (val == null) {
        o[key] = value;
      } else if (isObject(val) && isObject(value)) {
        defaultsDeep(val, value);
      }
    });
  }

  var len = arguments.length, i = 0;
  while (i < len) {
    var obj = arguments[i++];
    if (obj) {
      copy(o, obj);
    }
  }
  return o;
};

/**
 * Expose `defaultsDeep`
 */

module.exports = defaultsDeep;
<commit_msg>adds lazy-caching<commit_after>/*!
 * defaults-deep <https://github.com/jonschlinkert/defaults-deep>
 *
 * Copyright (c) 2014-2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var lazy = require('lazy-cache')(require);
lazy('is-extendable', 'isObject');
lazy('for-own', 'forOwn');

function defaultsDeep(target, objects) {
  target = target || {};

  function copy(target, current) {
    lazy.forOwn(current, function (value, key) {
      var val = target[key];
      // add the missing property, or allow a null property to be updated
      if (val == null) {
        target[key] = value;
      } else if (lazy.isObject(val) && lazy.isObject(value)) {
        defaultsDeep(val, value);
      }
    });
  }

  var len = arguments.length, i = 0;
  while (i < len) {
    var obj = arguments[i++];
    if (obj) {
      copy(target, obj);
    }
  }
  return target;
};

/**
 * Expose `defaultsDeep`
 */

module.exports = defaultsDeep;
<|endoftext|>


<commit_before>var rework = require('rework'),
    imprt = require('rework-npm'),
    vars = require('rework-vars'),
    calc = require('rework-calc'),
    namespace = require('rework-namespace'),
    autoprefixer = require('autoprefixer'),
    read = require('fs-extra').readFileSync,
    exists = require('fs-extra').existsSync;

module.exports = function(options) {
    options = options || {};
    var src = options.src,
        dest = options.dest,
        license = options.license || '',
        ns = options.namespace || '',
        browsers = options.browsers || [],
        debug = options.debug || false,
        output;

    if (!exists(src)) {
        throw new Error("Sorry, I couldn't find an input file. Did you supply one?");
    }

    output = rework(read(src, 'utf8'))
        .use(imprt())
        .use(vars())
        .use(calc)
        .use(rework.colors())
        .use(rework.extend())
        .use(namespace(ns))
        .use(autoprefixer(browsers).rework)
        .toString({sourcemap: debug}).replace(/(\/\*[\s\S]*?(license)[\s\S]*?\*\/)([\s\t]*(\r\n|\n|\r))/gi, '');

    return license + output;
};
<commit_msg>updated regex<commit_after>var rework = require('rework'),
    imprt = require('rework-npm'),
    vars = require('rework-vars'),
    calc = require('rework-calc'),
    namespace = require('rework-namespace'),
    autoprefixer = require('autoprefixer'),
    read = require('fs-extra').readFileSync,
    exists = require('fs-extra').existsSync;

module.exports = function(options) {
    options = options || {};
    var src = options.src,
        dest = options.dest,
        license = options.license || '',
        ns = options.namespace || '',
        browsers = options.browsers || [],
        debug = options.debug || false,
        output;

    if (!exists(src)) {
        throw new Error("Sorry, I couldn't find an input file. Did you supply one?");
    }

    output = rework(read(src, 'utf8'))
        .use(imprt())
        .use(vars())
        .use(calc)
        .use(rework.colors())
        .use(rework.extend())
        .use(namespace(ns))
        .use(autoprefixer(browsers).rework)
        .toString({sourcemap: debug}).replace(/(\/\*\*[\s\S]*?(license)[\s\S]*?\*\/)([\s\t]*)/gi, '');

    return license + output;
};
<|endoftext|>


<commit_before>var cluster = require('cluster')

if (cluster.isMaster) {
  var async = require('async')
  var config = require('./config')()
  var fs = require('fs')
  var path = require('path')
  var sharp = require('sharp')
  var io = require('socket.io')(config.stats_port)
  var vnstat = require('vnstat-dumpdb')
  var metadata = require(config.metadata_path)
  var moment = require('moment')
  console.log('Config:')
  console.log(config)

  try {
    var stats = require(config.stats_path)
  } catch (error) {
    var stats = { count: 0 }
  }

  try {
    var images = require(config.image_store_path)
  } catch (e) {
    var images = []
  }

  var publicStats = {}
  var bandWidth = 0

  io.on('connection', function (socket) {
    socket.emit('stats', publicStats)
  })

  var fetchStats = function () {
    publicStats = {
      count: stats.count,
      bandWidth: bandWidth,
      images: images.length
    }

    io.emit('stats', publicStats)
  }

  var fetchBandwidth = function () {
    vnstat.dumpdb(function (error, data) {
      if (error) {
        console.log('Couldn\'t fetch bandwidth: ' + error)
      } else {
        bandWidth = data.traffic ? data.traffic.total.tx : data.eth0.traffic.total.tx
      }
    })
  }

  setInterval(fetchBandwidth, 1000 * 30)
  setInterval(fetchStats, 1000)
  fetchBandwidth()
  fetchStats()

  var exited = false

  var saveToFileAndExit = function () {
    if (exited) {
      return
    } else {
      exited = true
    }

    console.log('Current stats:', stats)

    fs.writeFileSync(config.stats_path, JSON.stringify(stats), 'utf8')
    process.exit(0)
  }

  var saveToFile = function (callback) {
    fs.writeFile(config.stats_path, JSON.stringify(stats), 'utf8', function (error) {
      callback()
    })
  }

  process.on('exit', saveToFileAndExit)
  process.on('SIGINT', saveToFileAndExit)
  process.on('SIGTERM', saveToFileAndExit)
  process.on('uncaughtException', function (error) {
    console.log('Uncaught exception: ')
    console.trace(error)
    saveToFileAndExit()
  })

  var loadImages = function () {
    var newImages = []

    async.each(metadata, function (image, next) {
      if (image.deleted) {
        return setImmediate(next)
      }

      var existingImage = imageExists(image)

      if (existingImage) {
        existingImage.post_url = image.post_url
        existingImage.author = image.author
        existingImage.author_url = image.author_url
        newImages.push(existingImage)

        return setImmediate(next)
      }

      var filename = path.resolve(config.folder_path, image.filename)

      console.log('Getting info for new image %s', filename)

      sharp(filename).metadata(function (error, result) {
        if (error) {
          console.trace('imageScan error: %s filename: %s', error, filename)
          return setImmediate(next)
        }

        result.filename = filename
        result.id = image.id
        result.post_url = image.post_url
        result.author = image.author
        result.author_url = image.author_url
        newImages.push(result)

        next()
      })
    }, function (error) {
      writeImagesToFile(newImages)
    })
  }

  var imageExists = function (image) {
    for (var i in images) {
      if (images[i].id === image.id) {
        return images[i]
      }
    }

    return false
  }

  var writeImagesToFile = function (newImages) {
    newImages.sort(function (a, b) {
      return a.id - b.id
    })

    images = newImages

    fs.writeFile(config.image_store_path, JSON.stringify(newImages), 'utf8', function (error) {
      startWebServers()
    })
  }

  var startWebServers = function () {
    var cpuCount = require('os').cpus().length - 1

    if (cpuCount < 2) {
      cpuCount = 2
    }

    for (var i = 0, il=cpuCount; i < il; i++) {
      startWorker()
    }

    cluster.on('exit', function (worker) {
      console.log('Worker ' + worker.id + ' died')
      startWorker()
    })

    var triggerSaveToFile = function () {
      saveToFile(function () {
        setImmediate(setTimeout, triggerSaveToFile, 1000 * 5)
      })
    }

    setTimeout(triggerSaveToFile, 1000 * 5)
  }

  var startWorker = function () {
    var worker = cluster.fork()
    worker.on('message', handleWorkerMessage)
    console.log('Worker ' + worker.id + ' started')
  }

  var handleWorkerMessage = function (msg) {
    stats.count++
  }

  loadImages()
} else {
  var config = require('./config')()
  require('./server')(function (callback) {
    callback.listen(process.env.PORT || config.port, '0.0.0.0')
  })
}
<commit_msg>Create cache folder path on startup<commit_after>var cluster = require('cluster')

if (cluster.isMaster) {
  var async = require('async')
  var config = require('./config')()
  var fs = require('fs')
  var path = require('path')
  var sharp = require('sharp')
  var io = require('socket.io')(config.stats_port)
  var vnstat = require('vnstat-dumpdb')
  var metadata = require(config.metadata_path)
  var moment = require('moment')
  console.log('Config:')
  console.log(config)

  try {
    var stats = require(config.stats_path)
  } catch (error) {
    var stats = { count: 0 }
  }

  try {
    var images = require(config.image_store_path)
  } catch (e) {
    var images = []
  }

  var publicStats = {}
  var bandWidth = 0

  io.on('connection', function (socket) {
    socket.emit('stats', publicStats)
  })

  var fetchStats = function () {
    publicStats = {
      count: stats.count,
      bandWidth: bandWidth,
      images: images.length
    }

    io.emit('stats', publicStats)
  }

  var fetchBandwidth = function () {
    vnstat.dumpdb(function (error, data) {
      if (error) {
        console.log('Couldn\'t fetch bandwidth: ' + error)
      } else {
        bandWidth = data.traffic ? data.traffic.total.tx : data.eth0.traffic.total.tx
      }
    })
  }

  setInterval(fetchBandwidth, 1000 * 30)
  setInterval(fetchStats, 1000)
  fetchBandwidth()
  fetchStats()

  var exited = false

  var saveToFileAndExit = function () {
    if (exited) {
      return
    } else {
      exited = true
    }

    console.log('Current stats:', stats)

    fs.writeFileSync(config.stats_path, JSON.stringify(stats), 'utf8')
    process.exit(0)
  }

  var saveToFile = function (callback) {
    fs.writeFile(config.stats_path, JSON.stringify(stats), 'utf8', function (error) {
      callback()
    })
  }

  process.on('exit', saveToFileAndExit)
  process.on('SIGINT', saveToFileAndExit)
  process.on('SIGTERM', saveToFileAndExit)
  process.on('uncaughtException', function (error) {
    console.log('Uncaught exception: ')
    console.trace(error)
    saveToFileAndExit()
  })

  var loadImages = function () {
    var newImages = []

    async.each(metadata, function (image, next) {
      if (image.deleted) {
        return setImmediate(next)
      }

      var existingImage = imageExists(image)

      if (existingImage) {
        existingImage.post_url = image.post_url
        existingImage.author = image.author
        existingImage.author_url = image.author_url
        newImages.push(existingImage)

        return setImmediate(next)
      }

      var filename = path.resolve(config.folder_path, image.filename)

      console.log('Getting info for new image %s', filename)

      sharp(filename).metadata(function (error, result) {
        if (error) {
          console.trace('imageScan error: %s filename: %s', error, filename)
          return setImmediate(next)
        }

        result.filename = filename
        result.id = image.id
        result.post_url = image.post_url
        result.author = image.author
        result.author_url = image.author_url
        newImages.push(result)

        next()
      })
    }, function (error) {
      writeImagesToFile(newImages)
    })
  }

  var imageExists = function (image) {
    for (var i in images) {
      if (images[i].id === image.id) {
        return images[i]
      }
    }

    return false
  }

  var writeImagesToFile = function (newImages) {
    newImages.sort(function (a, b) {
      return a.id - b.id
    })

    images = newImages

    fs.writeFile(config.image_store_path, JSON.stringify(newImages), 'utf8', function (error) {
      startWebServers()
    })
  }

  var startWebServers = function () {
    var cpuCount = require('os').cpus().length - 1

    if (cpuCount < 2) {
      cpuCount = 2
    }

    for (var i = 0, il=cpuCount; i < il; i++) {
      startWorker()
    }

    cluster.on('exit', function (worker) {
      console.log('Worker ' + worker.id + ' died')
      startWorker()
    })

    var triggerSaveToFile = function () {
      saveToFile(function () {
        setImmediate(setTimeout, triggerSaveToFile, 1000 * 5)
      })
    }

    setTimeout(triggerSaveToFile, 1000 * 5)
  }

  var startWorker = function () {
    var worker = cluster.fork()
    worker.on('message', handleWorkerMessage)
    console.log('Worker ' + worker.id + ' started')
  }

  var handleWorkerMessage = function (msg) {
    stats.count++
  }

  fs.mkdir(config.cache_folder_path, function (error) {
    loadImages()
  })
} else {
  var config = require('./config')()
  require('./server')(function (callback) {
    callback.listen(process.env.PORT || config.port, '0.0.0.0')
  })
}
<|endoftext|>


<commit_before>var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
var player, cursors, walls;

function preload() {
    game.load.image('skyBackground', 'assets/sky.png');
    game.load.image('playerSprite', 'assets/player.png');
    game.load.image('wallSprite', 'assets/wall.png');
}

function create() {

    game.physics.startSystem(Phaser.Physics.ARCADE);

	//Adding things to world
	//Stuff is rendered in the order it's added (back to front)
	//Desired order: Background < Knives (to be added later) < Wind (later) < Players < Walls

    game.add.sprite(0, 0, 'skyBackground');

	player = game.add.sprite(game.world.width/2, game.world.height/2, 'playerSprite');
	game.physics.enable(player);
	player.body.gravity.y = 0;
	player.body.collideWorldBounds = true;

	walls = game.add.group();
	walls.enableBody = true;

	//Wallsprite is 50px*50px, scale is multiplicative
	var newWall = walls.create(game.world.width/4-25, game.world.height/4-25, 'wallSprite');
	newWall.scale.setTo(2, 1);
	newWall.body.immovable = true;

	newWall = walls.create(2*game.world.width/3, 3*game.world.height/4-75, 'wallSprite');
	newWall.scale.setTo(1, 3);
	newWall.body.immovable = true;

	//Todo in the future: Change arrow keys to WASD
    cursors = game.input.keyboard.createCursorKeys();
}

function update() {
	game.physics.arcade.collide(player, walls);

	player.body.velocity.x = 0;
	player.body.velocity.y = 0;
	var moveSpeed = 300;

	if(cursors.left.isDown)
	{
		player.body.velocity.x -= moveSpeed;
	}
	if(cursors.right.isDown)
	{
		player.body.velocity.x += moveSpeed;
	}
	if(cursors.up.isDown)
	{
		player.body.velocity.y -= moveSpeed;
	}
	if(cursors.down.isDown)
	{
		player.body.velocity.y += moveSpeed;
	}
}<commit_msg>Add placeholder NPC, knife<commit_after>"use strict";
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
var player, yourKnife, otherPlayers, otherKnives, cursors, walls;
//Other players' knives might not need to be simulated if the wind is synced well enough. Other players still ought to be for hit detection purposes -- both movement and knife-stabbing.

function preload() {
    game.load.image('skyBackground', 'assets/sky.png');
    game.load.image('playerSprite', 'assets/player.png');
    game.load.image('wallSprite', 'assets/wall.png');
}

function create() {

    game.physics.startSystem(Phaser.Physics.ARCADE);

	//Adding things to world
	//Stuff is rendered in the order it's added (back to front)
	//Desired order: Background < Wind (to be added later) < Players < Walls

    game.add.sprite(0, 0, 'skyBackground');

	player = game.add.sprite(game.world.width/2, game.world.height/2, 'playerSprite');
	game.physics.enable(player);
	player.body.gravity.y = 0;
	player.body.collideWorldBounds = true;

	otherPlayers = game.add.group();
	otherPlayers.enableBody = true;
	var newPlayer = otherPlayers.create(3*game.world.width/4, game.world.height/3, 'playerSprite');

	walls = game.add.group();
	walls.enableBody = true;

	//Wallsprite is 50px*50px, scale is multiplicative
	var newWall = walls.create(game.world.width/4-25, game.world.height/4-25, 'wallSprite');
	newWall.scale.setTo(2, 1);
	newWall.body.immovable = true;

	newWall = walls.create(2*game.world.width/3, 3*game.world.height/4-75, 'wallSprite');
	newWall.scale.setTo(1, 3);
	newWall.body.immovable = true;

	//Todo in the future: Change arrow keys to WASD
    cursors = game.input.keyboard.createCursorKeys();
	game.input.keyboard.addKeyCapture([Phaser.Keyboard.SPACEBAR]);
}

function update() {
	game.physics.arcade.collide(player, walls);
	game.physics.arcade.overlap(player, walls, destroySecondThing, null, this);
	game.physics.arcade.overlap(yourKnife, walls, destroyFirstThing, null, this);
	game.physics.arcade.overlap(yourKnife, otherPlayers, destroyBothThings, null, this);

	player.body.velocity.x = 0;
	player.body.velocity.y = 0;
	var moveSpeed = 300;

	if(cursors.left.isDown)
	{
		player.body.velocity.x -= moveSpeed;
	}
	if(cursors.right.isDown)
	{
		player.body.velocity.x += moveSpeed;
	}
	if(cursors.up.isDown)
	{
		player.body.velocity.y -= moveSpeed;
	}
	if(cursors.down.isDown)
	{
		player.body.velocity.y += moveSpeed;
	}

	//Enforces one-knife-at-once limit, re-enables throw as soon as existing knife dies. Todo: Add time delay like in unity game
	if(yourKnife == null)
	{
		if(game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR))
		{
			//Todo: Trigger this on mouse click, use position to determine knife velocity
			throwKnife(player.position.x+20, player.position.y+20, 400, 0);
		}
	}
	else
	{
		if(!yourKnife.alive)
		{
			yourKnife = null;
		}
	}
}

function throwKnife(posX, posY, velX, velY)
{
	yourKnife = game.add.sprite(posX, posY, 'wallSprite');
	game.physics.enable(yourKnife);
	yourKnife.body.gravity.y = 0;
	yourKnife.scale.setTo(1/5, 1/5);

	yourKnife.body.velocity.x = velX;
	yourKnife.body.velocity.y = velY;

	//also todo: only let player have one knife at once
}

//These will have to be replaced with more specific functions later, but they work for prototyping.
function destroyFirstThing(firstThing, secondThing){firstThing.destroy(); firstThing = null;}
function destroySecondThing(firstThing, secondThing){secondThing.destroy();}
function destroyBothThings(firstThing, secondThing)
{
	destroyFirstThing(firstThing, secondThing);
	destroySecondThing(firstThing, secondThing);
}<|endoftext|>


<commit_before>var on = require('dom-event');
var off = on.off;
var routes = require('routes');
var EventEmitter = require('events').EventEmitter;
var noop = function() {};

function router(settings) {

	if( !( this instanceof router ) ) {

		return new router(settings);
	}

	var s = this.s = settings || {};

	s.postHash = s.postHash || '!';

	this.lastRoute = null;
	this.childRouter = null;
	this.childFullRoute = null;
	this.childBaseRoute = null;
	this.router = routes();

	EventEmitter.call(this);
}

var p = router.prototype = Object.create(EventEmitter.prototype);

p.init = function() {

	var s = this.s;
	var i;

	// figure out a start section
	if( s[ '/' ] === undefined ) {

		// find the first path which would be a section
		for(i in s) {

			if( i[ 0 ] == '/' ) {

				s.start = i;

				break;
			}
		}
	} else {

		s.start = '/';
	}

	// now setup routes
	for(i in s) {

		if( i[ 0 ] == '/' || i == '404') {

			this.router.addRoute(i, noop);
		}
	}

	this.onURL = this.onURL.bind(this);

	if( global.location ) {
		on(global, 'hashchange', this.onURL);
	}

	this.onURL(); // force a hash change to start things up

	return this;
};

p.sub = function(settings) {

	// remove all veriable parts from lastRoute
	var splitIdx1 = this.lastRoute.indexOf('*');
	var splitIdx2 = this.lastRoute.indexOf(':');
	var splitIdx;

	if(splitIdx1 === -1 && splitIdx2 === -1) {
		throw new Error('when creating a sub router the parent route should have a variable route using either : or *');
	} else {
		splitIdx1 = splitIdx1 !== -1 ? splitIdx1 : this.lastRoute.length;
		splitIdx2 = splitIdx2 !== -1 ? splitIdx2 : this.lastRoute.length;
		splitIdx = splitIdx1 < splitIdx2 ? splitIdx1 : splitIdx2;
	}

	this.childFullRoute = this.lastRoute;
	this.childBaseRoute = this.lastRoute.substring(0, splitIdx - 1);

	settings.postHash = this.s.postHash + this.childBaseRoute;

	this.childRouter = new router(settings);

	this.emit('sub_create', {
		route: this.childFullRoute,
		router: this.childRouter
	});

	return this.childRouter;
};

p.destroySub = function(route) {

	// this.childBaseRoute
	if(this.childRouter && route.indexOf(this.childBaseRoute) !== 0) {
		this.childRouter.destroy();

		this.emit('sub_destroy', {
			route: this.childFullRoute,
			router: this.childRouter
		});

		this.childFullRoute = null;
		this.childBaseRoute = null;
		this.childRouter = null;
	}
};

p.destroy = function() {

	if(global.location) {
		off(global, 'hashchange', this.onURL);
	}
};

p.add = function(route, section) {

	var s = this.s;

	s[ route ] = section;

	return this;
};

p.go = function(routeStr) {

	var routeData;
	var section;
	var newURL;
	var doURLChange;

	if( routeStr.charAt(0) != '/' ) {
		routeStr = '/' + routeStr;
	}

	newURL = this.s.postHash + routeStr;
	routeData = this.getRouteData(routeStr) || this.getRouteData('404');
	section = this.getSection(routeData);
	doURLChange = this.useURL(section);

	// if this is not a section descriptor or it is a descriptor and we should updateURL
	if( global.location && doURLChange ) {
		if(global.location.hash.replace(/^#/, '') != newURL) {
			global.location.hash = newURL;
		} else if(section.duplicate || !section.useURL) {
			// Check if duplicate is set. The check is done here since, onhashchange event triggers
			// only when url changes and therefore cannot check to allow duplicate/repeating route

			// Additionally check if useURL is set to false. If not, the route is not triggered by
			// url changes
			this.doRoute(routeData, section, routeStr);
		}
	} else if( !global.location || !doURLChange ) {
		this.doRoute(routeData, section, routeStr);
	}
};

p.doRoute = function(routeData, section, path) {

	var s = this.s;

	// check if this is a redirect
	if( typeof section == 'string' ) {

		this.go(section);
	} else {

		if(routeData.route !== this.lastResolvedRoute || section.duplicate) {

			this.lastResolvedRoute = routeData.route;

			// otherwise treat it as a regular section
			// if this is a object definition vs a section definition (regular section or array)
			this.emit('route', {
				section: section.section || section,
				route: routeData,
				path: path
			});
		}
	}
};

p.getRouteData = function(routeStr) {

	var routeData = this.router.match(routeStr);

	if(routeData) {
		this.lastRoute = routeData.route;
		this.destroySub(routeData.route);
	}

	return routeData;
};

p.getSection = function(routeData) {

	if(routeData) {
		var hasWildcard = routeData.route.indexOf('*')>-1 || routeData.route.indexOf(':')>-1;
		var sec = this.s[ routeData.route ];
		if (hasWildcard && sec.duplicate===undefined) {
			if (!sec.section) {
				return {section: sec, duplicate: true};
			} else {
				sec.duplicate = true;
				return sec;
			}
		}	else {
			return sec;
		}
	} else {

		return null;
	}
};

p.useURL = function(section) {

	return section &&
		   ( section.section === undefined ||  // if this is not a section descriptor update url
		   ( section.section && section.useURL || section.useURL === undefined ) ); //is descriptor and has useURL or undefined
};

p.onURL = function() {

	var routeStr = '/';
	var routeData;
	var section;

	if( global.location && global.location.hash !== '' ) {

		// if we've already looked at this url then just get out of this function
		if(global.location.hash === this.resolved) {
			return;
		}

		this.resolved = global.location.hash;
		routeStr = global.location.hash.substr(1 + this.s.postHash.length);
	}

	routeData = this.getRouteData(routeStr) || this.getRouteData('404');
	section = this.getSection(routeData);

	// see if we can deep link into this section (either normal or 404 section)
	if( this.useURL(section) ) {
		this.doRoute(routeData, section, routeStr);
	// else check if there's a 404 if so then go there
	} else if( this.s['404'] ){

		routeData = this.getRouteData('404');
		section = this.getSection(routeData);
		this.doRoute(routeData, section, routeStr);
	}
};

module.exports = router;<commit_msg>Updated wildcard check<commit_after>var on = require('dom-event');
var off = on.off;
var routes = require('routes');
var EventEmitter = require('events').EventEmitter;
var noop = function() {};

function router(settings) {

	if( !( this instanceof router ) ) {

		return new router(settings);
	}

	var s = this.s = settings || {};

	s.postHash = s.postHash || '!';

	this.lastRoute = null;
	this.childRouter = null;
	this.childFullRoute = null;
	this.childBaseRoute = null;
	this.router = routes();

	EventEmitter.call(this);
}

var p = router.prototype = Object.create(EventEmitter.prototype);

p.init = function() {

	var s = this.s;
	var i;

	// figure out a start section
	if( s[ '/' ] === undefined ) {

		// find the first path which would be a section
		for(i in s) {

			if( i[ 0 ] == '/' ) {

				s.start = i;

				break;
			}
		}
	} else {

		s.start = '/';
	}

	// now setup routes
	for(i in s) {

		if( i[ 0 ] == '/' || i == '404') {

			this.router.addRoute(i, noop);
		}
	}

	this.onURL = this.onURL.bind(this);

	if( global.location ) {
		on(global, 'hashchange', this.onURL);
	}

	this.onURL(); // force a hash change to start things up

	return this;
};

p.sub = function(settings) {

	// remove all veriable parts from lastRoute
	var splitIdx1 = this.lastRoute.indexOf('*');
	var splitIdx2 = this.lastRoute.indexOf(':');
	var splitIdx;

	if(splitIdx1 === -1 && splitIdx2 === -1) {
		throw new Error('when creating a sub router the parent route should have a variable route using either : or *');
	} else {
		splitIdx1 = splitIdx1 !== -1 ? splitIdx1 : this.lastRoute.length;
		splitIdx2 = splitIdx2 !== -1 ? splitIdx2 : this.lastRoute.length;
		splitIdx = splitIdx1 < splitIdx2 ? splitIdx1 : splitIdx2;
	}

	this.childFullRoute = this.lastRoute;
	this.childBaseRoute = this.lastRoute.substring(0, splitIdx - 1);

	settings.postHash = this.s.postHash + this.childBaseRoute;

	this.childRouter = new router(settings);

	this.emit('sub_create', {
		route: this.childFullRoute,
		router: this.childRouter
	});

	return this.childRouter;
};

p.destroySub = function(route) {

	// this.childBaseRoute
	if(this.childRouter && route.indexOf(this.childBaseRoute) !== 0) {
		this.childRouter.destroy();

		this.emit('sub_destroy', {
			route: this.childFullRoute,
			router: this.childRouter
		});

		this.childFullRoute = null;
		this.childBaseRoute = null;
		this.childRouter = null;
	}
};

p.destroy = function() {

	if(global.location) {
		off(global, 'hashchange', this.onURL);
	}
};

p.add = function(route, section) {

	var s = this.s;

	s[ route ] = section;

	return this;
};

p.go = function(routeStr) {

	var routeData;
	var section;
	var newURL;
	var doURLChange;

	if( routeStr.charAt(0) != '/' ) {
		routeStr = '/' + routeStr;
	}

	newURL = this.s.postHash + routeStr;
	routeData = this.getRouteData(routeStr) || this.getRouteData('404');
	section = this.getSection(routeData);
	doURLChange = this.useURL(section);

	// if this is not a section descriptor or it is a descriptor and we should updateURL
	if( global.location && doURLChange ) {
		if(global.location.hash.replace(/^#/, '') != newURL) {
			global.location.hash = newURL;
		} else if(section.duplicate || !section.useURL) {
			// Check if duplicate is set. The check is done here since, onhashchange event triggers
			// only when url changes and therefore cannot check to allow duplicate/repeating route

			// Additionally check if useURL is set to false. If not, the route is not triggered by
			// url changes
			this.doRoute(routeData, section, routeStr);
		}
	} else if( !global.location || !doURLChange ) {
		this.doRoute(routeData, section, routeStr);
	}
};

p.doRoute = function(routeData, section, path) {

	var s = this.s;

	// check if this is a redirect
	if( typeof section == 'string' ) {

		this.go(section);
	} else {

		if(routeData.route !== this.lastResolvedRoute || section.duplicate) {

			this.lastResolvedRoute = routeData.route;

			// otherwise treat it as a regular section
			// if this is a object definition vs a section definition (regular section or array)
			this.emit('route', {
				section: section.section || section,
				route: routeData,
				path: path
			});
		}
	}
};

p.getRouteData = function(routeStr) {

	var routeData = this.router.match(routeStr);

	if(routeData) {
		this.lastRoute = routeData.route;
		this.destroySub(routeData.route);
	}

	return routeData;
};

p.getSection = function(routeData) {

	if(routeData) {
		var hasWildcard = routeData.route && (routeData.route.match(/.*[\[\]@!$&:'()*+,;=].*/g) || routeData.route instanceof RegExp);
		var sec = this.s[ routeData.route ];
		if (hasWildcard && sec.duplicate===undefined) {
			if (!sec.section) {
				return {section: sec, duplicate: true};
			} else {
				sec.duplicate = true;
				return sec;
			}
		}	else {
			return sec;
		}
	} else {

		return null;
	}
};

p.useURL = function(section) {

	return section &&
		   ( section.section === undefined ||  // if this is not a section descriptor update url
		   ( section.section && section.useURL || section.useURL === undefined ) ); //is descriptor and has useURL or undefined
};

p.onURL = function() {

	var routeStr = '/';
	var routeData;
	var section;

	if( global.location && global.location.hash !== '' ) {

		// if we've already looked at this url then just get out of this function
		if(global.location.hash === this.resolved) {
			return;
		}

		this.resolved = global.location.hash;
		routeStr = global.location.hash.substr(1 + this.s.postHash.length);
	}

	routeData = this.getRouteData(routeStr) || this.getRouteData('404');
	section = this.getSection(routeData);

	// see if we can deep link into this section (either normal or 404 section)
	if( this.useURL(section) ) {
		this.doRoute(routeData, section, routeStr);
	// else check if there's a 404 if so then go there
	} else if( this.s['404'] ){

		routeData = this.getRouteData('404');
		section = this.getSection(routeData);
		this.doRoute(routeData, section, routeStr);
	}
};

module.exports = router;<|endoftext|>