<commit_before>/**
 * MLJLib
 * MeshLabJS Library
 *
 * Copyright(C) 2015
 * Paolo Cignoni
 * Visual Computing Lab
 * ISTI - CNR
 *
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See theGNU General Public License
 * (http://www.gnu.org/licenses/gpl.txt) for more details.
 *
 */

/**
 * @file Defines MLJ.util namespace and AssociativeArray class
 * @author Stefano Gabriele
 */

/**
 * MLJ.util namespace
 * @namespace MLJ.util
 * @author Stefano Gabriele
 */
MLJ.util = {};

MLJ.util.loadFile = function (path, callback) {
    if (!jQuery.isFunction(callback)) {
        console.warn("The callback paramter must be a funciton.");
    }

    var tmpArray = [];
    if (jQuery.isArray(path)) {
        tmpArray = path;
    } else {
        tmpArray.push(path);
    }

    var results = new MLJ.util.AssociativeArray();
    function _load(path, _callback) {

        var fileName = path.substring(path.lastIndexOf('/')+1);

        $.ajax({
            url: path,
            error: function (xhr, textStatus, errorThrown) {
                var msg = "An error occurred. Status code: ";
                console.warn(msg + xhr.status + ". Status text: " + textStatus);
                results.set(fileName,"");
            },
            success: function (data) {
                results.set(fileName,data);
                _callback(data);
            }
        });
    }

    var i = 0;
    function _loadNextFile() {
        _load(tmpArray[i], function () {
            i++;
            if (i === tmpArray.length) {
                callback(results);
                return;
            } else {
                _loadNextFile();
            }
        });
    }

    _loadNextFile();
};

/**
 * Returns an array without duplicates
 * @param {type} array The array to be cleaned
 * @returns {Array} The array without duplicates
 */
