<commit_before>define(['q', 'knockout', 'util/galaxy', 'util/alerts', 'store/Blueprints', 'store/Stacks', 'api/api'],
function (Q, ko, $galaxy, alerts, BlueprintStore, StackStore, API) {
    var vm = function () {
        var self = this;

        /*
         *  ==================================================================================
         *   V I E W   V A R I A B L E S
         *  ==================================================================================
        */
        self.stackActions = ['Stop', 'Terminate', 'Start', 'Launch', 'Delete', 'Provision'];
        self.stackHostActions = ['Stop', 'Terminate', 'Start'];
        self.selectedProfile = null;
        self.selectedAccount = null;
        self.selectedBlueprint = ko.observable({title:''});
        self.blueprintProperties = ko.observable();
        self.selectedStack = ko.observable();
        self.BlueprintStore = BlueprintStore;
        self.StackStore = StackStore;
        self.$galaxy = $galaxy;

        /*
         *  ==================================================================================
         *   R E G I S T R A T I O N   S E C T I O N
         *  ==================================================================================
        */
        self.id = 'stack.list';
        self.templatePath = 'stacks.html';
        self.domBindingId = '#stack-list';

        try {
            $galaxy.join(self);
        } catch (ex) {
            console.log(ex);
        }

        /*
         *  ==================================================================================
         *   E V E N T   S U B S C R I P T I O N S
         *  ==================================================================================
         */
        $galaxy.network.subscribe(self.id + '.docked', function (data) {
            BlueprintStore.populate().then(function () {
                $('span').popover('hide');
                return StackStore.populate(true);
            }).catch(function (err) {
                console.error(err);
            });
        });

        /*
         *  ==================================================================================
         *   V I E W   M E T H O D S
         *  ==================================================================================
        */

        // This builds the HTML for the stack history popover element
        self.popoverBuilder = function (stack) {
            return stack.fullHistory.map(function (h) {
                var content = [];

                content.push("
");
                content.push("
');
                content.push(h.status);
                content.push('
');
                content.push("
");
                content.push(moment(h.created).fromNow());
                content.push('
');
                content.push('
');

                return content.join('');

            }).join('');
        };

        self.doStackAction = function (action, evt, stack) {
            var data = JSON.stringify({
                action: action.toLowerCase()
            });

            /*
             *  Unless the user wants to delete the stack permanently (see below)
             *  then just PUT to the API with the appropriate action.
             */
            if (action !== 'Delete') {
                $.ajax({
                    url: stack.action,
                    type: 'POST',
                    data: data,
                    headers: {
                        "X-CSRFToken": stackdio.settings.csrftoken,
                        "Accept": "application/json",
                        "Content-Type": "application/json"
                    },
                    success: function (response) {
                        alerts.showMessage('#success', 'Stack ' + action.toLowerCase() + ' has been initiated.', true);
                        StackStore.populate(true);
                    },
                    error: function (request, status, error) {
                        alerts.showMessage('#error', 'Unable to perform ' + action.toLowerCase() + ' action on that stack. ' + JSON.parse(request.responseText).detail, true, 7000);
                    }
                });

            /*
             *  Using the DELETE verb is truly destructive. Terminates all hosts, terminates all
             *  EBS volumes, and deletes stack/host details from the stackd.io database.
             */
            } else {
                $.ajax({
                    url: stack.action,
                    type: 'DELETE',
                    headers: {
                        "X-CSRFToken": stackdio.settings.csrftoken,
                        "Accept": "application/json",
                        "Content-Type": "application/json"
                    },
                    success: function (response) {
                        alerts.showMessage('#success', 'Stack is currently being torn down and will be deleted once all hosts are terminated.', true, 5000);
                        StackStore.populate(true);
                    },
                    error: function (request, status, error) {
                        alerts.showMessage('#error', 'Unable to delete this stack.', true, 2000);
                    }
                });
            }
        };

        self.showStackDetails = function (stack) {
            self.selectedStack(stack);

            API.Stacks.getProperties(stack).then(function (properties) {
                $('#stack_properties_preview_edit').val(JSON.stringify(properties, undefined, 3));
            }).done();

            $('#stack_title_edit').val(stack.title);
            $('#stack_description_edit').val(stack.description);
            $('#stack_namespace_edit').val(stack.id);

            API.StackHosts.load(stack).then(function (response) {
                $("#stack-edit-container").dialog("open");
            });
        };

        self.showStackDetails = function (stack) {
            $galaxy.transport({
                location: 'stack.detail',
                payload: {
                    stack: stack.id
                }
            });
        };

        self.createNewStack = function (blueprint) {
            API.Users.load().then(function (public_key) {
                if (public_key === '') {
                    alerts.showMessage('#error', 'You have not saved your public key, and cannot launch any new stacks. Please open your user profile to save one.', true, 4000);
                } else {
                    $galaxy.transport({
                        location: 'stack.detail',
                        payload: {
                            blueprint: blueprint.id
                        }
                    });
                }
            });
        };

    };
    return new vm();
});
<commit_msg>Fix: Deleting a stack no longer works...attempting to DELETE on the action API<commit_after>define(['q', 'knockout', 'util/galaxy', 'util/alerts', 'store/Blueprints', 'store/Stacks', 'api/api'],
function (Q, ko, $galaxy, alerts, BlueprintStore, StackStore, API) {
    var vm = function () {
        var self = this;

        /*
         *  ==================================================================================
         *   V I E W   V A R I A B L E S
         *  ==================================================================================
        */
        self.stackActions = ['Stop', 'Terminate', 'Start', 'Launch', 'Delete', 'Provision'];
        self.stackHostActions = ['Stop', 'Terminate', 'Start'];
        self.selectedProfile = null;
        self.selectedAccount = null;
        self.selectedBlueprint = ko.observable({title:''});
        self.blueprintProperties = ko.observable();
        self.selectedStack = ko.observable();
        self.BlueprintStore = BlueprintStore;
        self.StackStore = StackStore;
        self.$galaxy = $galaxy;

        /*
         *  ==================================================================================
         *   R E G I S T R A T I O N   S E C T I O N
         *  ==================================================================================
        */
        self.id = 'stack.list';
        self.templatePath = 'stacks.html';
        self.domBindingId = '#stack-list';

        try {
            $galaxy.join(self);
        } catch (ex) {
            console.log(ex);
        }

        /*
         *  ==================================================================================
         *   E V E N T   S U B S C R I P T I O N S
         *  ==================================================================================
         */
        $galaxy.network.subscribe(self.id + '.docked', function (data) {
            BlueprintStore.populate().then(function () {
                $('span').popover('hide');
                return StackStore.populate(true);
            }).catch(function (err) {
                console.error(err);
            });
        });

        /*
         *  ==================================================================================
         *   V I E W   M E T H O D S
         *  ==================================================================================
        */

        // This builds the HTML for the stack history popover element
        self.popoverBuilder = function (stack) {
            return stack.fullHistory.map(function (h) {
                var content = [];

                content.push("
");
                content.push("
');
                content.push(h.status);
                content.push('
');
                content.push("
");
                content.push(moment(h.created).fromNow());
                content.push('
');
                content.push('
');

                return content.join('');

            }).join('');
        };

        self.doStackAction = function (action, evt, stack) {
            var data = JSON.stringify({
                action: action.toLowerCase()
            });

            /*
             *  Unless the user wants to delete the stack permanently (see below)
             *  then just PUT to the API with the appropriate action.
             */
            if (action !== 'Delete') {
                $.ajax({
                    url: stack.action,
                    type: 'POST',
                    data: data,
                    headers: {
                        "X-CSRFToken": stackdio.settings.csrftoken,
                        "Accept": "application/json",
                        "Content-Type": "application/json"
                    },
                    success: function (response) {
                        alerts.showMessage('#success', 'Stack ' + action.toLowerCase() + ' has been initiated.', true);
                        StackStore.populate(true);
                    },
                    error: function (request, status, error) {
                        alerts.showMessage('#error', 'Unable to perform ' + action.toLowerCase() + ' action on that stack. ' + JSON.parse(request.responseText).detail, true, 7000);
                    }
                });

            /*
             *  Using the DELETE verb is truly destructive. Terminates all hosts, terminates all
             *  EBS volumes, and deletes stack/host details from the stackd.io database.
             */
            } else {
                $.ajax({
                    url: stack.url,
                    type: 'DELETE',
                    headers: {
                        "X-CSRFToken": stackdio.settings.csrftoken,
                        "Accept": "application/json",
                        "Content-Type": "application/json"
                    },
                    success: function (response) {
                        alerts.showMessage('#success', 'Stack is currently being torn down and will be deleted once all hosts are terminated.', true, 5000);
                        StackStore.populate(true);
                    },
                    error: function (request, status, error) {
                        alerts.showMessage('#error', 'Unable to delete this stack.', true, 2000);
                    }
                });
            }
        };

        self.showStackDetails = function (stack) {
            self.selectedStack(stack);

            API.Stacks.getProperties(stack).then(function (properties) {
                $('#stack_properties_preview_edit').val(JSON.stringify(properties, undefined, 3));
            }).done();

            $('#stack_title_edit').val(stack.title);
            $('#stack_description_edit').val(stack.description);
            $('#stack_namespace_edit').val(stack.id);

            API.StackHosts.load(stack).then(function (response) {
                $("#stack-edit-container").dialog("open");
            });
        };

        self.showStackDetails = function (stack) {
            $galaxy.transport({
                location: 'stack.detail',
                payload: {
                    stack: stack.id
                }
            });
        };

        self.createNewStack = function (blueprint) {
            API.Users.load().then(function (public_key) {
                if (public_key === '') {
                    alerts.showMessage('#error', 'You have not saved your public key, and cannot launch any new stacks. Please open your user profile to save one.', true, 4000);
                } else {
                    $galaxy.transport({
                        location: 'stack.detail',
                        payload: {
                            blueprint: blueprint.id
                        }
                    });
                }
            });
        };

    };
    return new vm();
});
<|endoftext|>


<commit_before>function LevelRoundState() {}

var playerLives, playerBall, enemy, smallerEnemies, largerEnemies, enemiesCollisionGroup, playerCollisionGroup;

var playerScale = 0.1;
var gamePlayed = false;
var hasRespawnedOnce = false;
var enemiesLeft = 0;

//accelerometer controls

var ax = 0, ay = 0,
vx = 0, vy = 0;

window.ondevicemotion = function(e) {
  ax = e.accelerationIncludingGravity.x * inputSensitivity; //acceleration along x axis
  ay = e.accelerationIncludingGravity.y * -inputSensitivity; //acceleration along y axis

  //TODO: make tilt increase logarithimacally

  vx = vx + ax;
  vy = vy + ay;

};

function createPlayer() {
    playerBall = game.add.sprite(centerx, centery, 'player');
    playerBall.scale.setTo(playerScale, playerScale);
    game.physics.p2.enable(playerBall);

    // //adding invicibility to the ball for 4 seconds

    playerBall.invincible = true;

    var invincibleAnimation = game.add.tween(playerBall);
    invincibleAnimation.to({alpha: 0}, 500, Phaser.Easing.Linear.None, true, 0, 7, false).to({alpha: 1}, 500);

    if (!gamePlayed) {
        gamePlayed = true;
        var getReadyScreen = game.add.sprite(centerx, centery + 50, 'getready');
        getReadyScreen.scale.setTo(0.5,0.5);
        var getReadyAnimation = game.add.tween(getReadyScreen);
        getReadyAnimation.to({alpha: 0}, 500, Phaser.Easing.Linear.None, true, 0, 7, false);
    }

    game.time.events.add(4000, (function() {
        playerBall.invincible = false;
    }), this);

    //setting the collision group for the player
    playerBall.body.setCollisionGroup(playerCollisionGroup);
    playerBall.body.collides(enemiesCollisionGroup, hitEnemy, this);
}

function createSmallerEnemies() {
    for (var x = 1; x < 18; x++) {
        var enemySpriteColors = ['blue_ball', 'red_ball', 'green_ball'];
        var enemy = smallerEnemies.create(game.world.randomX, game.world.randomY, game.rnd.pick(enemySpriteColors));
        var smallerEnemy = game.rnd.realInRange(0.015, playerBall.scale.x);

        //making enemies smaller than current player size
        enemy.scale.setTo(smallerEnemy, smallerEnemy);
        game.physics.p2.enable(enemy, false);

        //initiating enemy velocity.

        var randv = game.rnd.realInRange(-300, 300);
        var randv2 = game.rnd.realInRange(-300, 300);
        enemy.body.velocity.x = randv;
        enemy.body.velocity.y = randv2;

        //setting the collision group and having it collide with the player.
        enemy.body.setCollisionGroup(enemiesCollisionGroup);
        enemy.body.collides([enemiesCollisionGroup, playerCollisionGroup]);

        enemiesLeft++;
    }
}

function createLargerEnemies() {
    for (var x = 1; x < 4; x++) {
        var enemy = largerEnemies.create(game.world.randomX, game.world.randomY, 'ball');
        var largerEnemy = game.rnd.realInRange(playerBall.scale.x, playerBall.scale.x * 1.5);
        enemy.scale.setTo(largerEnemy, largerEnemy);
        game.physics.p2.enable(enemy, false);

         //initiating enemy velocity.

        var randv = game.rnd.realInRange(-300, 300);
        var randv2 = game.rnd.realInRange(-300, 300);

        enemy.body.velocity.x = randv;
        enemy.body.velocity.y = randv2;

        //setting the collision group and having it collide with the player.
        enemy.body.setCollisionGroup(enemiesCollisionGroup);
        enemy.body.collides([enemiesCollisionGroup, playerCollisionGroup]);

        enemiesLeft++;
    }
}

function moveLargerTowardPlayer (enemy) {
    accelerateToObject(enemy, playerBall, playerDifficulty * 75);
}

function moveSmallerTowardPlayer (enemy) {
    accelerateToObject(enemy, playerBall, 50);
}

function accelerateToObject(obj1, obj2, speed) {
    if (typeof speed === 'undefined') { speed = 60; }
    var angle = Math.atan2(obj2.y - obj1.y, obj2.x - obj1.x);
    obj1.body.rotation = angle + game.math.degToRad(90);  // correct angle of angry balls (depends on the sprite used)
    obj1.body.force.x = Math.cos(angle) * speed;    // accelerateToObject
    obj1.body.force.y = Math.sin(angle) * speed;
}

function restartGame() {
  game.state.start('level_round');
  // this.game.state.start('level_round');
  enemiesLeft = 0;
}

function levelUp(playerBall) {
  var newSize = playerBall.sprite.scale.x * 1.022;
  playerBall.sprite.scale.x = newSize;
  playerBall.sprite.scale.y = newSize;
  playerScale = newSize;
}

function hitEnemy(playerBall, enemy) {
    //  body1 is the playerBall (as it's the body that owns the callback)
    //  body2 is the body it impacted with, the enemy balls
    //  As body2 is a Phaser.Physics.P2.Body object, you access its own (the sprite) via the sprite property:

    if (playerBall.sprite.invincible) {
        return;
    }

    else if (enemy.sprite.scale.x > playerBall.sprite.scale.x) {

        if (playerLives.countLiving() !== 0) {
            game.add.tween(playerBall.sprite.scale).to({ x: 0, y: 0}, 100, Phaser.Easing.Quadratic.InOut, true, 0).onComplete.add(function() {
                playerBall.sprite.kill();
                    if (!playerBall.sprite.hasCollided) {
                        playerBall.sprite.hasCollided = true;
                        playerLives.next().destroy();

                        if (!hasRespawnedOnce) {
                            hasRespawnedOnce = true;
                            var respawnMessage = game.add.sprite(centerx, centery + 50, 'respawn');
                            respawnMessage.scale.setTo(0.25,0.25);
                            var respawnMessageAnimation = game.add.tween(respawnMessage);
                            respawnMessageAnimation.to({alpha: 0}, 500, Phaser.Easing.Linear.None, true, 0, 7, false);
                        }

                        game.time.events.add(2000, (function() {
                            createPlayer();
                        }), this);
                    }
            }, this);
        }

        if (playerLives.countLiving() === 0) {
            game.add.tween(playerBall.sprite.scale).to({ x: 0, y: 0}, 100, Phaser.Easing.Quadratic.InOut, true, 0);
            gameOverScreen = game.add.sprite(centerx, centery, 'gameogre');
            gameOverScreen.scale.setTo(1,1);
            gameOverScreen.anchor.setTo(0.5,0.5);
            gameOverScreen.inputEnabled = true;
            gameOverScreen.events.onInputDown.add(restartGame, this);
        }

      }

    else {
        game.add.tween(enemy.sprite.scale).to({ x: 0, y: 0}, 75, Phaser.Easing.Quadratic.InOut, true, 0).onComplete.add(function(){
        enemy.sprite.kill();
            if (!enemy.sprite.hasCollided) {
                levelUp(playerBall);
                enemy.sprite.hasCollided = true;
                enemiesLeft--;
            }
        }, this);

    }

}

function createLives() {
    playerLives = game.add.group();
    var firstLifeIconX = game.width - 50;
    for (var i = 0; i < 2; i++) {
        var lifeIcons = playerLives.create(firstLifeIconX - (60 * i), 50, 'player');
        lifeIcons.scale.setTo(0.1,0.1);
        lifeIcons.anchor.setTo(0.5, 0.5);
        lifeIcons.alpha = 0.8;
    }

}

LevelRoundState.prototype = {

  preload: function() {
    // This function will be executed at the beginning

  },

  create: function() {

    // starting the P2JS system
    game.physics.startSystem(Phaser.Physics.P2JS);

    // starting collision events
    game.physics.p2.setImpactEvents(true);
    game.physics.p2.restitution = 0.95;

    //creating a collision group for player and enemies

    playerCollisionGroup = game.physics.p2.createCollisionGroup();

    enemiesCollisionGroup = game.physics.p2.createCollisionGroup();

    game.physics.p2.updateBoundsCollisionGroup();

    smallerEnemies = game.add.group();
    largerEnemies = game.add.group();

    //setting initial playerscale

    playerScale = 0.1;

    createPlayer();

    createLives();

    createSmallerEnemies();

    createLargerEnemies();

  },

  update: function() {
    // This function is called 60 times per second
    // It contains the game's logic

    // document.getElementById("info").innerHTML = enemiesLeft; //used for debugging

    //assigning force using the accelerometer

    playerBall.body.force.x = ax;
    playerBall.body.force.y = ay;

    //larger enemies move faster towards you.

    largerEnemies.forEachAlive(moveLargerTowardPlayer, this);
    smallerEnemies.forEachAlive(moveSmallerTowardPlayer, this);

    //keyboard movement

    if (cursors.left.isDown) {playerBall.body.rotateLeft(inputSensitivity / 3);}   //playerBall movement
    else if (cursors.right.isDown){playerBall.body.rotateRight(inputSensitivity / 3);}
    else {playerBall.body.setZeroRotation();}
    if (cursors.up.isDown){playerBall.body.thrust(inputSensitivity * 2);}
    else if (cursors.down.isDown){playerBall.body.reverse(inputSensitivity * 2);}

    //checking for the game win condition

    if (enemiesLeft === 0) {
        var winScreen = game.add.sprite(centerx, centery, 'youwin');
        winScreen.scale.setTo(0.5,0.5);
        winScreen.anchor.setTo(0.5,0.5);
    }

  }
};<commit_msg>fixed a bug where gameogre screen would show up twice due to collision detection.<commit_after>function LevelRoundState() {}

var playerLives, playerBall, enemy, smallerEnemies, largerEnemies, enemiesCollisionGroup, playerCollisionGroup, gameOverScreen;

var playerScale = 0.1;
var gamePlayed = false;
var hasRespawnedOnce = false;
var enemiesLeft = 0;

//accelerometer controls

var ax = 0, ay = 0,
vx = 0, vy = 0;

window.ondevicemotion = function(e) {
  ax = e.accelerationIncludingGravity.x * inputSensitivity; //acceleration along x axis
  ay = e.accelerationIncludingGravity.y * -inputSensitivity; //acceleration along y axis

  //TODO: make tilt increase logarithimacally

  vx = vx + ax;
  vy = vy + ay;

};

function createPlayer() {
    playerBall = game.add.sprite(centerx, centery, 'player');
    playerBall.scale.setTo(playerScale, playerScale);
    game.physics.p2.enable(playerBall);

    // //adding invicibility to the ball for 4 seconds

    playerBall.invincible = true;

    var invincibleAnimation = game.add.tween(playerBall);
    invincibleAnimation.to({alpha: 0}, 500, Phaser.Easing.Linear.None, true, 0, 7, false).to({alpha: 1}, 500);

    if (!gamePlayed) {
        gamePlayed = true;
        var getReadyScreen = game.add.sprite(centerx, centery + 50, 'getready');
        getReadyScreen.scale.setTo(0.5,0.5);
        var getReadyAnimation = game.add.tween(getReadyScreen);
        getReadyAnimation.to({alpha: 0}, 500, Phaser.Easing.Linear.None, true, 0, 7, false);
    }

    game.time.events.add(4000, (function() {
        playerBall.invincible = false;
    }), this);

    //setting the collision group for the player
    playerBall.body.setCollisionGroup(playerCollisionGroup);
    playerBall.body.collides(enemiesCollisionGroup, hitEnemy, this);
}

function createSmallerEnemies() {
    for (var x = 1; x < 18; x++) {
        var enemySpriteColors = ['blue_ball', 'red_ball', 'green_ball'];
        var enemy = smallerEnemies.create(game.world.randomX, game.world.randomY, game.rnd.pick(enemySpriteColors));
        var smallerEnemy = game.rnd.realInRange(0.015, playerBall.scale.x);

        //making enemies smaller than current player size
        enemy.scale.setTo(smallerEnemy, smallerEnemy);
        game.physics.p2.enable(enemy, false);

        //initiating enemy velocity.

        var randv = game.rnd.realInRange(-300, 300);
        var randv2 = game.rnd.realInRange(-300, 300);
        enemy.body.velocity.x = randv;
        enemy.body.velocity.y = randv2;

        //setting the collision group and having it collide with the player.
        enemy.body.setCollisionGroup(enemiesCollisionGroup);
        enemy.body.collides([enemiesCollisionGroup, playerCollisionGroup]);

        enemiesLeft++;
    }
}

function createLargerEnemies() {
    for (var x = 1; x < 4; x++) {
        var enemy = largerEnemies.create(game.world.randomX, game.world.randomY, 'ball');
        var largerEnemy = game.rnd.realInRange(playerBall.scale.x, playerBall.scale.x * 1.5);
        enemy.scale.setTo(largerEnemy, largerEnemy);
        game.physics.p2.enable(enemy, false);

         //initiating enemy velocity.

        var randv = game.rnd.realInRange(-300, 300);
        var randv2 = game.rnd.realInRange(-300, 300);

        enemy.body.velocity.x = randv;
        enemy.body.velocity.y = randv2;

        //setting the collision group and having it collide with the player.
        enemy.body.setCollisionGroup(enemiesCollisionGroup);
        enemy.body.collides([enemiesCollisionGroup, playerCollisionGroup]);

        enemiesLeft++;
    }
}

function moveLargerTowardPlayer (enemy) {
    accelerateToObject(enemy, playerBall, playerDifficulty * 75);
}

function moveSmallerTowardPlayer (enemy) {
    accelerateToObject(enemy, playerBall, 50);
}

function accelerateToObject(obj1, obj2, speed) {
    if (typeof speed === 'undefined') { speed = 60; }
    var angle = Math.atan2(obj2.y - obj1.y, obj2.x - obj1.x);
    obj1.body.rotation = angle + game.math.degToRad(90);  // correct angle of angry balls (depends on the sprite used)
    obj1.body.force.x = Math.cos(angle) * speed;    // accelerateToObject
    obj1.body.force.y = Math.sin(angle) * speed;
}

function restartGame() {
  game.state.start('level_round');
  // this.game.state.start('level_round');
  enemiesLeft = 0;
}

function levelUp(playerBall) {
  var newSize = playerBall.sprite.scale.x * 1.022;
  playerBall.sprite.scale.x = newSize;
  playerBall.sprite.scale.y = newSize;
  playerScale = newSize;
}

function hitEnemy(playerBall, enemy) {
    //  body1 is the playerBall (as it's the body that owns the callback)
    //  body2 is the body it impacted with, the enemy balls
    //  As body2 is a Phaser.Physics.P2.Body object, you access its own (the sprite) via the sprite property:

    if (playerBall.sprite.invincible) {
        return;
    }

    else if (enemy.sprite.scale.x > playerBall.sprite.scale.x) {

        if (playerLives.countLiving() !== 0) {
            game.add.tween(playerBall.sprite.scale).to({ x: 0, y: 0}, 100, Phaser.Easing.Quadratic.InOut, true, 0).onComplete.add(function() {
                playerBall.sprite.kill();
                    if (!playerBall.sprite.hasCollided) {
                        playerBall.sprite.hasCollided = true;
                        playerLives.next().destroy();

                        if (!hasRespawnedOnce) {
                            hasRespawnedOnce = true;
                            var respawnMessage = game.add.sprite(centerx, centery + 50, 'respawn');
                            respawnMessage.scale.setTo(0.25,0.25);
                            var respawnMessageAnimation = game.add.tween(respawnMessage);
                            respawnMessageAnimation.to({alpha: 0}, 500, Phaser.Easing.Linear.None, true, 0, 7, false);
                        }

                        game.time.events.add(2000, (function() {
                            createPlayer();
                        }), this);
                    }
            }, this);
        }

        if (playerLives.countLiving() === 0) {
            game.add.tween(playerBall.sprite.scale).to({ x: 0, y: 0}, 100, Phaser.Easing.Quadratic.InOut, true, 0);
            if (!gameOverScreen) {
                gameOverScreen = game.add.sprite(centerx, centery, 'gameogre');
                gameOverScreen.scale.setTo(1,1);
                gameOverScreen.anchor.setTo(0.5,0.5);
                gameOverScreen.inputEnabled = true;
                gameOverScreen.events.onInputDown.add(restartGame, this);
            }

        }

      }

    else {
        game.add.tween(enemy.sprite.scale).to({ x: 0, y: 0}, 75, Phaser.Easing.Quadratic.InOut, true, 0).onComplete.add(function(){
        enemy.sprite.kill();
            if (!enemy.sprite.hasCollided) {
                levelUp(playerBall);
                enemy.sprite.hasCollided = true;
                enemiesLeft--;
            }
        }, this);

    }

}

function createLives() {
    playerLives = game.add.group();
    var firstLifeIconX = game.width - 50;
    for (var i = 0; i < 2; i++) {
        var lifeIcons = playerLives.create(firstLifeIconX - (60 * i), 50, 'player');
        lifeIcons.scale.setTo(0.1,0.1);
        lifeIcons.anchor.setTo(0.5, 0.5);
        lifeIcons.alpha = 0.8;
    }

}

LevelRoundState.prototype = {

  preload: function() {
    // This function will be executed at the beginning

  },

  create: function() {

    // starting the P2JS system
    game.physics.startSystem(Phaser.Physics.P2JS);

    // starting collision events
    game.physics.p2.setImpactEvents(true);
    game.physics.p2.restitution = 0.95;

    //creating a collision group for player and enemies

    playerCollisionGroup = game.physics.p2.createCollisionGroup();

    enemiesCollisionGroup = game.physics.p2.createCollisionGroup();

    game.physics.p2.updateBoundsCollisionGroup();

    smallerEnemies = game.add.group();
    largerEnemies = game.add.group();

    //setting initial playerscale

    playerScale = 0.1;

    createPlayer();

    createLives();

    createSmallerEnemies();

    createLargerEnemies();

  },

  update: function() {
    // This function is called 60 times per second
    // It contains the game's logic

    // document.getElementById("info").innerHTML = enemiesLeft; //used for debugging

    //assigning force using the accelerometer

    playerBall.body.force.x = ax;
    playerBall.body.force.y = ay;

    //larger enemies move faster towards you.

    largerEnemies.forEachAlive(moveLargerTowardPlayer, this);
    smallerEnemies.forEachAlive(moveSmallerTowardPlayer, this);

    //keyboard movement

    if (cursors.left.isDown) {playerBall.body.rotateLeft(inputSensitivity / 3);}   //playerBall movement
    else if (cursors.right.isDown){playerBall.body.rotateRight(inputSensitivity / 3);}
    else {playerBall.body.setZeroRotation();}
    if (cursors.up.isDown){playerBall.body.thrust(inputSensitivity * 2);}
    else if (cursors.down.isDown){playerBall.body.reverse(inputSensitivity * 2);}

    //checking for the game win condition

    if (enemiesLeft === 0) {
        var winScreen = game.add.sprite(centerx, centery, 'youwin');
        winScreen.scale.setTo(0.5,0.5);
        winScreen.anchor.setTo(0.5,0.5);
    }

  }
};<|endoftext|>


<commit_before>import React, {PropTypes} from 'react';

const puke = (obj) =>
{JSON.stringify(obj, 2, ' ')}

const Results = React.createClass({
    render() {
        return (

                Results: {puke(this.props)}

        );
    }
});

Results.propTypes = {
    isLoading: PropTypes.bool.isRequired,
    playersInfo: PropTypes.array.isRequired,
    scores: PropTypes.array.isRequired
}

export default Results;<commit_msg>Add the score result to the UI to show the battle's winner<commit_after>import React, {PropTypes} from 'react';
import {Link} from 'react-router';

import UserDetails from './UserDetails';
import UserDetailsWrapper from './UserDetailsWrapper';

const StartOver = () => {
    return (

            <Link to="/playerOne">
                <button type="button" className="btn btn-lg btn-danger">
                    Start Over
                </button>
            </Link>

    )
}

const Results = React.createClass({
    render() {
        const winnerIndex = this.props.scores[0] > this.props.scores[1] ? 0 : 1;
        const loserIndex = 1 - winnerIndex; // 1 - [0] = 1 ; 1 - [1] = 0

        if (this.props.isLoading) {
            return (

LOADING...

            )
        }

        if (this.props.scores[0] === this.props.scores[1]) {
            return (

It's a tie

                    <StartOver />

            )
        }

        return (

Results

                    <UserDetailsWrapper header="Winner">
                        <UserDetails score={this.props.scores[winnerIndex]} info={this.props.playersInfo[winnerIndex]} />
                    </UserDetailsWrapper>

                    <UserDetailsWrapper header="Loser">
                        <UserDetails score={this.props.scores[loserIndex]} info={this.props.playersInfo[loserIndex]} />
                    </UserDetailsWrapper>

                <StartOver />

        );
    }
});

Results.propTypes = {
    isLoading: PropTypes.bool.isRequired,
    playersInfo: PropTypes.array.isRequired,
    scores: PropTypes.array.isRequired
}

export default Results;<|endoftext|>


<commit_before>// @flow

import PropTypes from 'prop-types';
import * as d3 from 'd3';
import _ from 'lodash';
import ReactFauxDOM from 'react-faux-dom';
import { compose } from 'recompose';

import { withTooltip } from '@ncigdc/uikit/Tooltip';
import { withTheme } from '@ncigdc/theme';

const HALF_DEGREE_IN_RAD = 0.00872665;

const getNestedValue = (item, path) => {
  if (path.length === 1) {
    return item[path[0]];
  }

  const nextItem = item[path[0]];
  path.shift();

  return getNestedValue(nextItem, path);
};

const PieChart = compose(
  withTooltip,
  withTheme,
)(
  ({
    data,
    path = 'file_count',
    height = 160,
    width = 160,
    setTooltip,
    marginTop = 0,
  }) => {
    const color = d3.scaleOrdinal(d3.schemeCategory20);
    const outerRadius = height / 2 + 10;

    const node = ReactFauxDOM.createElement('div');
    node.style.setProperty('margin-top', `${marginTop}px`);
    node.style.setProperty('display', 'flex');
    node.style.setProperty('justify-content', 'center');
    node.setAttribute('class', 'test-pie-chart');

    const pie = d3
      .pie()
      .value(d => getNestedValue(d, path.split('.')))
      .padAngle(HALF_DEGREE_IN_RAD);

    const arc = d3
      .arc()
      .padRadius(outerRadius)
      .innerRadius(0);

    const svg = d3
      .select(node)
      .append('svg')
      .attr('width', width)
      .attr('height', height)
      .append('g')
      .attr('transform', `translate(${width / 2}, ${height / 2})`);

    const g = svg
      .selectAll('.arc')
      .data(pie(data))
      .enter()
      .append('g')
      .each(d => {
        d.outerRadius = outerRadius - 20;
      })
      .attr('class', 'arc');

    const gHover = svg
      .selectAll('.arc-hover')
      .data(pie(data))
      .enter()
      .append('g')
      .each(d => {
        d.outerRadius = outerRadius - 15;
      })
      .attr('class', 'arc-hover');

    const gPath = g.append('path');
    const gHoverPath = gHover.append('path');

    gPath.attr('d', arc).style('fill', (d, i) => color(i));

    const fillHover = gHoverPath
      .attr('d', arc)
      .style('fill', (d, i) => color(i))
      .style('opacity', 0);

    fillHover
      .attr('class', d => `pointer arc-hover-${_.snakeCase(d.data.id)}`)
      .on('mouseenter', d => {
        document.querySelector(
          `.arc-hover-${_.snakeCase(d.data.id)}`,
        ).style.opacity = 0.5;
        setTooltip(d.data.tooltip);
      })
      .on('mouseleave', d => {
        document.querySelector(
          `.arc-hover-${_.snakeCase(d.data.id)}`,
        ).style.opacity = 0;
        setTooltip();
      })
      .on('mousedown', d => {
        if (d.data.clickHandler) {
          d.data.clickHandler(d);
          setTooltip();
        }
      });

    return node.toReact();
  },
);

PieChart.propTypes = {
  data: PropTypes.array,
};

/*----------------------------------------------------------------------------*/

export default PieChart;
<commit_msg>adjust pie chart whitespace<commit_after>// @flow

import PropTypes from 'prop-types';
import * as d3 from 'd3';
import _ from 'lodash';
import ReactFauxDOM from 'react-faux-dom';
import { compose } from 'recompose';

import { withTooltip } from '@ncigdc/uikit/Tooltip';
import { withTheme } from '@ncigdc/theme';

const getNestedValue = (item, path) => {
  if (path.length === 1) {
    return item[path[0]];
  }

  const nextItem = item[path[0]];
  path.shift();

  return getNestedValue(nextItem, path);
};

const PieChart = compose(
  withTooltip,
  withTheme
)(
  ({
    data,
    path = 'file_count',
    height = 160,
    width = 160,
    setTooltip,
    marginTop = 0,
  }) => {
    const color = d3.scaleOrdinal(d3.schemeCategory20);
    const outerRadius = height / 2 + 10;

    const node = ReactFauxDOM.createElement('div');
    node.style.setProperty('margin-top', `${marginTop}px`);
    node.style.setProperty('display', 'flex');
    node.style.setProperty('justify-content', 'center');
    node.setAttribute('class', 'test-pie-chart');

    const pie = d3.pie().value(d => getNestedValue(d, path.split('.')));

    const arc = d3
      .arc()
      .padRadius(outerRadius)
      .innerRadius(0);

    const svg = d3
      .select(node)
      .append('svg')
      .attr('width', width)
      .attr('height', height)
      .append('g')
      .attr('transform', `translate(${width / 2}, ${height / 2})`);

    const g = svg
      .selectAll('.arc')
      .data(pie(data))
      .enter()
      .append('g')
      .each(d => {
        d.outerRadius = outerRadius - 20;
      })
      .attr('class', 'arc')
      .attr('stroke', '#fff')
      .attr('stroke-width', '0.5');

    const gHover = svg
      .selectAll('.arc-hover')
      .data(pie(data))
      .enter()
      .append('g')
      .each(d => {
        d.outerRadius = outerRadius - 15;
      })
      .attr('class', 'arc-hover');

    const gPath = g.append('path');
    const gHoverPath = gHover.append('path');

    gPath.attr('d', arc).style('fill', (d, i) => color(i));

    const fillHover = gHoverPath
      .attr('d', arc)
      .style('fill', (d, i) => color(i))
      .style('opacity', 0);

    fillHover
      .attr('class', d => `pointer arc-hover-${_.snakeCase(d.data.id)}`)
      .on('mouseenter', d => {
        document.querySelector(
          `.arc-hover-${_.snakeCase(d.data.id)}`
        ).style.opacity = 0.5;
        setTooltip(d.data.tooltip);
      })
      .on('mouseleave', d => {
        document.querySelector(
          `.arc-hover-${_.snakeCase(d.data.id)}`
        ).style.opacity = 0;
        setTooltip();
      })
      .on('mousedown', d => {
        if (d.data.clickHandler) {
          d.data.clickHandler(d);
          setTooltip();
        }
      });

    return node.toReact();
  }
);

PieChart.propTypes = {
  data: PropTypes.array,
};

/*----------------------------------------------------------------------------*/

export default PieChart;
<|endoftext|>


<commit_before>/**
 * Copyright 2018 The Subscribe with Google Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {ErrorUtils, createCancelError, isCancelError} from './errors';

describes.realWin('errors', {}, () => {
  describe('isCancelError', () => {
    it('should return true for an abort error', () => {
      const e = new DOMException('cancel', 'AbortError');
      expect(isCancelError(e)).to.be.true;
    });

    it('should return false for non-errors', () => {
      expect(isCancelError(undefined)).to.be.false;
      expect(isCancelError(null)).to.be.false;
      expect(isCancelError('')).to.be.false;
      expect(isCancelError('abc')).to.be.false;
      expect(isCancelError(0)).to.be.false;
      expect(isCancelError(1)).to.be.false;
      expect(isCancelError(true)).to.be.false;
      expect(isCancelError(false)).to.be.false;
    });

    it('should return false for a unrelated error', () => {
      expect(isCancelError(new Error())).to.be.false;
    });
  });

  describe('createCancelError', () => {
    const error = createCancelError(this, 'custom message');
    expect(error.code).to.equal(20);
    expect(error.message).to.equal('AbortError: custom message');
    expect(error.name).to.equal('AbortError');
  });

  describe('ErrorUtils', () => {
    describe('throwAsync', () => {
      it('throws error after a timeout', () => {
        let callback;
        sandbox.stub(this, 'setTimeout').callsFake(cb => {
          callback = cb;
        });

        ErrorUtils.throwAsync(new Error('delayed error'));

        expect(callback).to.throw(/delayed/);
      });
    });
  });
});
<commit_msg>Fixes references to window<commit_after>/**
 * Copyright 2018 The Subscribe with Google Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {ErrorUtils, createCancelError, isCancelError} from './errors';

describe('errors', () => {
  describe('isCancelError', () => {
    it('should return true for an abort error', () => {
      const e = new DOMException('cancel', 'AbortError');
      expect(isCancelError(e)).to.be.true;
    });

    it('should return false for non-errors', () => {
      expect(isCancelError(undefined)).to.be.false;
      expect(isCancelError(null)).to.be.false;
      expect(isCancelError('')).to.be.false;
      expect(isCancelError('abc')).to.be.false;
      expect(isCancelError(0)).to.be.false;
      expect(isCancelError(1)).to.be.false;
      expect(isCancelError(true)).to.be.false;
      expect(isCancelError(false)).to.be.false;
    });

    it('should return false for a unrelated error', () => {
      expect(isCancelError(new Error())).to.be.false;
    });
  });

  describe('createCancelError', () => {
    it('creates error', () => {
      const error = createCancelError(self, 'custom message');
      expect(error.code).to.equal(20);
      expect(error.message).to.equal('AbortError: custom message');
      expect(error.name).to.equal('AbortError');
    });
  });

  describe('ErrorUtils', () => {
    describe('throwAsync', () => {
      it('throws error after a timeout', () => {
        // Mock `setTimeout`
        let callback;
        const setTimeout = self.setTimeout;
        self.setTimeout = cb => {
          callback = cb;
        };

        ErrorUtils.throwAsync(new Error('delayed error'));
        expect(callback).to.throw(/delayed/);

        // Restore `setTimeout`
        self.setTimeout = setTimeout;
      });
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

/**
 * Rhizome - The API that feeds grassroots movements
 *
 * @file helpers.js
 * @description Helpers
 * @module System
 * @author Chris Bates-Keegan
 *
 */

module.exports.Promise = {};

module.exports.Promise.prop = prop => (val => val[prop]);
module.exports.Promise.func = func => (val => val[func]());
module.exports.Promise.nop = () => (() => null);

<commit_msg>- ADDED: inject - to insert an arbitrary value into the promise chain<commit_after>'use strict';

/**
 * Rhizome - The API that feeds grassroots movements
 *
 * @file helpers.js
 * @description Helpers
 * @module System
 * @author Chris Bates-Keegan
 *
 */

module.exports.Promise = {
  prop: prop => (val => val[prop]),
  func: func => (val => val[func]()),
  nop: () => (() => null),
  inject: value => (() => value)
};

<|endoftext|>


<commit_before>// @ts-check
"use strict";

var EOL = require("os").EOL;
var fs = require("fs");
var path = require("path");

var defaultJasmineOptions = {};

function logError(...args) {
    var errorArgs = Array.prototype.slice.call(arguments);
    errorArgs.unshift("NTVS_ERROR:");
    console.error.apply(console, errorArgs);
}

function getJasmineOptionsPath(projectFolder) {
    return path.join(projectFolder, "test", "jasmine.json");
}

function detectJasmine(projectFolder) {
    try {
        var node_modulesFolder = path.join(projectFolder, "node_modules");
        var options = loadJsonOptions(getJasmineOptionsPath(projectFolder));
        if (options && options.path) {
            node_modulesFolder = path.resolve(projectFolder, options.path);
        }
        return require(path.join(node_modulesFolder, "jasmine"));
    }
    catch (ex) {
        logError('Failed to find Jasmine package. Jasmine must be installed in the project locally.' + EOL +
            'Install Jasmine locally using the npm manager via solution explorer' + EOL +
            'or with ".npm install jasmine --save-dev" via the Node.js interactive window.');
    }
    return null;
}

function loadJsonOptions(optionsPath) {
    if (fs.existsSync(optionsPath)) {
        return require(optionsPath);
    }
}

function loadJasmineOptions(projectFolder) {
    var options = loadJsonOptions(getJasmineOptionsPath(projectFolder));
    if (options && options.configFile) {
        var optionsPath = path.join(projectFolder, "test", options.configFile);
        options = loadJsonOptions(optionsPath);
    }
    return options;
}

function mergeOptions(target, source) {
    for (var opt in source) {
        target[opt] = source[opt];
    }
}

function getJasmineOptions(projectFolder) {
    var jasmineOptions = defaultJasmineOptions;
    try {
        var options = loadJasmineOptions(projectFolder);
        options && mergeOptions(jasmineOptions, options);
        options && console.log("Found jasmine.json file.");
    }
    catch (ex) {
        console.error("Failed to load Jasmine setting, using default settings.", ex);
    }
    console.log("Using Jasmine settings: ", jasmineOptions);
    return jasmineOptions;
}

function applyJasmineOptions(jasmineInstance, options) {
    if (options) {
        jasmineInstance.loadConfig(options);
    }
}

function initializeJasmine(Jasmine, projectFolder) {
    var instance = new Jasmine();
    applyJasmineOptions(instance, getJasmineOptions(projectFolder));
    return instance;
}

/**
 * @param {jasmine.Suite} suite
 * @param {object[]} testList
 * @param {string} testFile
 */
function enumerateSpecs(suite, testList, testFile) {
    suite.children.forEach((child) => {
        if (child instanceof jasmine.Suite) {
            enumerateSpecs(child, testList, testFile);
        } else {
            testList.push({
                test: child.getFullName(),
                suite: suite.description,
                file: testFile,
                line: 0,
                column: 0
            });
        }
    });
}

/**
 * @param {string} testFileList
 * @param {string} discoverResultFile
 * @param {string} projectFolder
 */
function find_tests(testFileList, discoverResultFile, projectFolder) {
    var Jasmine = detectJasmine(projectFolder);
    if (!Jasmine) {
        return;
    }
    var jasmineInstance = initializeJasmine(Jasmine, projectFolder);
    jasmineInstance.env.specFilter = _ => false;

    var testList = [];
    testFileList.split(";").forEach((testFile) => {
        try {
            jasmineInstance.specDir = "";
            jasmineInstance.specFiles = [];
            jasmineInstance.addSpecFiles([testFile]);
            jasmineInstance.loadSpecs();

            var topSuite = jasmineInstance.env.topSuite();
            enumerateSpecs(topSuite, testList, testFile);
        }
        catch (ex) {
            //we would like continue discover other files, so swallow, log and continue;
            console.error("Test discovery error:", ex, "in", testFile);
        }
    });

    var fd = fs.openSync(discoverResultFile, 'w');
    fs.writeSync(fd, JSON.stringify(testList));
    fs.closeSync(fd);
}

exports.find_tests = find_tests;

function createTestResult() {
    return {
        title: "",
        passed: false,
        pending: false,
        stdout: "",
        stderr: ""
    };
}

var result = createTestResult();

function hookStandardOutputs() {
    process.stdout.write = (str, encording, callback) => {
        result.stdout += str;
        return true;
    };
    process.stderr.write = (str, encording, callback) => {
        result.stderr += str;
        return true;
    };
}

function sendTestProgress(callback, evtType, result, title) {
    var event = {
        type: evtType,
        result: result
    };
    title && (event.title = title);
    callback(event);
    hookStandardOutputs();
}

function createCustomReporter(callback) {
    return {
        jasmineStarted: (suiteInfo) => {
            sendTestProgress(callback, "start", result);
        },
        suiteStarted: (suiteResult) => {
            sendTestProgress(callback, "suite start", result);
        },
        specStarted: (specResult) => {
            result.title = specResult.fullName;
            sendTestProgress(callback, "test start", undefined, result.title);
        },
        specDone: (specResult) => {
            var type = "result";
            result.passed = specResult.status == "passed";
            if (specResult.status == "disabled" || specResult.status == "pending") {
                type = "pending";
                result.pending = true;
            }
            sendTestProgress(callback, type, result, specResult.fullName);
            result = createTestResult();
        },
        suiteDone: (suiteResult) => {
            sendTestProgress(callback, "suite end", result);
        },
        jasmineDone: (suiteInfo) => {
            sendTestProgress(callback, "end", result);
        }
    };
}

function run_tests(testCases, callback) {
    hookStandardOutputs();

    var projectFolder = testCases[0].projectFolder;
    var Jasmine = detectJasmine(projectFolder);
    if (!Jasmine) {
        return;
    }
    var testFileList = [];
    var testNameList = {};
    testCases.forEach((testCase) => {
        if (testFileList.indexOf(testCase.testFile) < 0) {
            testFileList.push(testCase.testFile);
        }
        testNameList[testCase.testName] = true;
    });
    try {
        var jasmineInstance = initializeJasmine(Jasmine, projectFolder);
        jasmineInstance.configureDefaultReporter({ showColors: false });
        jasmineInstance.env.specFilter = (spec) => {
            return testNameList.hasOwnProperty(spec.getSpecName(spec));
        };
        jasmineInstance.addReporter(createCustomReporter(callback));
        jasmineInstance.execute(testFileList);
    }
    catch (ex) {
        logError("Execute test error:", ex);
    }
}
exports.run_tests = run_tests;
<commit_msg>Fix Jasmine specFilter deprecation<commit_after>// @ts-check
"use strict";

var EOL = require("os").EOL;
var fs = require("fs");
var path = require("path");

var defaultJasmineOptions = {};

function logError(...args) {
    var errorArgs = Array.prototype.slice.call(arguments);
    errorArgs.unshift("NTVS_ERROR:");
    console.error.apply(console, errorArgs);
}

function getJasmineOptionsPath(projectFolder) {
    return path.join(projectFolder, "test", "jasmine.json");
}

function detectJasmine(projectFolder) {
    try {
        var node_modulesFolder = path.join(projectFolder, "node_modules");
        var options = loadJsonOptions(getJasmineOptionsPath(projectFolder));
        if (options && options.path) {
            node_modulesFolder = path.resolve(projectFolder, options.path);
        }
        return require(path.join(node_modulesFolder, "jasmine"));
    }
    catch (ex) {
        logError('Failed to find Jasmine package. Jasmine must be installed in the project locally.' + EOL +
            'Install Jasmine locally using the npm manager via solution explorer' + EOL +
            'or with ".npm install jasmine --save-dev" via the Node.js interactive window.');
    }
    return null;
}

function loadJsonOptions(optionsPath) {
    if (fs.existsSync(optionsPath)) {
        return require(optionsPath);
    }
}

function loadJasmineOptions(projectFolder) {
    var options = loadJsonOptions(getJasmineOptionsPath(projectFolder));
    if (options && options.configFile) {
        var optionsPath = path.join(projectFolder, "test", options.configFile);
        options = loadJsonOptions(optionsPath);
    }
    return options;
}

function mergeOptions(target, source) {
    for (var opt in source) {
        target[opt] = source[opt];
    }
}

function getJasmineOptions(projectFolder) {
    var jasmineOptions = defaultJasmineOptions;
    try {
        var options = loadJasmineOptions(projectFolder);
        options && mergeOptions(jasmineOptions, options);
        options && console.log("Found jasmine.json file.");
    }
    catch (ex) {
        console.error("Failed to load Jasmine setting, using default settings.", ex);
    }
    console.log("Using Jasmine settings: ", jasmineOptions);
    return jasmineOptions;
}

function applyJasmineOptions(jasmineInstance, options) {
    if (options) {
        jasmineInstance.loadConfig(options);
    }
}

function initializeJasmine(Jasmine, projectFolder) {
    var instance = new Jasmine();
    applyJasmineOptions(instance, getJasmineOptions(projectFolder));
    return instance;
}

/**
 * @param {jasmine.Suite} suite
 * @param {object[]} testList
 * @param {string} testFile
 */
function enumerateSpecs(suite, testList, testFile) {
    suite.children.forEach((child) => {
        if (child instanceof jasmine.Suite) {
            enumerateSpecs(child, testList, testFile);
        } else {
            testList.push({
                test: child.getFullName(),
                suite: suite.description,
                file: testFile,
                line: 0,
                column: 0
            });
        }
    });
}

/**
 * @param {string} testFileList
 * @param {string} discoverResultFile
 * @param {string} projectFolder
 */
function find_tests(testFileList, discoverResultFile, projectFolder) {
    var Jasmine = detectJasmine(projectFolder);
    if (!Jasmine) {
        return;
    }
    var jasmineInstance = initializeJasmine(Jasmine, projectFolder);
    setSpecFilter(jasmineInstance, _ => false);

    var testList = [];
    testFileList.split(";").forEach((testFile) => {
        try {
            jasmineInstance.specDir = "";
            jasmineInstance.specFiles = [];
            jasmineInstance.addSpecFiles([testFile]);
            jasmineInstance.loadSpecs();

            var topSuite = jasmineInstance.env.topSuite();
            enumerateSpecs(topSuite, testList, testFile);
        }
        catch (ex) {
            //we would like continue discover other files, so swallow, log and continue;
            console.error("Test discovery error:", ex, "in", testFile);
        }
    });

    var fd = fs.openSync(discoverResultFile, 'w');
    fs.writeSync(fd, JSON.stringify(testList));
    fs.closeSync(fd);
}

exports.find_tests = find_tests;

function createTestResult() {
    return {
        title: "",
        passed: false,
        pending: false,
        stdout: "",
        stderr: ""
    };
}

var result = createTestResult();

function hookStandardOutputs() {
    process.stdout.write = (str, encording, callback) => {
        result.stdout += str;
        return true;
    };
    process.stderr.write = (str, encording, callback) => {
        result.stderr += str;
        return true;
    };
}

function sendTestProgress(callback, evtType, result, title) {
    var event = {
        type: evtType,
        result: result
    };
    title && (event.title = title);
    callback(event);
    hookStandardOutputs();
}

function createCustomReporter(callback) {
    return {
        jasmineStarted: (suiteInfo) => {
            sendTestProgress(callback, "start", result);
        },
        suiteStarted: (suiteResult) => {
            sendTestProgress(callback, "suite start", result);
        },
        specStarted: (specResult) => {
            result.title = specResult.fullName;
            sendTestProgress(callback, "test start", undefined, result.title);
        },
        specDone: (specResult) => {
            var type = "result";
            result.passed = specResult.status == "passed";
            if (specResult.status == "disabled" || specResult.status == "pending") {
                type = "pending";
                result.pending = true;
            }
            sendTestProgress(callback, type, result, specResult.fullName);
            result = createTestResult();
        },
        suiteDone: (suiteResult) => {
            sendTestProgress(callback, "suite end", result);
        },
        jasmineDone: (suiteInfo) => {
            sendTestProgress(callback, "end", result);
        }
    };
}

function run_tests(testCases, callback) {
    hookStandardOutputs();

    var projectFolder = testCases[0].projectFolder;
    var Jasmine = detectJasmine(projectFolder);
    if (!Jasmine) {
        return;
    }
    var testFileList = [];
    var testNameList = {};
    testCases.forEach((testCase) => {
        if (testFileList.indexOf(testCase.testFile) < 0) {
            testFileList.push(testCase.testFile);
        }
        testNameList[testCase.testName] = true;
    });
    try {
        var jasmineInstance = initializeJasmine(Jasmine, projectFolder);
        jasmineInstance.configureDefaultReporter({ showColors: false });
        setSpecFilter(jasmineInstance, spec => testNameList.hasOwnProperty(spec.getSpecName(spec)));
        jasmineInstance.addReporter(createCustomReporter(callback));
        jasmineInstance.execute(testFileList);
    }
    catch (ex) {
        logError("Execute test error:", ex);
    }
}

function setSpecFilter(jasmineInstance, specFilter) {
    if (jasmineInstance.env.configure) {
        jasmineInstance.env.configure({ specFilter });
    } else {
        jasmineInstance.env.specFilter = specFilter;
    }
}

exports.run_tests = run_tests;
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();

var fs = require('fs-extra');
var uuid = require('uuid');
var moment = require('moment');
var getFolderSize = require('get-folder-size');
var path = require('path');

var paths = require('../paths');
var user = require('../user');

var dateFormat = 'ddd, D MMM YYYY HH:mm:ss ZZ';

var parseOAuthHeader = function(req, res, next) {
  var oauth = req.header('Authorization');
  console.log('OAuth: ' + oauth);

  var oauth = oauth.replace(/OAuth/, '');
  var oauth = oauth.replace(/\s/g, '');
  var oauth = oauth.replace(/\"/g, '');

  var parts = oauth.split(',');
  parts.forEach(function(part) {
    var keyValue = part.split('=');
    if (keyValue[0] == 'oauth_token') {
      req.oauthToken = keyValue[1];
    } else if (keyValue[0] == 'oauth_signature') {
      req.oauthSignature = keyValue[1];
    }
  });

  return next();
};

var verifyOAuthSecret = function(req, res, next) {
  var signatureParts = req.oauthSignature.split('&');
  console.log("Verify signature", signatureParts[1]);
  if (signatureParts[1] == req.oauthToken) {
    return next();
  } else {
    console.log('OAuth error, token', req.oauthToken,
    'signature', req.oauthSignature);
    res.sendStatus(403);
  }
};

/* GET home page. */
router.get('/files/sandbox/*', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/files/sandbox/', req.params[0]);

  var fullPath = paths.getDataPath(req.oauthToken, req.params[0]);
  fs.stat(fullPath, function(err, stats) {
    if (err) {
      console.log(err);
      req.status(500).send(err.stack);
      return;
    }

    var fileSize = stats.size;
    if (fileSize < req.range.last) {
      req.range.last = fileSize;
    }
    res.range({
         first: req.range.first,
         last: req.range.last,
         length: req.range.last - req.range.first
       });

    console.log('range', req.range);
    var s = fs.createReadStream(fullPath,
       {start: req.range.first, end: req.range.last}).pipe(res);
    s.on('finish', function() {res.end();});
  });
});

router.put('/files_put/sandbox/*', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/files_put/sandbox/', req.params[0]);
  var fullPath = paths.getDataPath(req.oauthToken, req.params[0]);

  var dir = path.dirname(fullPath);
  fs.mkdirp(dir, function(err) {
    if (err) {
      res.sendStatus(500);
    } else {
      var stream = fs.createWriteStream(fullPath);
      stream.write(req.body, function() {
        fs.stat(fullPath, function(err, stats) {
          res.json({
            bytes: stats.size,
            path: '/' + req.params[0],
            modified: moment(stats.mtime).format(dateFormat),
          });
        });
      });
    }
  });
});

router.put('/chunked_upload', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/files_put/chunked_upload/', req.query.upload_id, req.query.offset, req.header('Content-Length'));
  var upload_id = req.query.upload_id;
  var fileMode = 'r+';
  if (!upload_id) {
    upload_id = uuid();
    fileMode = 'w';
  }

  var offset = req.query.offset;
  if (!offset) {
    offset = 0;
  }

  var chunkPath = paths.getChunkPath(req.oauthToken, upload_id);
  var stream = fs.createWriteStream(chunkPath, {flags: fileMode, defaultEncoding: 'binary', start: Number(offset)});
  stream.write(req.body, function () {
    fs.stat(chunkPath, function(err, stats) {
      console.log('Chunk uploaded', chunkPath, 'total size', stats['size']);
      res.json({
        upload_id: upload_id,
        offset: stats.size,
        expires: 'Tue, 19 Jul 2021 21:55:38 +0000'});
    });
  });
});

router.post('/commit_chunked_upload/sandbox/*', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/commit_chunked_upload/sandbox/', req.params[0], req.body.upload_id);
  if (req.body.upload_id) {
    var chunkPath = paths.getChunkPath(req.oauthToken, req.body.upload_id);
    var datapath = paths.getDataPath(req.oauthToken, req.params[0]);

    var dir = path.dirname(datapath);
    fs.mkdirp(dir, function(err) {
      if (err) {
        res.sendStatus(500);
      } else {
        fs.rename(chunkPath, datapath, function(err) {
          fs.stat(datapath, function(err, stats) {
            res.json({
              bytes: stats.size,
              path: '/' + req.params[0],
              modified: moment(stats.mtime).format(dateFormat),
            });
          });
        });
      }
    });
  } else {
    res.sendStatus(400);
  }
});

router.get('/metadata/sandbox/*', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/metadata/sandbox/', req.params[0]);
    var fullPath = paths.getDataPath(req.oauthToken, req.params[0]);
    fs.stat(fullPath, function(err, stats) {
      if(err) {
        res.sendStatus(404);
      } else {
        res.json({
          bytes: stats.size,
          path: '/' + req.params[0],
          modified: moment(stats.mtime).utc().format(dateFormat),
          is_dir: stats.isDirectory()
        });
      }
    });
});

router.post('/fileops/create_folder', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/fileops/create_folder/', req.body.path);
  var fullPath = paths.getDataPath(req.oauthToken, req.body.path);
  fs.mkdirp(fullPath, function(err) {
    if (err) {
      res.sendStatus(403);
    } else {
      res.json({
        bytes: 0,
        path: '/' + req.body.path,
        modified: moment().utc().format(dateFormat),
        is_dir: true
      });
    }
  });
});

router.post('/fileops/delete', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/fileops/delete/', req.body.path);
  var fullPath = paths.getDataPath(req.oauthToken, req.body.path);
  fs.remove(fullPath, function(err) {
    if (err) {
      res.sendStatus(403);
    } else {
      res.json({
        bytes: 0,
        path: '/' + req.body.path,
        modified: moment().utc().format(dateFormat),
        is_deleted: true
      });
    }
  });
});

router.get('/account/info', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/account/info');
  getFolderSize(paths.getDataPath(req.oauthToken, ''), function(err, size) {
    if (err) {
      res.status(500).send(err.stack);
    } else {
      res.json({
        uid: user.getUserId(req.oauthToken),
        quota_info: {
          shared: 0,
          quota: 2*1024*1024*1024,
          normal: size
        }
      });
    }
  });

});

module.exports = router;
<commit_msg>Fix auth checks<commit_after>var express = require('express');
var router = express.Router();

var fs = require('fs-extra');
var uuid = require('uuid');
var moment = require('moment');
var getFolderSize = require('get-folder-size');
var path = require('path');

var paths = require('../paths');
var user = require('../user');

var dateFormat = 'ddd, D MMM YYYY HH:mm:ss ZZ';

var parseOAuthHeader = function(req, res, next) {
  var oauth = req.header('Authorization');
  console.log('OAuth: ' + oauth);

  if (!oauth) {
    return res.sendStatus(403);
  }

  var oauth = oauth.replace(/OAuth/, '');
  var oauth = oauth.replace(/\s/g, '');
  var oauth = oauth.replace(/\"/g, '');

  var parts = oauth.split(',');
  parts.forEach(function(part) {
    var keyValue = part.split('=');
    if (keyValue[0] == 'oauth_token') {
      req.oauthToken = keyValue[1];
    } else if (keyValue[0] == 'oauth_signature') {
      req.oauthSignature = keyValue[1];
    }
  });

  return next();
};

var verifyOAuthSecret = function(req, res, next) {
  if (!req.oauthSignature || !req.oauthToken) {
    return res.sendStatus(403);
  }

  var signatureParts = req.oauthSignature.split('&');
  console.log("Verify signature", signatureParts[1]);
  if (signatureParts[1] == req.oauthToken) {
    return next();
  } else {
    console.log('OAuth error, token', req.oauthToken,
    'signature', req.oauthSignature);
    res.sendStatus(403);
  }
};

/* GET home page. */
router.get('/files/sandbox/*', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/files/sandbox/', req.params[0]);

  var fullPath = paths.getDataPath(req.oauthToken, req.params[0]);
  fs.stat(fullPath, function(err, stats) {
    if (err) {
      console.log(err);
      req.status(500).send(err.stack);
      return;
    }

    var fileSize = stats.size;
    if (fileSize < req.range.last) {
      req.range.last = fileSize;
    }
    res.range({
         first: req.range.first,
         last: req.range.last,
         length: req.range.last - req.range.first
       });

    console.log('range', req.range);
    var s = fs.createReadStream(fullPath,
       {start: req.range.first, end: req.range.last}).pipe(res);
    s.on('finish', function() {res.end();});
  });
});

router.put('/files_put/sandbox/*', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/files_put/sandbox/', req.params[0]);
  var fullPath = paths.getDataPath(req.oauthToken, req.params[0]);

  var dir = path.dirname(fullPath);
  fs.mkdirp(dir, function(err) {
    if (err) {
      res.sendStatus(500);
    } else {
      var stream = fs.createWriteStream(fullPath);
      stream.write(req.body, function() {
        fs.stat(fullPath, function(err, stats) {
          res.json({
            bytes: stats.size,
            path: '/' + req.params[0],
            modified: moment(stats.mtime).format(dateFormat),
          });
        });
      });
    }
  });
});

router.put('/chunked_upload', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/files_put/chunked_upload/', req.query.upload_id, req.query.offset, req.header('Content-Length'));
  var upload_id = req.query.upload_id;
  var fileMode = 'r+';
  if (!upload_id) {
    upload_id = uuid();
    fileMode = 'w';
  }

  var offset = req.query.offset;
  if (!offset) {
    offset = 0;
  }

  var chunkPath = paths.getChunkPath(req.oauthToken, upload_id);
  var stream = fs.createWriteStream(chunkPath, {flags: fileMode, defaultEncoding: 'binary', start: Number(offset)});
  stream.write(req.body, function () {
    fs.stat(chunkPath, function(err, stats) {
      console.log('Chunk uploaded', chunkPath, 'total size', stats['size']);
      res.json({
        upload_id: upload_id,
        offset: stats.size,
        expires: 'Tue, 19 Jul 2021 21:55:38 +0000'});
    });
  });
});

router.post('/commit_chunked_upload/sandbox/*', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/commit_chunked_upload/sandbox/', req.params[0], req.body.upload_id);
  if (req.body.upload_id) {
    var chunkPath = paths.getChunkPath(req.oauthToken, req.body.upload_id);
    var datapath = paths.getDataPath(req.oauthToken, req.params[0]);

    var dir = path.dirname(datapath);
    fs.mkdirp(dir, function(err) {
      if (err) {
        res.sendStatus(500);
      } else {
        fs.rename(chunkPath, datapath, function(err) {
          fs.stat(datapath, function(err, stats) {
            res.json({
              bytes: stats.size,
              path: '/' + req.params[0],
              modified: moment(stats.mtime).format(dateFormat),
            });
          });
        });
      }
    });
  } else {
    res.sendStatus(400);
  }
});

router.get('/metadata/sandbox/*', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/metadata/sandbox/', req.params[0]);
    var fullPath = paths.getDataPath(req.oauthToken, req.params[0]);
    fs.stat(fullPath, function(err, stats) {
      if(err) {
        res.sendStatus(404);
      } else {
        res.json({
          bytes: stats.size,
          path: '/' + req.params[0],
          modified: moment(stats.mtime).utc().format(dateFormat),
          is_dir: stats.isDirectory()
        });
      }
    });
});

router.post('/fileops/create_folder', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/fileops/create_folder/', req.body.path);
  var fullPath = paths.getDataPath(req.oauthToken, req.body.path);
  fs.mkdirp(fullPath, function(err) {
    if (err) {
      res.sendStatus(403);
    } else {
      res.json({
        bytes: 0,
        path: '/' + req.body.path,
        modified: moment().utc().format(dateFormat),
        is_dir: true
      });
    }
  });
});

