<commit_before>/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

var CONST = require('../const');

/**
 * The pool into which the canvas elements are placed.
 *
 * @property pool
 * @type Array
 */
var pool = [];

//  This singleton is instantiated as soon as Phaser loads,
//  before a Phaser.Game instance has even been created.
//  Which means all instances of Phaser Games on the same page
//  can share the one single pool

/**
* The CanvasPool is a global static object, that allows Phaser to recycle and pool Canvas DOM elements.
*
* @class Phaser.CanvasPool
* @static
*/
var CanvasPool = function ()
{
    /**
    * Creates a new Canvas DOM element, or pulls one from the pool if free.
    *
    * @method Phaser.CanvasPool.create
    * @static
    * @param {any} parent - The parent of the canvas element.
    * @param {number} width - The width of the canvas element.
    * @param {number} height - The height of the canvas element.
    * @return {HTMLCanvasElement} The canvas element.
    */
    var create = function (parent, width, height, type)
    {
        if (width === undefined) { width = 1; }
        if (height === undefined) { height = 1; }
        if (type === undefined) { type = CONST.CANVAS; }

        var canvas;
        var container = first(type);

        if (container === null)
        {
            // console.log('CanvasPool.create new');

            container = {
                parent: parent,
                canvas: document.createElement('canvas'),
                type: type
            };

            pool.push(container);

            canvas = container.canvas;
        }
        else
        {
            // console.log('CanvasPool.create existing');

            container.parent = parent;

            canvas = container.canvas;
        }

        canvas.width = width;
        canvas.height = height;

        return canvas;
    };

    var create2D = function (parent, width, height)
    {
        return create(parent, width, height, CONST.CANVAS);
    };

    var createWebGL = function (parent, width, height)
    {
        return create(parent, width, height, CONST.WEBGL);
    };

    /**
    * Gets the first free canvas index from the pool.
    *
    * @static
    * @method Phaser.CanvasPool.getFirst
    * @return {number}
    */
    var first = function (type)
    {
        if (type === undefined) { type = CONST.CANVAS; }

        pool.forEach(function (container)
        {
            if (!container.parent && container.type === type)
            {
                return container;
            }
        });

        return null;
    };

    /**
    * Looks up a canvas based on its parent, and if found puts it back in the pool, freeing it up for re-use.
    * The canvas has its width and height set to 1, and its parent attribute nulled.
    *
    * @static
    * @method Phaser.CanvasPool.remove
    * @param {any|HTMLCanvasElement} parent - The parent of the canvas element.
    */
    var remove = function (parent)
    {
        //  Check to see if the parent is a canvas object
        var isCanvas = parent instanceof HTMLCanvasElement;

        pool.forEach(function (container)
        {
            if ((isCanvas && container.canvas === parent) || (!isCanvas && container.parent === parent))
            {
                // console.log('CanvasPool.remove found and removed');
                container.parent = null;
                container.canvas.width = 1;
                container.canvas.height = 1;
            }
        });
    };

    /**
    * Gets the total number of used canvas elements in the pool.
    *
    * @static
    * @method Phaser.CanvasPool.getTotal
    * @return {number} The number of in-use (parented) canvas elements in the pool.
    */
    var total = function ()
    {
        var c = 0;

        pool.forEach(function (container)
        {
            if (container.parent)
            {
                c++;
            }
        });

        return c;
    };

    /**
    * Gets the total number of free canvas elements in the pool.
    *
    * @static
    * @method Phaser.CanvasPool.getFree
    * @return {number} The number of free (un-parented) canvas elements in the pool.
    */
    var free = function ()
    {
        return pool.length - total();
    };

    return {
        create: create,
        create2D: create2D,
        createWebGL: createWebGL,
        first: first,
        remove: remove,
        total: total,
        free: free,
        pool: pool
    };
};

//  If we export the called function here, it'll only be invoked once (not every time it's required).
module.exports = CanvasPool();
<commit_msg>ESLint fix.<commit_after>/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

var CONST = require('../const');

/**
 * The pool into which the canvas elements are placed.
 *
 * @property pool
 * @type Array
 */
var pool = [];

//  This singleton is instantiated as soon as Phaser loads,
//  before a Phaser.Game instance has even been created.
//  Which means all instances of Phaser Games on the same page
//  can share the one single pool

/**
* The CanvasPool is a global static object, that allows Phaser to recycle and pool Canvas DOM elements.
*
* @class Phaser.CanvasPool
* @static
*/
var CanvasPool = function ()
{
    /**
    * Creates a new Canvas DOM element, or pulls one from the pool if free.
    *
    * @method Phaser.CanvasPool.create
    * @static
    * @param {any} parent - The parent of the canvas element.
    * @param {number} width - The width of the canvas element.
    * @param {number} height - The height of the canvas element.
    * @return {HTMLCanvasElement} The canvas element.
    */
    var create = function (parent, width, height, type)
    {
        if (width === undefined) { width = 1; }
        if (height === undefined) { height = 1; }
        if (type === undefined) { type = CONST.CANVAS; }

        var canvas;
        var container = first(type);

        if (container === null)
        {
            // console.log('CanvasPool.create new');

            container = {
                parent: parent,
                canvas: document.createElement('canvas'),
                type: type
            };

            pool.push(container);

            canvas = container.canvas;
        }
        else
        {
            // console.log('CanvasPool.create existing');

            container.parent = parent;

            canvas = container.canvas;
        }

        canvas.width = width;
        canvas.height = height;

        return canvas;
    };

    var create2D = function (parent, width, height)
    {
        return create(parent, width, height, CONST.CANVAS);
    };

    var createWebGL = function (parent, width, height)
    {
        return create(parent, width, height, CONST.WEBGL);
    };

    /**
    * Gets the first free canvas index from the pool.
    *
    * @static
    * @method Phaser.CanvasPool.getFirst
    * @return {number}
    */
    var first = function (type)
    {
        if (type === undefined) { type = CONST.CANVAS; }

        pool.forEach(function (container)
        {
            if (!container.parent && container.type === type)
            {
                return container;
            }
        });

        return null;
    };

    /**
    * Looks up a canvas based on its parent, and if found puts it back in the pool, freeing it up for re-use.
    * The canvas has its width and height set to 1, and its parent attribute nulled.
    *
    * @static
    * @method Phaser.CanvasPool.remove
    * @param {any|HTMLCanvasElement} parent - The parent of the canvas element.
    */
    var remove = function (parent)
    {
        //  Check to see if the parent is a canvas object
        var isCanvas = parent instanceof HTMLCanvasElement;

        pool.forEach(function (container)
        {
            if ((isCanvas && container.canvas === parent) || (!isCanvas && container.parent === parent))
            {
                // console.log('CanvasPool.remove found and removed');
                container.parent = null;
                container.canvas.width = 1;
                container.canvas.height = 1;
            }
        });
    };

    /**
    * Gets the total number of used canvas elements in the pool.
    *
    * @static
    * @method Phaser.CanvasPool.getTotal
    * @return {number} The number of in-use (parented) canvas elements in the pool.
    */
    var total = function ()
    {
        var c = 0;

        pool.forEach(function (container)
        {
            if (container.parent)
            {
                c++;
            }
        });

        return c;
    };

    /**
    * Gets the total number of free canvas elements in the pool.
    *
    * @static
    * @method Phaser.CanvasPool.getFree
    * @return {number} The number of free (un-parented) canvas elements in the pool.
    */
    var free = function ()
    {
        return pool.length - total();
    };

    return {
        create: create,
        create2D: create2D,
        createWebGL: createWebGL,
        first: first,
        remove: remove,
        total: total,
        free: free,
        pool: pool
    };
};

//  If we export the called function here, it'll only be invoked once (not every time it's required).
module.exports = CanvasPool();
<|endoftext|>


<commit_before>var Class = require('../../utils/Class');
var Matrix4 = require('../../math/Matrix4');
var Vector2 = require('../../math/Vector2');
var Vector3 = require('../../math/Vector3');