MLJ.util.arrayUnique = function (array) {

    var a = array.concat();
    for (var i = 0; i < a.length; ++i) {
        for (var j = i + 1; j < a.length; ++j) {
            if (a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
};

/**
 * @class Create an Associative array
 * @memberOf MLJ.util
 * @author Stefano Gabriele
 * @example
Usage example:

 * var aa = new MLJ.util.AssociativeArray();
 * aa.set("key1", obj1);
 * aa.set("key2", obj2);
 * var iter = aa.iterator();
 * var obj;
 * while(iter.hasNext()) {
 *    obj = iter.next();
 *    //do something with obj
 * }
 */
MLJ.util.AssociativeArray = function () {

    //Contains the keys (key = keys[0 ... _length-1])
    var keys = [];
    //Associative arrays (value = values[key]);
    var values = [];

    /**
     * @class Create a new _Iterator
     * @private
     * @author Stefano Gabriele
     */
    var _Iterator = function () {
        var _ind = 0;

        /**
         * Returns true if the iteration has more elements
         * @returns {Boolean} true if the iteration has more elements,
         * false otherwise
         */
        this.hasNext = function () {
            return _ind < keys.length;
        };

        /**
         * Returns the next element in the iteration
         * @returns {Object} the next element in the iteration
         */
        this.next = function () {
            var next = values[keys[_ind]];
            _ind++;
            return next;
        };
    };

    /**
     * Returns the last inserted value of this associative array or
     * null if the array is empty
     * @returns the last inserted value or null if the array is empty
     * @author Stefano Gabriele
     */
    this.getLast = function() {
        if(this.size() === 0)
            return null;

        return values[keys[0]];
    };

    /**
     * Returns the first inserted value of this associative array or
     * null if the array is empty
     * @returns the first inserted value or null if the array is empty
     * @author Stefano Gabriele
     */
    this.getFirst = function() {
        if(this.size() === 0)
            return null;

        return values[keys[keys.length - 1]];
    };

    /**
     * Returns the value to which the specified key is mapped, or
     * undefined if this array contains no mapping for the key
     * @param {string} key the key whose associated value is to be returned
     * @returns the value to which the specified key is mapped, or
     * undefined if this array contains no mapping for the key
     * @author Stefano Gabriele
     */
    this.getByKey = function (key) {
        return values[key];
    };

    /**
     * Returns the number of elements in this array
     * @returns {Integer} The number of elements in this array
     * @author Stefano Gabriele
     */
    this.size = function () {
        return keys.length;
    };

    /**
     * Inserts an element in this associative array. Note that if the array
     * previously contained a mapping for the key, the old value is replaced
     * @param {String} key The key with which the specified value is to be associated
     * @param {Object} value The value to be associated with the specified key
     * @author Stefano Gabriele
     */
    this.set = function (key, value) {
        //if key not exists
        if (!values[key]) {
            keys.push(key);
        }
        //Note that if key aleady exists, the new entry wll override the old
        values[key] = value;
    };

    /**
     * Removes an element from this associative array
     * @param {String} key The key whose mapping is to be removed from the array
     * @returns {Object} The removed element if the array contains a mapping for
     * the key, null otherwise
     */
    this.remove = function (key) {
        var element = values[key];
        delete values[key];
        for (var i = 0, m = keys.length; i < m; i++) {
            if (keys[i] === key) {
                keys.splice(i, 1);
                //we have finished
                return element;
            }
        }

        return null;
    };

    /**
     * Returns an iterator over the elements in this array
     * @returns {MLJ.util.AssociativeArray._Iterator}
     */
    this.iterator = function () {
        return new _Iterator();
    };
};
<commit_msg>Added function sortByKey<commit_after>/**
 * MLJLib
 * MeshLabJS Library
 *
 * Copyright(C) 2015
 * Paolo Cignoni
 * Visual Computing Lab
 * ISTI - CNR
 *
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See theGNU General Public License
 * (http://www.gnu.org/licenses/gpl.txt) for more details.
 *
 */

/**
 * @file Defines MLJ.util namespace and AssociativeArray class
 * @author Stefano Gabriele
 */

/**
 * MLJ.util namespace
 * @namespace MLJ.util
 * @author Stefano Gabriele
 */
MLJ.util = {};

MLJ.util.loadFile = function (path, callback) {
    if (!jQuery.isFunction(callback)) {
        console.warn("The callback paramter must be a funciton.");
    }

    var tmpArray = [];
    if (jQuery.isArray(path)) {
        tmpArray = path;
    } else {
        tmpArray.push(path);
    }

    var results = new MLJ.util.AssociativeArray();
    function _load(path, _callback) {

        var fileName = path.substring(path.lastIndexOf('/')+1);

        $.ajax({
            url: path,
            error: function (xhr, textStatus, errorThrown) {
                var msg = "An error occurred. Status code: ";
                console.warn(msg + xhr.status + ". Status text: " + textStatus);
                results.set(fileName,"");
            },
            success: function (data) {
                results.set(fileName,data);
                _callback(data);
            }
        });
    }

    var i = 0;
    function _loadNextFile() {
        _load(tmpArray[i], function () {
            i++;
            if (i === tmpArray.length) {
                callback(results);
                return;
            } else {
                _loadNextFile();
            }
        });
    }

    _loadNextFile();
};

/**
 * Returns an array without duplicates
 * @param {type} array The array to be cleaned
 * @returns {Array} The array without duplicates
 */
MLJ.util.arrayUnique = function (array) {

    var a = array.concat();
    for (var i = 0; i < a.length; ++i) {
        for (var j = i + 1; j < a.length; ++j) {
            if (a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
};

/**
 * @class Create an Associative array
 * @memberOf MLJ.util
 * @author Stefano Gabriele
 * @example
Usage example:

 * var aa = new MLJ.util.AssociativeArray();
 * aa.set("key1", obj1);
 * aa.set("key2", obj2);
 * var iter = aa.iterator();
 * var obj;
 * while(iter.hasNext()) {
 *    obj = iter.next();
 *    //do something with obj
 * }
 */
MLJ.util.AssociativeArray = function () {

    //Contains the keys (key = keys[0 ... _length-1])
    var keys = [];
    //Associative arrays (value = values[key]);
    var values = [];

    /**
     * @class Create a new _Iterator
     * @private
     * @author Stefano Gabriele
     */
    var _Iterator = function () {
        var _ind = 0;

        /**
         * Returns true if the iteration has more elements
         * @returns {Boolean} true if the iteration has more elements,
         * false otherwise
         */
        this.hasNext = function () {
            return _ind < keys.length;
        };

        /**
         * Returns the next element in the iteration
         * @returns {Object} the next element in the iteration
         */
        this.next = function () {
            var next = values[keys[_ind]];
            _ind++;
            return next;
        };
    };

    /**
     * Returns the last inserted value of this associative array or
     * null if the array is empty
     * @returns the last inserted value or null if the array is empty
     * @author Stefano Gabriele
     */
    this.getLast = function() {
        if(this.size() === 0)
            return null;

        return values[keys[0]];
    };

    /**
     * Returns the first inserted value of this associative array or
     * null if the array is empty
     * @returns the first inserted value or null if the array is empty
     * @author Stefano Gabriele
     */
    this.getFirst = function() {
        if(this.size() === 0)
            return null;

        return values[keys[keys.length - 1]];
    };

    /**
     * Returns the value to which the specified key is mapped, or
     * undefined if this array contains no mapping for the key
     * @param {string} key the key whose associated value is to be returned
     * @returns the value to which the specified key is mapped, or
     * undefined if this array contains no mapping for the key
     * @author Stefano Gabriele
     */
    this.getByKey = function (key) {
        return values[key];
    };

    /**
     * Returns the number of elements in this array
     * @returns {Integer} The number of elements in this array
     * @author Stefano Gabriele
     */
    this.size = function () {
        return keys.length;
    };

    /**
     * Inserts an element in this associative array. Note that if the array
     * previously contained a mapping for the key, the old value is replaced
     * @param {String} key The key with which the specified value is to be associated
     * @param {Object} value The value to be associated with the specified key
     * @author Stefano Gabriele
     */
    this.set = function (key, value) {
        //if key not exists
        if (!values[key]) {
            keys.push(key);
        }
        //Note that if key aleady exists, the new entry wll override the old
        values[key] = value;
    };

    /**
     * Removes an element from this associative array
     * @param {String} key The key whose mapping is to be removed from the array
     * @returns {Object} The removed element if the array contains a mapping for
     * the key, null otherwise
     */
    this.remove = function (key) {
        var element = values[key];
        delete values[key];
        for (var i = 0, m = keys.length; i < m; i++) {
            if (keys[i] === key) {
                keys.splice(i, 1);
                //we have finished
                return element;
            }
        }

        return null;
    };

    /**
     * Returns an iterator over the elements in this array
     * @returns {MLJ.util.AssociativeArray._Iterator}
     */
    this.iterator = function () {
        return new _Iterator();
    };

    /**
     * Sorts the items of the AssociativeArray rearranging its keys
     * in ascending (default) or descending order.
     * @param {String} order The sort order: ascending (up) or
     * descending (down)
     * @author Stefano Gabriele
     */
    this.sortByKey = function(order) {
        keys.sort();

        if(order === "down") {
            keys.reverse();
        }
    };
};
<|endoftext|>


<commit_before>function generalAttack(attacker, receiver, weaponBonus){
	//Weapon bonus of one means attacker gets bonus, 0 = neutral, and -1 = penalty
	if(attacker.attack > receiver.defense){
		if(weaponBonus == 1){
			receiver.health = receiver.health - ((attacker.attack + 2) - receiver.defense);
		}else if(weaponBonus == -1{
			receiver.health = reciever.health - ((attacker.attack - 2) - reciever.defense);
		}else{
			receiver.health = reciever.health - (attacker.attack - reciever.defense);
		}
	}else {
		 receiver.health -= 2;
	}
}

var healthPlaceholder = 0;
var damageTaken = 0;
var totalDamageDealt = 0;
var totalDamageTaken = 0;
var totalKills = 0;
var totalTurns = 0;

function wolvesAttack() {
var wolf = new Character();
		wolf.health = 30;
		wolf.attack = 5;
		wolf.defense = 5;

	while(wolf.health > 0 && hero.health > 0)
	{
		var chance = Math.floor((Math.random() * 100) + 1);
		if(chance < 20){
			print_to_path(hero.health);
			healthPlaceholder = hero.health;
			generalAttack(wolf, hero);
			damageTaken = healthPlaceholder - hero.health;
			totalDamageTaken += damageTaken;
			if(chance % 2 == 0){
				print_to_path("The wolf ran up to you and bit you for " + damageTaken + " Damage");
			}else{
				print_to_path("The wolf clawed you for " + damageTaken + " Damage");
			}
		}
		else {
			healthPlaceholder = wolf.health;
			if(hero.weapon == "Mace"){
			generalAttack(hero, wolf,1);
			}
			totalDamageDealt += (healthPlaceholder - wolf.health);
			print_to_path(hero.name+" has attacked the wolf! and dealt: " + (healthPlaceholder - wolf.health));
			print_to_path("wolfs health: "+wolf.health);
		}
		update_status();
		totalTurns += 1;
	}
	totalKills += 1;
}

function banditsAttack() {
var bandit = new Character();
		bandit.health = 40;
		bandit.attack = 10;
		bandit.defense = 5;
	while(bandit.health > 0 && hero.health > 0)
	{
		var chance = Math.floor((Math.random() * 100) + 1);
		if(chance < 30){
			print_to_path(hero.health);
			healthPlaceholder = hero.health;
			generalAttack(bandit, hero);
			damageTaken = healthPlaceholder - hero.health;
			totalDamageTaken += damageTaken;
			if(chance % 2 == 0){
				print_to_path("A clan of bandits knock you on the ground kicking you for " + damageTaken + " Damage");
			}else{
				print_to_path("A bandit snuck up from behind you and stabbed you dealing " + damageTaken + " Damage");
			}
		}
		else {
			healthPlaceholder = bandit.health;
			generalAttack(hero, bandit);
			totalDamageDealt += (healthPlaceholder - bandit.health);
			print_to_path(hero.name+" has attacked a bandit");
			print_to_path("bandit health: "+bandit.health);
		}
		update_status();
		totalTurns += 1;
	}
	totalKills += 1;
}
function trollsAttack() {
var troll = new Character();
		troll.health = 50;
		troll.attack = 25;
		troll.defense = 15;
	while(troll.health > 0 && hero.health > 0)
	{
		var chance = Math.floor((Math.random() * 100) + 1);
		if(chance < 35){
			print_to_path(hero.health);
			healthPlaceholder = hero.health;
			generalAttack(troll, hero);
			damageTaken = healthPlaceholder - hero.health;
			totalDamageTaken += damageTaken;
			if(chance % 2 == 0){
				print_to_path("a troll threw a small axe at you, hitting your chest dealing " + damageTaken + " Damage");
			}else{
				print_to_path("The Troll smashed you with his club for " + damageTaken + " Damage");
			}
		}
		else {
			healthPlaceholder = troll.health;
			generalAttack(hero, troll);
			totalDamageDealt += (healthPlaceholder - troll.health);
			print_to_path(hero.name+" has attacked the troll");
			print_to_path("troll health: "+troll.health);
		}
		update_status();
		totalTurns += 1;
	}
	totalKills += 1;
}

function golemsAttack() {
var golem = new Character();
		golem.health = 60;
		golem.attack = 10;
		golem.defense = 50;
	while(golem.health > 0 && hero.health > 0)
	{
		var chance = Math.floor((Math.random() * 100) + 1);
		if(chance < 20){
			print_to_path(hero.health);
			healthPlaceholder = hero.health;
			generalAttack(golem, hero);
			damageTaken = healthPlaceholder - hero.health;
			totalDamageTaken += damageTaken;
			if(chance % 2 == 0){
				print_to_path("Flails its arms smashing you into the ground. You took " + damageTaken + " Damage");
			}else{
				print_to_path("Stomps its foot on the ground causing rocks to fall on you from the nearby mountain. You took " + damageTaken + " Damage");
			}
		}
		else {
			healthPlaceholder = golem.health;
			generalAttack(hero, golem);
			totalDamageDealt += (healthPlaceholder - golem.health);
			print_to_path(hero.name+" has attacked the golem");
			print_to_path("golem health: "+golem.health);
		}
		update_status();
		totalTurns += 1;
	}
	totalKills += 1;
}

function dragonAttack() {
// atk 30
var dragon = new Character();
		dragon.health = 60;
		dragon.attack = 30;
		dragon.defense = 30;
	while(dragon.health > 0 && hero.health > 0)
	{
		var chance = Math.floor((Math.random() * 100) + 1);
		if(chance < 20){
			print_to_path(hero.health);
			healthPlaceholder = hero.health;
			generalAttack(dragon, hero);
			damageTaken = healthPlaceholder - hero.health;
			totalDamageTaken += damageTaken;
			if(chance % 2 == 0){
				print_to_path("Breaths green flames at you which inflicted a burn on you. You took " + damageTaken + " Damage");
			}else{
				print_to_path("Swipes its tail along the floor flinging you into the wall. You took " + damageTaken + " Damage");
			}
		}
		else {
			healthPlaceholder = dragon.health;
			generalAttack(hero, dragon);
			totalDamageDealt += (healthPlaceholder - dragon.health);
			print_to_path(hero.name+" has attacked the dragon!");
			print_to_path("dragon health: "+dragon.health);
		}
		update_status();
		totalTurns += 1;
	}
	totalKills += 1;
}

function blackSquirrelAttacks() {
	//I has no Tail D:
}

function statistics() {
	print_to_path("totalKills: " + totalKills);
	print_to_path("totalTurns: " + totalTurns);
	print_to_path("totalDamageDealt: " + totalDamageDealt);
	print_to_path("totalDamageTaken: " + totalDamageTaken);
}
<commit_msg>Goddamn syntax errors<commit_after>function generalAttack(attacker, receiver, weaponBonus){
	//Weapon bonus of one means attacker gets bonus, 0 = neutral, and -1 = penalty
	if(attacker.attack > receiver.defense){
		if(weaponBonus == 1){
			receiver.health = receiver.health - ((attacker.attack + 2) - receiver.defense);
		}else if(weaponBonus == -1){
			receiver.health = reciever.health - ((attacker.attack - 2) - reciever.defense);
		}else{
			receiver.health = reciever.health - (attacker.attack - reciever.defense);
		}
	}else {
		 receiver.health -= 2;
	}
}

var healthPlaceholder = 0;
var damageTaken = 0;
var totalDamageDealt = 0;
var totalDamageTaken = 0;
var totalKills = 0;
var totalTurns = 0;

function wolvesAttack() {
var wolf = new Character();
		wolf.health = 30;
		wolf.attack = 5;
		wolf.defense = 5;

	while(wolf.health > 0 && hero.health > 0)
	{
		var chance = Math.floor((Math.random() * 100) + 1);
		if(chance < 20){
			print_to_path(hero.health);
			healthPlaceholder = hero.health;
			generalAttack(wolf, hero);
			damageTaken = healthPlaceholder - hero.health;
			totalDamageTaken += damageTaken;
			if(chance % 2 == 0){
				print_to_path("The wolf ran up to you and bit you for " + damageTaken + " Damage");
			}else{
				print_to_path("The wolf clawed you for " + damageTaken + " Damage");
			}
		}
		else {
			healthPlaceholder = wolf.health;
			if(hero.weapon == "Mace"){
			generalAttack(hero, wolf,1);
			}
			totalDamageDealt += (healthPlaceholder - wolf.health);
			print_to_path(hero.name+" has attacked the wolf! and dealt: " + (healthPlaceholder - wolf.health));
			print_to_path("wolfs health: "+wolf.health);
		}
		update_status();
		totalTurns += 1;
	}
	totalKills += 1;
}

function banditsAttack() {
var bandit = new Character();
		bandit.health = 40;
		bandit.attack = 10;
		bandit.defense = 5;
	while(bandit.health > 0 && hero.health > 0)
	{
		var chance = Math.floor((Math.random() * 100) + 1);
		if(chance < 30){
			print_to_path(hero.health);
			healthPlaceholder = hero.health;
			generalAttack(bandit, hero);
			damageTaken = healthPlaceholder - hero.health;
			totalDamageTaken += damageTaken;
			if(chance % 2 == 0){
				print_to_path("A clan of bandits knock you on the ground kicking you for " + damageTaken + " Damage");
			}else{
				print_to_path("A bandit snuck up from behind you and stabbed you dealing " + damageTaken + " Damage");
			}
		}
		else {
			healthPlaceholder = bandit.health;
			generalAttack(hero, bandit);
			totalDamageDealt += (healthPlaceholder - bandit.health);
			print_to_path(hero.name+" has attacked a bandit");
			print_to_path("bandit health: "+bandit.health);
		}
		update_status();
		totalTurns += 1;
	}
	totalKills += 1;
}
function trollsAttack() {
var troll = new Character();
		troll.health = 50;
		troll.attack = 25;
		troll.defense = 15;
	while(troll.health > 0 && hero.health > 0)
	{
		var chance = Math.floor((Math.random() * 100) + 1);
		if(chance < 35){
			print_to_path(hero.health);
			healthPlaceholder = hero.health;
			generalAttack(troll, hero);
			damageTaken = healthPlaceholder - hero.health;
			totalDamageTaken += damageTaken;
			if(chance % 2 == 0){
				print_to_path("a troll threw a small axe at you, hitting your chest dealing " + damageTaken + " Damage");
			}else{
				print_to_path("The Troll smashed you with his club for " + damageTaken + " Damage");
			}
		}
		else {
			healthPlaceholder = troll.health;
			generalAttack(hero, troll);
			totalDamageDealt += (healthPlaceholder - troll.health);
			print_to_path(hero.name+" has attacked the troll");
			print_to_path("troll health: "+troll.health);
		}
		update_status();
		totalTurns += 1;
	}
	totalKills += 1;
}

function golemsAttack() {
var golem = new Character();
		golem.health = 60;
		golem.attack = 10;
		golem.defense = 50;
	while(golem.health > 0 && hero.health > 0)
	{
		var chance = Math.floor((Math.random() * 100) + 1);
		if(chance < 20){
			print_to_path(hero.health);
			healthPlaceholder = hero.health;
			generalAttack(golem, hero);
			damageTaken = healthPlaceholder - hero.health;
			totalDamageTaken += damageTaken;
			if(chance % 2 == 0){
				print_to_path("Flails its arms smashing you into the ground. You took " + damageTaken + " Damage");
			}else{
				print_to_path("Stomps its foot on the ground causing rocks to fall on you from the nearby mountain. You took " + damageTaken + " Damage");
			}
		}
		else {
			healthPlaceholder = golem.health;
			generalAttack(hero, golem);
			totalDamageDealt += (healthPlaceholder - golem.health);
			print_to_path(hero.name+" has attacked the golem");
			print_to_path("golem health: "+golem.health);
		}
		update_status();
		totalTurns += 1;
	}
	totalKills += 1;
}

function dragonAttack() {
// atk 30
var dragon = new Character();
		dragon.health = 60;
		dragon.attack = 30;
		dragon.defense = 30;
	while(dragon.health > 0 && hero.health > 0)
	{
		var chance = Math.floor((Math.random() * 100) + 1);
		if(chance < 20){
			print_to_path(hero.health);
			healthPlaceholder = hero.health;
			generalAttack(dragon, hero);
			damageTaken = healthPlaceholder - hero.health;
			totalDamageTaken += damageTaken;
			if(chance % 2 == 0){
				print_to_path("Breaths green flames at you which inflicted a burn on you. You took " + damageTaken + " Damage");
			}else{
				print_to_path("Swipes its tail along the floor flinging you into the wall. You took " + damageTaken + " Damage");
			}
		}
		else {
			healthPlaceholder = dragon.health;
			generalAttack(hero, dragon);
			totalDamageDealt += (healthPlaceholder - dragon.health);
			print_to_path(hero.name+" has attacked the dragon!");
			print_to_path("dragon health: "+dragon.health);
		}
		update_status();
		totalTurns += 1;
	}
	totalKills += 1;
}

function blackSquirrelAttacks() {
	//I has no Tail D:
}

function statistics() {
	print_to_path("totalKills: " + totalKills);
	print_to_path("totalTurns: " + totalTurns);
	print_to_path("totalDamageDealt: " + totalDamageDealt);
	print_to_path("totalDamageTaken: " + totalDamageTaken);
}
<|endoftext|>


<commit_before>/**
 * Created by zzn on 2015-05-05.
 * Contains the MVC framework working for a PostItem
 *
 * Requires jQuery
 */

var PostItemMVC = (function ($, wx, zHelper) {
    "use strict";
    var CONST_SPREADSHEET_URL = "https://spreadsheets.google.com/feeds/list/1vzugrYLpgXmFODqysSx331Lhq8LpDQGJ4sQtwSMrtV4/1/public/values?alt=json";
    var CONST_FIELD_KEYS = {
        xq: "gsx$需求类别",
        qssj: "gsx$预计起始日期超过这个日期本条信息失效",
        qy: "gsx$区域",
        ybhzcs: "gsx$邮编或者城市",
        yqjg: "gsx$预期价格美元每月",
        grjs: "gsx$租房需求介绍和自我介绍",
        wxId: "gsx$微信号",
        xb: "gsx$性别",
        dhyx: "gsx$其他联系方式电话邮箱等",
        fbsj: "gsx$timestamp",
        ltst: "gsx$shorttermorlongterm",
        entryid: "gsx$entryid"
    };

    var CONST_FIELDS = [
        'xq', 'qssj', 'qy', 'ybhzcs', 'yqjg', 'grjs',
        'wxId', 'xb', 'dhyx', 'fbsj', 'ltst'
    ];

    var CONST_VALUE_ID_PREFIX = "#value_";
    var CONST_ITEM_TEMPLATE_ID = "#value_panel_template";
    var CONST_DOMAIN_NAME = "rent.zzn.im";
    /**
     * Class definition of Model
     * @constructor
     */
    var Model = function () {
        this.clearData(); // init with clear data
    };

    /**
     *
     * Creates a view as a clone of template
     * @constructor
     */
    var ItemView = function (guid) {
        this.guid_ = guid;
        this.templateClone_ = $(CONST_ITEM_TEMPLATE_ID).clone();
        this.guidLink_ = "http://" + CONST_DOMAIN_NAME + "/?" + $.param({"guid": guid});
    };

    var PanelView = function () {
        this.panelDom_ = $("#value_panel_parent");
    };

    /**
     * Class definition of Controller
     * @constructor
     */
    var Controller = function () {
        this.model_ = new Model();
        this.panelView_ = new PanelView();
    };

    // Set up cors proxy for jQuery
    $.ajaxPrefilter(function (options) {
        if (options.crossDomain && jQuery.support.cors) {
            var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
            options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
        }
    });

    Model.prototype.loadDataAsync = function (callback) {
        var that = this;
        $.get(CONST_SPREADSHEET_URL, function (data) {
            zHelper.log("loaded data from CORS proxy");
            that.cachedData_ = {}; //update data;
            data.feed.entry.forEach(function (row) {
                var guid = row[CONST_FIELD_KEYS.entryid]["$t"] || "N/A";
                var datum = {};
                CONST_FIELDS.forEach(function (fieldName) {
                    datum[fieldName] = row[CONST_FIELD_KEYS[fieldName]]["$t"] || "N/A";
                });
                that.cachedData_[guid] = datum;
                that.guidArray_.push(guid);
            });
            callback(data); // done
        });
    };

    Model.prototype.clearData = function () {
        this.cachedData_ = {};
        this.guidArray_ = [];
    };

    Model.prototype.getGuidArray = function () {
        return this.guidArray_;
    };

    Model.prototype.getFieldData = function (fieldName, guid) {
        return this.cachedData_[guid][fieldName];
    };

    /**
     * Add Guid Related Links
     * @param guid
     * @private
     */
    ItemView.prototype.decrorate_ = function () {
        var guid = this.guid_;
        var template = this.templateClone_;
        var guidLink = this.guidLink_;
        template.find("#qrcode").qrcode(guidLink);
        template.find("#row_link").attr("href", guidLink);
        template.find("#btn_share").attr("data-guid", guid);
        template.find("#btn_like").attr("data-guid", guid);
        template.show();
    };

    /**
     *
     * @param should boolean to indicate show(true) or hide(false)
     */
    ItemView.prototype.shouldShowContactInfo = function (should, model) {
        var that = this;
        var template = this.templateClone_;
        if (should) {
            template.find("#btn_show_wxId").hide();
            template.find("#btn_show_dhyx").hide();
        } else {
            template.find("#value_wxId").hide();
            template.find("#value_dhyx").hide();

            template.find("#value_wxId").hide();
            template.find("#btn_show_wxId").click(function () {
                template.find("#btn_show_wxId").hide();
                template.find("#value_wxId").show();
            });
            template.find("#btn_show_dhyx").click(function () {
                template.find("#btn_show_dhyx").hide();
                template.find("#value_dhyx").show();
            });

        }
    };

    ItemView.prototype.displayData = function (model) {
        var template = this.templateClone_;
        var guid = this.guid_;
        var xq = model.getFieldData("xq", guid);
        if (xq == "出租") {
            template.addClass("panel-success");
        } else if (xq == "求租") {
            template.addClass("panel-primary");
        } else if (xq == "找室友") {
            template.addClass("panel-warning");
        }
        CONST_FIELDS.forEach(function (fieldName) {
            template.find(CONST_VALUE_ID_PREFIX + fieldName).text(model.getFieldData(fieldName, guid));
        });

        // Set up Id of template
        template.attr("id", "value_panel" + guid);
        this.decrorate_();
    };
    ItemView.prototype.getDom = function () {
        return this.templateClone_;
    };

    ItemView.prototype.configureWeChat_ = function(model){
        zHelper.logAlert("clicked configure wechat!");
        var guidLink = this.guidLink_;
        var guid = this.guid_;
        var xq = model.getFieldData("xq", guid);
        var title, link, imgUrl, desc;
        if (xq == "出租") {
            imgUrl = "http://" + CONST_DOMAIN_NAME + "/img/logo-v1-green-1024sq2.jpg";
        } else if (xq == "求租") {
            imgUrl = "http://" + CONST_DOMAIN_NAME + "/img/logo-v1-blue-1024sq2.jpg";
        } else if (xq == "找室友") {
            imgUrl = "http://" + CONST_DOMAIN_NAME +"/img/logo-v1-yellow-1024sq2.jpg";
        }
        title = "湾区好室友 - " + model.getFieldData("qy", guid) + xq;
        link = guidLink;
        desc = "时间是" + model.getFieldData("qssj", guid) + "左右开始。\r\n"
            + "情况简介：" + model.getFieldData("grjs", guid);
        var wxData = {
            title: title,
            link: link,
            imgUrl: imgUrl,
            desc: desc,
            trigger: function (res) {
                zHelper.logAlert('用户点击发送给朋友');
            },
            success: function (ret) {
                zHelper.logAlert("shared!");
                zHelper.logAlert("ret=" + JSON.stringify(ret));
            },
            cancel: function (ret) {
                zHelper.logAlert("cancel share!");
                zHelper.logAlert("ret=" + JSON.stringify(ret));
            }
        };
        wx.onMenuShareAppMessage(wxData);
        wx.onMenuShareTimeline(wxData);

    };
    PanelView.prototype.addChild = function (item) {
        this.panelDom_.append(item);
    };

    PanelView.prototype.clearChildren = function () {
        this.panelDom_.empty();
    };

    Controller.prototype.initAsync = function (callback) {
        this.model_.loadDataAsync(callback);
    };

    Controller.prototype.showAllItems = function () {
        var that = this;
        this.panelView_.clearChildren();
        this.model_.getGuidArray().forEach(function (guid) {
            var item = new ItemView(guid);
            item.displayData(that.model_, guid);
            item.shouldShowContactInfo(false, that.model_);
            that.panelView_.addChild(item.getDom());

        });
    };

    /**
     *
     * @param guid The GUID of a given listing post
     */
    Controller.prototype.showItemByGuid = function (guid) {
        this.panelView_.clearChildren();
        var that = this;
        var item = new ItemView(guid);
        item.displayData(this.model_, guid);
        item.shouldShowContactInfo(true, this.model_);

        wx.ready(function(res){
            zHelper.log(res);
            wx.checkJsApi({
                jsApiList: [
                    "onMenuShareTimeline",
                    "onMenuShareAppMessage"
                ],
                success: function (res) {
                    zHelper.logAlert("wxCheckJsApi, success, configuring WeChat");
                    zHelper.log(JSON.stringify(res));
                    // TODO(zzn):
                    // uncomment update it here
                    item.configureWeChat_(that.model_);
                },
                fail: function (res) {
                    zHelper.logAlert("wxCheckJsApi, faile");
                    zHelper.log(JSON.stringify(res));
                }
            });

        });

        zHelper.log("XXX after setting wechat");
        this.panelView_.addChild(item.getDom());
    };

    return {
        Controller: Controller
    };
})($, wx, zHelper);<commit_msg>Update<commit_after>/**
 * Created by zzn on 2015-05-05.
 * Contains the MVC framework working for a PostItem
 *
 * Requires jQuery
 */

var PostItemMVC = (function ($, wx, zHelper) {
    "use strict";
    var CONST_SPREADSHEET_URL = "https://spreadsheets.google.com/feeds/list/1vzugrYLpgXmFODqysSx331Lhq8LpDQGJ4sQtwSMrtV4/1/public/values?alt=json";
    var CONST_FIELD_KEYS = {
        xq: "gsx$需求类别",
        qssj: "gsx$预计起始日期超过这个日期本条信息失效",
        qy: "gsx$区域",
        ybhzcs: "gsx$邮编或者城市",
        yqjg: "gsx$预期价格美元每月",
        grjs: "gsx$租房需求介绍和自我介绍",
        wxId: "gsx$微信号",
        xb: "gsx$性别",
        dhyx: "gsx$其他联系方式电话邮箱等",
        fbsj: "gsx$timestamp",
        ltst: "gsx$shorttermorlongterm",
        entryid: "gsx$entryid"
    };

    var CONST_FIELDS = [
        'xq', 'qssj', 'qy', 'ybhzcs', 'yqjg', 'grjs',
        'wxId', 'xb', 'dhyx', 'fbsj', 'ltst'
    ];

    var CONST_VALUE_ID_PREFIX = "#value_";
    var CONST_ITEM_TEMPLATE_ID = "#value_panel_template";
    var CONST_DOMAIN_NAME = "rent.zzn.im";
    /**
     * Class definition of Model
     * @constructor
     */
    var Model = function () {
        this.clearData(); // init with clear data
    };

    /**
     *
     * Creates a view as a clone of template
     * @constructor
     */
    var ItemView = function (guid) {
        this.guid_ = guid;
        this.templateClone_ = $(CONST_ITEM_TEMPLATE_ID).clone();
        this.guidLink_ = "http://" + CONST_DOMAIN_NAME + "/?" + $.param({"guid": guid});
    };

    var PanelView = function () {
        this.panelDom_ = $("#value_panel_parent");
    };

    /**
     * Class definition of Controller
     * @constructor
     */
    var Controller = function () {
        this.model_ = new Model();
        this.panelView_ = new PanelView();
    };

    // Set up cors proxy for jQuery
    $.ajaxPrefilter(function (options) {
        if (options.crossDomain && jQuery.support.cors) {
            var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
            options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
        }
    });

    Model.prototype.loadDataAsync = function (callback) {
        var that = this;
        $.get(CONST_SPREADSHEET_URL, function (data) {
            zHelper.log("loaded data from CORS proxy");
            that.cachedData_ = {}; //update data;
            data.feed.entry.forEach(function (row) {
                var guid = row[CONST_FIELD_KEYS.entryid]["$t"] || "N/A";
                var datum = {};
                CONST_FIELDS.forEach(function (fieldName) {
                    datum[fieldName] = row[CONST_FIELD_KEYS[fieldName]]["$t"] || "N/A";
                });
                that.cachedData_[guid] = datum;
                that.guidArray_.push(guid);
            });
            callback(data); // done
        });
    };

    Model.prototype.clearData = function () {
        this.cachedData_ = {};
        this.guidArray_ = [];
    };

    Model.prototype.getGuidArray = function () {
        return this.guidArray_;
    };

    Model.prototype.getFieldData = function (fieldName, guid) {
        return this.cachedData_[guid][fieldName];
    };

    /**
     * Add Guid Related Links
     * @param guid
     * @private
     */
    ItemView.prototype.decrorate_ = function () {
        var guid = this.guid_;
        var template = this.templateClone_;
        var guidLink = this.guidLink_;
        template.find("#qrcode").qrcode(guidLink);
        template.find("#row_link").attr("href", guidLink);
        template.find("#btn_share").attr("data-guid", guid);
        template.find("#btn_like").attr("data-guid", guid);
        template.show();
    };

    /**
     *
     * @param should boolean to indicate show(true) or hide(false)
     */
    ItemView.prototype.shouldShowContactInfo = function (should, model) {
        var that = this;
        var template = this.templateClone_;
        if (should) {
            template.find("#btn_show_wxId").hide();
            template.find("#btn_show_dhyx").hide();
        } else {
            template.find("#value_wxId").hide();
            template.find("#value_dhyx").hide();

            template.find("#value_wxId").hide();
            template.find("#btn_show_wxId").click(function () {
                template.find("#btn_show_wxId").hide();
                template.find("#value_wxId").show();
            });
            template.find("#btn_show_dhyx").click(function () {
                template.find("#btn_show_dhyx").hide();
                template.find("#value_dhyx").show();
            });

        }
    };

    ItemView.prototype.displayData = function (model) {
        var template = this.templateClone_;
        var guid = this.guid_;
        var xq = model.getFieldData("xq", guid);
        if (xq == "出租") {
            template.addClass("panel-success");
        } else if (xq == "求租") {
            template.addClass("panel-primary");
        } else if (xq == "找室友") {
            template.addClass("panel-warning");
        }
        CONST_FIELDS.forEach(function (fieldName) {
            template.find(CONST_VALUE_ID_PREFIX + fieldName).text(model.getFieldData(fieldName, guid));
        });

        // Set up Id of template
        template.attr("id", "value_panel" + guid);
        this.decrorate_();
    };
    ItemView.prototype.getDom = function () {
        return this.templateClone_;
    };

    ItemView.prototype.configureWeChat_ = function(model){
        zHelper.logAlert("clicked configure wechat!");
        var guidLink = this.guidLink_;
        var guid = this.guid_;
        var xq = model.getFieldData("xq", guid);
        var title, link, imgUrl, desc;
        if (xq == "出租") {
            imgUrl = "http://" + CONST_DOMAIN_NAME + "/img/logo-v1-green-1024sq2.jpg";
        } else if (xq == "求租") {
            imgUrl = "http://" + CONST_DOMAIN_NAME + "/img/logo-v1-blue-1024sq2.jpg";
        } else if (xq == "找室友") {
            imgUrl = "http://" + CONST_DOMAIN_NAME +"/img/logo-v1-yellow-1024sq2.jpg";
        }
        title = "湾区好室友 - " + model.getFieldData("qy", guid) + xq;
        link = guidLink;
        desc = model.getFieldData("qssj", guid) + "左右开始。\r\n"
            + "简介：" + model.getFieldData("grjs", guid);
        var wxData = {
            title: title,
            link: link,
            imgUrl: imgUrl,
            desc: desc,
            trigger: function (res) {
                zHelper.logAlert('用户点击发送给朋友');
            },
            success: function (ret) {
                zHelper.logAlert("shared!");
                zHelper.logAlert("ret=" + JSON.stringify(ret));
            },
            cancel: function (ret) {
                zHelper.logAlert("cancel share!");
                zHelper.logAlert("ret=" + JSON.stringify(ret));
            }
        };
        wx.onMenuShareAppMessage(wxData);
        wx.onMenuShareTimeline(wxData);

    };
    PanelView.prototype.addChild = function (item) {
        this.panelDom_.append(item);
    };

    PanelView.prototype.clearChildren = function () {
        this.panelDom_.empty();
    };

    Controller.prototype.initAsync = function (callback) {
        this.model_.loadDataAsync(callback);
    };

    Controller.prototype.showAllItems = function () {
        var that = this;
        this.panelView_.clearChildren();
        this.model_.getGuidArray().forEach(function (guid) {
            var item = new ItemView(guid);
            item.displayData(that.model_, guid);
            item.shouldShowContactInfo(false, that.model_);
            that.panelView_.addChild(item.getDom());

        });
    };

    /**
     *
     * @param guid The GUID of a given listing post
     */
    Controller.prototype.showItemByGuid = function (guid) {
        this.panelView_.clearChildren();
        var that = this;
        var item = new ItemView(guid);
        item.displayData(this.model_, guid);
        item.shouldShowContactInfo(true, this.model_);

        wx.ready(function(res){
            zHelper.log(res);
            wx.checkJsApi({
                jsApiList: [
                    "onMenuShareTimeline",
                    "onMenuShareAppMessage"
                ],
                success: function (res) {
                    zHelper.logAlert("wxCheckJsApi, success, configuring WeChat");
                    zHelper.log(JSON.stringify(res));
                    // TODO(zzn):
                    // uncomment update it here
                    item.configureWeChat_(that.model_);
                },
                fail: function (res) {
                    zHelper.logAlert("wxCheckJsApi, faile");
                    zHelper.log(JSON.stringify(res));
                }
            });

        });

        zHelper.log("XXX after setting wechat");
        this.panelView_.addChild(item.getDom());
    };

    return {
        Controller: Controller
    };
})($, wx, zHelper);<|endoftext|>


<commit_before>/*

This file contains all of the code needed to create four JSONs corresponding
to four distinct sections in index.html: work, education, projects and a
header with biographical information.

In addition, this file also uses code from helper.js to render index.html
correctly.

 */

/* JSON object containing biographical info */
var bio = {
    "name": "Vishal Lama",
    "role": "Web Developer",
    "contacts": {
        "mobile": "123-456-7890",
        "email": "contact@vishallama.org",
        "github": "vishallama",
        "twitter": "@vishallama",
        "location": "Cedar City, UT"
    },
    "welcomeMessage": "Welcome!",
    "skills": [
        "Python",
        "JavaScript",
        "SML(NJ)",
        "Scala",
        "HTML/CSS",
        "Bootstrap",
        "Linux"
    ],
    "biopic": "images/vishal.png",
    "display": function() {
        var formattedName = HTMLheaderName.replace("%data%", bio.name);
        var formattedRole = HTMLheaderRole.replace("%data%", bio.role);

        var formattedMobile = HTMLmobile.replace("%data%", bio.contacts.mobile);
        var formattedEmail= HTMLemail.replace("%data%", bio.contacts.email);
        var formattedTwitter= HTMLtwitter.replace("%data%", bio.contacts.twitter);
        var formattedGithub = HTMLgithub.replace("%data%", bio.contacts.github);
        var formattedLocation = HTMLlocation.replace("%data%", bio.contacts.location);

        var formattedBioPic = HTMLbioPic.replace("%data%", bio.biopic);
        var formattedWelcomeMessage = HTMLwelcomeMsg.replace("%data%", bio.welcomeMessage);

        var contactItems = [
            formattedMobile,
            formattedEmail,
            formattedTwitter,
            formattedGithub,
            formattedLocation
        ];

        $("#header").prepend(formattedName, formattedRole);

        $("#topContacts").prepend(contactItems);
        $("#footerContacts").prepend(contactItems);

        $("#header").append(formattedBioPic, formattedWelcomeMessage);

        $("#header").append(HTMLskillsStart);

        bio.skills.forEach(function (skill) {
            var formattedSkill = HTMLskills.replace("%data%", skill);
            $("#skills").append(formattedSkill);
        });
    }
};

/* JSON object containing work info */
var work = {
    "jobs": [
        {
            "employer": "Cedar City Yogurt LLC",
            "title": "Co-owner",
            "location": "Cedar City, UT",
            "dates": "2014 - 2015",
            "description": "Ran and managed a family-owned frozen yogurt store."
        },
        {
            "employer": "Arabic and Indian Foods LLC",
            "title": "Co-owner",
            "location": "Cedar City, UT",
            "dates": "2012 - 2015",
            "description": "Ran and managed a grocery store."
        },
        {
            "employer": "Southern Utah University",
            "title": "Tutor, Grader and TA",
            "location": "Cedar City, UT",
            "dates": "2006- 2011",
            "description": "Tutored, graded HW and performed TA-related tasks " +
            "for a variety of math and computer science courses, including " +
            "calculus, probability and statistics, linear algebra, college " +
            "algebra, introductory logic, and introductory java programming."
        }
    ],
    "display": function(){
        work.jobs.forEach(function(workEntry) {
            var formattedWorkEmployer = HTMLworkEmployer.
                replace("%data%", workEntry.employer);
            var formattedWorkTitle = HTMLworkTitle.
                replace("%data%", workEntry.title);
            var formattedWorkLocation = HTMLworkLocation.
                replace("%data%", workEntry.location);
            var formattedWorkDates = HTMLworkDates.
                replace("%data%", workEntry.dates);
            var formattedWorkDescription = HTMLworkDescription.
                replace("%data%", workEntry.description);

            $("#workExperience").
                append(
                HTMLworkStart,
                formattedWorkEmployer,
                formattedWorkTitle,
                formattedWorkLocation,
                formattedWorkDates,
                formattedWorkDescription
            );
        });
    }
};

/* JSON object containing info on projects */
var projects = {
    "projects": [
        {
            "title": "Udacity Front-End Web Developer Nanodegree - Portfolio Site",
            "dates": "2015",
            "description": "One-page fully-responsive website to display a portfolio of " +
            "projects. Written using HTML, CSS, jQuery, and Bootstrap.",
            "images": [
                "images/udacity-frontend-portfolio-img01-600x300small.png",
                "images/udacity-frontend-portfolio-img02-600x300small.png"
            ]
        },
        {
            "title": "Udacity Front-End Web Developer Nanodegree - Online Resume",
            "dates": "2015",
            "description": "One-page responsive website for displaying an interactive " +
            "online resume. Written using HTML, CSS, JavaScript, and jQuery.",
            "images": [
                "images/",
                "images/"
            ]
        },
        {
            "title": "Udacity Full Stack Web Developer Nanodegree - Movie Trailer Website",
            "dates": "2015",
            "description": "One-page responsive website for displaying movie trailers. " +
            "Written using HTML, CSS, jQuery, and Bootstrap.",
            "images": [
                "images/udacity-fullstack-movie-trailer-img01-600x300small.png",
                "images/udacity-fullstack-movie-trailer-img04-600x300small.png"
            ]
        }
    ],
    "display": function(){
        projects.projects.forEach(function(project) {
            var formattedProjectTitle = HTMLprojectTitle.
                replace("%data%", project.title);
            var formattedProjectDates = HTMLprojectDates.
                replace("%data%", project.dates);
            var formattedProjectDescription = HTMLprojectDescription.
                replace("%data%", project.description);

            $("#projects").append(
                HTMLprojectStart,
                formattedProjectTitle,
                formattedProjectDates,
                formattedProjectDescription
            );

            project.images.forEach(function (imageUrl) {
                var formattedProjectImage = HTMLprojectImage.
                    replace("%data%", imageUrl);
                $("#projects").append(formattedProjectImage);
            });

        });
    }
};

/* JSON object containing education info */
var education = {
    "schools": [
        {
            "name": "Southern Utah University",
            "location": "Cedar City, UT",
            "degree": "BS",
            "majors": ["Math (Pure)"],
            "dates": 2011,
            "url": ""
        }
    ],
    "onlineCourses": [
        {
            "title": "Intro to HTML and CSS",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/intro-to-html-and-css--ud304"
        },
        {
            "title": "Responsive Web Design Fundamentals",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/responsive-web-design-fundamentals--ud893"
        },
        {
            "title": "Responsive Images",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/responsive-images--ud882"
        },
        {
            "title": "JavaScript Basics",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/javascript-basics--ud804"
        },
        {
            "title": "Linux Command Line Basics",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/linux-command-line-basics--ud595"
        },
        {
            "title": "How to Use Git and GitHub",
            "school": "Udacity",
            "date": 2015,
            "url":"https://www.udacity.com/course/how-to-use-git-and-github--ud775"
        },
        {
            "title": "Programming Foundations with Python",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/programming-foundations-with-python--ud036"
        },
        {
            "title": "Intro to Relational Databases",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/intro-to-relational-databases--ud197"
        },
        {
            "title": "Intro to DevOps",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/intro-to-devops--ud611"
        },
        {
            "title": "Configuring Linux Web Servers",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/configuring-linux-web-servers--ud299"
        }
    ],
    "display": function () {
    }
};

/*
Execute display() from each object to render index.html correctly
 */

/* Bio */
bio.display();

/* Work */
work.display();

/* Projects */
projects.display();

<commit_msg>Add a couple of image urls<commit_after>/*

This file contains all of the code needed to create four JSONs corresponding
to four distinct sections in index.html: work, education, projects and a
header with biographical information.

In addition, this file also uses code from helper.js to render index.html
correctly.

 */

/* JSON object containing biographical info */
var bio = {
    "name": "Vishal Lama",
    "role": "Web Developer",
    "contacts": {
        "mobile": "123-456-7890",
        "email": "contact@vishallama.org",
        "github": "vishallama",
        "twitter": "@vishallama",
        "location": "Cedar City, UT"
    },
    "welcomeMessage": "Welcome!",
    "skills": [
        "Python",
        "JavaScript",
        "SML(NJ)",
        "Scala",
        "HTML/CSS",
        "Bootstrap",
        "Linux"
    ],
    "biopic": "images/vishal.png",
    "display": function() {
        var formattedName = HTMLheaderName.replace("%data%", bio.name);
        var formattedRole = HTMLheaderRole.replace("%data%", bio.role);

        var formattedMobile = HTMLmobile.replace("%data%", bio.contacts.mobile);
        var formattedEmail= HTMLemail.replace("%data%", bio.contacts.email);
        var formattedTwitter= HTMLtwitter.replace("%data%", bio.contacts.twitter);
        var formattedGithub = HTMLgithub.replace("%data%", bio.contacts.github);
        var formattedLocation = HTMLlocation.replace("%data%", bio.contacts.location);

        var formattedBioPic = HTMLbioPic.replace("%data%", bio.biopic);
        var formattedWelcomeMessage = HTMLwelcomeMsg.replace("%data%", bio.welcomeMessage);

        var contactItems = [
            formattedMobile,
            formattedEmail,
            formattedTwitter,
            formattedGithub,
            formattedLocation
        ];

        $("#header").prepend(formattedName, formattedRole);

        $("#topContacts").prepend(contactItems);
        $("#footerContacts").prepend(contactItems);

        $("#header").append(formattedBioPic, formattedWelcomeMessage);

        $("#header").append(HTMLskillsStart);

        bio.skills.forEach(function (skill) {
            var formattedSkill = HTMLskills.replace("%data%", skill);
            $("#skills").append(formattedSkill);
        });
    }
};

/* JSON object containing work info */
var work = {
    "jobs": [
        {
            "employer": "Cedar City Yogurt LLC",
            "title": "Co-owner",
            "location": "Cedar City, UT",
            "dates": "2014 - 2015",
            "description": "Ran and managed a family-owned frozen yogurt store."
        },
        {
            "employer": "Arabic and Indian Foods LLC",
            "title": "Co-owner",
            "location": "Cedar City, UT",
            "dates": "2012 - 2015",
            "description": "Ran and managed a grocery store."
        },
        {
            "employer": "Southern Utah University",
            "title": "Tutor, Grader and TA",
            "location": "Cedar City, UT",
            "dates": "2006- 2011",
            "description": "Tutored, graded HW and performed TA-related tasks " +
            "for a variety of math and computer science courses, including " +
            "calculus, probability and statistics, linear algebra, college " +
            "algebra, introductory logic, and introductory java programming."
        }
    ],
    "display": function(){
        work.jobs.forEach(function(workEntry) {
            var formattedWorkEmployer = HTMLworkEmployer.
                replace("%data%", workEntry.employer);
            var formattedWorkTitle = HTMLworkTitle.
                replace("%data%", workEntry.title);
            var formattedWorkLocation = HTMLworkLocation.
                replace("%data%", workEntry.location);
            var formattedWorkDates = HTMLworkDates.
                replace("%data%", workEntry.dates);
            var formattedWorkDescription = HTMLworkDescription.
                replace("%data%", workEntry.description);

            $("#workExperience").
                append(
                HTMLworkStart,
                formattedWorkEmployer,
                formattedWorkTitle,
                formattedWorkLocation,
                formattedWorkDates,
                formattedWorkDescription
            );
        });
    }
};

/* JSON object containing info on projects */
var projects = {
    "projects": [
        {
            "title": "Udacity Front-End Web Developer Nanodegree - Portfolio Site",
            "dates": "2015",
            "description": "One-page fully-responsive website to display a portfolio of " +
            "projects. Written using HTML, CSS, jQuery, and Bootstrap.",
            "images": [
                "images/udacity-frontend-portfolio-img01-600x300small.png",
                "images/udacity-frontend-portfolio-img02-600x300small.png"
            ]
        },
        {
            "title": "Udacity Front-End Web Developer Nanodegree - Online Resume",
            "dates": "2015",
            "description": "One-page responsive website for displaying an interactive " +
            "online resume. Written using HTML, CSS, JavaScript, and jQuery.",
            "images": [
                "images/udacity-fullstack-movie-trailer-img02-600x300small.png",
                "images/udacity-fullstack-movie-trailer-img03-600x300small.png"
            ]
        },
        {
            "title": "Udacity Full Stack Web Developer Nanodegree - Movie Trailer Website",
            "dates": "2015",
            "description": "One-page responsive website for displaying movie trailers. " +
            "Written using HTML, CSS, jQuery, and Bootstrap.",
            "images": [
                "images/udacity-fullstack-movie-trailer-img01-600x300small.png",
                "images/udacity-fullstack-movie-trailer-img04-600x300small.png"
            ]
        }
    ],
    "display": function(){
        projects.projects.forEach(function(project) {
            var formattedProjectTitle = HTMLprojectTitle.
                replace("%data%", project.title);
            var formattedProjectDates = HTMLprojectDates.
                replace("%data%", project.dates);
            var formattedProjectDescription = HTMLprojectDescription.
                replace("%data%", project.description);

            $("#projects").append(
                HTMLprojectStart,
                formattedProjectTitle,
                formattedProjectDates,
                formattedProjectDescription
            );

            project.images.forEach(function (imageUrl) {
                var formattedProjectImage = HTMLprojectImage.
                    replace("%data%", imageUrl);
                $("#projects").append(formattedProjectImage);
            });

        });
    }
};

/* JSON object containing education info */
var education = {
    "schools": [
        {
            "name": "Southern Utah University",
            "location": "Cedar City, UT",
            "degree": "BS",
            "majors": ["Math (Pure)"],
            "dates": 2011,
            "url": ""
        }
    ],
    "onlineCourses": [
        {
            "title": "Intro to HTML and CSS",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/intro-to-html-and-css--ud304"
        },
        {
            "title": "Responsive Web Design Fundamentals",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/responsive-web-design-fundamentals--ud893"
        },
        {
            "title": "Responsive Images",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/responsive-images--ud882"
        },
        {
            "title": "JavaScript Basics",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/javascript-basics--ud804"
        },
        {
            "title": "Linux Command Line Basics",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/linux-command-line-basics--ud595"
        },
        {
            "title": "How to Use Git and GitHub",
            "school": "Udacity",
            "date": 2015,
            "url":"https://www.udacity.com/course/how-to-use-git-and-github--ud775"
        },
        {
            "title": "Programming Foundations with Python",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/programming-foundations-with-python--ud036"
        },
        {
            "title": "Intro to Relational Databases",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/intro-to-relational-databases--ud197"
        },
        {
            "title": "Intro to DevOps",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/intro-to-devops--ud611"
        },
        {
            "title": "Configuring Linux Web Servers",
            "school": "Udacity",
            "date": 2015,
            "url": "https://www.udacity.com/course/configuring-linux-web-servers--ud299"
        }
    ],
    "display": function () {
    }
};

/*
Execute display() from each object to render index.html correctly
 */

/* Bio */
bio.display();

/* Work */
work.display();

/* Projects */
projects.display();

<|endoftext|>


<commit_before>game.TitleScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('title-screen')), -10); // TODO

		me.input.bindKey(me.input.KEY.ENTER, "start");
		me.audio.playTrack("Awesomenauts-partyTune");

		me.game.world.addChild(new (me.Renderable.extend({
			init: function() {
				this._super(me.Renderable, 'init', [510, 30, me.game.viewport.width, me.game.viewport.height]);
				/*the settings of the text*/
				this.font = new me.Font("Arial", 60, "gold");
			},

			/*Adds the text and sets the coordinates of the text*/
			draw: function(renderer) {
				this.font.draw(renderer.getContext(), "AWESOMENAUTS", 290, 40);
				this.font.draw(renderer.getContext(), "Press ENTER to play", 280, 500);
			}
		})));

		this.handler = me.event.subscribe(me.event.KEYDOWN, function(action, keyCode, edge) {
			if(action === "start"){
				me.state.change(me.state.PLAY);
			}
		});
	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		me.input.unbindKey(me.input.KEY.ENTER); // TODO
		me.event.unsubscribe(this.handler);
		me.audio.stopTrack();
	}
});
<commit_msg>completed video 39<commit_after>game.TitleScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('title-screen')), -10); // TODO

		me.audio.playTrack("Awesomenauts-partyTune");

		me.game.world.addChild(new (me.Renderable.extend({
			init: function() {
				this._super(me.Renderable, 'init', [270, 240, 300, 50]);
				/*the settings of the text*/
				this.font = new me.Font("Arial", 60, "gold");
				me.input.registerPointerEvent('pointerdown', this, this.newGame.bind(this), true);
			},

			/*Adds the text and sets the coordinates of the text*/
			draw: function(renderer) {
				this.font.draw(renderer.getContext(), "START A NEW GAME", this.pos.x, this.pos.y);
			},

			update: function(dt) {
				return true;
			},

			newGame: function() {
				me.input.releasePointerEvent('pointerdown', this);
				me.save.remove('exp');
				me.save.remove('exp1');
				me.save.remove('exp2');
				me.save.remove('exp3');
				me.save.remove('exp4');
				me.state.change(me.state.PLAY);
			}
		})));
	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		me.audio.stopTrack();
	}
});
<|endoftext|>