router.post('/fileops/delete', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/fileops/delete/', req.body.path);
  var fullPath = paths.getDataPath(req.oauthToken, req.body.path);
  fs.remove(fullPath, function(err) {
    if (err) {
      res.sendStatus(403);
    } else {
      res.json({
        bytes: 0,
        path: '/' + req.body.path,
        modified: moment().utc().format(dateFormat),
        is_deleted: true
      });
    }
  });
});

router.get('/account/info', parseOAuthHeader, verifyOAuthSecret, function(req, res, next) {
  console.log('/account/info');
  getFolderSize(paths.getDataPath(req.oauthToken, ''), function(err, size) {
    if (err) {
      res.status(500).send(err.stack);
    } else {
      res.json({
        uid: user.getUserId(req.oauthToken),
        quota_info: {
          shared: 0,
          quota: 2*1024*1024*1024,
          normal: size
        }
      });
    }
  });

});

module.exports = router;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Link, hashHistory } from 'react-router';
import { connect } from 'react-redux';
import styles from './Sidebar.css';
import Project_List from './Project_List';
import {fetchUserProjects} from '../reducers/projects_list';
import {logUserOut} from '../reducers/login';
import * as fs from 'fs';
import * as FEActions from '../../utilities/vcfrontend';
import axios from 'axios';