var Mesh = new Class({

    initialize:

    function Mesh (data, x, y, z)
    {
        //  May contain multiple models
        this.data = data;
        this.vertices = data.vertices;

        this.position = new Vector3(x, y, z);
        this.rotation = new Vector3();
        this.scale = new Vector3(1, 1, 1);

        this.visible = true;

        this.thickness = 1;
        this.strokeColor = 0x00ff00;
        this.strokeAlpha = 1;

        this.fillColor = 0x00ff00;
        this.fillAlpha = 1;

        this.points = [];

        this._tempVec3 = new Vector3();

        this.worldMatrix = new Matrix4();

        this.createPoints();
    },

    createPoints: function ()
    {
        var points = this.points;

        for (var i = 0; i < this.data.maxVertices; i++)
        {
            points.push(new Vector2());
        }
    },

    fill: function (graphics)
    {
        if (!this.visible || this.alpha === 0)
        {
            return;
        }

        this.worldMatrix.setWorldMatrix(this.rotation, this.position, this.scale, graphics.viewMatrix, graphics.projectionMatrix);

        graphics.fillStyle(this.fillColor, this.fillAlpha);

        for (var m = 0; m < this.data.models.length; m++)
        {
            var model = this.data.models[m];

            for (var f = 0; f < model.faces.length; f++)
            {
                var face = model.faces[f];

                if (face.type === 0)
                {
                    this.fillTriangle(graphics, face);
                }
                else
                {
                    this.fillPoly(graphics, face);
                }
            }
        }

    },

    fillTriangle: function (graphics, face)
    {
        var a = this.points[0];
        var b = this.points[1];
        var c = this.points[2];

        var verts = this.vertices;
        var world = this.worldMatrix;

        this.project(graphics, a, verts[face.vertices[0].vertexIndex], world);
        this.project(graphics, b, verts[face.vertices[1].vertexIndex], world);
        this.project(graphics, c, verts[face.vertices[2].vertexIndex], world);

        graphics.fillTriangle(a.x, a.y, b.x, b.y, c.x, c.y);
    },

    fillPoly: function (graphics, face)
    {
        var points = this.points;
        var verts = this.vertices;
        var world = this.worldMatrix;

        var size = face.vertices.length;

        //  Project
        for (var i = 0; i < size; i++)
        {
            this.project(graphics, points[i], verts[face.vertices[i].vertexIndex], world);
        }

        graphics.fillPoints(points, true, size);
    },

    stroke: function (graphics)
    {
        if (!this.visible || this.alpha === 0)
        {
            return;
        }

        this.worldMatrix.setWorldMatrix(this.rotation, this.position, this.scale, graphics.viewMatrix, graphics.projectionMatrix);

        graphics.lineStyle(this.thickness, this.strokeColor, this.strokeAlpha);

        for (var m = 0; m < this.data.models.length; m++)
        {
            var model = this.data.models[m];

            for (var f = 0; f < model.faces.length; f++)
            {
                var face = model.faces[f];

                if (face.type === 0)
                {
                    this.strokeTriangle(graphics, face);
                }
                else
                {
                    this.strokePoly(graphics, face);
                }
            }
        }
    },

    strokeTriangle: function (graphics, face)
    {
        var a = this.points[0];
        var b = this.points[1];
        var c = this.points[2];

        var verts = this.vertices;
        var world = this.worldMatrix;

        this.project(graphics, a, verts[face.vertices[0].vertexIndex], world);
        this.project(graphics, b, verts[face.vertices[1].vertexIndex], world);
        this.project(graphics, c, verts[face.vertices[2].vertexIndex], world);

        graphics.strokeTriangle(a.x, a.y, b.x, b.y, c.x, c.y);
    },

    strokePoly: function (graphics, face)
    {
        var points = this.points;
        var verts = this.vertices;
        var world = this.worldMatrix;

        var size = face.vertices.length;

        //  Project
        for (var i = 0; i < size; i++)
        {
            this.project(graphics, points[i], verts[face.vertices[i].vertexIndex], world);
        }

        graphics.strokePoints(points, true, size);
    },

    //  local is a Vec2 that is changed in place (so not returned)
    project: function (graphics, local, coord, transMat)
    {
        var w = graphics.viewportWidth;
        var h = graphics.viewportHeight;

        var point = this._tempVec3;

        point.copy(coord);

        point.transformCoordinates(transMat);

        local.x = point.x * w + w / 2 >> 0;
        local.y = -point.y * h + h / 2 >> 0;
    },

    setPosition: function (x, y, z)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = x; }
        if (z === undefined) { z = x; }

        this.position.x = x;
        this.position.y = y;
        this.position.z = z;

        return this;
    },

    setRotation: function (x, y, z)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = x; }
        if (z === undefined) { z = x; }

        this.rotation.x = x;
        this.rotation.y = y;
        this.rotation.z = z;

        return this;
    },

    setScale: function (x, y, z)
    {
        if (x === undefined) { x = 1; }
        if (y === undefined) { y = x; }
        if (z === undefined) { z = x; }

        this.scale.x = x;
        this.scale.y = y;
        this.scale.z = z;

        return this;
    },

    setStrokeColor: function (color)
    {
        this.strokeColor = color;

        return this;
    },

    setStrokeAlpha: function (alpha)
    {
        this.strokeAlpha = alpha;

        return this;
    },

    setFillColor: function (color)
    {
        this.fillColor = color;

        return this;
    },

    setFillAlpha: function (alpha)
    {
        this.fillAlpha = alpha;

        return this;
    },

    lineStyle: function (lineWidth, color, alpha)
    {
        this.thickness = lineWidth;
        this.strokeColor = color;
        this.strokeAlpha = alpha;

        return this;
    },

    fillStyle: function (color, alpha)
    {
        this.fillColor = color;
        this.fillAlpha = alpha;

        return this;
    },

    setVisible: function (value)
    {
        this.visible = value;

        return this;
    },

    x: {

        get: function ()
        {
            return this.position.x;
        },

        set: function (value)
        {
            this.position.x = value;
        }

    },

    y: {

        get: function ()
        {
            return this.position.y;
        },

        set: function (value)
        {
            this.position.y = value;
        }

    },

    z: {

        get: function ()
        {
            return this.position.z;
        },

        set: function (value)
        {
            this.position.z = value;
        }

    }

});

module.exports = Mesh;
<commit_msg>Backface culling support added to tris<commit_after>var Class = require('../../utils/Class');
var Matrix4 = require('../../math/Matrix4');
var Vector2 = require('../../math/Vector2');
var Vector3 = require('../../math/Vector3');

var Mesh = new Class({

    initialize:

    function Mesh (data, x, y, z)
    {
        //  May contain multiple models
        this.data = data;
        this.vertices = data.vertices;

        this.position = new Vector3(x, y, z);
        this.rotation = new Vector3();
        this.scale = new Vector3(1, 1, 1);

        this.visible = true;

        this.thickness = 1;
        this.strokeColor = 0x00ff00;
        this.strokeAlpha = 1;

        this.fillColor = 0x00ff00;
        this.fillAlpha = 1;

        this.backfaceCull = true;

        this.points = [];

        this._tempVec3 = new Vector3();

        this.worldMatrix = new Matrix4();

        this.createPoints();
    },

    createPoints: function ()
    {
        var points = this.points;

        for (var i = 0; i < this.data.maxVertices; i++)
        {
            points.push(new Vector2());
        }
    },

    fill: function (graphics)
    {
        if (!this.visible || this.alpha === 0)
        {
            return;
        }

        this.worldMatrix.setWorldMatrix(this.rotation, this.position, this.scale, graphics.viewMatrix, graphics.projectionMatrix);

        graphics.fillStyle(this.fillColor, this.fillAlpha);

        for (var m = 0; m < this.data.models.length; m++)
        {
            var model = this.data.models[m];

            for (var f = 0; f < model.faces.length; f++)
            {
                var face = model.faces[f];

                if (face.type === 0)
                {
                    this.fillTriangle(graphics, face);
                }
                else
                {
                    this.fillPoly(graphics, face);
                }
            }
        }

    },

    fillTriangle: function (graphics, face)
    {
        var a = this.points[0];
        var b = this.points[1];
        var c = this.points[2];

        var verts = this.vertices;
        var world = this.worldMatrix;

        this.project(graphics, a, verts[face.vertices[0].vertexIndex], world);
        this.project(graphics, b, verts[face.vertices[1].vertexIndex], world);
        this.project(graphics, c, verts[face.vertices[2].vertexIndex], world);

        if (this.backfaceCull && !this.isBackFacing(a, b, c))
        {
            graphics.fillTriangle(a.x, a.y, b.x, b.y, c.x, c.y);
        }
    },

    fillPoly: function (graphics, face)
    {
        var points = this.points;
        var verts = this.vertices;
        var world = this.worldMatrix;

        var size = face.vertices.length;

        //  Project
        for (var i = 0; i < size; i++)
        {
            this.project(graphics, points[i], verts[face.vertices[i].vertexIndex], world);
        }

        graphics.fillPoints(points, true, size);
    },

    stroke: function (graphics)
    {
        if (!this.visible || this.alpha === 0)
        {
            return;
        }

        this.worldMatrix.setWorldMatrix(this.rotation, this.position, this.scale, graphics.viewMatrix, graphics.projectionMatrix);

        graphics.lineStyle(this.thickness, this.strokeColor, this.strokeAlpha);

        for (var m = 0; m < this.data.models.length; m++)
        {
            var model = this.data.models[m];

            for (var f = 0; f < model.faces.length; f++)
            {
                var face = model.faces[f];

                if (face.type === 0)
                {
                    this.strokeTriangle(graphics, face);
                }
                else
                {
                    this.strokePoly(graphics, face);
                }
            }
        }
    },

    strokeTriangle: function (graphics, face)
    {
        var a = this.points[0];
        var b = this.points[1];
        var c = this.points[2];

        var verts = this.vertices;
        var world = this.worldMatrix;

        this.project(graphics, a, verts[face.vertices[0].vertexIndex], world);
        this.project(graphics, b, verts[face.vertices[1].vertexIndex], world);
        this.project(graphics, c, verts[face.vertices[2].vertexIndex], world);

        if (this.backfaceCull && !this.isBackFacing(a, b, c))
        {
            graphics.strokeTriangle(a.x, a.y, b.x, b.y, c.x, c.y);
        }
    },

    strokePoly: function (graphics, face)
    {
        var points = this.points;
        var verts = this.vertices;
        var world = this.worldMatrix;

        var size = face.vertices.length;

        //  Project
        for (var i = 0; i < size; i++)
        {
            this.project(graphics, points[i], verts[face.vertices[i].vertexIndex], world);
        }

        graphics.strokePoints(points, true, size);
    },

    //  local is a Vec2 that is changed in place (so not returned)
    project: function (graphics, local, coord, transMat)
    {
        var w = graphics.viewportWidth;
        var h = graphics.viewportHeight;

        var point = this._tempVec3;

        point.copy(coord);

        point.transformCoordinates(transMat);

        local.x = point.x * w + w / 2 >> 0;
        local.y = -point.y * h + h / 2 >> 0;
    },

    isBackFacing: function (a, b, c)
    {
        var ax = c.x - a.x;
        var ay = c.y - a.y;

        var bx = b.x - c.x;
        var by = b.y - c.y;

        var result = ax * by - ay * bx;

        return (result >= 0);
    },

    setPosition: function (x, y, z)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = x; }
        if (z === undefined) { z = x; }

        this.position.x = x;
        this.position.y = y;
        this.position.z = z;

        return this;
    },

    setRotation: function (x, y, z)
    {
        if (x === undefined) { x = 0; }
        if (y === undefined) { y = x; }
        if (z === undefined) { z = x; }

        this.rotation.x = x;
        this.rotation.y = y;
        this.rotation.z = z;

        return this;
    },

    setScale: function (x, y, z)
    {
        if (x === undefined) { x = 1; }
        if (y === undefined) { y = x; }
        if (z === undefined) { z = x; }

        this.scale.x = x;
        this.scale.y = y;
        this.scale.z = z;

        return this;
    },

    setStrokeColor: function (color)
    {
        this.strokeColor = color;

        return this;
    },

    setStrokeAlpha: function (alpha)
    {
        this.strokeAlpha = alpha;

        return this;
    },

    setFillColor: function (color)
    {
        this.fillColor = color;

        return this;
    },

    setFillAlpha: function (alpha)
    {
        this.fillAlpha = alpha;

        return this;
    },

    lineStyle: function (lineWidth, color, alpha)
    {
        this.thickness = lineWidth;
        this.strokeColor = color;
        this.strokeAlpha = alpha;

        return this;
    },

    fillStyle: function (color, alpha)
    {
        this.fillColor = color;
        this.fillAlpha = alpha;

        return this;
    },

    setVisible: function (value)
    {
        this.visible = value;

        return this;
    },

    x: {

        get: function ()
        {
            return this.position.x;
        },

        set: function (value)
        {
            this.position.x = value;
        }

    },

    y: {

        get: function ()
        {
            return this.position.y;
        },

        set: function (value)
        {
            this.position.y = value;
        }

    },

    z: {

        get: function ()
        {
            return this.position.z;
        },

        set: function (value)
        {
            this.position.z = value;
        }

    }

});