<commit_before>game.TitleScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('title-screen')), -10); // TODO
	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		; // TODO
	}
});
<commit_msg>done with video 27 making the screen appear<commit_after>game.TitleScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('title-screen')), -10); // TODO

                me.input.bindKey(me.input.KEY.ENTER, "start");

                me.game.world.addChild(me.Renderable.extend({
                    init: function(){
                        this._super(me.Renderable, 'init', [510, 30, me.game.viewport.width, me.game.viewport.height])
                        this.font = new me.Font("Arial", 46, "white");
                    },

                    draw: function(renderer){
                        this.font.draw(renderer.getContext(), "Awesomenauts!", 450, 130);
                        this.font.draw(renderer.getContext(), "Press ENTER to play!", 250, 530);
                    }
                }));

                this.handler = me.event.subscribe(me.event.KEYDOWN, function (action, keyCode, edge){
                   if(action === "start"){
                       me.state.change(me.state.PLAY);
                   }
                });

        },

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		me.input.unbindKey(me.input.KEY.ENTER); // TODO
                me.event.unsubscribe(this.handler);
	}
});
<|endoftext|>


<commit_before>game.TitleScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('title-screen')), -10); // TODO

		me.game.world.addChild(new (me.Renderable.extend({
			init: function(){
				this._super(me.Renderable, 'init', [270, 240, 300,50]);
				this.font = new me.Font("Ariel", 46, "white");
				me.input.registerPointerEvent('pointerdown', this, this.newGame.bind(this), true);
			},

			draw: function(render){
				this.font.draw(render.getContext(), "START A NEW GAME", this.pos.x, this.pos.y);
			},

			update: function(dt){
				return true;
			},

			newGame: function(){
				me.input.releasePointerEvent('pointerdown', this);
				me.save.remove('exp');
				me.save.remove('exp1');
				me.save.remove('exp2');
				me.save.remove('exp3');
				me.save.remove('exp4');
				me.state.change(me.state.PLAY);
			}
		})));

	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {

	}
});
<commit_msg>finished video 40 all done<commit_after>game.TitleScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('title-screen')), -10); // TODO

		me.game.world.addChild(new (me.Renderable.extend({
			init: function(){
				this._super(me.Renderable, 'init', [270, 240, 300,50]);
				this.font = new me.Font("Ariel", 46, "white");
				me.input.registerPointerEvent('pointerdown', this, this.newGame.bind(this), true);
			},

			draw: function(render){
				this.font.draw(render.getContext(), "START A NEW GAME", this.pos.x, this.pos.y);
			},

			update: function(dt){
				return true;
			},

			newGame: function(){
				me.input.releasePointerEvent('pointerdown', this);
				me.save.remove('exp');
				me.save.remove('exp1');
				me.save.remove('exp2');
				me.save.remove('exp3');
				me.save.remove('exp4');
				me.state.change(me.state.PLAY);
			}
		})));

		me.game.world.addChild(new (me.Renderable.extend({
			init: function(){
				this._super(me.Renderable, 'init', [380, 340, 280,50]);
				this.font = new me.Font("Ariel", 46, "white");
				me.input.registerPointerEvent('pointerdown', this, this.newGame.bind(this), true);
			},

			draw: function(render){
				this.font.draw(render.getContext(), "CONTINUE", this.pos.x, this.pos.y);
			},

			update: function(dt){
				return true;
			},

			newGame: function(){
				me.input.releasePointerEvent('pointerdown', this);
				me.state.change(me.state.PLAY);
			}
		})));

	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {

	}
});
<|endoftext|>