export class Sidebar extends Component {
    constructor(props) {
      super(props)
      this.localLogUserOut = this.localLogUserOut.bind(this);
      this.linkToHomeView = this.linkToHomeView.bind(this);
      this.onClickArchiveUpdate = this.onClickArchiveUpdate.bind(this);
      this.onClickAddFile = this.onClickAddFile.bind(this);
      this.onClickAddArchive = this.onClickAddArchive.bind(this);
    }

  onClickAddArchive(event) {
    const project = this.props.currents && this.props.currents.currentProject
      ? this.props.currents.currentProject : undefined;
    project && axios.get(`http://localhost:3000/api/vcontrol/${project.id}`)
      .then(project => {
        const projectData = project.data[0];
        // Note the object structure
        // project.commits[0].blob.files[0];

        // create the directory if it doesn't already exist
        const dirPath = `./${projectData.name}`;
        try{
          fs.statSync(dirPath).isDirectory()
        } catch (err) {
          fs.mkdirSync(dirPath);
        }
        // create the file if it doesn't already exist
        // NOTE: WILL CONTAIN MOST RECENT DATA
        const commits = projectData.commits;
        const fileData = commits[commits.length - 1].blob.files[0];
        const filePath = `${dirPath}/${fileData.file_name}.txt`
        fs.writeFileSync(filePath, fileData.file_contents, 'utf-8');

        // then create the .archive directory
        try {
          fs.statSync(`${dirPath}/.archive`).isDirectory()
        } catch (err){
          FEActions.initNewProject(dirPath);
        }

        // then create all the .archive files
        projectData.commits.forEach((commit, index) => {
          // commitFileChanges(filePath, message, mergeHash, date)
          const fileHash = commit.blob.hash;
          const fileContent = commit.blob.files[0].file_contents;
          FEActions.commitFileChanges(filePath, commit.message, undefined, commit.date, fileHash, fileContent);
        })
      })
  }