module.exports = Mesh;
<|endoftext|>


<commit_before>$.jCanvas.defaults.fromCenter = false;
var $comicCanvas = $('#comic-canvas'); // <canvas id="comic-canvas" height="590" width="767">
var $savedComicCanvas = $('#saved-comic-canvas'); //<canvas id="saved-comic-canvas" width="767" height="129">
var hasBackground = false;
// var selectedIndex;

// EVENT HANDLERS
$(document).on('dragstart', function(e) {
	var target = e.target;
	if (target.className != 'draggable') {return};
	e.dataTransfer = e.originalEvent.dataTransfer;
	e.dataTransfer.setData('text/plain', target.src);
	if (target.src.includes("backgrounds")) {return};
	var img = new Image();
	img.src = target.src;
	e.dataTransfer.setDragImage(img, img.width/2, img.height/2);
});

$comicCanvas.on('dragover', function(e) {
	e.preventDefault();
	e.dataTransfer = e.originalEvent.dataTransfer;
	e.dataTransfer.dropEffect = 'move';
});

$comicCanvas.on('drop', function(e) {
	e.preventDefault();
	e.dataTransfer = e.originalEvent.dataTransfer;
	var src = e.dataTransfer.getData('text');

	// Find image size
	var img = new Image();
	img.src = src;

	// Use image size to draw on canvas right where you drop it.
	var x = e.pageX - $comicCanvas.offset().left - img.width/2;
	var y = e.pageY - $comicCanvas.offset().top - img.height/2;
	addLayer(src, x, y);
});

$('#images').on('click', 'img', function() {
	if(hasBackground){
		var x = ($comicCanvas.getLayers().length - 1) * 100;
	}else{
		var x = $comicCanvas.getLayers().length * 100; //TODO Change this line to bound the x, y and keep the image on screen by default
	}
	addLayer(this.src, x, 0);
});

// $comicCanvas.on('click', function(e) {
// 	deSelectLayers();
// });

$('#delete-button').on('click', function(e) {
	deleteSelectedLayer();
});

// HELPER FUNCTIONS

function addLayer(src, x, y) {
	var index, isBackground;
	console.log(src.includes('backgrounds'));
	if (src.includes('backgrounds')) {
		isBackground = true;
		// Backgrounds are centered in canvas...
		x = 0;
		y = 0;
		// And replace the previous background if already drawn
		if (hasBackground) {
			$comicCanvas.removeLayer(0);
			index = 0;
		}
		hasBackground = true;
	} else {
		isBackground = false;
		index = 1 + $comicCanvas.getLayers().length;
	};

	$comicCanvas.addLayer({
		type: 'image',
		source: src,
		x: x, y: y,
		draggable: false,
		index: index,
		// sel: true,
		isBackground: isBackground,
		// When selected, change to .6 opaque
		click: function(layer){
			// Deselect when background image is clicked
			if(isBackground){
				deSelectLayers();
			// Otherwise, select clicked layer
			}else{
				selectLayer(layer);
			}
		}
	});

	// TODO: Refactor to prevent issues with unwanted selection -- see 'Issues' in Git Hub Repo.
	// Get layer we just added and select it
	var length = $comicCanvas.getLayers().length;
	var layer = $comicCanvas.getLayers()[length - 1];
	selectLayer(layer);

	$comicCanvas.drawLayers();
};

function selectLayer(layer) {
	// Backgrounds aren't selectable
	if (layer.isBackground) {return};
	// deSelectLayers();
	// layer.sel = true; // No longer needed. After testing, safe to remove.
	layer.opacity = 0.6;
	// selectedIndex = layer.index; // No longer needed. After testing, remove this line.
	$comicCanvas.setLayer(layer, { draggable: true })
	// Uses built in JCanvas functionality to track the selected images
	.addLayerToGroup(layer, 'selected')
	// JCanvas alows chaining for funcitons with the same canvas root (same as $comicCanvas.drawLayers() when used after above lines)
	.drawLayers();
	// console.log($comicCanvas.getLayerGroup('selected'));
}

function deSelectLayers() {
	var layers = $comicCanvas.getLayers();
	$comicCanvas.setLayerGroup('selected', {
		opacity: 1,
		draggable: false
	})
	for (var i=0; i < layers.length; i++) {
		var layer = layers[i];
		// layer.sel = false;
		// layer.draggable = false;
		// layer.opacity = 1;
		// selectedIndex = null;
		$comicCanvas.removeLayerFromGroup(layer, 'selected')
		.drawLayers();
	}
}

function deleteSelectedLayer() {
	//Removes all layers from the 'selected' group and redraws layers
	$comicCanvas.removeLayerGroup('selected')
	.drawLayers();
}

<commit_msg>Comment code. Refactor excess drawLayers()<commit_after>$.jCanvas.defaults.fromCenter = false; // Sets default draw start point to be from upper left corner
var $comicCanvas = $('#comic-canvas'); // <canvas id="comic-canvas" height="590" width="767">
var $savedComicCanvas = $('#saved-comic-canvas'); //<canvas id="saved-comic-canvas" width="767" height="129">
var hasBackground = false;

// EVENT HANDLERS
$(document).on('dragstart', function(e) {
	var target = e.target;
	if (target.className != 'draggable') {return};
	e.dataTransfer = e.originalEvent.dataTransfer;
	e.dataTransfer.setData('text/plain', target.src);
	if (target.src.includes("backgrounds")) {return};
	var img = new Image();
	img.src = target.src;
	e.dataTransfer.setDragImage(img, img.width/2, img.height/2);
});

$comicCanvas.on('dragover', function(e) {
	e.preventDefault();
	e.dataTransfer = e.originalEvent.dataTransfer;
	e.dataTransfer.dropEffect = 'move';
});

$comicCanvas.on('drop', function(e) {
	e.preventDefault();
	e.dataTransfer = e.originalEvent.dataTransfer;
	var src = e.dataTransfer.getData('text');

	// Find image size
	var img = new Image();
	img.src = src;

	// Use image size to draw on canvas right where you drop it.
	var x = e.pageX - $comicCanvas.offset().left - img.width/2;
	var y = e.pageY - $comicCanvas.offset().top - img.height/2;
	addLayer(src, x, y);
});

$('#images').on('click', 'img', function() {
	if(hasBackground){
		var x = ($comicCanvas.getLayers().length - 1) * 100;
	}else{
		//TODO: Change this line to bound the x, y and keep the image on screen by default
		var x = $comicCanvas.getLayers().length * 100;
	}
	addLayer(this.src, x, 0);
});

// Discuss the necessity of this event before removing.
// $comicCanvas.on('click', function(e) {
// 	deSelectLayers();
// });

$('#delete-button').on('click', function(e) {
	deleteSelectedLayer();
});

// HELPER FUNCTIONS

function addLayer(src, x, y) {
	var index, isBackground;
	console.log(src.includes('backgrounds'));
	if (src.includes('backgrounds')) {
		isBackground = true;
		// Backgrounds are centered in canvas...
		x = 0;
		y = 0;
		// And replace the previous background if already drawn
		if (hasBackground) {
			$comicCanvas.removeLayer(0);
			index = 0;
		}
		hasBackground = true;
	} else {
		isBackground = false;
		index = 1 + $comicCanvas.getLayers().length;
	};

	$comicCanvas.addLayer({
		type: 'image',
		source: src,
		x: x, y: y,
		draggable: false,
		index: index,
		// sel: true,
		isBackground: isBackground,
		// When selected, change to .6 opaque
		click: function(layer){
			// Deselect when background image is clicked
			if(isBackground){
				deSelectLayers();
			// Otherwise, select clicked layer
			}else{
				selectLayer(layer);
			}
		}
	});

	// TODO: Refactor to prevent issues with unwanted selection -- see 'Issues' in Git Hub Repo.
	// Get layer we just added and select it
	var length = $comicCanvas.getLayers().length;
	var layer = $comicCanvas.getLayers()[length - 1];
	selectLayer(layer);

	$comicCanvas.drawLayers();
};

function selectLayer(layer) {
	// Backgrounds aren't selectable by default
	if (layer.isBackground) {return};
	layer.opacity = 0.6;
	$comicCanvas.setLayer(layer, { draggable: true })
	// Uses built in JCanvas functionality to track the selected images
	.addLayerToGroup(layer, 'selected');
}

function deSelectLayers() {
	//Creates and array of all layers on the canvas
	var layers = $comicCanvas.getLayers();
	//Sets all the layer group to opacity 1 and draggable false
	$comicCanvas.setLayerGroup('selected', {
		opacity: 1,
		draggable: false
	})
	//Remove all layers in the 'selected' group and redraw
	for (var i=0; i < layers.length; i++) {
		var layer = layers[i];
		$comicCanvas.removeLayerFromGroup(layer, 'selected');
	}
}

function deleteSelectedLayer() {
	//Removes all layers from canvas in the 'selected' group and redraws layers
	$comicCanvas.removeLayerGroup('selected')
	.drawLayers();
}<|endoftext|>


<commit_before>/*
 * (c) Copyright Ascensio System SIA 2010-2019
 *
 * This program is a free software product. You can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License (AGPL)
 * version 3 as published by the Free Software Foundation. In accordance with
 * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
 * that Ascensio System SIA expressly excludes the warranty of non-infringement
 * of any third-party rights.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
 * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
 *
 * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
 * street, Riga, Latvia, EU, LV-1050.
 *
 * The  interactive user interfaces in modified source and object code versions
 * of the Program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU AGPL version 3.
 *
 * Pursuant to Section 7(b) of the License you must retain the original Product
 * logo when distributing the program. Pursuant to Section 7(e) we decline to
 * grant you any rights under trademark law for use of our trademarks.
 *
 * All the Product's GUI elements, including illustrations and icon sets, as
 * well as technical writing content are licensed under the terms of the
 * Creative Commons Attribution-ShareAlike 4.0 International. See the License
 * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
 *
 */

var editor = undefined;
var window = {};
var navigator = {};
navigator.userAgent = "chrome";
window.navigator = navigator;
window.location = {};

window.location.protocol = "";
window.location.host = "";
window.location.href = "";
window.location.pathname = "";

window.XMLHttpRequest = function () {};

window.NATIVE_EDITOR_ENJINE = true;
window.NATIVE_EDITOR_ENJINE_SYNC_RECALC = true;

var document = {};
window.document = document;

window["Asc"] = {};
var Asc = window["Asc"];

window["AscFonts"] = {};
var AscFonts = window["AscFonts"];