<commit_before>var Sheets2sqlite = function(db, workbookId, tablesToProcess) {
    this.db = db;
    this.tablesToProcess = tablesToProcess;
    this.tables = [];
    this.control = {
        reqs: 0,
        reqOk: false,
        resps: 0,

        ok: function() {
            return (this.reqOk && (this.reqs == this.resps));
        },

        reset: function() {
            this.reqs = 0;
            this.resps = 0;
            this.reqOk = false;
        }
    };

    this.url = '//spreadsheets.google.com/feeds/worksheets/' + workbookId + '/public/values?alt=json';
};

Sheets2sqlite.prototype.start = function(done) {
    this.done = done;
    var that = this;

    $.ajax({
        url: this.url
    }).done(function(workbookData) {
        for(var i=0; i<workbookData.feed.entry.length; i++) {
            var entry = workbookData.feed.entry[i];
            var item = { name : entry.title.$t, link : entry.link[1].href.replace('https:', '') + '?alt=json' };

            that.control.reqs++;
            (function(name, link) {
                $.ajax({
                    url: link
                }).done(function(worksheetData) {
                    that.processWorksheetData(name, worksheetData);
                });
            }) (item.name, item.link);
        }
        that.control.reqOk = true;
    });
};

Sheets2sqlite.prototype.processWorksheetData = function(tableName, worksheetData) {
    this.control.resps++;
    if($.inArray(tableName, this.tablesToProcess) >= 0) {
        var table = this.createTable(tableName, worksheetData);
        this.insertData(table, worksheetData);
        this.tables.push(table);
    }

    if(this.control.ok()) {
        this.loadData(this.tables);
        this.done();
        this.control.reset();
    }
};