  onClickArchiveUpdate(event) {
  }

  onClickAddFile(event) {
    // Hardcode this to the current filePath since we're only doing one file
    const project = this.props.currents && this.props.currents.currentProject
      ? this.props.currents.currentProject : undefined;
    const fileData = project ? project.commits[0].blob.files[0] : undefined;
    const filePath = project && fileData
      ? `./${project.name}/${fileData.file_name}.txt` : undefined;
    if(filePath){
      // Check to make sure the file exists first
      try {
        fs.statSync(filePath).isFile();
      } catch (err) {
        console.log(`file ${filePath} does not exist!`);
        return false;
      }

      const fileContents = fs.readFileSync(filePath, 'utf-8');
      console.log(fileContents);
    }
  }

  componentDidUpdate() {
    if (this.props.loginUser.id && !Object.keys(this.props.projects).length) {
      this.props.onLoadProjects(this.props.loginUser.id);
    }
  }

  linkToHomeView(){
    hashHistory.push('/mainHome');
  }

  localLogUserOut(){
    this.props.logMeOut();
  }

  render() {
    return (

                info
                  <button className="btn-floating btn-large waves-effect waves-light pink accent-1 left"
                    onClick={this.onClickAddArchive}>
                    queue
                  </button>
                  info

                  <button className="btn-floating btn-large waves-effect waves-light light-green accent-3 left"
                    onClick={this.onClickArchiveUpdate}>
                    play_for_work
                  </button>

                  <button className="btn-floating btn-large waves-effect waves-light light-blue accent-2 left"
                    onClick={this.onClickAddFile}>
                    trending_up
                  </button>

                <Link onClick={this.linkToHomeView}>

Welcome, {this.props.loginUser.first_name}

                  person_pin
                </Link>

                <Link to={'/'}>

Logout

                </Link>

                <Project_List/>

    );
  }
}