window["AscCommon"] = {};
var AscCommon = window["AscCommon"];

window["AscFormat"] = {};
var AscFormat = window["AscFormat"];

window["AscDFH"] = {};
var AscDFH = window["AscDFH"];

window["AscCH"] = {};
var AscCH = window["AscCH"];

window["AscCommonExcel"] = {};
var AscCommonExcel = window["AscCommonExcel"];

window["AscCommonWord"] = {};
var AscCommonWord = window["AscCommonWord"];

window["AscCommonSlide"] = {};
var AscCommonSlide = window["AscCommonSlide"];

function Image()
{
	this.src = "";
	this.onload = function () {};
	this.onerror = function () {};
}

function _image_data()
{
	this.data = null;
	this.length = 0;
}

function native_pattern_fill()
{
}
native_pattern_fill.prototype =
{
	setTransform: function (transform) {}
};

function native_gradient_fill() {}
native_gradient_fill.prototype =
{
	addColorStop: function (offset, color) {}
};

function native_context2d(parent)
{
	this.canvas = parent;

	this.globalAlpha = 0;
	this.globalCompositeOperation = "";
	this.fillStyle = "#000000";
	this.strokeStyle = "#000000";

	this.lineWidth = 0;
	this.lineCap = 0;
	this.lineJoin = 0;
	this.miterLimit = 0;
	this.shadowOffsetX = 0;
	this.shadowOffsetY = 0;
	this.shadowBlur = 0;
	this.shadowColor = 0;
	this.font = "";
	this.textAlign = 0;
	this.textBaseline = 0;
}
native_context2d.prototype =
{
	save: function () {},
	restore: function () {},

	scale: function (x, y) {},
	rotate: function (angle) {},
	translate: function (x, y) {},
	transform: function (m11, m12, m21, m22, dx, dy) {},
	setTransform: function (m11, m12, m21, m22, dx, dy) {},

	createLinearGradient: function (x0, y0, x1, y1) {},
	createRadialGradient: function (x0, y0, r0, x1, y1, r1) {},
	createPattern: function (image, repetition) {},

	clearRect: function (x, y, w, h) {},
	fillRect: function (x, y, w, h) {},
	strokeRect: function (x, y, w, h) {},

	beginPath: function () {},
	closePath: function () {},
	moveTo: function (x, y) {},
	lineTo: function (x, y) {},
	quadraticCurveTo: function (cpx, cpy, x, y) {},
	bezierCurveTo: function (cp1x, cp1y, cp2x, cp2y, x, y) {},
	arcTo: function (x1, y1, x2, y2, radius) {},
	rect: function (x, y, w, h) {},
	arc: function (x, y, radius, startAngle, endAngle, anticlockwise) {},

	fill: function () {},
	stroke: function () {},
	clip: function () {},
	isPointInPath: function (x, y) {},
	drawFocusRing: function (element, xCaret, yCaret, canDrawCustom) {},

	fillText: function (text, x, y, maxWidth) {},
	strokeText: function (text, x, y, maxWidth) {},
	measureText: function (text) {},

	drawImage: function (img_elem, dx_or_sx, dy_or_sy, dw_or_sw, dh_or_sh, dx, dy, dw, dh) {},

	createImageData: function (imagedata_or_sw, sh)
	{
		var _data = new _image_data();
		_data.length = imagedata_or_sw * sh * 4;
		_data.data = (typeof(Uint8Array) != 'undefined') ? new Uint8Array(_data.length) : new Array(_data.length);
		return _data;
	},
	getImageData: function (sx, sy, sw, sh) {},
	putImageData: function (image_data, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) {}
};

function native_canvas()
{
	this.id = "";
	this.width = 300;
	this.height = 150;

	this.nodeType = 1;
}
native_canvas.prototype =
{
	getContext: function (type) { return (type == "2d") ? new native_context2d(this) : null; },
	toDataUrl: function (type) { return ""; },
	addEventListener: function () {},
	attr: function () {}
};

var _null_object = {};
_null_object.length = 0;
_null_object.nodeType = 1;
_null_object.offsetWidth = 1;
_null_object.offsetHeight = 1;
_null_object.clientWidth = 1;
_null_object.clientHeight = 1;
_null_object.scrollWidth = 1;
_null_object.scrollHeight = 1;
_null_object.style = {};
_null_object.documentElement = _null_object;
_null_object.body = _null_object;
_null_object.ownerDocument = _null_object;
_null_object.defaultView = _null_object;

_null_object.addEventListener = function () {};
_null_object.setAttribute = function () {};
_null_object.getElementsByTagName = function () { return []; };
_null_object.appendChild = function () {};
_null_object.removeChild = function () {};
_null_object.insertBefore = function () {};
_null_object.childNodes = [];
_null_object.parent = _null_object;
_null_object.parentNode = _null_object;
_null_object.find = function () { return this; };
_null_object.appendTo = function () { return this; };
_null_object.css = function () { return this; };
_null_object.width = function () { return 0; };
_null_object.height = function () { return 0; };
_null_object.attr = function () { return this; };
_null_object.prop = function () { return this; };
_null_object.val = function () { return this; };
_null_object.remove = function () {};
_null_object.getComputedStyle = function () { return null; };
_null_object.getContext = function (type) { return (type == "2d") ? new native_context2d(this) : null; };
_null_object.getBoundingClientRect = function() { return { left : 0, top : 0, right : this.width(), bottom : this.height() }; };

window._null_object = _null_object;

document.createElement = function (type)
{
	if (type && type.toLowerCase)
	{
		if (type.toLowerCase() == "canvas")
			return new native_canvas();
	}

	return _null_object;
};

function _return_empty_html_element() { return _null_object; }

document.createDocumentFragment = _return_empty_html_element;
document.getElementsByTagName = function (tag) { return ("head" == tag) ? [_null_object] : []; };
document.insertBefore = function () {};
document.appendChild = function () {};
document.removeChild = function () {};
document.getElementById = function () {	return _null_object; };
document.createComment = function () { return undefined; };

document.documentElement = _null_object;
document.body = _null_object;

// NATIVE OBJECT
var native = (typeof native === undefined) ? undefined : native;
if (!native)
{
	if (typeof NativeEngine === "undefined")
		native = CreateNativeEngine();
	else
		native = NativeEngine;
}

window.native = native;
function GetNativeEngine() { return window.native; }

var Api = null; // main builder object
window.devicePixelRatio = 1;
if (window.native && window.native.GetDevicePixelRatio)
	window.devicePixelRatio = window.native.GetDevicePixelRatio();

// OPEN
function NativeOpenFileData(data, version, xlsx_file_path, options)
{
	window.NATIVE_DOCUMENT_TYPE = window.native.GetEditorType();
    Api = null;

    if (options && options["printOptions"] && options["printOptions"]["retina"])
        AscBrowser.isRetina = true;

	if (window.NATIVE_DOCUMENT_TYPE == "presentation" || window.NATIVE_DOCUMENT_TYPE == "document")
	{
        Api = new window["Asc"]["asc_docs_api"]({});
        Api.asc_nativeOpenFile(data, version);
	}
	else
	{
        Api = new window["Asc"]["spreadsheet_api"]({});
        if (options && undefined !== options["locale"])
            Api.asc_setLocale(options["locale"]);
        Api.asc_nativeOpenFile(data, version, undefined, xlsx_file_path);
	}
}

var clearTimeout = window.clearTimeout = function() {};
var setTimeout = window.setTimeout = function() {};
var clearInterval = window.clearInterval = function() {};
var setInterval = window.setInterval = function() {};

var console = {
	log: function (param) { window.native.ConsoleLog(param); },
	time: function (param) {},
	timeEnd: function (param) {}
};

var performance = window.performance = (function(){
	var basePerformanceOffset = Date.now();
	return {
		now : function() { return Date.now() - basePerformanceOffset; }
	};
})();
<commit_msg>[bug] For bug 46818 (assembling in doctrenderer)<commit_after>/*
 * (c) Copyright Ascensio System SIA 2010-2019
 *
 * This program is a free software product. You can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License (AGPL)
 * version 3 as published by the Free Software Foundation. In accordance with
 * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
 * that Ascensio System SIA expressly excludes the warranty of non-infringement
 * of any third-party rights.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
 * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
 *
 * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
 * street, Riga, Latvia, EU, LV-1050.
 *
 * The  interactive user interfaces in modified source and object code versions
 * of the Program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU AGPL version 3.
 *
 * Pursuant to Section 7(b) of the License you must retain the original Product
 * logo when distributing the program. Pursuant to Section 7(e) we decline to
 * grant you any rights under trademark law for use of our trademarks.
 *
 * All the Product's GUI elements, including illustrations and icon sets, as
 * well as technical writing content are licensed under the terms of the
 * Creative Commons Attribution-ShareAlike 4.0 International. See the License
 * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
 *
 */

var editor = undefined;
var window = {};
var navigator = {};
navigator.userAgent = "chrome";
window.navigator = navigator;
window.location = {};

window.location.protocol = "";
window.location.host = "";
window.location.href = "";
window.location.pathname = "";

window.XMLHttpRequest = function () {};

window.NATIVE_EDITOR_ENJINE = true;
window.NATIVE_EDITOR_ENJINE_SYNC_RECALC = true;

var document = {};
window.document = document;

window["Asc"] = {};
var Asc = window["Asc"];

window["AscFonts"] = {};
var AscFonts = window["AscFonts"];

window["AscCommon"] = {};
var AscCommon = window["AscCommon"];

window["AscFormat"] = {};
var AscFormat = window["AscFormat"];

window["AscDFH"] = {};
var AscDFH = window["AscDFH"];

window["AscCH"] = {};
var AscCH = window["AscCH"];

window["AscCommonExcel"] = {};
var AscCommonExcel = window["AscCommonExcel"];

window["AscCommonWord"] = {};
var AscCommonWord = window["AscCommonWord"];

window["AscCommonSlide"] = {};
var AscCommonSlide = window["AscCommonSlide"];

function Image()
{
	this.src = "";
	this.onload = function () {};
	this.onerror = function () {};
}

function _image_data()
{
	this.data = null;
	this.length = 0;
}

function native_pattern_fill()
{
}
native_pattern_fill.prototype =
{
	setTransform: function (transform) {}
};

function native_gradient_fill() {}
native_gradient_fill.prototype =
{
	addColorStop: function (offset, color) {}
};