Sheets2sqlite.prototype.createTable = function(tableName, worksheetData) {
    var columns = [];
    var table = {
        name: tableName,
        fkCount: false,
        validColumns: [],
        regularIndexes: [],
        uniqueIndexes: [],
        createSQL: function() {
            var sSQL = 'CREATE TABLE ' + this.name + ' (';
            for(var i=0; i<this.columns.length; i++) {
                var column = this.columns[i];
                sSQL += column.name + ' ' + column.type;
                if(column.name == 'id') sSQL += ' primary key';
                if(i+1 != this.columns.length || this.fkCount > 0) {
                    sSQL += ', ';
                }
            }

            var tempFkCount = 0;
            if(this.fkCount > 0) {
                for(var i=0; i<this.columns.length; i++) {
                    var column = this.columns[i];
                    if(column.fk !== '') {
                        tempFkCount++;
                        sSQL += 'FOREIGN KEY(' + column.name + ') REFERENCES ' + column.fk;
                        if(tempFkCount != this.fkCount) {
                            sSQL += ', ';
                        } else {
                            break;
                        }
                    }
                }
            }

            sSQL += ');';

            for(var i=0; i<this.regularIndexes.length; i++) {
                var index = this.regularIndexes[i];
                sSQL += this.indexSQL(index, false);
            }

            for(var i=0; i<this.uniqueIndexes.length; i++) {
                var index = this.uniqueIndexes[i];
                sSQL += this.indexSQL(index, true);
            }

            return sSQL;
        },
        indexSQL: function(index, unique) {
            var temp = 'CREATE ' + (unique ? 'UNIQUE ' : '') + 'INDEX IF NOT EXISTS ';
            temp += index.name;
            temp += ' ON ';
            temp += this.name;

            var indexNames = [];
            for(var i=0; i<index.columns.length; i++) {
                indexNames.push(index.columns[i].name);
            }

            temp += ' (' + indexNames.join(', ') + ');';

            return temp;
        },
        insertSQL: function() {
            var sSQL = '';
            for(var j=0; j<this.rows.length; j++) {
                var row = this.rows[j];
                var sSQLData = '';

                sSQL += 'INSERT INTO ' + this.name + '(';
                for(var i=0; i<this.columns.length; i++) {
                    var col = this.columns[i];
                    sSQL += col.name;

                    var value = escape(row.cells[i]);
                    if(value === '') {
                        sSQLData += 'NULL';
                    } else if(col.type.toLowerCase() == 'text') {
                        sSQLData += '\'' + value + '\'';
                    } else {
                        sSQLData += value;
                    }

                    if(i+1 != this.columns.length) {
                        sSQL += ', ';
                        sSQLData += ', ';
                    }
                }
                sSQL += ') VALUES (' + sSQLData + ');';
            }

            return sSQL;
        },
        getRegularIndex: function(indexName) {
            return this.getIndex(this.regularIndexes, indexName);
        },
        getUniqueIndex: function(indexName) {
            return this.getIndex(this.uniqueIndexes, indexName);
        },
        getIndex: function(indexes, indexName) {
            for(var i=0; i<indexes; i++) {
                var index = indexes[i];
                if(index.name == indexName) {
                    return index;
                }
            }
            return null;
        }
    };

    for(var i=0; i<worksheetData.feed.entry.length; i++) {
        var item = worksheetData.feed.entry[i];

        if(item.gs$cell.row == '1') {
            var pos = parseInt(item.gs$cell.col, 10) - 1;
            var value = item.gs$cell.$t;
            var name = value.substring(0, value.indexOf('(')).trim();
            var type = value.substring(value.indexOf('(') + 1, value.indexOf(')')).trim();

            var column = {
                pos: pos,
                name: name,
                type: type,
                fk: ''
            };

            columns.push(column);
            table.validColumns.push(pos);
        } else if(item.gs$cell.row == '2') {
            var pos = parseInt(item.gs$cell.col, 10) - 1;
            var column = columns[table.validColumns.indexOf(pos)];
            var value = item.gs$cell.$t;

            if(value !== '') {
                var indexes = value.split(',');
                for(var j=0; j<indexes.length; j++) {
                    var index = indexes[j].trim();
                    if(index.toLowerCase().indexOf('fk_') >= 0) {
                        table.fkCount++;
                        //column.fk = index.substring(3, index.length);
                        column.fk = index.substring(index.indexOf('(') + 1, index.indexOf(')')).replace('.', '(') + ')';
                    } else if(index.toLowerCase().indexOf('in_') >= 0) {
                        var regularIndex = table.getRegularIndex(index.toLowerCase());

                        if(regularIndex === null) {
                            regularIndex = {
                                name: index.toLowerCase(),
                                columns: []
                            };

                            table.regularIndexes.push(regularIndex);
                        }

                        regularIndex.columns.push(column);
                    } else if(index.toLowerCase().indexOf('un_') >= 0) {
                        var uniqueIndex = table.getUniqueIndex(index.toLowerCase());

                        if(uniqueIndex === null) {
                            uniqueIndex = {
                                name: index.toLowerCase(),
                                columns: []
                            };

                            table.uniqueIndexes.push(uniqueIndex);
                        }

                        uniqueIndex.columns.push(column);
                    }
                }
            }
        } else {
            break;
        }
    }

    table.columns = columns;

    return table;
};