function mapStateToProps(state) {
  return {
    loginUser: state.login,
    projects: state.projects,
    currents: state.currents
  }
}

function mapDispatchToProps(dispatch) {
  return {
    onLoadProjects: function (user) {
      dispatch(fetchUserProjects(user));
    },
    logMeOut: function(){
      dispatch(logUserOut());
    }
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Sidebar);<commit_msg>logging to see when adding archive<commit_after>import React, { Component } from 'react';
import { Link, hashHistory } from 'react-router';
import { connect } from 'react-redux';
import styles from './Sidebar.css';
import Project_List from './Project_List';
import {fetchUserProjects} from '../reducers/projects_list';
import {logUserOut} from '../reducers/login';
import * as fs from 'fs';
import * as FEActions from '../../utilities/vcfrontend';
import axios from 'axios';

export class Sidebar extends Component {
    constructor(props) {
      super(props)
      this.localLogUserOut = this.localLogUserOut.bind(this);
      this.linkToHomeView = this.linkToHomeView.bind(this);
      this.onClickArchiveUpdate = this.onClickArchiveUpdate.bind(this);
      this.onClickAddFile = this.onClickAddFile.bind(this);
      this.onClickAddArchive = this.onClickAddArchive.bind(this);
    }

  onClickAddArchive(event) {
    console.log('adding archive to local machine');
    const project = this.props.currents && this.props.currents.currentProject
      ? this.props.currents.currentProject : undefined;
    project && axios.get(`http://localhost:3000/api/vcontrol/${project.id}`)
      .then(project => {
        const projectData = project.data[0];
        // Note the object structure
        // project.commits[0].blob.files[0];

        // create the directory if it doesn't already exist
        const dirPath = `./${projectData.name}`;
        try{
          fs.statSync(dirPath).isDirectory()
        } catch (err) {
          fs.mkdirSync(dirPath);
        }
        // create the file if it doesn't already exist
        // NOTE: WILL CONTAIN MOST RECENT DATA
        const commits = projectData.commits;
        const fileData = commits[commits.length - 1].blob.files[0];
        const filePath = `${dirPath}/${fileData.file_name}.txt`
        fs.writeFileSync(filePath, fileData.file_contents, 'utf-8');

        // then create the .archive directory
        try {
          fs.statSync(`${dirPath}/.archive`).isDirectory()
        } catch (err){
          FEActions.initNewProject(dirPath);
        }

        // then create all the .archive files
        projectData.commits.forEach((commit, index) => {
          // commitFileChanges(filePath, message, mergeHash, date)
          const fileHash = commit.blob.hash;
          const fileContent = commit.blob.files[0].file_contents;
          FEActions.commitFileChanges(filePath, commit.message, undefined, commit.date, fileHash, fileContent);
        })
      })
  }

  onClickArchiveUpdate(event) {
  }

  onClickAddFile(event) {
    // Hardcode this to the current filePath since we're only doing one file
    const project = this.props.currents && this.props.currents.currentProject
      ? this.props.currents.currentProject : undefined;
    const fileData = project ? project.commits[0].blob.files[0] : undefined;
    const filePath = project && fileData
      ? `./${project.name}/${fileData.file_name}.txt` : undefined;
    if(filePath){
      // Check to make sure the file exists first
      try {
        fs.statSync(filePath).isFile();
      } catch (err) {
        console.log(`file ${filePath} does not exist!`);
        return false;
      }

      const fileContents = fs.readFileSync(filePath, 'utf-8');
      console.log(fileContents);
    }
  }

  componentDidUpdate() {
    if (this.props.loginUser.id && !Object.keys(this.props.projects).length) {
      this.props.onLoadProjects(this.props.loginUser.id);
    }
  }

  linkToHomeView(){
    hashHistory.push('/mainHome');
  }

  localLogUserOut(){
    this.props.logMeOut();
  }

  render() {
    return (

                info
                  <button className="btn-floating btn-large waves-effect waves-light pink accent-1 left"
                    onClick={this.onClickAddArchive}>
                    queue
                  </button>
                  info

                  <button className="btn-floating btn-large waves-effect waves-light light-green accent-3 left"
                    onClick={this.onClickArchiveUpdate}>
                    play_for_work
                  </button>

                  <button className="btn-floating btn-large waves-effect waves-light light-blue accent-2 left"
                    onClick={this.onClickAddFile}>
                    trending_up
                  </button>

                <Link onClick={this.linkToHomeView}>

Welcome, {this.props.loginUser.first_name}

                  person_pin
                </Link>

                <Link to={'/'}>

Logout

                </Link>

                <Project_List/>

    );
  }
}

function mapStateToProps(state) {
  return {
    loginUser: state.login,
    projects: state.projects,
    currents: state.currents
  }
}

function mapDispatchToProps(dispatch) {
  return {
    onLoadProjects: function (user) {
      dispatch(fetchUserProjects(user));
    },
    logMeOut: function(){
      dispatch(logUserOut());
    }
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Sidebar);<|endoftext|>


<commit_before>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

/**
 * Method using a factory pattern variant to get a reducer
 * for a particular page or page style.
 *
 * For a new page - create a constant object with the
 * methods from reducerMethods which are composed to create
 * a reducer. Add to PAGE_REDUCERS.
 *
 * Each key value pair in a reducer object should be in the form
 * action type: reducer function, returning a new state object
 *
 */

import {
  filterData,
  focusNextCell,
  selectRow,
  deselectRow,
  deselectAll,
  focusCell,
  sortData,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
  addItem,
  editTheirRef,
  editComment,
  deleteRecordsById,
  refreshData,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
} from './reducerMethods';

/**
 * Used for actions that should be in all pages using a data table.
 */
const BASE_TABLE_PAGE_REDUCER = {
  focusNextCell,
  focusCell,
  sortData,
};

const customerInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  editField,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
  addItem,
  editTheirRef,
  editComment,
  deleteRecordsById,
  refreshData,
};

const customerInvoices = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  deleteRecordsById,
};

const supplierInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  closeBasicModal,
  openBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addItem,
  editField,
  deleteRecordsById,
};

const supplierRequisition = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addMasterListItems,
  addItem,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
  deleteRecordsById,
};

const programSupplierRequisition = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addMasterListItems,
  addItem,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
};

const supplierRequisitions = {
  sortData,
  filterData,
  selectRow,
  deselectRow,
  openBasicModal,
  closeBasicModal,
  refreshData,
};

const stocktakes = {
  openBasicModal,
  closeBasicModal,
  filterData,
  selectRow,
  deselectAll,
  deselectRow,
  sortData,
};

const PAGE_REDUCERS = {
  customerInvoice,
  customerInvoices,
  supplierInvoice,
  supplierRequisitions,
  supplierRequisition,
  programSupplierRequisition,
  stocktakes,
};

const getReducer = page => {
  const reducer = PAGE_REDUCERS[page];
  return (state, action) => {
    const { type } = action;
    if (!reducer[type]) return state;
    return reducer[type](state, action);
  };
};

export default getReducer;
<commit_msg>Add basic functionality to stocktakeManagePage reducer<commit_after>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

/**
 * Method using a factory pattern variant to get a reducer
 * for a particular page or page style.
 *
 * For a new page - create a constant object with the
 * methods from reducerMethods which are composed to create
 * a reducer. Add to PAGE_REDUCERS.
 *
 * Each key value pair in a reducer object should be in the form
 * action type: reducer function, returning a new state object
 *
 */