function native_context2d(parent)
{
	this.canvas = parent;

	this.globalAlpha = 0;
	this.globalCompositeOperation = "";
	this.fillStyle = "#000000";
	this.strokeStyle = "#000000";

	this.lineWidth = 0;
	this.lineCap = 0;
	this.lineJoin = 0;
	this.miterLimit = 0;
	this.shadowOffsetX = 0;
	this.shadowOffsetY = 0;
	this.shadowBlur = 0;
	this.shadowColor = 0;
	this.font = "";
	this.textAlign = 0;
	this.textBaseline = 0;
}
native_context2d.prototype =
{
	save: function () {},
	restore: function () {},

	scale: function (x, y) {},
	rotate: function (angle) {},
	translate: function (x, y) {},
	transform: function (m11, m12, m21, m22, dx, dy) {},
	setTransform: function (m11, m12, m21, m22, dx, dy) {},

	createLinearGradient: function (x0, y0, x1, y1) {},
	createRadialGradient: function (x0, y0, r0, x1, y1, r1) {},
	createPattern: function (image, repetition) {},

	clearRect: function (x, y, w, h) {},
	fillRect: function (x, y, w, h) {},
	strokeRect: function (x, y, w, h) {},

	beginPath: function () {},
	closePath: function () {},
	moveTo: function (x, y) {},
	lineTo: function (x, y) {},
	quadraticCurveTo: function (cpx, cpy, x, y) {},
	bezierCurveTo: function (cp1x, cp1y, cp2x, cp2y, x, y) {},
	arcTo: function (x1, y1, x2, y2, radius) {},
	rect: function (x, y, w, h) {},
	arc: function (x, y, radius, startAngle, endAngle, anticlockwise) {},

	fill: function () {},
	stroke: function () {},
	clip: function () {},
	isPointInPath: function (x, y) {},
	drawFocusRing: function (element, xCaret, yCaret, canDrawCustom) {},

	fillText: function (text, x, y, maxWidth) {},
	strokeText: function (text, x, y, maxWidth) {},
	measureText: function (text) {},

	drawImage: function (img_elem, dx_or_sx, dy_or_sy, dw_or_sw, dh_or_sh, dx, dy, dw, dh) {},

	createImageData: function (imagedata_or_sw, sh)
	{
		var _data = new _image_data();
		_data.length = imagedata_or_sw * sh * 4;
		_data.data = (typeof(Uint8Array) != 'undefined') ? new Uint8Array(_data.length) : new Array(_data.length);
		return _data;
	},
	getImageData: function (sx, sy, sw, sh) {},
	putImageData: function (image_data, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) {}
};

function native_canvas()
{
	this.id = "";
	this.width = 300;
	this.height = 150;

	this.nodeType = 1;
}
native_canvas.prototype =
{
	getContext: function (type) { return (type == "2d") ? new native_context2d(this) : null; },
	toDataUrl: function (type) { return ""; },
	addEventListener: function () {},
	attr: function () {}
};

var _null_object = {};
_null_object.length = 0;
_null_object.nodeType = 1;
_null_object.offsetWidth = 1;
_null_object.offsetHeight = 1;
_null_object.clientWidth = 1;
_null_object.clientHeight = 1;
_null_object.scrollWidth = 1;
_null_object.scrollHeight = 1;
_null_object.style = {};
_null_object.documentElement = _null_object;
_null_object.body = _null_object;
_null_object.ownerDocument = _null_object;
_null_object.defaultView = _null_object;

_null_object.addEventListener = function () {};
_null_object.setAttribute = function () {};
_null_object.getElementsByTagName = function () { return []; };
_null_object.appendChild = function () {};
_null_object.removeChild = function () {};
_null_object.insertBefore = function () {};
_null_object.childNodes = [];
_null_object.parent = _null_object;
_null_object.parentNode = _null_object;
_null_object.find = function () { return this; };
_null_object.appendTo = function () { return this; };
_null_object.css = function () { return this; };
_null_object.width = function () { return 0; };
_null_object.height = function () { return 0; };
_null_object.attr = function () { return this; };
_null_object.prop = function () { return this; };
_null_object.val = function () { return this; };
_null_object.remove = function () {};
_null_object.getComputedStyle = function () { return null; };
_null_object.getContext = function (type) { return (type == "2d") ? new native_context2d(this) : null; };
_null_object.getBoundingClientRect = function() { return { left : 0, top : 0, right : this.width(), bottom : this.height() }; };

window._null_object = _null_object;

document.createElement = function (type)
{
	if (type && type.toLowerCase)
	{
		if (type.toLowerCase() == "canvas")
			return new native_canvas();
	}

	return _null_object;
};

function _return_empty_html_element() { return _null_object; }

document.createDocumentFragment = _return_empty_html_element;
document.getElementsByTagName = function (tag) { return ("head" == tag) ? [_null_object] : []; };
document.insertBefore = function () {};
document.appendChild = function () {};
document.removeChild = function () {};
document.getElementById = function () {	return _null_object; };
document.createComment = function () { return undefined; };

document.documentElement = _null_object;
document.body = _null_object;

// NATIVE OBJECT
var native = (typeof native === undefined) ? undefined : native;
if (!native)
{
	if (typeof NativeEngine === "undefined")
		native = CreateNativeEngine();
	else
		native = NativeEngine;
}

window.native = native;
function GetNativeEngine() { return window.native; }

var Api = null; // main builder object
window.devicePixelRatio = 1;
if (window.native && window.native.GetDevicePixelRatio)
	window.devicePixelRatio = window.native.GetDevicePixelRatio();

// OPEN
function NativeOpenFileData(data, version, xlsx_file_path, options)
{
	window.NATIVE_DOCUMENT_TYPE = window.native.GetEditorType();
    Api = null;

    if (options && options["printOptions"] && options["printOptions"]["retina"])
        AscBrowser.isRetina = true;

	if (window.NATIVE_DOCUMENT_TYPE == "presentation" || window.NATIVE_DOCUMENT_TYPE == "document")
	{
        Api = new window["Asc"]["asc_docs_api"]({});
		if (options && options["documentLayout"] && undefined !== options["documentLayout"]["openedAt"])
			Api.openedAt = options["documentLayout"]["openedAt"];
        Api.asc_nativeOpenFile(data, version);
	}
	else
	{
        Api = new window["Asc"]["spreadsheet_api"]({});
        if (options && undefined !== options["locale"])
            Api.asc_setLocale(options["locale"]);
        Api.asc_nativeOpenFile(data, version, undefined, xlsx_file_path);
	}
}

var clearTimeout = window.clearTimeout = function() {};
var setTimeout = window.setTimeout = function() {};
var clearInterval = window.clearInterval = function() {};
var setInterval = window.setInterval = function() {};

var console = {
	log: function (param) { window.native.ConsoleLog(param); },
	time: function (param) {},
	timeEnd: function (param) {}
};

var performance = window.performance = (function(){
	var basePerformanceOffset = Date.now();
	return {
		now : function() { return Date.now() - basePerformanceOffset; }
	};
})();
<|endoftext|>