Sheets2sqlite.prototype.insertData = function(table, worksheetData) {
    var rows = [];

    var linhaInicial = 3;

    for(var i=0; i<worksheetData.feed.entry.length; i++) {
        var item = worksheetData.feed.entry[i];
        var col = parseInt(item.gs$cell.col, 10) - 1;
        var row = parseInt(item.gs$cell.row, 10) - linhaInicial;

        if(row < 0) {
            continue;
        }

        if(col === 0) {
            rows.push({
                row: row,
                cells: []
            });
        }

        if(table.validColumns.indexOf(col) >= 0) {
            var line = rows[row];
            line.cells.push(item.gs$cell.$t);
        }
    }

    table.rows = rows;
};

Sheets2sqlite.prototype.loadData = function(tables) {
    for(var i=0; i<tables.length; i++) {
        var table = tables[i];

        console.log('createSQL:', table.createSQL());
        console.log('insertSQL:', table.insertSQL());

        this.db.exec(table.createSQL());
        this.db.exec(table.insertSQL());
    }
};

var escape = function(text) {
    if(text === '' || typeof text == 'undefined') {
        return '';
    }

    var temp = text.replace('\'', '\'\'');
    temp = temp.replace('"', '""');
    return temp;
};

var tableCreate = function () {
    function valconcat(vals, tagName) {
        if (vals.length === 0) return '';
        var open = '<'+tagName+'>', close='</'+tagName+'>';
        return open + vals.join(close + open) + close;
    }

    return function (columns, values) {
        var tbl  = document.createElement('table');
        var html = '
' + valconcat(columns, 'th') + '
';
        var rows = values.map(function(v){ return valconcat(v, 'td'); });
        html += '
' + valconcat(rows, 'tr') + '
';
        tbl.innerHTML = html;
        return tbl;
    };
};<commit_msg>escape fix<commit_after>var Sheets2sqlite = function(db, workbookId, tablesToProcess) {
    this.db = db;
    this.tablesToProcess = tablesToProcess;
    this.tables = [];
    this.control = {
        reqs: 0,
        reqOk: false,
        resps: 0,

        ok: function() {
            return (this.reqOk && (this.reqs == this.resps));
        },

        reset: function() {
            this.reqs = 0;
            this.resps = 0;
            this.reqOk = false;
        }
    };

    this.url = '//spreadsheets.google.com/feeds/worksheets/' + workbookId + '/public/values?alt=json';
};