import {
  filterData,
  focusNextCell,
  selectRow,
  deselectRow,
  deselectAll,
  focusCell,
  sortData,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
  addItem,
  editTheirRef,
  editComment,
  deleteRecordsById,
  refreshData,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
} from './reducerMethods';

/**
 * Used for actions that should be in all pages using a data table.
 */
const BASE_TABLE_PAGE_REDUCER = {
  focusNextCell,
  focusCell,
  sortData,
};

const customerInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  editField,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  addMasterListItems,
  addItem,
  editTheirRef,
  editComment,
  deleteRecordsById,
  refreshData,
};

const customerInvoices = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  deleteRecordsById,
};

const supplierInvoice = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  closeBasicModal,
  openBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addItem,
  editField,
  deleteRecordsById,
};

const supplierRequisition = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addMasterListItems,
  addItem,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
  deleteRecordsById,
};

const programSupplierRequisition = {
  ...BASE_TABLE_PAGE_REDUCER,
  filterData,
  selectRow,
  deselectRow,
  deselectAll,
  openBasicModal,
  closeBasicModal,
  editTheirRef,
  editComment,
  refreshData,
  addMasterListItems,
  addItem,
  createAutomaticOrder,
  hideOverStocked,
  showOverStocked,
  editField,
};

const supplierRequisitions = {
  sortData,
  filterData,
  selectRow,
  deselectRow,
  openBasicModal,
  closeBasicModal,
  refreshData,
};