<commit_before>module.exports = function (Member) {
    var loopback = require('../../node_modules/loopback/lib/loopback');
    var appRoot = require('../../server/server');

    //send verification email after registration
    Member.afterRemote('create', function (context, user, next) {
        //define object model
        var RoleMember = appRoot.models.roleMember;
        var RoleMapping = appRoot.models.RoleMappingMember;

        //retrive role admin object
        RoleMember.find({ where: { name: 'member' } }, function (err, role) {
            var role_member = role[0];
            //create a new admin member
            RoleMapping.create({ principalType: 'USER', principalId: user.id, roleId: role_member.id, memberId: user.id }, function (err, member) {

                var options = {
                    type: 'email',
                    to: user.email,
                    from: 'noreply@loopback.com',
                    subject: 'Thanks for registering.',
                    redirect: '/#/confirmation',
                    user: user,
                };
                user.verify(options, function (err, response) {
                    if (err) return next(err);
                    next();
                });

            })
        })
    });

    Member.afterRemoteError('confirm', function (context, member) {
        context.res.redirect('/#/member-confirm-error');
        context.res.end();

    })
    Member.afterRemote('confirm', function (context, member, next) {
        var Container = appRoot.models.container;
        Container.createContainer({ name: member.id.toString() }, function (err, c) {
            next();
        });
    })
    //send error response when login proccess is failed
    Member.afterRemoteError('login', function (context, next) {
        delete context.error.stack;
        if (context.error.code == 'LOGIN_FAILED_EMAIL_NOT_VERIFIED') {
            context.error.message = "Please verify your email before login"
            context = context.error;
            next();
        }
        else {
            Member.find({ where: { email: context.req.body.email } }, function (err, user) {
                if (user.length == 0) {
                    context.error.message = "Login failed, " + context.req.body.email + " is not registered";
                }
                else {
                    context.error.message = "Login failed, please enter a valid password";
                }
                context = context.error;
                next();
            })
        }
    });

    //delete unused information on reset password response
    Member.afterRemoteError('resetPassword', function (context, next) {
        delete context.error.stack;
        context = context.error;
        next();
    });

    //check whether the request is from Admin or unauthenticated member.
    Member.beforeRemote('create', function (context, user, next) {

        context.req.body.created_date = new Date();
        if (typeof (context.req.body.username) == 'undefined' || context.req.body.username == '') {
            var error = new Error();
            error.name = 'BAD_REQUEST'
            error.status = 400;
            error.message = 'Username is empty';
            error.code = 'USERNAME_IS_EMPTY';
            return next(error)
        }
        else {

            Member.find({ where: { username: context.req.body.username, email: context.req.body.email } }, function (err, member) {
                if (member.length == 1) {
                    if (!member.emailVerified) {
                        var created_time = member[0].created_date.getTime();
                        var current_time = new Date().getTime();
                        var time_range_in_minutes = (current_time - created_time) / 60000;
                        if (time_range_in_minutes >= Member.app.settings.repeated_signup_interval) {
                            Member.destroyById(member[0].id, function (err, response) {
                                next();
                            })
                        }
                        else {
                            var error = new Error();
                            error.name = '412'
                            error.status = 400;
                            error.message = 'Please sign up in next ' + (Math.round(Member.app.settings.repeated_signup_interval - time_range_in_minutes)) + ' minutes';
                            error.code = 'RE_SIGNUP_ERROR';
                            return next(error)

                        }
                    }
                    else {
                        next();
                    }
                }
                else {
                    //define object model
                    var AccessToken = appRoot.models.AccessToken;
                    var RoleMember = appRoot.models.roleMember;
                    var RoleMapping = appRoot.models.RoleMappingMember;

                    //check whether access token is valid or not
                    AccessToken.findForRequest(context.req, {}, function (aux, accessToken) {
                        //request is from unauthenticated member
                        if (typeof (accessToken) == 'undefined') {
                            next();
                        }

                        //request is from authenticated member
                        else {
                            //retrive role admin object
                            RoleMember.find({ where: { name: 'admin' } }, function (err, role) {
                                var role_admin = role[0];

                                //check whether there is role mapping from memberId and role admin id
                                RoleMapping.find({ where: { memberId: context.req.accessToken.userId, roleId: role_admin.id } }, function (err, roleMapping) {
                                    //if the request from admin user
                                    if (roleMapping.length > 0) {
                                        var userRequest = context.req.body;
                                        userRequest.emailVerified = false;

                                        //create a new admin member
                                        role_admin.members.create(userRequest, function (err, admin) {
                                            //error occured when create a new admin
                                            if (err) {
                                                var error = new Error();
                                                error.name = 'CONFLICT'
                                                error.status = 409;
                                                error.message = 'Email or Username already exist';
                                                error.code = 'EMAIL_USERNAME_EXIST';
                                                next(error)
                                            }

                                            //successfully create a new admin
                                            else {

                                                //create a token
                                                var tokenGenerator = Member.generateVerificationToken;
                                                tokenGenerator(admin, function (err, token) {
                                                    if (err) { }
                                                    else {
                                                        admin.verificationToken = token;
                                                        admin.save(function (err) {
                                                        });
                                                    }

                                                    //add adminId and roleId into RoleMapping
                                                    RoleMapping.find({ where: { roleId: role.id, memberId: admin.id } }, function (err, roleMapping) {
                                                        roleMapping[0].principalType = RoleMapping.USER,
                                                        roleMapping[0].principalId = admin.id;
                                                        roleMapping[0].save(function (err) {
                                                            if (err) {

                                                            }
                                                            else {
                                                                return context.res.sendStatus(202);
                                                            }
                                                        });
                                                    })
                                                });
                                            }
                                        });
                                    }

                                    //role mapping with adminId and roleId Admin not found
                                    else {
                                        next();
                                    }
                                })
                            })
                        }
                    },
                        function (error) {
                            console.log(error)
                        })
                }
            })

        }

    })

    //reset the user's pasword
    Member.beforeRemote('resetPassword', function (context, user, next) {
        if (context.req.body.password) {
            if (!context.req.headers.access_token) return context.res.sendStatus(401);

            //verify passwords match
            if (!context.req.body.password ||
                !context.req.body.password_confirmation ||
                context.req.body.password !== context.req.body.password_confirmation) {

                var error = new Error();
                error.name = 'BAD_REQUEST'
                error.status = 400;
                error.message = 'Passwords do not match';
                error.code = 'PASSWORDS_DO_NOT_MATCH';
                return next(error)
            }

            Member.findById(context.req.body.id, function (err, user) {
                if (err) return context.res.sendStatus(404);
                user.updateAttribute('password', context.req.body.password, function (err, user) {
                    if (err) return context.res.sendStatus(404);
                    console.log('> password reset processed successfully');
                    return context.res.sendStatus(202);
                });
            });

        }
        else {
            next();
        }

    });

    //send password reset link when requested
    Member.on('resetPasswordRequest', function (info) {
        var host = (Member.app && Member.app.settings.host) || 'localhost';
        var port = (Member.app && Member.app.settings.port) || 3000;
        var url = host + ':' + port + '/#/reset-password';
        var html = 'Click here to reset your password';

        var options = {
            type: 'email',
            to: info.email,
            from: '',
            subject: 'Reset Password Request',
            html: html
        };

        var Email = options.mailer || this.constructor.email || loopback.getModelByType(loopback.Email);
        options.headers = options.headers || {};

        Email.send(options, function (err, email) {
            if (err) {
                console.log(err)
            } else {
                console.log("message sent")
            }
        });
    });
};

<commit_msg>fix bug:delete member after determined interval sign up<commit_after>module.exports = function (Member) {
    var loopback = require('../../node_modules/loopback/lib/loopback');
    var appRoot = require('../../server/server');

    //send verification email after registration
    Member.afterRemote('create', function (context, user, next) {
        //define object model
        var RoleMember = appRoot.models.roleMember;
        var RoleMapping = appRoot.models.RoleMappingMember;

        //retrive role admin object
        RoleMember.find({ where: { name: 'member' } }, function (err, role) {
            var role_member = role[0];
            //create a new admin member
            RoleMapping.create({ principalType: 'USER', principalId: user.id, roleId: role_member.id, memberId: user.id }, function (err, member) {

                var options = {
                    type: 'email',
                    to: user.email,
                    from: 'noreply@loopback.com',
                    subject: 'Thanks for registering.',
                    redirect: '/#/confirmation',
                    user: user,
                };
                user.verify(options, function (err, response) {
                    if (err) return next(err);
                    next();
                });

            })
        })
    });

    Member.afterRemoteError('confirm', function (context, member) {
        context.res.redirect('/#/member-confirm-error');
        context.res.end();

    })
    Member.afterRemote('confirm', function (context, member, next) {
        var Container = appRoot.models.container;
        Container.createContainer({ name: member.id.toString() }, function (err, c) {
            next();
        });
    })
    //send error response when login proccess is failed
    Member.afterRemoteError('login', function (context, next) {
        delete context.error.stack;
        if (context.error.code == 'LOGIN_FAILED_EMAIL_NOT_VERIFIED') {
            context.error.message = "Please verify your email before login"
            context = context.error;
            next();
        }
        else {
            Member.find({ where: { email: context.req.body.email } }, function (err, user) {
                if (user.length == 0) {
                    context.error.message = "Login failed, " + context.req.body.email + " is not registered";
                }
                else {
                    context.error.message = "Login failed, please enter a valid password";
                }
                context = context.error;
                next();
            })
        }
    });

    //delete unused information on reset password response
    Member.afterRemoteError('resetPassword', function (context, next) {
        delete context.error.stack;
        context = context.error;
        next();
    });

    //check whether the request is from Admin or unauthenticated member.
    Member.beforeRemote('create', function (context, user, next) {

        context.req.body.created_date = new Date();
        if (typeof (context.req.body.username) == 'undefined' || context.req.body.username == '') {
            var error = new Error();
            error.name = 'BAD_REQUEST'
            error.status = 400;
            error.message = 'Username is empty';
            error.code = 'USERNAME_IS_EMPTY';
            return next(error)
        }
        else {

            Member.find({ where: { username: context.req.body.username, email: context.req.body.email } }, function (err, member) {
                if (member.length == 1) {
                    if (!member.emailVerified) {
                        var created_time = member[0].created_date.getTime();
                        var current_time = new Date().getTime();
                        var time_range_in_minutes = (current_time - created_time) / 60000;
                        if (time_range_in_minutes >= Member.app.settings.repeated_signup_interval) {
                            Member.destroyById(member[0].__data.id, function (err, response) {
                                next();
                            })
                        }
                        else {
                            var interval = (Math.round(Member.app.settings.repeated_signup_interval - time_range_in_minutes));
                            if(interval == 0){
                                interval = 1;
                            }
                            var error = new Error();
                            error.name = '412'
                            error.status = 400;
                            error.message = 'Please sign up in next ' + interval + ' minutes';
                            error.code = 'RE_SIGNUP_ERROR';
                            return next(error)

                        }
                    }
                    else {
                        next();
                    }
                }
                else {
                    //define object model
                    var AccessToken = appRoot.models.AccessToken;
                    var RoleMember = appRoot.models.roleMember;
                    var RoleMapping = appRoot.models.RoleMappingMember;

                    //check whether access token is valid or not
                    AccessToken.findForRequest(context.req, {}, function (aux, accessToken) {
                        //request is from unauthenticated member
                        if (typeof (accessToken) == 'undefined') {
                            next();
                        }

                        //request is from authenticated member
                        else {
                            //retrive role admin object
                            RoleMember.find({ where: { name: 'admin' } }, function (err, role) {
                                var role_admin = role[0];

                                //check whether there is role mapping from memberId and role admin id
                                RoleMapping.find({ where: { memberId: context.req.accessToken.userId, roleId: role_admin.id } }, function (err, roleMapping) {
                                    //if the request from admin user
                                    if (roleMapping.length > 0) {
                                        var userRequest = context.req.body;
                                        userRequest.emailVerified = false;

                                        //create a new admin member
                                        role_admin.members.create(userRequest, function (err, admin) {
                                            //error occured when create a new admin
                                            if (err) {
                                                var error = new Error();
                                                error.name = 'CONFLICT'
                                                error.status = 409;
                                                error.message = 'Email or Username already exist';
                                                error.code = 'EMAIL_USERNAME_EXIST';
                                                next(error)
                                            }

                                            //successfully create a new admin
                                            else {

                                                //create a token
                                                var tokenGenerator = Member.generateVerificationToken;
                                                tokenGenerator(admin, function (err, token) {
                                                    if (err) { }
                                                    else {
                                                        admin.verificationToken = token;
                                                        admin.save(function (err) {
                                                        });
                                                    }

                                                    //add adminId and roleId into RoleMapping
                                                    RoleMapping.find({ where: { roleId: role.id, memberId: admin.id } }, function (err, roleMapping) {
                                                        roleMapping[0].principalType = RoleMapping.USER,
                                                        roleMapping[0].principalId = admin.id;
                                                        roleMapping[0].save(function (err) {
                                                            if (err) {

                                                            }
                                                            else {
                                                                return context.res.sendStatus(202);
                                                            }
                                                        });
                                                    })
                                                });
                                            }
                                        });
                                    }

                                    //role mapping with adminId and roleId Admin not found
                                    else {
                                        next();
                                    }
                                })
                            })
                        }
                    },
                        function (error) {
                            console.log(error)
                        })
                }
            })

        }

    })

    //reset the user's pasword
    Member.beforeRemote('resetPassword', function (context, user, next) {
        if (context.req.body.password) {
            if (!context.req.headers.access_token) return context.res.sendStatus(401);

            //verify passwords match
            if (!context.req.body.password ||
                !context.req.body.password_confirmation ||
                context.req.body.password !== context.req.body.password_confirmation) {

                var error = new Error();
                error.name = 'BAD_REQUEST'
                error.status = 400;
                error.message = 'Passwords do not match';
                error.code = 'PASSWORDS_DO_NOT_MATCH';
                return next(error)
            }

            Member.findById(context.req.body.id, function (err, user) {
                if (err) return context.res.sendStatus(404);
                user.updateAttribute('password', context.req.body.password, function (err, user) {
                    if (err) return context.res.sendStatus(404);
                    console.log('> password reset processed successfully');
                    return context.res.sendStatus(202);
                });
            });

        }
        else {
            next();
        }

    });

    //send password reset link when requested
    Member.on('resetPasswordRequest', function (info) {
        var host = (Member.app && Member.app.settings.host) || 'localhost';
        var port = (Member.app && Member.app.settings.port) || 3000;
        var url = host + ':' + port + '/#/reset-password';
        var html = 'Click here to reset your password';

        var options = {
            type: 'email',
            to: info.email,
            from: '',
            subject: 'Reset Password Request',
            html: html
        };

        var Email = options.mailer || this.constructor.email || loopback.getModelByType(loopback.Email);
        options.headers = options.headers || {};

        Email.send(options, function (err, email) {
            if (err) {
                console.log(err)
            } else {
                console.log("message sent")
            }
        });
    });
};