Sheets2sqlite.prototype.start = function(done) {
    this.done = done;
    var that = this;

    $.ajax({
        url: this.url
    }).done(function(workbookData) {
        for(var i=0; i<workbookData.feed.entry.length; i++) {
            var entry = workbookData.feed.entry[i];
            var item = { name : entry.title.$t, link : entry.link[1].href.replace('https:', '') + '?alt=json' };

            that.control.reqs++;
            (function(name, link) {
                $.ajax({
                    url: link
                }).done(function(worksheetData) {
                    that.processWorksheetData(name, worksheetData);
                });
            }) (item.name, item.link);
        }
        that.control.reqOk = true;
    });
};

Sheets2sqlite.prototype.processWorksheetData = function(tableName, worksheetData) {
    this.control.resps++;
    if($.inArray(tableName, this.tablesToProcess) >= 0) {
        var table = this.createTable(tableName, worksheetData);
        this.insertData(table, worksheetData);
        this.tables.push(table);
    }

    if(this.control.ok()) {
        this.loadData(this.tables);
        this.done();
        this.control.reset();
    }
};

Sheets2sqlite.prototype.createTable = function(tableName, worksheetData) {
    var columns = [];
    var table = {
        name: tableName,
        fkCount: false,
        validColumns: [],
        regularIndexes: [],
        uniqueIndexes: [],
        createSQL: function() {
            var sSQL = 'CREATE TABLE ' + this.name + ' (';
            for(var i=0; i<this.columns.length; i++) {
                var column = this.columns[i];
                sSQL += column.name + ' ' + column.type;
                if(column.name == 'id') sSQL += ' primary key';
                if(i+1 != this.columns.length || this.fkCount > 0) {
                    sSQL += ', ';
                }
            }

            var tempFkCount = 0;
            if(this.fkCount > 0) {
                for(var i=0; i<this.columns.length; i++) {
                    var column = this.columns[i];
                    if(column.fk !== '') {
                        tempFkCount++;
                        sSQL += 'FOREIGN KEY(' + column.name + ') REFERENCES ' + column.fk;
                        if(tempFkCount != this.fkCount) {
                            sSQL += ', ';
                        } else {
                            break;
                        }
                    }
                }
            }

            sSQL += ');';

            for(var i=0; i<this.regularIndexes.length; i++) {
                var index = this.regularIndexes[i];
                sSQL += this.indexSQL(index, false);
            }

            for(var i=0; i<this.uniqueIndexes.length; i++) {
                var index = this.uniqueIndexes[i];
                sSQL += this.indexSQL(index, true);
            }

            return sSQL;
        },
        indexSQL: function(index, unique) {
            var temp = 'CREATE ' + (unique ? 'UNIQUE ' : '') + 'INDEX IF NOT EXISTS ';
            temp += index.name;
            temp += ' ON ';
            temp += this.name;

            var indexNames = [];
            for(var i=0; i<index.columns.length; i++) {
                indexNames.push(index.columns[i].name);
            }

            temp += ' (' + indexNames.join(', ') + ');';

            return temp;
        },
        insertSQL: function() {
            var sSQL = '';
            for(var j=0; j<this.rows.length; j++) {
                var row = this.rows[j];
                var sSQLData = '';

                sSQL += 'INSERT INTO ' + this.name + '(';
                for(var i=0; i<this.columns.length; i++) {
                    var col = this.columns[i];
                    sSQL += col.name;

                    var value = escape(row.cells[i]);
                    if(value === '') {
                        sSQLData += 'NULL';
                    } else if(col.type.toLowerCase() == 'text') {
                        sSQLData += '\'' + value + '\'';
                    } else {
                        sSQLData += value;
                    }

                    if(i+1 != this.columns.length) {
                        sSQL += ', ';
                        sSQLData += ', ';
                    }
                }
                sSQL += ') VALUES (' + sSQLData + ');';
            }

            return sSQL;
        },
        getRegularIndex: function(indexName) {
            return this.getIndex(this.regularIndexes, indexName);
        },
        getUniqueIndex: function(indexName) {
            return this.getIndex(this.uniqueIndexes, indexName);
        },
        getIndex: function(indexes, indexName) {
            for(var i=0; i<indexes; i++) {
                var index = indexes[i];
                if(index.name == indexName) {
                    return index;
                }
            }
            return null;
        }
    };

    for(var i=0; i<worksheetData.feed.entry.length; i++) {
        var item = worksheetData.feed.entry[i];

        if(item.gs$cell.row == '1') {
            var pos = parseInt(item.gs$cell.col, 10) - 1;
            var value = item.gs$cell.$t;
            var name = value.substring(0, value.indexOf('(')).trim();
            var type = value.substring(value.indexOf('(') + 1, value.indexOf(')')).trim();

            var column = {
                pos: pos,
                name: name,
                type: type,
                fk: ''
            };

            columns.push(column);
            table.validColumns.push(pos);
        } else if(item.gs$cell.row == '2') {
            var pos = parseInt(item.gs$cell.col, 10) - 1;
            var column = columns[table.validColumns.indexOf(pos)];
            var value = item.gs$cell.$t;

            if(value !== '') {
                var indexes = value.split(',');
                for(var j=0; j<indexes.length; j++) {
                    var index = indexes[j].trim();
                    if(index.toLowerCase().indexOf('fk_') >= 0) {
                        table.fkCount++;
                        //column.fk = index.substring(3, index.length);
                        column.fk = index.substring(index.indexOf('(') + 1, index.indexOf(')')).replace('.', '(') + ')';
                    } else if(index.toLowerCase().indexOf('in_') >= 0) {
                        var regularIndex = table.getRegularIndex(index.toLowerCase());

                        if(regularIndex === null) {
                            regularIndex = {
                                name: index.toLowerCase(),
                                columns: []
                            };

                            table.regularIndexes.push(regularIndex);
                        }

                        regularIndex.columns.push(column);
                    } else if(index.toLowerCase().indexOf('un_') >= 0) {
                        var uniqueIndex = table.getUniqueIndex(index.toLowerCase());

                        if(uniqueIndex === null) {
                            uniqueIndex = {
                                name: index.toLowerCase(),
                                columns: []
                            };

                            table.uniqueIndexes.push(uniqueIndex);
                        }

                        uniqueIndex.columns.push(column);
                    }
                }
            }
        } else {
            break;
        }
    }

    table.columns = columns;

    return table;
};