const stocktakes = {
  openBasicModal,
  closeBasicModal,
  filterData,
  selectRow,
  deselectAll,
  deselectRow,
  sortData,
};

const stocktakeManager = {
  selectRow,
  deselectAll,
  deselectRow,
  sortData,
  filterData,
};

const PAGE_REDUCERS = {
  customerInvoice,
  customerInvoices,
  supplierInvoice,
  supplierRequisitions,
  supplierRequisition,
  programSupplierRequisition,
  stocktakes,
  stocktakeManager,
};

const getReducer = page => {
  const reducer = PAGE_REDUCERS[page];
  return (state, action) => {
    const { type } = action;
    if (!reducer[type]) return state;
    return reducer[type](state, action);
  };
};

export default getReducer;
<|endoftext|>


<commit_before>const _ = require('lodash');

const validate = val => {
  if (_.isNil(val)) {
    return true;
  }

  return val.__proto__.constructor === Object;
};

const message = '<%= propertyName %> is not an object.';

export default {validate, message};
<commit_msg>Use specific ramda function<commit_after>import isNil from 'ramda/src/isNil';

const validate = val => {
  if (isNil(val)) {
    return true;
  }

  return val.__proto__.constructor === Object;
};

const message = '<%= propertyName %> is not an object.';

export default {validate, message};
<|endoftext|>


<commit_before>import Session from 'ember-parse/services/session';

export default Session;
<commit_msg>Rename session import to ParseSession<commit_after>import ParseSession from 'ember-parse/services/session';

export default ParseSession;
<|endoftext|>


<commit_before>import React from 'react'
import {appFactory, storeFactory} from 'tocco-util'
import MergeWizardContainer from './containers/MergeWizardContainer'
import {getDispatchActions} from './utils/input'
//
import reducers, {sagas} from './modules/reducers'

const packageName = 'merge'

const initApp = (id, input, events, publicPath) => {
  const dispatchActions = getDispatchActions(input)

  return appFactory.createApp(
    packageName,
    <MergeWizardContainer/>,
    reducers,
    sagas,
    input,
    events,
    dispatchActions,
    publicPath
  )
}

(() => {
  if (__DEV__) {
    const fetchMock = require('fetch-mock')
    const setupFetchMocks = require('./dev/fetchMocks')
    setupFetchMocks(fetchMock)

    const input = require('./dev/input.json')

    const app = initApp('id', input)

    if (module.hot) {
      module.hot.accept('./modules/reducers', () => {
        let reducers = require('./modules/reducers').default
        storeFactory.hotReloadReducers(app.store, reducers)
      })
    }

    appFactory.renderApp(app.renderComponent)
  } else {
    storeFactory.registerAppInRegistry(packageName, initApp)
  }
})()
<commit_msg>refactor(merge): fixes due to appFactory changes<commit_after>import React from 'react'
import {appFactory, storeFactory} from 'tocco-util'
import MergeWizardContainer from './containers/MergeWizardContainer'
import {getDispatchActions} from './utils/input'
//
import reducers, {sagas} from './modules/reducers'

const packageName = 'merge'

const initApp = (id, input, events, publicPath) => {
  const dispatchActions = getDispatchActions(input)

  return appFactory.createApp(
    packageName,
    <MergeWizardContainer/>,
    reducers,
    sagas,
    input,
    events,
    dispatchActions,
    publicPath
  )
}

(() => {
  if (__DEV__) {
    const fetchMock = require('fetch-mock')
    const setupFetchMocks = require('./dev/fetchMocks')
    setupFetchMocks(fetchMock)

    const input = require('./dev/input.json')

    const app = initApp('id', input)

    if (module.hot) {
      module.hot.accept('./modules/reducers', () => {
        let reducers = require('./modules/reducers').default
        storeFactory.hotReloadReducers(app.store, reducers)
      })
    }

    appFactory.renderApp(app.renderComponent())
  } else {
    appFactory.registerAppInRegistry(packageName, initApp)
  }
})()
<|endoftext|>


<commit_before>/*!
 * wwwhisper - web access control.
 */
(function () {
  'use strict';
  var stub = new wwwhisper.Stub();

  /**
   * Sends an assertion from a BrowserID sign-in window to the
   * authentication back-end. Reloads the page if login succeeded.
   */
  function verifyEmail(email) {
    stub.ajax('POST', '/wwwhisper/auth/api/send-token/',
              {'email' : email,
               'path': location.pathname
              },
              function() {
                alert('verifivation email was sent');
              },
              function(errorMessage, errorStatus) {
                if (errorStatus === 403) {
                  // Login failed because the user is unknown.
                  $('#login-required').addClass('hide');
                  $('#nothing-shared').removeClass('hide');
                } else {
                  // Other error.
                  $('body').html(errorMessage);
                }
              });
  }

  /**
   * Goes to the logout page if the user is already authenticated.
   */
  function gotoLogoutIfAuthenticated() {
    // Whoami succeeds only for authenticated users.
    stub.ajax('GET', '/wwwhisper/auth/api/whoami/', null,
              function() {
                window.location = '/wwwhisper/auth/logout';
              },
              function() {
                // Logget out (errorStatus 401) or some other error.
                // If error was caused by disabled cookies (CSRF token
                // missing), Persona dialog will inform the user how
                // to enable cookies.
              });
  }

  $('#login-required').removeClass('hide');

  // Register a callback to process a BrowserID assertion.
  $('#verify-button').click(function() {
    verifyEmail($('#email-input').val());
  });

  gotoLogoutIfAuthenticated();

}());
<commit_msg>Revert accidentally committed changes to login JavaScript logic.<commit_after>/*!
 * wwwhisper - web access control.
 */
(function () {
  'use strict';
  var stub = new wwwhisper.Stub();

  /**
   * Sends an assertion from a BrowserID sign-in window to the
   * authentication back-end. Reloads the page if login succeeded.
   */
  function login(assertion) {
    if (assertion) {
      stub.ajax('POST', '/wwwhisper/auth/api/login/',
                { 'assertion' : assertion.toString() },
                function() {
                  window.location.reload(true);
                },
                function(errorMessage, errorStatus) {
                  if (errorStatus === 403) {
                    // Login failed because the user is unknown.
                    $('#login-required').addClass('hide');
                    $('#nothing-shared').removeClass('hide');
                  } else {
                    // Other error.
                    $('body').html(errorMessage);
                  }
                });
    }
  }

  /**
   * Goes to the logout page if the user is already authenticated.
   */
  function gotoLogoutIfAuthenticated() {
    // Whoami succeeds only for authenticated users.
    stub.ajax('GET', '/wwwhisper/auth/api/whoami/', null,
              function() {
                window.location = '/wwwhisper/auth/logout';
              },
              function() {
                // Logget out (errorStatus 401) or some other error.
                // If error was caused by disabled cookies (CSRF token
                // missing), Persona dialog will inform the user how
                // to enable cookies.
              });
  }

  $('#login-required').removeClass('hide');
  $('#login').removeClass('hide');

  // Register a callback to process a BrowserID assertion.
  $('#login').click(function() {
    navigator.id.get(login);
    return false;
  });

  gotoLogoutIfAuthenticated();

}());
<|endoftext|>


<commit_before>'use strict';

var URI = require('URIjs');
var config = require('./config.js');
var PocketClient = require('./pocket_client.js');
var common = require('./common.js');
var client = new PocketClient(config.pocket);
var runClearItemCacheInterval = 1000 * 60 * 60 * 3;

chrome.webNavigation.onCommitted.addListener(function(details) {
  if (details.frameId === 0) {
    var uri = new URI(details.url);
    var found = false;
    var key;

    var data = {
      domain: uri.host(),
      state: 'all',
      detailType: 'complete'
    };
    var success = function(pocketItem) {
      var matchedItem = client.urlMatch(details.url, pocketItem);
      if (matchedItem) {
        common.displaySavedIcon(details.tabId);
        common.itemCache.set(matchedItem);
      } else {
        common.displayUnsavedIcon(details.tabId);
      }

    };
    var error = function() {
      common.displayOfflineIcon(details.tabId);
    };

    if (localStorage.accessToken) {
      client.retrieve(localStorage.accessToken, data, success, error);
    } else {
      error();
    }
  }
});

// TODO:
var clearItemCache = function() {};
// window.setInterval(clearItemCache, runClearItemCacheInterval);
<commit_msg>Add a background task: clear item cache<commit_after>'use strict';

var URI = require('URIjs');
var config = require('./config.js');
var PocketClient = require('./pocket_client.js');
var common = require('./common.js');
var client = new PocketClient(config.pocket);

chrome.webNavigation.onCommitted.addListener(function(details) {
  if (details.frameId === 0) {
    var uri = new URI(details.url);
    var found = false;
    var key;

    var data = {
      domain: uri.host(),
      state: 'all',
      detailType: 'complete'
    };
    var success = function(pocketItem) {
      var matchedItem = client.urlMatch(details.url, pocketItem);
      if (matchedItem) {
        common.displaySavedIcon(details.tabId);
        common.itemCache.set(matchedItem);
      } else {
        common.displayUnsavedIcon(details.tabId);
      }

    };
    var error = function() {
      common.displayOfflineIcon(details.tabId);
    };

    if (window.localStorage.accessToken) {
      client.retrieve(window.localStorage.accessToken, data, success, error);
    } else {
      error();
    }
  }
});

// 3 hours.
var runClearItemCacheInterval = 1000 * 60 * 60 * 3;

var clearItemCache = function() {
  var reservedKeys = {
    'accessToken': true,
    'requestToken': true
  };

  chrome.tabs.query({}, function(tabs) {
    var urls = {};
    var i;
    var k;

    for (i = 0; i < tabs.length; ++i) {
      urls[tabs[i].url] = true;
    }

    for (i = 0; i < window.localStorage.length; ++i) {
      k = window.localStorage.key(i);
      if (!urls[k] && !reservedKeys[k]) {
        window.localStorage.removeItem(k);
      }
    }
  });
};

window.setInterval(clearItemCache, runClearItemCacheInterval);
window.onload = function() {
  clearItemCache();
}
<|endoftext|>