<|endoftext|>


<commit_before>var path = require('path');
var async = require('async'); // NB: async is used here in the benchmarking code, in case co or
                              // asyncawait won't run on the version of node being benchmarked.
var _ = require('lodash');

// Functions available for benchmarking
var functions = {
    countFiles: 'countFiles',
    largest: 'largest'
};

// Variants available for benchmarking.
var variants = {
    async: 'async',
    asyncawait: 'asyncawait',
    callbacks: 'callbacks',
    co: 'co',
    synchronous: 'synchronous'
};

// ================================================================================
// Benchmark configuration - adjust to suit.

var SELECTED_FUNCTION = functions.largest;

var SELECTED_VARIANT = variants.asyncawait;

var SAMPLES_PER_RUN = 1000;   // How many times the function will be called per run

var RUNS_PER_BENCHMARK = 10;  // How many runs make up the whole benchmark

var JUST_CHECK_THE_FUNCTION = false; // If true, just call the function once and display its results

// ================================================================================

// Run the benchmark (or just check the function).
if (JUST_CHECK_THE_FUNCTION) {
    var name = SELECTED_FUNCTION + '-' + SELECTED_VARIANT;
    var sample = createSampleFunction();
    console.log("========== CHECKING '" + name + "': ==========");
    sample(function(err, result) {
        console.log(err || result);
    });
} else {
    benchmark();
}

function benchmark() {
    var name = SELECTED_FUNCTION + '-' + SELECTED_VARIANT;
    var sample = createSampleFunction();
    console.log('========== PERFORMING ' + RUNS_PER_BENCHMARK + " RUNS ON '" + name + "': ==========");
    var times = [];
    async.timesSeries(
        RUNS_PER_BENCHMARK,
        function(n, next) {
            process.stdout.write('RUN ' + (n + 1));
            run(sample, function(err, elapsed) {
                if (err) {
                    next(err);
                } else {
                    times.push(elapsed);
                    var msg = SAMPLES_PER_RUN
                        + ' samples took '
                        + (elapsed / 1000.0)
                        + ' seconds ('
                        + (SAMPLES_PER_RUN * 1000.0 / elapsed)
                        + ' samples/sec)';
                    console.log(msg);
                    next();
                }
            });
        },
        function(err) {
            if (err) {
                console.log(err);
                process.exit();
            } else {
                totalTime = _.reduce(times, function (sum, time) { return sum + time; });
                var averageTime = totalTime / RUNS_PER_BENCHMARK;
                    var msg = 'Average time: '
                        + (averageTime / 1000.0)
                        + ' seconds ('
                        + (SAMPLES_PER_RUN * 1000.0 / averageTime)
                        + ' samples/sec)';
                console.log('========== ' + msg + ' ==========');
            }
        });

}

function run(sample, callback) {
    var start = new Date().getTime();
    async.timesSeries(
        SAMPLES_PER_RUN,
        function(n, next) {
            process.stdout.write('.');
            sample(next);
        },
        function(err) {
            process.stdout.write('\n');
            if (err) { callback(err); return; }
            var elapsed = new Date().getTime() - start;
            callback(null, elapsed);
        });
};

function createSampleFunction() {
    var selectedFunction = require('./' + SELECTED_FUNCTION + '/' + SELECTED_FUNCTION + '-' + SELECTED_VARIANT);
    switch (SELECTED_FUNCTION) {
        case functions.largest:
            var dirToCheck = path.join(__dirname, '.');
            var options = { recurse: true, preview: true };
            var sample = function (callback) { selectedFunction(dirToCheck, options, callback); };
            break;

        case functions.countFiles:
            var dirToCheck = path.join(__dirname, '.');
            var sample = function (callback) { selectedFunction(dirToCheck, callback); };
    }
    return sample;
}
<commit_msg>Update benchmark.js<commit_after>var path = require('path');
var async = require('async'); // NB: async is used here in the benchmarking code, in case co or
                              // asyncawait won't run on the version of node being benchmarked.
var _ = require('lodash');

// Functions available for benchmarking.
var functions = {
    countFiles: 'countFiles',
    largest: 'largest'
};

// Variants available for benchmarking.
var variants = {
    async: 'async',
    asyncawait: 'asyncawait',
    callbacks: 'callbacks',
    co: 'co',
    synchronous: 'synchronous'
};

// ================================================================================
// Benchmark configuration - adjust to suit.

var SELECTED_FUNCTION = functions.largest;

var SELECTED_VARIANT = variants.asyncawait;

var SAMPLES_PER_RUN = 1000;   // How many times the function will be called per run

var RUNS_PER_BENCHMARK = 10;  // How many runs make up the whole benchmark

var JUST_CHECK_THE_FUNCTION = false; // If true, just call the function once and display its results

// ================================================================================

// Run the benchmark (or just check the function).
if (JUST_CHECK_THE_FUNCTION) {
    var name = SELECTED_FUNCTION + '-' + SELECTED_VARIANT;
    var sample = createSampleFunction();
    console.log("========== CHECKING '" + name + "': ==========");
    sample(function(err, result) {
        console.log(err || result);
    });
} else {
    benchmark();
}

function benchmark() {
    var name = SELECTED_FUNCTION + '-' + SELECTED_VARIANT;
    var sample = createSampleFunction();
    console.log('========== PERFORMING ' + RUNS_PER_BENCHMARK + " RUNS ON '" + name + "': ==========");
    var times = [];
    async.timesSeries(
        RUNS_PER_BENCHMARK,
        function(n, next) {
            process.stdout.write('RUN ' + (n + 1));
            run(sample, function(err, elapsed) {
                if (err) {
                    next(err);
                } else {
                    times.push(elapsed);
                    var msg = SAMPLES_PER_RUN
                        + ' samples took '
                        + (elapsed / 1000.0)
                        + ' seconds ('
                        + (SAMPLES_PER_RUN * 1000.0 / elapsed)
                        + ' samples/sec)';
                    console.log(msg);
                    next();
                }
            });
        },
        function(err) {
            if (err) {
                console.log(err);
                process.exit();
            } else {
                totalTime = _.reduce(times, function (sum, time) { return sum + time; });
                var averageTime = totalTime / RUNS_PER_BENCHMARK;
                    var msg = 'Average time: '
                        + (averageTime / 1000.0)
                        + ' seconds ('
                        + (SAMPLES_PER_RUN * 1000.0 / averageTime)
                        + ' samples/sec)';
                console.log('========== ' + msg + ' ==========');
            }
        });

}

function run(sample, callback) {
    var start = new Date().getTime();
    async.timesSeries(
        SAMPLES_PER_RUN,
        function(n, next) {
            process.stdout.write('.');
            sample(next);
        },
        function(err) {
            process.stdout.write('\n');
            if (err) { callback(err); return; }
            var elapsed = new Date().getTime() - start;
            callback(null, elapsed);
        });
};

function createSampleFunction() {
    var selectedFunction = require('./' + SELECTED_FUNCTION + '/' + SELECTED_FUNCTION + '-' + SELECTED_VARIANT);
    switch (SELECTED_FUNCTION) {
        case functions.largest:
            var dirToCheck = path.join(__dirname, '.');
            var options = { recurse: true, preview: true };
            var sample = function (callback) { selectedFunction(dirToCheck, options, callback); };
            break;

        case functions.countFiles:
            var dirToCheck = path.join(__dirname, '.');
            var sample = function (callback) { selectedFunction(dirToCheck, callback); };
    }
    return sample;
}
<|endoftext|>


<commit_before>/**
 * Class that defines the attributes of a robot Enemy
 * @param {number} x     Initial x position
 * @param {number} y     Initial y position
 * @param {number} level Initial level
 * @constructor
 */
var Robot = function(x, y, level) {
	Enemy.call(this, x, y, level); // Call super constructor

	this.attackSpeed = 2;
	this.movementSpeed = 10;
	this.moveLength = 2;
	this.attack = level + 5;
	this.defense = level - 15;
	this.hp = 1*level;

	if (this.defense < 1) {
		this.defense = 1;
	}

	this.spriteSheet = new createjs.SpriteSheet({
		"images": [loader.getResult("robot")],
		"frames": {
			"width": 14,
			"height": 16,
			"count": 5
		},
		"animations": {
			"still": {
				"frames": [0],
				"next": "still",
				"speed": 1
			},
			"move": {
				"frames": [0, 1, 2],
				"next": "move",
				"speed": 1
			},

			"attack": {
				"frames": [3, 4],
				"next": "attack",
				"speed": 1
			}
		}
	});

	this.animations = new createjs.Container();

	this.sprite = new createjs.Sprite(this.spriteSheet, "still");
	this.sprite.x = this.x;
	this.sprite.y = this.y;

	this.animations.addChild(this.sprite, this.healthBar);
	renderer.activeObjectsContainer.addChild(this.animations);

	/**
	 * Updates the robot's animation based on what direction it is moving
	 * @param  {number} deltax Robot's movement on the x-axis
	 * @param  {number} deltay Robot's movement on the y-axis
	 */
	this.updateMovementAnimation = function(deltax, deltay) {
		if (deltax > 0 && this.lastFrameDirection !== "walk-right") {
			this.animations.scaleX = 1;
			this.lastFrameDirection = "walk-right";
		} else if (deltax < 0 && this.lastFrameDirection !== "walk-left") {
			this.animations.scaleX = -1;
			this.lastFrameDirection = "walk-left";
		}
	};

	/**
	 * Function that is called when the robot is done moving
	 */
	this.cleanUpMovement = function() {
		this.turnCounter = 0;
		this.sprite.gotoAndPlay("still");
	};
};