Sheets2sqlite.prototype.insertData = function(table, worksheetData) {
    var rows = [];

    var linhaInicial = 3;

    for(var i=0; i<worksheetData.feed.entry.length; i++) {
        var item = worksheetData.feed.entry[i];
        var col = parseInt(item.gs$cell.col, 10) - 1;
        var row = parseInt(item.gs$cell.row, 10) - linhaInicial;

        if(row < 0) {
            continue;
        }

        if(col === 0) {
            rows.push({
                row: row,
                cells: []
            });
        }

        if(table.validColumns.indexOf(col) >= 0) {
            var line = rows[row];
            line.cells.push(item.gs$cell.$t);
        }
    }

    table.rows = rows;
};

Sheets2sqlite.prototype.loadData = function(tables) {
    for(var i=0; i<tables.length; i++) {
        var table = tables[i];

        console.log('createSQL:', table.createSQL());
        console.log('insertSQL:', table.insertSQL());

        this.db.exec(table.createSQL());
        this.db.exec(table.insertSQL());
    }
};

var escape = function(text) {
    if(text === '' || typeof text == 'undefined') {
        return '';
    }

    var temp = text.replace(/'/g, '\'\'');
    temp = temp.replace('"', '""');
    return temp;
};

var tableCreate = function () {
    function valconcat(vals, tagName) {
        if (vals.length === 0) return '';
        var open = '<'+tagName+'>', close='</'+tagName+'>';
        return open + vals.join(close + open) + close;
    }

    return function (columns, values) {
        var tbl  = document.createElement('table');
        var html = '
' + valconcat(columns, 'th') + '
';
        var rows = values.map(function(v){ return valconcat(v, 'td'); });
        html += '
' + valconcat(rows, 'tr') + '
';
        tbl.innerHTML = html;
        return tbl;
    };
};<|endoftext|>


<commit_before>var zmq = require('zmq'),
    sock = zmq.socket('rep');
var r = require('rethinkdb');

sock.bindSync('tcp://172.16.42.1:3003');
console.log('storage relay on 3003')

sock.on('message', function(data){
  try {
    var message = JSON.parse(data)
    var payload = message.payload
    var fullname = message.username+"/"+message.scriptname

    r.connect({host:'localhost', port:28015, db:'cointhink'},
      function(err, conn) {
        r.table('scripts').get(fullname).run(conn, function(err, doc){
          if(err){
            console.log(err)
            respond({"status":"dberr"})
          } else {
            if(doc){
              if(doc.key == message.key){
                var storage = doc.storage
                if(payload.action == 'get'){
                  var value = storage[payload.key]
                  console.log(fullname+' get '+payload.key+' '+value)
                  respond({"status":"ok", "payload":value})
                }
                if(payload.action == 'set'){
                  console.log(fullname+' set '+payload.key+' '+payload.value)
                  storage[payload.key] = payload.value
                  r.table('scripts').get(fullname).update({storage:storage}).run(conn, function(status){
                    respond({"status":"ok", "payload":status})
                  })
                }
                if(payload.action == 'load'){
                  console.log(fullname+' load storage')
                  respond({"status":"ok", "payload":storage})
                }
                if(payload.action == 'store'){
                  console.log(fullname+' store storage')
                  r.table('scripts').get(fullname).update({storage:payload.storage}).run(conn, function(status){
                    respond({"status":"ok", "payload":status})
                  })
                }
                if(payload.action == 'trade'){
                  console.log(fullname+' trade '+payload.exchange+' '+payload.market+' '+payload.buysell)
                  var response = trade(payload, doc.inventory)
                  if(response.status == 'ok'){
                    r.table('scripts').get(fullname)('trades').
                    prepend(response.payload.trade).run(conn, function(err){
                      if(err) console.log(err)
                      r.table('scripts').get(fullname).
                      update({inventory:doc.inventory}).run(conn, function(err){
                        if(err) console.log(err)
                        var trade_msg = "["+payload.exchange+"] "+payload.buysell+" "+payload.quantity+payload.market+"@"+payload.amount+payload.currency
                        r.table('signals').insert({name:fullname,
                                                   time:(new Date()).toISOString(),
                                                   type:payload.action,
                                                   msg:trade_msg}).run(conn, function(err){if(err)console.log(err)})
                        respond(response)
                      })
                    })
                  } else {
                    respond(response)
                  }
                }
              } else {
                console.log(fullname+" bad key!")
                respond({"status":"badkey"})
              }
            } else {
              console.log(fullname+" empty doc!")
              respond({"status":"nodoc"})
            }
          }
        })
      }
    )
  } catch (ex) {
    console.log(ex+' ignoring "'+data+'"')
    respond({"status":"garbled"})
  }
})

function respond(payload){
  sock.send(JSON.stringify(payload))
}

function trade(payload, inventory){
//trade('mtgox','btc',4,'buy','usd',92)
//trade('mtgox','btc',4,'sell','usd',97)
  var result
  if(payload.buysell == 'buy') {
    var on_hand = inventory[payload.currency]
    if(on_hand){
      var price = (payload.amount * payload.quantity)
      if(on_hand >= price) {
        inventory[payload.currency] -= price
        result = {"status":"ok", payload: {trade:payload, inventory:inventory}}
      } else {
        result = {"status":"err", payload:""+on_hand+payload.currency+" is in sufficient for "+price}
      }
    } else {
      result = {"status":"err", payload:"no "+payload.currency+" in inventory"}
    }
  } else if (payload.buysell == 'sell') {
    var on_hand = inventory[payload.market]
    if(on_hand){
      if(on_hand >= payload.quantity){
        inventory[payload.market] -= payload.quantity
        result = {"status":"ok", payload: {trade:payload, inventory:inventory}}
      } else {
        result = {"status":"err", payload:""+on_hand+payload.market+" is in sufficient for "+payload.quantity}
      }
    } else {
      result = {"status":"err", payload:"no "+payload.market+" in inventory"}
    }
  }

  return result
}
<commit_msg>validate trade requests with the most recent market price<commit_after>var zmq = require('zmq'),
    sock = zmq.socket('rep');
var r = require('rethinkdb'),
    redis = require('redis').createClient()

sock.bindSync('tcp://172.16.42.1:3003');
console.log('storage relay on 3003')

sock.on('message', function(data){
  try {
    var message = JSON.parse(data)
    var payload = message.payload
    var fullname = message.username+"/"+message.scriptname

    r.connect({host:'localhost', port:28015, db:'cointhink'},
      function(err, conn) {
        r.table('scripts').get(fullname).run(conn, function(err, doc){
          if(err){
            console.log(err)
            respond({"status":"dberr"})
          } else {
            if(doc){
              if(doc.key == message.key){
                var storage = doc.storage
                if(payload.action == 'get'){
                  var value = storage[payload.key]
                  console.log(fullname+' get '+payload.key+' '+value)
                  respond({"status":"ok", "payload":value})
                }
                if(payload.action == 'set'){
                  console.log(fullname+' set '+payload.key+' '+payload.value)
                  storage[payload.key] = payload.value
                  r.table('scripts').get(fullname).update({storage:storage}).run(conn, function(status){
                    respond({"status":"ok", "payload":status})
                  })
                }
                if(payload.action == 'load'){
                  console.log(fullname+' load storage')
                  respond({"status":"ok", "payload":storage})
                }
                if(payload.action == 'store'){
                  console.log(fullname+' store storage')
                  r.table('scripts').get(fullname).update({storage:payload.storage}).run(conn, function(status){
                    respond({"status":"ok", "payload":status})
                  })
                }
                if(payload.action == 'trade'){
                  console.log(fullname+' trade '+payload.exchange+' '+payload.market+' '+payload.buysell)
                  var hashname = payload.exchange.toLowerCase()+"-ticker-"+
                                 payload.market.toUpperCase()+
                                 payload.currency.toUpperCase()
                  redis.hgetall(hashname, function(err,ticker){
                    var response = trade(payload, doc.inventory, ticker)
                    if(response.status == 'ok'){
                      r.table('scripts').get(fullname)('trades').
                      prepend(response.payload.trade).run(conn, function(err){
                        if(err) console.log(err)
                        r.table('scripts').get(fullname).
                        update({inventory:doc.inventory}).run(conn, function(err){
                          if(err) console.log(err)
                          var trade_msg = "["+payload.exchange+"] "+payload.buysell+" "+payload.quantity+payload.market+"@"+payload.amount+payload.currency
                          r.table('signals').insert({name:fullname,
                                                     time:(new Date()).toISOString(),
                                                     type:payload.action,
                                                     msg:trade_msg}).run(conn, function(err){if(err)console.log(err)})
                          respond(response)
                        })
                      })
                    } else {
                      respond(response)
                    }
                  })
                }
              } else {
                console.log(fullname+" bad key!")
                respond({"status":"badkey"})
              }
            } else {
              console.log(fullname+" empty doc!")
              respond({"status":"nodoc"})
            }
          }
        })
      }
    )
  } catch (ex) {
    console.log(ex+' ignoring "'+data+'"')
    respond({"status":"garbled"})
  }
})

function respond(payload){
  sock.send(JSON.stringify(payload))
}

//trade('mtgox','btc',4,'buy','usd',92)
//trade('mtgox','btc',4,'sell','usd',97)
function trade(payload, inventory, ticker){
  var result // return value
  var ticker_age_sec = ((new Date()) - new Date(ticker.now))/1000
  if(ticker_age_sec < 120){
    var price_diff_ratio = (Math.abs(payload.amount - ticker.value))/ticker.value
    if(price_diff_ratio <= 0.01){
      if(payload.buysell == 'buy') {
        var on_hand = inventory[payload.currency]
        if(on_hand){
          var price = (payload.amount * payload.quantity)
          if(on_hand >= price) {
              inventory[payload.currency] -= price
              result = {"status":"ok", payload: {trade:payload, inventory:inventory}}
          } else {
            result = {"status":"err", payload:""+on_hand+payload.currency+" is in sufficient for "+price}
          }
        } else {
          result = {"status":"err", payload:"no "+payload.currency+" in inventory"}
        }
      } else if (payload.buysell == 'sell') {
        var on_hand = inventory[payload.market]
        if(on_hand){
          if(on_hand >= payload.quantity){
            inventory[payload.market] -= payload.quantity
            result = {"status":"ok", payload: {trade:payload, inventory:inventory}}
          } else {
            result = {"status":"err", payload:""+on_hand+payload.market+" is in sufficient for "+payload.quantity}
          }
        } else {
          result = {"status":"err", payload:"no "+payload.market+" in inventory"}
        }
      }
    } else {
      result = {"status":"err", payload:"price of "+payload.amount+" is more than 1% away from exchange "+payload.exchange+" price "+ticker.value}
    }
  } else {
    result = {"status":"err", payload:"exchange "+payload.exchange+" price too old ("+age+" secs) validate this try. please try again."}
  }

  return result
}
<|endoftext|>