Robot.prototype = new Enemy;
Robot.prototype.constructor = Robot;<commit_msg>fixed disappearing left sprite movement on robot<commit_after>/**
 * Class that defines the attributes of a robot Enemy
 * @param {number} x     Initial x position
 * @param {number} y     Initial y position
 * @param {number} level Initial level
 * @constructor
 */
var Robot = function(x, y, level) {
	Enemy.call(this, x, y, level); // Call super constructor

	this.attackSpeed = 2;
	this.movementSpeed = 10;
	this.moveLength = 2;
	this.attack = level + 5;
	this.defense = level - 15;
	this.hp = 1*level;

	if (this.defense < 1) {
		this.defense = 1;
	}

	this.spriteSheet = new createjs.SpriteSheet({
		"images": [loader.getResult("robot")],
		"frames": {
			"width": 14,
			"height": 16,
			"count": 5
		},
		"animations": {
			"still": {
				"frames": [0],
				"next": "still",
				"speed": 1
			},
			"move": {
				"frames": [0, 1, 2],
				"next": "move",
				"speed": 1
			},

			"attack": {
				"frames": [3, 4],
				"next": "attack",
				"speed": 1
			}
		}
	});

	this.animations = new createjs.Container();

	this.sprite = new createjs.Sprite(this.spriteSheet, "still");
	this.sprite.x = this.x;
	this.sprite.y = this.y;

	this.animations.addChild(this.sprite, this.healthBar);
	renderer.activeObjectsContainer.addChild(this.animations);

	/**
	 * Updates the robot's animation based on what direction it is moving
	 * @param  {number} deltax Robot's movement on the x-axis
	 * @param  {number} deltay Robot's movement on the y-axis
	 */
	this.updateMovementAnimation = function(deltax, deltay) {
		if (deltax > 0 && this.lastFrameDirection !== "walk-right") {
			this.lastFrameDirection = "walk-right";
		} else if (deltax < 0 && this.lastFrameDirection !== "walk-left") {
			this.lastFrameDirection = "walk-left";
		}
	};

	/**
	 * Function that is called when the robot is done moving
	 */
	this.cleanUpMovement = function() {
		this.turnCounter = 0;
		this.sprite.gotoAndPlay("still");
	};
};

Robot.prototype = new Enemy;
Robot.prototype.constructor = Robot;<|endoftext|>


<commit_before>import React from 'react';

class Home extends React.Component {
    render() {
        return (

SlideWiki revolutionises how educational material is authored, shared and used.

Features

Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

Presentations

                                Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

                                    Try Sample Deck Imported from SlideWiki.org »
                                    See documentation deck»

User Activities

Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

        );
    }
}

export default Home;
<commit_msg>Update deck link on home page<commit_after>import React from 'react';

class Home extends React.Component {
    render() {
        return (

SlideWiki revolutionises how educational material is authored, shared and used.

Features

Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

Presentations

                                Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

                                    Try Sample Deck Imported from SlideWiki.org »
                                    See documentation deck»

User Activities

Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

        );
    }
}

export default Home;
<|endoftext|>


<commit_before>var SteamTotp = require('steam-totp');
var SteamCommunity = require('../index.js');

var ETwoFactorTokenType = {
	"None": 0,                  // No token-based two-factor authentication
	"ValveMobileApp": 1,        // Tokens generated using Valve's special charset (5 digits, alphanumeric)
	"ThirdParty": 2             // Tokens generated using literally everyone else's standard charset (6 digits, numeric). This is disabled.
};

SteamCommunity.prototype.enableTwoFactor = function(callback) {
	var self = this;

	this.getWebApiOauthToken(function(err, token) {
		if(err) {
			callback(err);
			return;
		}

		self.httpRequestPost({
			"uri": "https://api.steampowered.com/ITwoFactorService/AddAuthenticator/v1/",
			"form": {
				"steamid": self.steamID.getSteamID64(),
				"access_token": token,
				"authenticator_time": Math.floor(Date.now() / 1000),
				"authenticator_type": ETwoFactorTokenType.ValveMobileApp,
				"device_identifier": SteamTotp.getDeviceID(self.steamID),
				"sms_phone_id": "1"
			},
			"json": true
		}, function(err, response, body) {
			if (err) {
				callback(err);
				return;
			}

			if(!body.response) {
				callback(new Error("Malformed response"));
				return;
			}

			if(body.response.status != 1) {
				var error = new Error("Error " + body.response.status);
				error.eresult = body.response.status;
				callback(error);
				return;
			}

			callback(null, body.response);
		}, "steamcommunity");
	});
};

SteamCommunity.prototype.finalizeTwoFactor = function(secret, activationCode, callback) {
	var attemptsLeft = 30;
	var diff = 0;

	var self = this;
	this.getWebApiOauthToken(function(err, token) {
		if(err) {
			callback(err);
			return;
		}

		finalize(token);
	});

	function finalize(token) {
		var code = SteamTotp.generateAuthCode(secret, diff);

		self.httpRequestPost({
			"uri": "https://api.steampowered.com/ITwoFactorService/FinalizeAddAuthenticator/v1/",
			"form": {
				"steamid": self.steamID.getSteamID64(),
				"access_token": token,
				"authenticator_code": code,
				"authenticator_time": Math.floor(Date.now() / 1000),
				"activation_code": activationCode
			},
			"json": true
		}, function(err, response, body) {
			if (err) {
				callback(err);
				return;
			}

			if(!body.response) {
				callback(new Error("Malformed response"));
				return;
			}

			body = body.response;

			if(body.server_time) {
				diff = body.server_time - Math.floor(Date.now() / 1000);
			}

			if(body.status == 89) {
				callback(new Error("Invalid activation code"));
			} else if(body.want_more) {
				attemptsLeft--;
				diff += 30;

				finalize(token);
			} else if(!body.success) {
				callback(new Error("Error " + body.status));
			} else {
				callback(null);
			}
		}, "steamcommunity");
	}
};

SteamCommunity.prototype.disableTwoFactor = function(revocationCode, callback) {
	var self = this;

	this.getWebApiOauthToken(function(err, token) {
		if(err) {
			callback(err);
			return;
		}

		self.httpRequestPost({
			"uri": "https://api.steampowered.com/ITwoFactorService/RemoveAuthenticator/v1/",
			"form": {
				"steamid": self.steamID.getSteamID64(),
				"access_token": token,
				"revocation_code": revocationCode,
				"steamguard_scheme": 1
			},
			"json": true
		}, function(err, response, body) {
			if (err) {
				callback(err);
				return;
			}

			if(!body.response) {
				callback(new Error("Malformed response"));
				return;
			}

			if(!body.response.success) {
				callback(new Error("Request failed"));
				return;
			}

			// success = true means it worked
			callback(null);
		}, "steamcommunity");
	});
};
<commit_msg>Automatically handle time offset when enabling 2FA (fixes #98)<commit_after>var SteamTotp = require('steam-totp');
var SteamCommunity = require('../index.js');

var ETwoFactorTokenType = {
	"None": 0,                  // No token-based two-factor authentication
	"ValveMobileApp": 1,        // Tokens generated using Valve's special charset (5 digits, alphanumeric)
	"ThirdParty": 2             // Tokens generated using literally everyone else's standard charset (6 digits, numeric). This is disabled.
};

SteamCommunity.prototype.enableTwoFactor = function(callback) {
	var self = this;

	this.getWebApiOauthToken(function(err, token) {
		if(err) {
			callback(err);
			return;
		}

		self.httpRequestPost({
			"uri": "https://api.steampowered.com/ITwoFactorService/AddAuthenticator/v1/",
			"form": {
				"steamid": self.steamID.getSteamID64(),
				"access_token": token,
				"authenticator_time": Math.floor(Date.now() / 1000),
				"authenticator_type": ETwoFactorTokenType.ValveMobileApp,
				"device_identifier": SteamTotp.getDeviceID(self.steamID),
				"sms_phone_id": "1"
			},
			"json": true
		}, function(err, response, body) {
			if (err) {
				callback(err);
				return;
			}

			if(!body.response) {
				callback(new Error("Malformed response"));
				return;
			}

			if(body.response.status != 1) {
				var error = new Error("Error " + body.response.status);
				error.eresult = body.response.status;
				callback(error);
				return;
			}

			callback(null, body.response);
		}, "steamcommunity");
	});
};

SteamCommunity.prototype.finalizeTwoFactor = function(secret, activationCode, callback) {
	var attemptsLeft = 30;
	var diff = 0;

	var self = this;
	this.getWebApiOauthToken(function(err, token) {
		if(err) {
			callback(err);
			return;
		}

		SteamTotp.getTimeOffset(function(err, offset, latency) {
			if (err) {
				callback(err);
				return;
			}

			diff = offset;
			finalize(token);
		});
	});

	function finalize(token) {
		var code = SteamTotp.generateAuthCode(secret, diff);

		self.httpRequestPost({
			"uri": "https://api.steampowered.com/ITwoFactorService/FinalizeAddAuthenticator/v1/",
			"form": {
				"steamid": self.steamID.getSteamID64(),
				"access_token": token,
				"authenticator_code": code,
				"authenticator_time": Math.floor(Date.now() / 1000),
				"activation_code": activationCode
			},
			"json": true
		}, function(err, response, body) {
			if (err) {
				callback(err);
				return;
			}

			if(!body.response) {
				callback(new Error("Malformed response"));
				return;
			}

			body = body.response;

			if(body.server_time) {
				diff = body.server_time - Math.floor(Date.now() / 1000);
			}

			if(body.status == 89) {
				callback(new Error("Invalid activation code"));
			} else if(body.want_more) {
				attemptsLeft--;
				diff += 30;

				finalize(token);
			} else if(!body.success) {
				callback(new Error("Error " + body.status));
			} else {
				callback(null);
			}
		}, "steamcommunity");
	}
};

SteamCommunity.prototype.disableTwoFactor = function(revocationCode, callback) {
	var self = this;

	this.getWebApiOauthToken(function(err, token) {
		if(err) {
			callback(err);
			return;
		}

		self.httpRequestPost({
			"uri": "https://api.steampowered.com/ITwoFactorService/RemoveAuthenticator/v1/",
			"form": {
				"steamid": self.steamID.getSteamID64(),
				"access_token": token,
				"revocation_code": revocationCode,
				"steamguard_scheme": 1
			},
			"json": true
		}, function(err, response, body) {
			if (err) {
				callback(err);
				return;
			}

			if(!body.response) {
				callback(new Error("Malformed response"));
				return;
			}

			if(!body.response.success) {
				callback(new Error("Request failed"));
				return;
			}

			// success = true means it worked
			callback(null);
		}, "steamcommunity");
	});
};
<|endoftext|>