<commit_before>module.exports = function(config){
    var obj = {};
    var cmd = require('node-cmd');

    var sysExec = function(command, callback){
        // console.log('sysExec: ', command, '||| callback:', callback)
        cmd.get('unset XDG_SESSION_ID XDG_RUNTIME_DIR; cgm movepid all virt $$; '+command, callback)
    }
/*    var obj = {};
    var child = require('child'),
        sshBind = config.sshBind || false;

    //http://stackoverflow.com/questions/10530532/
    function textToArgs(s){
        var words = [];
        s.replace(/"([^"]*)"|'([^']*)'|(\S+)/g,function(g0,g1,g2,g3){ words.push(g1 || g2 || g3 || '')});
        return words;
    }

    var sysExec = function(command, onData, onClose){

        onData = onData || function(){};
        onClose = onClose || function(){};

        if (sshBind != false)
        {
            var runCommand = sshBind.slice();
            runCommand.push(command);
        } else {
            var runCommand = textToArgs('unset XDG_SESSION_ID XDG_RUNTIME_DIR; cgm movepid all virt $$; '+command);
        }

        var errors = '';

        child({
            command: runCommand.slice(0,1)[0],
            args: runCommand.slice(1),
            cbStdout: function(data){ onData(''+data) },
            cbStderr: function(data){ errors+=data; onData(''+data) },
            cbClose: function(exitCode){ onClose(exitCode == 0 ? null:exitCode,  errors) }
        }).start();
    };
*/

    obj.create = function(name, template, config, cbComplete){
        sysExec('lxc-create -n '+name+' -t '+template, cbComplete);
    };

    obj.clone = function(name, base_name, cbComplete, cbData){
        sysExec('lxc-clone -o '+base_name+ ' -n '+name +' -B overlayfs -s', cbComplete, cbData);
    };

    obj.destroy = function(name, callback){
        sysExec('lxc-destroy -n '+ name, function(data){
            callback(!data.match(/Destroyed container/))
        });
    };

    obj.start = function(name, callback){
        var cmd = 'lxc-start --name '+name+' --daemon';
        console.log('start cmd\n', cmd, '\n');
        sysExec(cmd, callback);
    };

    obj.startEphemeral = function(name, base_name, callback){

        var output = '';
        sysExec('lxc-start-ephemeral -o '+base_name+ ' -n '+name +' --union-type overlayfs -d', function(data){
            if(data.match("doesn't exist.")) return callback({status: 500, error: "doesn't exist."});
            if(data.match("already exists.")) return callback({status: 500, error: "already exists"});
            if(data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)) return callback({status: 200, state:'RUNNING', ip: data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)[0]});
            callback({'?': '?', data: data, name: name, base_name: base_name});
        });
    };

    obj.stop = function(name, callback){
        console.log('stop', name);
        sysExec('lxc-stop -n '+ name, callback);
    };

    obj.freeze = function(name, cbComplete, cbData){
        sysExec('lxc-freeze -n '+name, cbComplete, cbData);
    };

    obj.unfreeze = function(name, cbComplete, cbData){
        sysExec('lxc-unfreeze -n '+name, cbComplete, cbData);
    };

    obj.info = function(name, callback){

        var output = '';
        sysExec('lxc-info -n '+name, function(data){
            console.log('info', name, data)
            if(data.match("doesn't exist")) return callback({state: 'NULL'});
            var info = {};
            data = data.replace(/\suse/ig, '').replace(/\sbytes/ig, '').split("\n").slice(0,-1);
            for(var i in data){
                var temp = data[i].split(/\:\s+/);
                info[temp[0].toLowerCase().trim()] = temp[1].trim();
            }
            callback(info);
        });
    };

    obj.list = function(callback){
        sysExec('lxc-ls --fancy', function(data){
            var output = data.split("\n");
            var keys = output.splice(0,1)[0].split(/\s+/).slice(0,-1);
            var info = [];

            keys = keys.map(function(v){return v.toLowerCase()});
            output = output.slice(0).splice(1).slice(0,-1);

            for (var i in output)
            {

                var aIn = output[i].split(/\s+/).slice(0,-1),
                    mapOut = {};
                aIn.map( function(v,i){ mapOut[keys[i]] = v; } );
                info.push(mapOut);

            }
            callback(info);
        });
    };

    return obj;
};<commit_msg>formating<commit_after>module.exports = function(config){
	var obj = {};
	var cmd = require('node-cmd');

	var sysExec = function(command, callback){
		// console.log('sysExec: ', command, '||| callback:', callback)
		cmd.get('unset XDG_SESSION_ID XDG_RUNTIME_DIR; cgm movepid all virt $$; '+command, callback)
	}

	obj.create = function(name, template, config, cbComplete){
		sysExec('lxc-create -n '+name+' -t '+template, cbComplete);
	};

	obj.clone = function(name, base_name, cbComplete, cbData){
		sysExec('lxc-clone -o '+base_name+ ' -n '+name +' -B overlayfs -s', cbComplete, cbData);
	};

	obj.destroy = function(name, callback){
		sysExec('lxc-destroy -n '+ name, function(data){
			callback(!data.match(/Destroyed container/))
		});
	};

	obj.start = function(name, callback){
		var cmd = 'lxc-start --name '+name+' --daemon';
		console.log('start cmd\n', cmd, '\n');
		sysExec(cmd, callback);
	};

	obj.startEphemeral = function(name, base_name, callback){

		var output = '';
		sysExec('lxc-start-ephemeral -o '+base_name+ ' -n '+name +' --union-type overlayfs -d', function(data){
			if(data.match("doesn't exist.")) return callback({status: 500, error: "doesn't exist."});
			if(data.match("already exists.")) return callback({status: 500, error: "already exists"});
			if(data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)) return callback({status: 200, state:'RUNNING', ip: data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)[0]});
			callback({'?': '?', data: data, name: name, base_name: base_name});
		});
	};

	obj.stop = function(name, callback){
		console.log('stop', name);
		sysExec('lxc-stop -n '+ name, callback);
	};

	obj.freeze = function(name, cbComplete, cbData){
		sysExec('lxc-freeze -n '+name, cbComplete, cbData);
	};

	obj.unfreeze = function(name, cbComplete, cbData){
		sysExec('lxc-unfreeze -n '+name, cbComplete, cbData);
	};

	obj.info = function(name, callback){

		var output = '';
		sysExec('lxc-info -n '+name, function(data){
			console.log('info', name, data)
			if(data.match("doesn't exist")) return callback({state: 'NULL'});
			var info = {};
			data = data.replace(/\suse/ig, '').replace(/\sbytes/ig, '').split("\n").slice(0,-1);
			for(var i in data){
				var temp = data[i].split(/\:\s+/);
				info[temp[0].toLowerCase().trim()] = temp[1].trim();
			}
			callback(info);
		});
	};

	obj.list = function(callback){
		sysExec('lxc-ls --fancy', function(data){
			var output = data.split("\n");
			var keys = output.splice(0,1)[0].split(/\s+/).slice(0,-1);
			var info = [];

			keys = keys.map(function(v){return v.toLowerCase()});
			output = output.slice(0).splice(1).slice(0,-1);

			for (var i in output)
			{

				var aIn = output[i].split(/\s+/).slice(0,-1),
					mapOut = {};
				aIn.map( function(v,i){ mapOut[keys[i]] = v; } );
				info.push(mapOut);

			}
			callback(info);
		});
	};

	return obj;
};<|endoftext|>


<commit_before>var screenWidth = 1024;
var screenHeight = 768;
var loseText = 'Game over, man! Game over!';
var pauseText = 'Paused';
var zombieHitboxScale = 0.5;

var lzs = new Phaser.Game(screenWidth, screenHeight, Phaser.AUTO, 'lzs', { preload: preload, create: create, update: update, render: render });

function preload() {
	// Load sounds and sprites

	lzs.load.spritesheet('ray', 'assets/sprites/ray-sheet.png', 145, 128, 7);
	lzs.load.spritesheet('zombie', 'assets/sprites/zombie-sheet.png', 119, 128);

	lzs.load.image('beam', 'assets/sprites/beam-01.png');
	lzs.load.image('background', 'assets/sprites/grass-dirt-mix-pixeled-gray.png');
	lzs.load.image('logo', 'assets/sprites/logo.png');

	lzs.load.audio('alive', 'assets/sounds/angel1.mp3');
	lzs.load.audio('hit', 'assets/sounds/grunt1.mp3');
	lzs.load.audio('pew', 'assets/sounds/raygun1.mp3');
	lzs.load.audio('soundtrack', 'assets/sounds/soundtrack.mp3');
	lzs.load.audio('zombie', 'assets/sounds/zombie1.mp3');
}

// Game vars

var alive;
var bulletSpeed = 1500;
var cursors;
var fireButton;
var fireDelay =200;
var fireTime = 0;
var gameLost = false;
var hit;
var logo;
var pew;
var ray;
var raySpeed = 600;
var score = 0;
var scoreString = 'Score: ';
var scoreText;
var soundtrack;
var tween;
var volume = 1;
var zombieHitPoints = 3;
var zombies;
var zombieSpawn;
var zombieSpeed = 50;
var zombieWidth = 119;

function create() {
	lzs.add.tileSprite(0, 0, screenWidth, screenHeight, 'background');

	logo = lzs.add.sprite(50, 100, 'logo');

	setTimeout(function() {
		logo.destroy();
		ray.play('walkForward');
	}, 4000);

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

	ray = lzs.add.sprite(screenWidth * 0.5, screenHeight * 0.8, 'ray');

	ray.animations.add('walkForward', [1, 2], 6, false);
	ray.animations.add('walkSide', [3, 4], 6, false);
	ray.animations.add('walkBack', [0], 6, false);
	ray.animations.add('fireForward', [5], true);

	ray.anchor.setTo(0.5, 1);

	//rays
	bullets = lzs.add.group();
	bullets.enableBody = true;
	bullets.physicsBodyType = Phaser.Physics.ARCADE;
	bullets.createMultiple(30, 'beam');
	bullets.setAll('anchor.x', 0.5);
	bullets.setAll('anchor.y', 1);
	bullets.setAll('outOfBoundsKill', true);
	bullets.setAll('checkWorldBounds', true);

	lzs.physics.enable(ray, Phaser.Physics.ARCADE);

	//controls
	cursors = lzs.input.keyboard.createCursorKeys();
	fireButton = lzs.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);

	createZombies();

	//audio
	alive = lzs.add.audio('alive', volume);
	hit = lzs.add.audio('hit', volume);
	pew = lzs.add.audio('pew', volume);
	zombieSpawn = lzs.add.audio('zombie', volume);
	soundtrack = lzs.add.audio('soundtrack', volume, true);

	soundtrack.play('',0,0.3,true);
	setTimeout(function() {zombieSpawn.play();}, 2000);

	//text
	stateText = lzs.add.text(lzs.world.centerX, lzs.world.centerY, ' ', {fill: '#E9B3F7'});
	stateText.anchor.setTo(0.5, 0.5);
	stateText.visible = false;
	stateText.font = "badaboom";
	stateText.fontSize  = "84";

	//Score
	scoreText = lzs.add.text(20, screenHeight - 65, scoreString + score, {fill: '#E9B3F7' });
	scoreText.font = "badaboom";
	scoreText.fontSize  = "48";
	scoreText.visible = false;
}

function update() {
	if (ray.alive) {
		ray.body.velocity.setTo(0, 0);

		if (cursors.left.isDown) {
			if (ray.position.x > 0) {
				ray.body.velocity.x = -raySpeed;
				ray.scale.x = 1;
				ray.play('walkSide');
			}
		}
		if (cursors.right.isDown) {
			if (ray.position.x < lzs.world.width) {
				ray.body.velocity.x = raySpeed;
				ray.scale.x = -1;
				ray.play('walkSide');
			}
		}
		if (cursors.up.isDown) {
			if (ray.position.y > (lzs.world.height / 2)) {
				ray.body.velocity.y = -raySpeed;
				ray.scale.x = 1;
				ray.play('walkForward');
			}
		}
		if (cursors.down.isDown) {
			if (ray.position.y < (lzs.world.height)) {
				ray.body.velocity.y = raySpeed;
				ray.scale.x = 1;
				ray.play('walkBack');
			}
		}

		if (fireButton.isDown) {
			fireRay();
		}

		//collision detection
		lzs.physics.arcade.overlap(bullets, zombies, zombieBulletCollisionHandler);
		lzs.physics.arcade.overlap(ray, zombies, loseGame);

		zombies.forEach(function(zombie) {
			if (zombie.position.y > (lzs.world.height - zombie.height)) {
				gameLost = true;
			}
		}, this);

		if (gameLost) {
			loseGame();
		}
	}
}

function fireRay() {
	if (lzs.time.now > fireTime) {
		pew.play();

		bullet = bullets.getFirstExists(false);

		if (bullet) {
			bullet.reset(ray.x + 10, ray.y - ray.height);
			bullet.body.velocity.y = -bulletSpeed;
			fireTime = lzs.time.now + fireDelay;

			ray.play('fireForward');

			setTimeout(function() {
				ray.play('walkForward');
			}, 100);
		}
	}
}

function createZombies() {
	zombies = lzs.add.group();
	zombies.enableBody = true;
	zombies.physicsBodyType = Phaser.Physics.ARCADE;
	zombies.setAll('outOfBoundsKill', true);

	lzs.time.events.loop(2000, createZombie, this);
}

function createZombie() {
	var position = Math.min(screenWidth * Math.random(), screenWidth - zombieWidth);

	var zombie = zombies.create(position, -30, 'zombie');
	zombie.anchor.setTo(0.5, 1);

	zombie.animations.add('walkGreen', [0, 1, 2, 3], 3, true);
	zombie.animations.add('walkRed', [4, 5, 6, 7], 3, true);
	zombie.animations.add('leave', [9, 10, 11], 6, true);
	zombie.animations.add('transform', [8], 1, false);

	if (Math.random() > 0.5) {
		zombie.play('walkGreen');
		zombie.hits = 0;
	}
	else {
		zombie.play('walkRed');
		zombie.hits = -2;
	}

	zombie.body.velocity.y = zombieSpeed;
	zombie.alive = false;

	zombie.body.setSize(zombie.width * zombieHitboxScale, zombie.height * zombieHitboxScale, 0, -40);
}

function zombieBulletCollisionHandler(bullet, zombie) {
	if (!zombie.alive) {
		bullet.kill();
		zombie.hits++;

		if (zombie.hits < zombieHitPoints) {
			hit.play();
		}

		if (zombie.hits == zombieHitPoints) {
			zombie.alive = true;
			zombie.body.velocity.y = 0;

			if (zombie.position.x > (lzs.world.width * 0.5)) {
				zombie.body.velocity.x = zombieSpeed * 3;
			}
			else {
				zombie.body.velocity.x = -zombieSpeed * 3;
				zombie.scale.x = -1;
			}

			zombie.play('transform');

			setTimeout(function() {
				zombie.play('leave');
				alive.play();
			}, 200);

			alive.play();

			score += 20;
			scoreText.visible = true;
			scoreText.text = scoreString + score;
		}
	}
}

function loseGame() {
	stateText.text = loseText;
	stateText.visible = true;
	zombies.destroy();
	bullets.destroy();
	ray.destroy();
}

function render() {
	// debug
}

function toggleMute() {
	volume = 1 - volume;

	for (var audio of [alive, hit, pew, zombieSpawn]) {
		audio.volume = 1 - audio.volume;
	}

	if (!soundtrack.paused) {
		soundtrack.pause();

		document.getElementById('mute').innerHTML = 'Unmute';
	}
	else {
		soundtrack.resume();

		document.getElementById('mute').innerHTML = 'Mute';
	}
}

function togglePaused(game) {
	lzs.paused = !lzs.paused;

	if (lzs.paused) {
		stateText.text = pauseText;
		stateText.visible = true;

		document.getElementById('pause').innerHTML = 'Unpause';
	}
	else {
		stateText.visible = false;

		document.getElementById('pause').innerHTML = 'Pause';
	}
}
<commit_msg>Source Formatting<commit_after>var screenWidth = 1024;
var screenHeight = 768;

var lzs = new Phaser.Game(screenWidth, screenHeight, Phaser.AUTO, 'lzs', { preload: preload, create: create, update: update, render: render });

function preload() {
	// Load sounds and sprites

	lzs.load.spritesheet('ray', 'assets/sprites/ray-sheet.png', 145, 128, 7);
	lzs.load.spritesheet('zombie', 'assets/sprites/zombie-sheet.png', 119, 128);

	lzs.load.image('beam', 'assets/sprites/beam-01.png');
	lzs.load.image('background', 'assets/sprites/grass-dirt-mix-pixeled-gray.png');
	lzs.load.image('logo', 'assets/sprites/logo.png');

	lzs.load.audio('alive', 'assets/sounds/angel1.mp3');
	lzs.load.audio('hit', 'assets/sounds/grunt1.mp3');
	lzs.load.audio('pew', 'assets/sounds/raygun1.mp3');
	lzs.load.audio('soundtrack', 'assets/sounds/soundtrack.mp3');
	lzs.load.audio('zombie', 'assets/sounds/zombie1.mp3');
}

// Game vars

var alive;
var bulletSpeed = 1500;
var cursors;
var fireButton;
var fireDelay =200;
var fireTime = 0;
var gameLost = false;
var hit;
var logo;
var loseText = 'Game over, man! Game over!';
var pauseText = 'Paused';
var pew;
var ray;
var raySpeed = 600;
var score = 0;
var scoreString = 'Score: ';
var scoreText;
var soundtrack;
var tween;
var volume = 1;
var zombieHitboxScale = 0.5;
var zombieHitPoints = 3;
var zombies;
var zombieSpawn;
var zombieSpeed = 50;
var zombieWidth = 119;

function create() {
	lzs.add.tileSprite(0, 0, screenWidth, screenHeight, 'background');

	logo = lzs.add.sprite(50, 100, 'logo');

	setTimeout(function() {
		logo.destroy();
		ray.play('walkForward');
	}, 4000);

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

	ray = lzs.add.sprite(screenWidth * 0.5, screenHeight * 0.8, 'ray');

	ray.animations.add('walkForward', [1, 2], 6, false);
	ray.animations.add('walkSide', [3, 4], 6, false);
	ray.animations.add('walkBack', [0], 6, false);
	ray.animations.add('fireForward', [5], true);

	ray.anchor.setTo(0.5, 1);

	//rays
	bullets = lzs.add.group();
	bullets.enableBody = true;
	bullets.physicsBodyType = Phaser.Physics.ARCADE;
	bullets.createMultiple(30, 'beam');
	bullets.setAll('anchor.x', 0.5);
	bullets.setAll('anchor.y', 1);
	bullets.setAll('outOfBoundsKill', true);
	bullets.setAll('checkWorldBounds', true);

	lzs.physics.enable(ray, Phaser.Physics.ARCADE);

	//controls
	cursors = lzs.input.keyboard.createCursorKeys();
	fireButton = lzs.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);

	createZombies();

	//audio
	alive = lzs.add.audio('alive', volume);
	hit = lzs.add.audio('hit', volume);
	pew = lzs.add.audio('pew', volume);
	zombieSpawn = lzs.add.audio('zombie', volume);
	soundtrack = lzs.add.audio('soundtrack', volume, true);

	soundtrack.play('',0,0.3,true);
	setTimeout(function() {zombieSpawn.play();}, 2000);

	//text
	stateText = lzs.add.text(lzs.world.centerX, lzs.world.centerY, ' ', {fill: '#E9B3F7'});
	stateText.anchor.setTo(0.5, 0.5);
	stateText.visible = false;
	stateText.font = 'badaboom';
	stateText.fontSize  = '84';

	//Score
	scoreText = lzs.add.text(20, screenHeight - 65, scoreString + score, {fill: '#E9B3F7' });
	scoreText.font = 'badaboom';
	scoreText.fontSize  = '48';
	scoreText.visible = false;
}

function update() {
	if (ray.alive) {
		ray.body.velocity.setTo(0, 0);

		if (cursors.left.isDown) {
			if (ray.position.x > 0) {
				ray.body.velocity.x = -raySpeed;
				ray.scale.x = 1;
				ray.play('walkSide');
			}
		}
		if (cursors.right.isDown) {
			if (ray.position.x < lzs.world.width) {
				ray.body.velocity.x = raySpeed;
				ray.scale.x = -1;
				ray.play('walkSide');
			}
		}
		if (cursors.up.isDown) {
			if (ray.position.y > (lzs.world.height / 2)) {
				ray.body.velocity.y = -raySpeed;
				ray.scale.x = 1;
				ray.play('walkForward');
			}
		}
		if (cursors.down.isDown) {
			if (ray.position.y < (lzs.world.height)) {
				ray.body.velocity.y = raySpeed;
				ray.scale.x = 1;
				ray.play('walkBack');
			}
		}

		if (fireButton.isDown) {
			fireRay();
		}

		//collision detection
		lzs.physics.arcade.overlap(bullets, zombies, zombieBulletCollisionHandler);
		lzs.physics.arcade.overlap(ray, zombies, loseGame);

		zombies.forEach(function(zombie) {
			if (zombie.position.y > (lzs.world.height - zombie.height)) {
				gameLost = true;
			}
		}, this);

		if (gameLost) {
			loseGame();
		}
	}
}

function fireRay() {
	if (lzs.time.now > fireTime) {
		pew.play();

		bullet = bullets.getFirstExists(false);

		if (bullet) {
			bullet.reset(ray.x + 10, ray.y - ray.height);
			bullet.body.velocity.y = -bulletSpeed;
			fireTime = lzs.time.now + fireDelay;

			ray.play('fireForward');

			setTimeout(function() {
				ray.play('walkForward');
			}, 100);
		}
	}
}

function createZombies() {
	zombies = lzs.add.group();
	zombies.enableBody = true;
	zombies.physicsBodyType = Phaser.Physics.ARCADE;
	zombies.setAll('outOfBoundsKill', true);

	lzs.time.events.loop(2000, createZombie, this);
}

function createZombie() {
	var position = Math.min(screenWidth * Math.random(), screenWidth - zombieWidth);
	var zombie = zombies.create(position, -30, 'zombie');

	zombie.anchor.setTo(0.5, 1);

	zombie.animations.add('walkGreen', [0, 1, 2, 3], 3, true);
	zombie.animations.add('walkRed', [4, 5, 6, 7], 3, true);
	zombie.animations.add('leave', [9, 10, 11], 6, true);
	zombie.animations.add('transform', [8], 1, false);

	if (Math.random() > 0.5) {
		zombie.play('walkGreen');
		zombie.hits = 0;
	}
	else {
		zombie.play('walkRed');
		zombie.hits = -2;
	}

	zombie.body.velocity.y = zombieSpeed;
	zombie.alive = false;

	zombie.body.setSize(zombie.width * zombieHitboxScale, zombie.height * zombieHitboxScale, 0, -40);
}

function zombieBulletCollisionHandler(bullet, zombie) {
	if (!zombie.alive) {
		bullet.kill();
		zombie.hits++;

		if (zombie.hits < zombieHitPoints) {
			hit.play();
		}

		if (zombie.hits == zombieHitPoints) {
			zombie.alive = true;
			zombie.body.velocity.y = 0;

			if (zombie.position.x > (lzs.world.width * 0.5)) {
				zombie.body.velocity.x = zombieSpeed * 3;
			}
			else {
				zombie.body.velocity.x = -zombieSpeed * 3;
				zombie.scale.x = -1;
			}

			zombie.play('transform');

			setTimeout(function() {
				zombie.play('leave');
				alive.play();
			}, 200);

			alive.play();

			score += 20;
			scoreText.visible = true;
			scoreText.text = scoreString + score;
		}
	}
}

function loseGame() {
	stateText.text = loseText;
	stateText.visible = true;
	zombies.destroy();
	bullets.destroy();
	ray.destroy();
}

function render() {
	// debug
}

function toggleMute() {
	volume = 1 - volume;

	for (var audio of [alive, hit, pew, zombieSpawn]) {
		audio.volume = 1 - audio.volume;
	}

	if (!soundtrack.paused) {
		soundtrack.pause();

		document.getElementById('mute').innerHTML = 'Unmute';
	}
	else {
		soundtrack.resume();

		document.getElementById('mute').innerHTML = 'Mute';
	}
}

function togglePaused(game) {
	lzs.paused = !lzs.paused;

	if (lzs.paused) {
		stateText.text = pauseText;
		stateText.visible = true;

		document.getElementById('pause').innerHTML = 'Unpause';
	}
	else {
		stateText.visible = false;

		document.getElementById('pause').innerHTML = 'Pause';
	}
}
<|endoftext|>


<commit_before>var path = require('path')
var fs = require('fs')
var child = require('child_process')

var plist = require('plist')
var mv = require('mv')
var ncp = require('ncp').ncp
var series = require('run-series')
var common = require('./common')

module.exports = {
  createApp: function createApp (opts, templatePath, callback) {
    var appRelativePath = path.join('Electron.app', 'Contents', 'Resources', 'app')
    common.initializeApp(opts, templatePath, appRelativePath, function buildMacApp (err, tempPath) {
      if (err) return callback(err)

      var contentsPath = path.join(tempPath, 'Electron.app', 'Contents')
      var helperPath = path.join(contentsPath, 'Frameworks', 'Electron Helper.app')
      var appPlistFilename = path.join(contentsPath, 'Info.plist')
      var helperPlistFilename = path.join(helperPath, 'Contents', 'Info.plist')
      var appPlist = plist.parse(fs.readFileSync(appPlistFilename).toString())
      var helperPlist = plist.parse(fs.readFileSync(helperPlistFilename).toString())

      // Update plist files
      var defaultBundleName = 'com.electron.' + opts.name.toLowerCase().replace(/ /g, '_')
      var appVersion = opts['app-version']

      appPlist.CFBundleDisplayName = opts.name
      appPlist.CFBundleIdentifier = opts['app-bundle-id'] || defaultBundleName
      appPlist.CFBundleName = opts.name
      helperPlist.CFBundleIdentifier = opts['helper-bundle-id'] || defaultBundleName + '.helper'
      helperPlist.CFBundleName = opts.name

      if (appVersion) {
        appPlist.CFBundleVersion = appVersion
      }

      if (opts.protocols) {
        helperPlist.CFBundleURLTypes = appPlist.CFBundleURLTypes = opts.protocols.map(function (protocol) {
          return {
            CFBundleURLName: protocol.name,
            CFBundleURLSchemes: [].concat(protocol.schemes)
          }
        })
      }

      fs.writeFileSync(appPlistFilename, plist.build(appPlist))
      fs.writeFileSync(helperPlistFilename, plist.build(helperPlist))

      var operations = []

      if (opts.icon) {
        operations.push(function (cb) {
          common.normalizeExt(opts.icon, '.icns', function (err, icon) {
            if (err) {
              // Ignore error if icon doesn't exist, in case it's only available for other OS
              cb(null)
            } else {
              ncp(icon, path.join(contentsPath, 'Resources', 'atom.icns'), cb)
            }
          })
        })
      }

      // Move Helper binary, then Helper.app, then top-level .app
      var finalAppPath = path.join(tempPath, opts.name + '.app')
      operations.push(function (cb) {
        var helperBinaryPath = path.join(helperPath, 'Contents', 'MacOS')
        mv(path.join(helperBinaryPath, 'Electron Helper'), path.join(helperBinaryPath, opts.name + ' Helper'), cb)
      }, function (cb) {
        mv(helperPath, path.join(path.dirname(helperPath), opts.name + ' Helper.app'), cb)
      }, function (cb) {
        mv(path.dirname(contentsPath), finalAppPath, cb)
      })

      if (opts.sign) {
        operations.push(function (cb) {
          child.exec('codesign --deep --force --sign "' + opts.sign + '" ' + finalAppPath, cb)
        })
      }

      series(operations, function () {
        common.moveApp(opts, tempPath, callback)
      })
    })
  }
}
<commit_msg>fix(mac): handle spaces when signing<commit_after>var path = require('path')
var fs = require('fs')
var child = require('child_process')

var plist = require('plist')
var mv = require('mv')
var ncp = require('ncp').ncp
var series = require('run-series')
var common = require('./common')

module.exports = {
  createApp: function createApp (opts, templatePath, callback) {
    var appRelativePath = path.join('Electron.app', 'Contents', 'Resources', 'app')
    common.initializeApp(opts, templatePath, appRelativePath, function buildMacApp (err, tempPath) {
      if (err) return callback(err)

      var contentsPath = path.join(tempPath, 'Electron.app', 'Contents')
      var helperPath = path.join(contentsPath, 'Frameworks', 'Electron Helper.app')
      var appPlistFilename = path.join(contentsPath, 'Info.plist')
      var helperPlistFilename = path.join(helperPath, 'Contents', 'Info.plist')
      var appPlist = plist.parse(fs.readFileSync(appPlistFilename).toString())
      var helperPlist = plist.parse(fs.readFileSync(helperPlistFilename).toString())

      // Update plist files
      var defaultBundleName = 'com.electron.' + opts.name.toLowerCase().replace(/ /g, '_')
      var appVersion = opts['app-version']

      appPlist.CFBundleDisplayName = opts.name
      appPlist.CFBundleIdentifier = opts['app-bundle-id'] || defaultBundleName
      appPlist.CFBundleName = opts.name
      helperPlist.CFBundleIdentifier = opts['helper-bundle-id'] || defaultBundleName + '.helper'
      helperPlist.CFBundleName = opts.name

      if (appVersion) {
        appPlist.CFBundleVersion = appVersion
      }

      if (opts.protocols) {
        helperPlist.CFBundleURLTypes = appPlist.CFBundleURLTypes = opts.protocols.map(function (protocol) {
          return {
            CFBundleURLName: protocol.name,
            CFBundleURLSchemes: [].concat(protocol.schemes)
          }
        })
      }

      fs.writeFileSync(appPlistFilename, plist.build(appPlist))
      fs.writeFileSync(helperPlistFilename, plist.build(helperPlist))

      var operations = []

      if (opts.icon) {
        operations.push(function (cb) {
          common.normalizeExt(opts.icon, '.icns', function (err, icon) {
            if (err) {
              // Ignore error if icon doesn't exist, in case it's only available for other OS
              cb(null)
            } else {
              ncp(icon, path.join(contentsPath, 'Resources', 'atom.icns'), cb)
            }
          })
        })
      }

      // Move Helper binary, then Helper.app, then top-level .app
      var finalAppPath = path.join(tempPath, opts.name + '.app')
      operations.push(function (cb) {
        var helperBinaryPath = path.join(helperPath, 'Contents', 'MacOS')
        mv(path.join(helperBinaryPath, 'Electron Helper'), path.join(helperBinaryPath, opts.name + ' Helper'), cb)
      }, function (cb) {
        mv(helperPath, path.join(path.dirname(helperPath), opts.name + ' Helper.app'), cb)
      }, function (cb) {
        mv(path.dirname(contentsPath), finalAppPath, cb)
      })

      if (opts.sign) {
        operations.push(function (cb) {
          child.exec('codesign --deep --force --sign "' + opts.sign + '" "' + finalAppPath + '"', cb)
        })
      }

      series(operations, function () {
        common.moveApp(opts, tempPath, callback)
      })
    })
  }
}
<|endoftext|>


<commit_before>"use strict";

var CityTour = CityTour || {};

CityTour.TerrainGenerator = (function() {
  var SUB_DIVISIONS = 1;
  var MAX_INITIAL_TERRAIN_HEIGHT = 6;
  var HEIGHT_JITTER_PER_ITERATION = 20;
  var HEIGHT_JITTER_DECAY_PER_ITERATION = 0.65;
  var LAND = 'land';
  var WATER = 'water';

  var emptyTerrain = function(columns, rows) {
    var x, z;
    var terrainCoordinates = [];

    for (x = 0; x <= columns; x++) {
      terrainCoordinates[x] = [];

      for (z = 0; z <= rows; z++) {
        terrainCoordinates[x][z] = { material: LAND, height: 0.0 };
      }
    }

    return terrainCoordinates;
  };

  var normalizeCoordinates = function(terrainCoordinates, columns, columnsToGenerate, rows, rowsToGenerate) {
    var x, z;
    var halfColumns = columns / 2;
    var halfRows = rows / 2;
    var columnOffset = halfColumns + ((columnsToGenerate - columns) / 2);
    var rowOffset = halfRows + ((rowsToGenerate - rows) / 2);
    var material;
    var stepAmount = 1 / SUB_DIVISIONS;
    var oldXIndex, oldZIndex;

    var normalizedTerrainCoordinates = [];

    for (x = -halfColumns; x <= halfColumns; x += stepAmount) {
      normalizedTerrainCoordinates[x] = [];
      oldXIndex = (x * SUB_DIVISIONS) + columnOffset;

      for (z = -halfRows; z <= halfRows; z += stepAmount) {
        oldZIndex = (z * SUB_DIVISIONS) + rowOffset;

        normalizedTerrainCoordinates[x][z] = {
          material: terrainCoordinates[oldXIndex][oldZIndex].material,
          height: terrainCoordinates[oldXIndex][oldZIndex].height,
        }
      }
    }

    return normalizedTerrainCoordinates;
  };

  var nextPowerOfTwo = function(n) {
    return Math.pow(2, Math.ceil(Math.log2(n)));
  };

  var buildTerrainCoordinates = function(columns, rows) {
    var columnsToGenerate = nextPowerOfTwo(columns * SUB_DIVISIONS);
    var rowsToGenerate = nextPowerOfTwo(rows * SUB_DIVISIONS);

    var terrainCoordinates = emptyTerrain(columnsToGenerate, rowsToGenerate);

    // Initial randomization of corners
    terrainCoordinates[0][0].height = Math.floor(Math.random() * MAX_INITIAL_TERRAIN_HEIGHT);
    terrainCoordinates[0][rowsToGenerate].height = Math.floor(Math.random() * MAX_INITIAL_TERRAIN_HEIGHT);
    terrainCoordinates[columnsToGenerate][0].height = Math.floor(Math.random() * MAX_INITIAL_TERRAIN_HEIGHT);
    terrainCoordinates[columnsToGenerate][rowsToGenerate].height = Math.floor(Math.random() * MAX_INITIAL_TERRAIN_HEIGHT);

    // City must be (2^n + 1) blocks on both x and z dimensions for this to work
    midpointDisplace(terrainCoordinates,
                     HEIGHT_JITTER_PER_ITERATION,
                     HEIGHT_JITTER_DECAY_PER_ITERATION,
                     0,
                     rowsToGenerate,
                     columnsToGenerate,
                     0);

    addRiver(terrainCoordinates, rowsToGenerate, columnsToGenerate);

    // Convert to final coordinates
    var finalTerrainCoordinates = normalizeCoordinates(terrainCoordinates, columns, columnsToGenerate, rows, rowsToGenerate);

    return finalTerrainCoordinates;
  };

  var addRiver = function(terrainCoordinates, rows, columns) {
    var x, z;
    var minimumRiverBankHeight;
    var vector, topVector, bottomVector;
    var topCurve, bottomCurve;

    topCurve = new THREE.CubicBezierCurve(
	    new THREE.Vector2(0, (rows / 2) + 4),
      new THREE.Vector2(columns / 3, (rows / 2) - 3),
      new THREE.Vector2((columns / 3) * 2, (rows / 2) + 7),
      new THREE.Vector2(columns, (rows / 2) + 6)
    );

    bottomCurve = new THREE.CubicBezierCurve(
	    new THREE.Vector2(0, (rows / 2) + 20),
      new THREE.Vector2(columns / 3, (rows / 2) + 4),
      new THREE.Vector2((columns / 3) * 2, (rows / 2) + 17),
      new THREE.Vector2(columns, (rows / 2) + 10)
    );

    //topCurve = new THREE.LineCurve(new THREE.Vector2(0, (rows / 2) + 6), new THREE.Vector2(columns, (rows / 2) + 3));
    //bottomCurve = new THREE.LineCurve(new THREE.Vector2(0, (rows / 2) + 10), new THREE.Vector2(columns, (rows / 2) + 20));

    minimumRiverBankHeight = Number.POSITIVE_INFINITY;
    for (x = 0.0; x <= 1.0; x += 1 / columns) {
      vector = topCurve.getPoint(x);
      if (terrainCoordinates[vector.x][Math.round(vector.y)].height < minimumRiverBankHeight) {
        minimumRiverBankHeight = terrainCoordinates[vector.x][Math.round(vector.y)].height;
      }
    }
    for (x = 0.0; x <= 1.0; x += 1 / columns) {
      vector = bottomCurve.getPoint(x);
      if (terrainCoordinates[vector.x][Math.round(vector.y)].height < minimumRiverBankHeight) {
        minimumRiverBankHeight = terrainCoordinates[vector.x][Math.round(vector.y)].height;
      }
    }

    for (x = 0.0; x <= 1.0; x += 1 / columns) {
      topVector = topCurve.getPoint(x);
      bottomVector = bottomCurve.getPoint(x);

      for (z = Math.ceil(topVector.y); z < bottomVector.y; z++) {
        terrainCoordinates[topVector.x][z].height = minimumRiverBankHeight;
      }
    }

    floodFill(terrainCoordinates, 0, topCurve.getPoint(0).y, minimumRiverBankHeight, WATER);
  };

  var floodFill = function(terrainCoordinates, x, z, height, material) {
    terrainCoordinates[x][z].height = height;
    terrainCoordinates[x][z].material = material;

    if (terrainCoordinates[x - 1] &&
        terrainCoordinates[x - 1][z] &&
        terrainCoordinates[x - 1][z].height <= height &&
        terrainCoordinates[x - 1][z].material != material) {
      floodFill(terrainCoordinates, x - 1, z, height, material);
    }
    if (terrainCoordinates[x + 1] &&
        terrainCoordinates[x + 1][z] &&
        terrainCoordinates[x + 1][z].height <= height &&
        terrainCoordinates[x + 1][z].material != material) {
      floodFill(terrainCoordinates, x + 1, z, height, material);
    }
    if (terrainCoordinates[x] &&
        terrainCoordinates[x][z - 1] &&
        terrainCoordinates[x][z - 1].height <= height &&
        terrainCoordinates[x][z - 1].material != material) {
      floodFill(terrainCoordinates, x, z - 1, height, material);
    }
    if (terrainCoordinates[x] &&
        terrainCoordinates[x][z + 1] &&
        terrainCoordinates[x][z + 1].height <= height &&
        terrainCoordinates[x][z + 1].material != material) {
      floodFill(terrainCoordinates, x, z + 1, height, material);
    }
  };

  // Adapted from http://stevelosh.com/blog/2016/02/midpoint-displacement/
  var midpointDisplace = function(terrainCoordinates, jitterAmount, jitterDecay, top, right, bottom, left) {
    var topLeftHeight     = terrainCoordinates[top][left].height;
    var topRightHeight    = terrainCoordinates[top][right].height;
    var bottomLeftHeight  = terrainCoordinates[bottom][left].height;
    var bottomRightHeight = terrainCoordinates[bottom][right].height;

    var midY = top + ((bottom - top) / 2);
    var midX = left + ((right - left) / 2);

    var jitter;
    var newJitterAmount;
    var halfJitterAmount = jitterAmount / 2;

    // Left column
    jitter = (Math.random() * jitterAmount) - halfJitterAmount;
    terrainCoordinates[midY][left].height = ((topLeftHeight + bottomLeftHeight) / 2) + jitter;
    // Right column
    jitter = (Math.random() * jitterAmount) - halfJitterAmount;
    terrainCoordinates[midY][right].height = ((topRightHeight + bottomRightHeight) / 2) + jitter;
    // Top row
    jitter = (Math.random() * jitterAmount) - halfJitterAmount;
    terrainCoordinates[top][midX].height = ((topLeftHeight + topRightHeight) / 2) + jitter;
    // Bottom row
    jitter = (Math.random() * jitterAmount) - halfJitterAmount;
    terrainCoordinates[bottom][midX].height = ((bottomLeftHeight + bottomRightHeight) / 2) + jitter;

    // Middle
    var middleAverage = (terrainCoordinates[midY][left].height + terrainCoordinates[midY][right].height + terrainCoordinates[top][midX].height + terrainCoordinates[bottom][midX].height) / 4;
    terrainCoordinates[midY][midX].height = middleAverage;

    if ((midY - top) >= 2) {
      newJitterAmount = jitterAmount * jitterDecay;
      midpointDisplace(terrainCoordinates, newJitterAmount, jitterDecay, top, midX, midY, left);
      midpointDisplace(terrainCoordinates, newJitterAmount, jitterDecay, top, right, midY, midX);
      midpointDisplace(terrainCoordinates, newJitterAmount, jitterDecay, midY, midX, bottom, left);
      midpointDisplace(terrainCoordinates, newJitterAmount, jitterDecay, midY, right, bottom, midX);
    }
  };

  var terrainGenerator = {};

  terrainGenerator.generate = function(columns, rows) {
    var terrainCoordinates = buildTerrainCoordinates(columns, rows);
    return new CityTour.Terrain(terrainCoordinates, SUB_DIVISIONS);
  };

  return terrainGenerator;
})();
<commit_msg>General code cleanup<commit_after>"use strict";

var CityTour = CityTour || {};

CityTour.TerrainGenerator = (function() {
  var SUB_DIVISIONS = 1;
  var MAX_INITIAL_TERRAIN_HEIGHT = 6;
  var HEIGHT_JITTER_PER_ITERATION = 20;
  var HEIGHT_JITTER_DECAY_PER_ITERATION = 0.65;
  var LAND = 'land';
  var WATER = 'water';

  var emptyTerrain = function(columns, rows) {
    var x, z;
    var terrainCoordinates = [];

    for (x = 0; x <= columns; x++) {
      terrainCoordinates[x] = [];

      for (z = 0; z <= rows; z++) {
        terrainCoordinates[x][z] = { material: LAND, height: 0.0 };
      }
    }

    return terrainCoordinates;
  };

  var normalizeCoordinates = function(terrainCoordinates, columns, columnsToGenerate, rows, rowsToGenerate) {
    var x, z;
    var halfColumns = columns / 2;
    var halfRows = rows / 2;
    var columnOffset = halfColumns + ((columnsToGenerate - columns) / 2);
    var rowOffset = halfRows + ((rowsToGenerate - rows) / 2);
    var material;
    var stepAmount = 1 / SUB_DIVISIONS;
    var oldXIndex, oldZIndex;

    var normalizedTerrainCoordinates = [];

    for (x = -halfColumns; x <= halfColumns; x += stepAmount) {
      normalizedTerrainCoordinates[x] = [];
      oldXIndex = (x * SUB_DIVISIONS) + columnOffset;

      for (z = -halfRows; z <= halfRows; z += stepAmount) {
        oldZIndex = (z * SUB_DIVISIONS) + rowOffset;

        normalizedTerrainCoordinates[x][z] = {
          material: terrainCoordinates[oldXIndex][oldZIndex].material,
          height: terrainCoordinates[oldXIndex][oldZIndex].height,
        }
      }
    }

    return normalizedTerrainCoordinates;
  };

  var nextPowerOfTwo = function(n) {
    return Math.pow(2, Math.ceil(Math.log2(n)));
  };

  var buildTerrainCoordinates = function(columns, rows) {
    var columnsToGenerate = nextPowerOfTwo(columns * SUB_DIVISIONS);
    var rowsToGenerate = nextPowerOfTwo(rows * SUB_DIVISIONS);

    var terrainCoordinates = emptyTerrain(columnsToGenerate, rowsToGenerate);

    // Initial randomization of corners
    terrainCoordinates[0][0].height = Math.floor(Math.random() * MAX_INITIAL_TERRAIN_HEIGHT);
    terrainCoordinates[0][rowsToGenerate].height = Math.floor(Math.random() * MAX_INITIAL_TERRAIN_HEIGHT);
    terrainCoordinates[columnsToGenerate][0].height = Math.floor(Math.random() * MAX_INITIAL_TERRAIN_HEIGHT);
    terrainCoordinates[columnsToGenerate][rowsToGenerate].height = Math.floor(Math.random() * MAX_INITIAL_TERRAIN_HEIGHT);

    // City must be (2^n + 1) blocks on both x and z dimensions for this to work
    midpointDisplace(terrainCoordinates,
                     HEIGHT_JITTER_PER_ITERATION,
                     HEIGHT_JITTER_DECAY_PER_ITERATION,
                     0,
                     rowsToGenerate,
                     columnsToGenerate,
                     0);

    addRiver(terrainCoordinates, rowsToGenerate / 2, columnsToGenerate);

    // Convert to final coordinates
    var finalTerrainCoordinates = normalizeCoordinates(terrainCoordinates, columns, columnsToGenerate, rows, rowsToGenerate);

    return finalTerrainCoordinates;
  };

  var addRiver = function(terrainCoordinates, middleRow, columnsToGenerate) {
    var x, z, xStep;
    var minimumRiverBankHeight;
    var vector, topVector, bottomVector;
    var topCurve, bottomCurve;

    topCurve = new THREE.CubicBezierCurve(
	    new THREE.Vector2(0, middleRow + 4),
      new THREE.Vector2(columnsToGenerate / 3, middleRow - 3),
      new THREE.Vector2((columnsToGenerate / 3) * 2, middleRow + 7),
      new THREE.Vector2(columnsToGenerate, middleRow + 6)
    );

    bottomCurve = new THREE.CubicBezierCurve(
	    new THREE.Vector2(0, middleRow + 20),
      new THREE.Vector2(columnsToGenerate / 3, middleRow + 4),
      new THREE.Vector2((columnsToGenerate / 3) * 2, middleRow + 17),
      new THREE.Vector2(columnsToGenerate, middleRow + 10)
    );

    xStep = 1 / columnsToGenerate;

    minimumRiverBankHeight = Number.POSITIVE_INFINITY;
    for (x = 0.0; x <= 1.0; x += xStep) {
      vector = topCurve.getPoint(x);
      if (terrainCoordinates[vector.x][Math.round(vector.y)].height < minimumRiverBankHeight) {
        minimumRiverBankHeight = terrainCoordinates[vector.x][Math.round(vector.y)].height;
      }
    }
    for (x = 0.0; x <= 1.0; x += xStep) {
      vector = bottomCurve.getPoint(x);
      if (terrainCoordinates[vector.x][Math.round(vector.y)].height < minimumRiverBankHeight) {
        minimumRiverBankHeight = terrainCoordinates[vector.x][Math.round(vector.y)].height;
      }
    }

    for (x = 0.0; x <= 1.0; x += xStep) {
      topVector = topCurve.getPoint(x);
      bottomVector = bottomCurve.getPoint(x);

      for (z = Math.ceil(topVector.y); z < bottomVector.y; z++) {
        terrainCoordinates[topVector.x][z].height = minimumRiverBankHeight;
      }
    }

    floodFill(terrainCoordinates, 0, topCurve.getPoint(0).y, minimumRiverBankHeight, WATER);
  };

  var floodFill = function(terrainCoordinates, x, z, height, material) {
    terrainCoordinates[x][z].height = height;
    terrainCoordinates[x][z].material = material;

    if (terrainCoordinates[x - 1] &&
        terrainCoordinates[x - 1][z] &&
        terrainCoordinates[x - 1][z].height <= height &&
        terrainCoordinates[x - 1][z].material != material) {
      floodFill(terrainCoordinates, x - 1, z, height, material);
    }
    if (terrainCoordinates[x + 1] &&
        terrainCoordinates[x + 1][z] &&
        terrainCoordinates[x + 1][z].height <= height &&
        terrainCoordinates[x + 1][z].material != material) {
      floodFill(terrainCoordinates, x + 1, z, height, material);
    }
    if (terrainCoordinates[x] &&
        terrainCoordinates[x][z - 1] &&
        terrainCoordinates[x][z - 1].height <= height &&
        terrainCoordinates[x][z - 1].material != material) {
      floodFill(terrainCoordinates, x, z - 1, height, material);
    }
    if (terrainCoordinates[x] &&
        terrainCoordinates[x][z + 1] &&
        terrainCoordinates[x][z + 1].height <= height &&
        terrainCoordinates[x][z + 1].material != material) {
      floodFill(terrainCoordinates, x, z + 1, height, material);
    }
  };

  // Adapted from http://stevelosh.com/blog/2016/02/midpoint-displacement/
  var midpointDisplace = function(terrainCoordinates, jitterAmount, jitterDecay, top, right, bottom, left) {
    var topLeftHeight     = terrainCoordinates[top][left].height;
    var topRightHeight    = terrainCoordinates[top][right].height;
    var bottomLeftHeight  = terrainCoordinates[bottom][left].height;
    var bottomRightHeight = terrainCoordinates[bottom][right].height;

    var midY = top + ((bottom - top) / 2);
    var midX = left + ((right - left) / 2);

    var jitter;
    var newJitterAmount;
    var halfJitterAmount = jitterAmount / 2;

    // Left column
    jitter = (Math.random() * jitterAmount) - halfJitterAmount;
    terrainCoordinates[midY][left].height = ((topLeftHeight + bottomLeftHeight) / 2) + jitter;
    // Right column
    jitter = (Math.random() * jitterAmount) - halfJitterAmount;
    terrainCoordinates[midY][right].height = ((topRightHeight + bottomRightHeight) / 2) + jitter;
    // Top row
    jitter = (Math.random() * jitterAmount) - halfJitterAmount;
    terrainCoordinates[top][midX].height = ((topLeftHeight + topRightHeight) / 2) + jitter;
    // Bottom row
    jitter = (Math.random() * jitterAmount) - halfJitterAmount;
    terrainCoordinates[bottom][midX].height = ((bottomLeftHeight + bottomRightHeight) / 2) + jitter;

    // Middle
    var middleAverage = (terrainCoordinates[midY][left].height + terrainCoordinates[midY][right].height + terrainCoordinates[top][midX].height + terrainCoordinates[bottom][midX].height) / 4;
    terrainCoordinates[midY][midX].height = middleAverage;

    if ((midY - top) >= 2) {
      newJitterAmount = jitterAmount * jitterDecay;
      midpointDisplace(terrainCoordinates, newJitterAmount, jitterDecay, top, midX, midY, left);
      midpointDisplace(terrainCoordinates, newJitterAmount, jitterDecay, top, right, midY, midX);
      midpointDisplace(terrainCoordinates, newJitterAmount, jitterDecay, midY, midX, bottom, left);
      midpointDisplace(terrainCoordinates, newJitterAmount, jitterDecay, midY, right, bottom, midX);
    }
  };

  var terrainGenerator = {};

  terrainGenerator.generate = function(columns, rows) {
    var terrainCoordinates = buildTerrainCoordinates(columns, rows);
    return new CityTour.Terrain(terrainCoordinates, SUB_DIVISIONS);
  };

  return terrainGenerator;
})();
<|endoftext|>


<commit_before>var $ = require('jquery');
var Backbone = require('backbone');
var util = require('cdb.core.util');

var CartoDBLayerGroupBase = Backbone.Model.extend({
  defaults: {
    visible: true
  },

  initialize: function (attributes, options) {
    options = options || {};

    if (!options.windshaftMap) {
      throw new Error('windshaftMap option is required');
    }

    this.layers = new Backbone.Collection(options.layers || []);
    this._windshaftMap = options.windshaftMap;

    // When a new instance of the map is created in Windshaft, we will need to use
    // new URLs for the tiles (`urls` attribute) and also for the attributes (`baseURL`)
    this._windshaftMap.bind('instanceCreated', function (mapInstance) {

      // TODO: We might need to get tiles of other type of layers too. For example, when we're generating
      // static images, we can't the layer with labels on top to be included.
      this.set({
        baseURL: mapInstance.getBaseURL(),
        urls: mapInstance.getTiles('mapnik')
      });
    }, this);
  },

  isEqual: function () {
    return false;
  },

  /**
   * Returns a TileJSON format object for the given layerIndex
   * @param  {number} layerIndex The index of one of the CartoDB layers grouped by this class.
   */
  getTileJSONFromTiles: function (layerIndex) {
    var urls = this.get('urls');
    if (urls) {
      return {
        tilejson: '2.0.0',
        scheme: 'xyz',
        grids: urls.grids[this._convertToMapnikLayerIndex(layerIndex)],
        tiles: urls.tiles,
        formatter: function (options, data) { return data; }
      };
    }
  },

  /**
   * Converts an index of a layer in relation to the layerGroup to
   * the corresponding index of that layer in the Windshaft Map Instance.
   */
  _convertToWindshaftLayerIndex: function (layerIndex) {
    throw new Error('_convertToWindshaftLayerIndex must be implemented');
  },

  /**
   * Converts the index of a 'CartoDB' layer in this layerGroup to
   * the corresponding index of that same layer in the Windshaft Map Instance,
   * only considering 'mapnik' layers (eg: ignoring possible `http` below the
   * `mapnik` layers ).
   */
  _convertToMapnikLayerIndex: function (layerIndex) {
    throw new Error('_convertToMapnikLayerIndex must be implemented');
  },

  fetchAttributes: function (layerIndex, featureID, callback) {
    if (!this.get('baseURL')) {
      throw new Error('Attributes cannot be fetched until baseURL is set');
    }

    var windhaftLayerIndex = this._convertToWindshaftLayerIndex(layerIndex);
    if (windhaftLayerIndex >= 0) {
      var url = this.get('baseURL') + '/' + windhaftLayerIndex + '/attributes/' + featureID;
      var apiKey = this._windshaftMap.get('apiKey');
      if (apiKey) {
        url += '?api_key=' + apiKey;
      }

      $.ajax({
        dataType: 'jsonp',
        url: url,
        jsonpCallback: '_cdbi_layer_attributes_' + util.uniqueCallbackName(this.toJSON()),
        cache: true,
        success: function (data) {
          // loadingTime.end();
          callback(data);
        },
        error: function (data) {
          // loadingTime.end();
          // cartodb.core.Profiler.metric('cartodb-js.named_map.attributes.error').inc();
          callback(null);
        }
      });
    } else {
      callback(null);
    }
  }
});

module.exports = CartoDBLayerGroupBase;
<commit_msg>Fixed linting error<commit_after>var $ = require('jquery');
var Backbone = require('backbone');
var util = require('cdb.core.util');

var CartoDBLayerGroupBase = Backbone.Model.extend({
  defaults: {
    visible: true
  },

  initialize: function (attributes, options) {
    options = options || {};

    if (!options.windshaftMap) {
      throw new Error('windshaftMap option is required');
    }

    this.layers = new Backbone.Collection(options.layers || []);
    this._windshaftMap = options.windshaftMap;

    // When a new instance of the map is created in Windshaft, we will need to use
    // new URLs for the tiles (`urls` attribute) and also for the attributes (`baseURL`)
    this._windshaftMap.bind('instanceCreated', function (mapInstance) {
      // TODO: We might need to get tiles of other type of layers too. For example, when we're generating
      // static images, we can't the layer with labels on top to be included.
      this.set({
        baseURL: mapInstance.getBaseURL(),
        urls: mapInstance.getTiles('mapnik')
      });
    }, this);
  },

  isEqual: function () {
    return false;
  },

  /**
   * Returns a TileJSON format object for the given layerIndex
   * @param  {number} layerIndex The index of one of the CartoDB layers grouped by this class.
   */
  getTileJSONFromTiles: function (layerIndex) {
    var urls = this.get('urls');
    if (urls) {
      return {
        tilejson: '2.0.0',
        scheme: 'xyz',
        grids: urls.grids[this._convertToMapnikLayerIndex(layerIndex)],
        tiles: urls.tiles,
        formatter: function (options, data) { return data; }
      };
    }
  },

  /**
   * Converts an index of a layer in relation to the layerGroup to
   * the corresponding index of that layer in the Windshaft Map Instance.
   */
  _convertToWindshaftLayerIndex: function (layerIndex) {
    throw new Error('_convertToWindshaftLayerIndex must be implemented');
  },

  /**
   * Converts the index of a 'CartoDB' layer in this layerGroup to
   * the corresponding index of that same layer in the Windshaft Map Instance,
   * only considering 'mapnik' layers (eg: ignoring possible `http` below the
   * `mapnik` layers ).
   */
  _convertToMapnikLayerIndex: function (layerIndex) {
    throw new Error('_convertToMapnikLayerIndex must be implemented');
  },

  fetchAttributes: function (layerIndex, featureID, callback) {
    if (!this.get('baseURL')) {
      throw new Error('Attributes cannot be fetched until baseURL is set');
    }

    var windhaftLayerIndex = this._convertToWindshaftLayerIndex(layerIndex);
    if (windhaftLayerIndex >= 0) {
      var url = this.get('baseURL') + '/' + windhaftLayerIndex + '/attributes/' + featureID;
      var apiKey = this._windshaftMap.get('apiKey');
      if (apiKey) {
        url += '?api_key=' + apiKey;
      }

      $.ajax({
        dataType: 'jsonp',
        url: url,
        jsonpCallback: '_cdbi_layer_attributes_' + util.uniqueCallbackName(this.toJSON()),
        cache: true,
        success: function (data) {
          // loadingTime.end();
          callback(data);
        },
        error: function (data) {
          // loadingTime.end();
          // cartodb.core.Profiler.metric('cartodb-js.named_map.attributes.error').inc();
          callback(null);
        }
      });
    } else {
      callback(null);
    }
  }
});

module.exports = CartoDBLayerGroupBase;
<|endoftext|>


<commit_before>/* Copyright 2014 Jack Wakefield
 *
 * 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.
 */

/**
 * The connecting module.
 * @type {Object}
 */
export let connectingModule = angular.module('global.connecting', []);
<commit_msg>fix(connecting): add communication module as a module dependency<commit_after>/* Copyright 2014 Jack Wakefield
 *
 * 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.
 */

/**
 * The connecting module.
 * @type {Object}
 */
export let connectingModule = angular.module('global.connecting', [
    'ct.ui.router.extras',
    'components.communication']);
<|endoftext|>


<commit_before>'use strict';

angular.module('ui.utils.masks.global.percentage', [
	'ui.utils.masks.helpers'
])
.directive('uiPercentageMask',
	['$locale', '$parse', 'PreFormatters', 'NumberMasks', 'NumberValidators',
	function ($locale, $parse, PreFormatters, NumberMasks, NumberValidators) {
		function preparePercentageToFormatter (value, decimals) {
			return PreFormatters.clearDelimitersAndLeadingZeros((parseFloat(value)*100).toFixed(decimals));
		}

		return {
			restrict: 'A',
			require: 'ngModel',
			link: function (scope, element, attrs, ctrl) {
				var decimalDelimiter = $locale.NUMBER_FORMATS.DECIMAL_SEP,
					thousandsDelimiter = $locale.NUMBER_FORMATS.GROUP_SEP,
					decimals = parseInt(attrs.uiPercentageMask);

				if (angular.isDefined(attrs.uiHideGroupSep)){
					thousandsDelimiter = '';
				}

				if(isNaN(decimals)) {
					decimals = 2;
				}
				var numberDecimals = decimals + 2;
				var viewMask = NumberMasks.viewMask(decimals, decimalDelimiter, thousandsDelimiter),
					modelMask = NumberMasks.modelMask(numberDecimals);

				ctrl.$formatters.push(function(value) {
					if(!value) {
						return value;
					}

					var valueToFormat = preparePercentageToFormatter(value, decimals);
					return viewMask.apply(valueToFormat) + ' %';
				});

				function parse(value) {
					if(!value) {
						return value;
					}

					var valueToFormat = PreFormatters.clearDelimitersAndLeadingZeros(value) || '0';
					if(value.length > 1 && value.indexOf('%') === -1) {
						valueToFormat = valueToFormat.slice(0,valueToFormat.length-1);
					}
					var formatedValue = viewMask.apply(valueToFormat) + ' %';
					var actualNumber = parseFloat(modelMask.apply(valueToFormat));

					if (ctrl.$viewValue !== formatedValue) {
						ctrl.$setViewValue(formatedValue);
						ctrl.$render();
					}

					return actualNumber;
				}

				ctrl.$parsers.push(parse);

				if (attrs.uiPercentageMask) {
					scope.$watch(attrs.uiPercentageMask, function(decimals) {
						if(isNaN(decimals)) {
							decimals = 2;
						}
						numberDecimals = decimals + 2;
						viewMask = NumberMasks.viewMask(decimals, decimalDelimiter, thousandsDelimiter);
						modelMask = NumberMasks.modelMask(numberDecimals);

						parse(ctrl.$viewValue || '');
					});
				}

				if(attrs.min){
					ctrl.$parsers.push(function(value) {
						var min = $parse(attrs.min)(scope);
						return NumberValidators.minNumber(ctrl, value, min);
					});

					scope.$watch('min', function(value) {
						NumberValidators.minNumber(ctrl, ctrl.$modelValue, value);
					});
				}

				if(attrs.max) {
					ctrl.$parsers.push(function(value) {
						var max = $parse(attrs.max)(scope);
						return NumberValidators.maxNumber(ctrl, value, max);
					});

					scope.$watch('max', function(value) {
						NumberValidators.maxNumber(ctrl, ctrl.$modelValue, value);
					});
				}
			}
		};
	}
]);
<commit_msg>fix(percentage): fix the result for 0 and other edge cases<commit_after>'use strict';

angular.module('ui.utils.masks.global.percentage', [
	'ui.utils.masks.helpers'
])
.directive('uiPercentageMask',
	['$locale', '$parse', 'PreFormatters', 'NumberMasks', 'NumberValidators',
	function ($locale, $parse, PreFormatters, NumberMasks, NumberValidators) {
		function preparePercentageToFormatter (value, decimals) {
			return PreFormatters.clearDelimitersAndLeadingZeros((parseFloat(value)*100).toFixed(decimals));
		}

		return {
			restrict: 'A',
			require: 'ngModel',
			link: function (scope, element, attrs, ctrl) {
				var decimalDelimiter = $locale.NUMBER_FORMATS.DECIMAL_SEP,
					thousandsDelimiter = $locale.NUMBER_FORMATS.GROUP_SEP,
					decimals = parseInt(attrs.uiPercentageMask);

				if (angular.isDefined(attrs.uiHideGroupSep)){
					thousandsDelimiter = '';
				}

				if(isNaN(decimals)) {
					decimals = 2;
				}

				var numberDecimals = decimals + 2;
				var viewMask = NumberMasks.viewMask(decimals, decimalDelimiter, thousandsDelimiter),
					modelMask = NumberMasks.modelMask(numberDecimals);

				function formatter(value) {
					if(ctrl.$isEmpty(value)) {
						return value;
					}

					var valueToFormat = preparePercentageToFormatter(value, decimals);
					return viewMask.apply(valueToFormat) + ' %';
				}

				function parse(value) {
					if(ctrl.$isEmpty(value)) {
						return value;
					}

					var valueToFormat = PreFormatters.clearDelimitersAndLeadingZeros(value) || '0';
					if(value.length > 1 && value.indexOf('%') === -1) {
						valueToFormat = valueToFormat.slice(0,valueToFormat.length-1);
					}
					var formatedValue = viewMask.apply(valueToFormat) + ' %';
					var actualNumber = parseFloat(modelMask.apply(valueToFormat));

					if (ctrl.$viewValue !== formatedValue) {
						ctrl.$setViewValue(formatedValue);
						ctrl.$render();
					}

					return actualNumber;
				}

				ctrl.$formatters.push(formatter);
				ctrl.$parsers.push(parse);

				if (attrs.uiPercentageMask) {
					scope.$watch(attrs.uiPercentageMask, function(decimals) {
						if(isNaN(decimals)) {
							decimals = 2;
						}
						numberDecimals = decimals + 2;
						viewMask = NumberMasks.viewMask(decimals, decimalDelimiter, thousandsDelimiter);
						modelMask = NumberMasks.modelMask(numberDecimals);

						parse(ctrl.$viewValue || '');
					});
				}

				if(attrs.min){
					ctrl.$parsers.push(function(value) {
						var min = $parse(attrs.min)(scope);
						return NumberValidators.minNumber(ctrl, value, min);
					});

					scope.$watch('min', function(value) {
						NumberValidators.minNumber(ctrl, ctrl.$modelValue, value);
					});
				}

				if(attrs.max) {
					ctrl.$parsers.push(function(value) {
						var max = $parse(attrs.max)(scope);
						return NumberValidators.maxNumber(ctrl, value, max);
					});

					scope.$watch('max', function(value) {
						NumberValidators.maxNumber(ctrl, ctrl.$modelValue, value);
					});
				}
			}
		};
	}
]);
<|endoftext|>


<commit_before>import determineCondition from '../utils/determineCondition';

const convertStylesToArray = (obj, previousSelectors, recursiveOptions = {}) => {
  if(typeof obj !== 'object') return obj;
  const newObj = Object.entries(obj);
  return newObj.map(([key, value]) => {
    let selectors = [...previousSelectors];
    // All @-stuff from css, should go global.
    if(key.startsWith('@')) {
      selectors = [ key ];
    }

    let type = 'node';
    let condition = null;
    if(key.startsWith('_')) {
      type = 'mixin';
    }
    else if(Array.isArray(value)) {
      type = 'array';
      value = value.map((v, i) => {
        if(typeof v === 'object') {
          return convertStylesToArray(v, selectors);
        }
        return {
          type: 'node',
          selectors,
          append: true,
          key,
          value: v,
          condition,
        };
      })
    }
    else if(typeof value === 'object' && value){
      type = 'nested';
      // If media query, take current selector, and put it after the media query
      if(key.startsWith('@media')) {
        selectors.push(previousSelectors[previousSelectors.length - 1]);
      }
      else if(selectors[0].startsWith('@keyframes')) {
        if(!key.startsWith('@keyframes')){
          selectors.push(key);
        }
      }
      // CSS Selectors like "&:hover" etc.
      else if(key.indexOf('&') > -1) {
        selectors[selectors.length - 1] = key;
      }
      // Else we assume this is prop based conditions
      else {
        // setting condition to determine if styles should be applied
        if(!recursiveOptions.disableProps) {
          condition = determineCondition(key);
          if(condition && recursiveOptions.__touchedConditionalProps) {
            recursiveOptions.__touchedConditionalProps[condition.key] = true;
          }
        }
      }
      value = convertStylesToArray(value, selectors, recursiveOptions);
    }

    return {
      type,
      key,
      value,
      selectors,
      condition,
    };
  })
}
export default convertStylesToArray;<commit_msg>preparing logic for multi conditions<commit_after>import determineCondition from '../utils/determineCondition';

const convertStylesToArray = (obj, previousSelectors, recursiveOptions = {}) => {
  if(typeof obj !== 'object') return obj;
  const newObj = Object.entries(obj);
  return newObj.map(([key, value]) => {
    let selectors = [...previousSelectors];
    // All @-stuff from css, should go global.
    if(key.startsWith('@')) {
      selectors = [ key ];
    }

    let type = 'node';
    let condition = null;
    if(key.startsWith('_')) {
      type = 'mixin';
    }
    else if(Array.isArray(value)) {
      type = 'array';
      value = value.map((v, i) => {
        if(typeof v === 'object') {
          return convertStylesToArray(v, selectors);
        }
        return {
          type: 'node',
          selectors,
          append: true,
          key,
          value: v,
          condition,
        };
      })
    }
    else if(typeof value === 'object' && value){
      type = 'nested';
      // If media query, take current selector, and put it after the media query
      if(key.startsWith('@media')) {
        selectors.push(previousSelectors[previousSelectors.length - 1]);
      }
      else if(selectors[0].startsWith('@keyframes')) {
        if(!key.startsWith('@keyframes')){
          selectors.push(key);
        }
      }
      // CSS Selectors like "&:hover" etc.
      else if(key.indexOf('&') > -1 && key.indexOf('&&') === -1) {
        selectors[selectors.length - 1] = key;
      }
      // Else we assume this is prop based conditions
      else {
        // setting condition to determine if styles should be applied
        if(!recursiveOptions.disableProps) {
          condition = determineCondition(key);
          if(condition && recursiveOptions.__touchedConditionalProps) {
            recursiveOptions.__touchedConditionalProps[condition.key] = true;
          }
        }
      }
      value = convertStylesToArray(value, selectors, recursiveOptions);
    }

    return {
      type,
      key,
      value,
      selectors,
      condition,
    };
  })
}
export default convertStylesToArray;<|endoftext|>


<commit_before>'use strict';

angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, storageService, $ionicScrollDelegate, $window, bwcError, gettextCatalog) {

  var HISTORY_SHOW_LIMIT = 10;
  var currentTxHistoryPage = 0;
  var listeners = [];
  $scope.txps = [];
  $scope.completeTxHistory = [];
  $scope.openTxpModal = txpModalService.open;
  $scope.isCordova = platformInfo.isCordova;
  $scope.isAndroid = platformInfo.isAndroid;
  $scope.isIOS = platformInfo.isIOS;

  $scope.amountIsCollapsible = !$scope.isAndroid;

  $scope.openExternalLink = function(url, target) {
    externalLinkService.open(url, target);
  };

  var setPendingTxps = function(txps) {

    /* Uncomment to test multiple outputs */

    // var txp = {
    //   message: 'test multi-output',
    //   fee: 1000,
    //   createdOn: new Date() / 1000,
    //   outputs: [],
    //   wallet: $scope.wallet
    // };
    //
    // function addOutput(n) {
    //   txp.outputs.push({
    //     amount: 600,
    //     toAddress: '2N8bhEwbKtMvR2jqMRcTCQqzHP6zXGToXcK',
    //     message: 'output #' + (Number(n) + 1)
    //   });
    // };
    // lodash.times(15, addOutput);
    // txps.push(txp);

    if (!txps) {
      $scope.txps = [];
      return;
    }
    $scope.txps = lodash.sortBy(txps, 'createdOn').reverse();
  };

  var updateStatus = function(force) {
    $scope.updatingStatus = true;
    $scope.updateStatusError = null;
    $scope.walletNotRegistered = false;

    walletService.getStatus($scope.wallet, {
      force: !!force,
    }, function(err, status) {
      $scope.updatingStatus = false;
      if (err) {
        if (err === 'WALLET_NOT_REGISTERED') {
          $scope.walletNotRegistered = true;
        } else {
          $scope.updateStatusError = bwcError.msg(err, gettextCatalog.getString('Could not update wallet'));
        }
        $scope.status = null;
      } else {
        setPendingTxps(status.pendingTxps);
        $scope.status = status;
      }
      refreshAmountSection();
      $timeout(function() {
        $scope.$apply();
      });

    });
  };

  $scope.openSearchModal = function() {
    $scope.color = $scope.wallet.color;

    $ionicModal.fromTemplateUrl('views/modals/search.html', {
      scope: $scope,
      focusFirstInput: true
    }).then(function(modal) {
      $scope.searchModal = modal;
      $scope.searchModal.show();
    });

    $scope.close = function() {
      $scope.searchModal.hide();
    };

    $scope.openTx = function(tx) {
      $ionicHistory.nextViewOptions({
        disableAnimate: true
      });
      $scope.searchModal.hide();
      $scope.openTxModal(tx);
    };
  };

  $scope.openTxModal = function(btx) {
    $scope.btx = lodash.cloneDeep(btx);
    $scope.walletId = $scope.wallet.id;
    $state.transitionTo('tabs.wallet.tx-details', {
      txid: $scope.btx.txid,
      walletId: $scope.walletId
    });
  };

  $scope.openBalanceModal = function() {
    $ionicModal.fromTemplateUrl('views/modals/wallet-balance.html', {
      scope: $scope
    }).then(function(modal) {
      $scope.walletBalanceModal = modal;
      $scope.walletBalanceModal.show();
    });

    $scope.close = function() {
      $scope.walletBalanceModal.hide();
    };
  };

  $scope.recreate = function() {
    walletService.recreate($scope.wallet, function(err) {
      if (err) return;
      $timeout(function() {
        walletService.startScan($scope.wallet, function() {
          $scope.updateAll();
          $scope.$apply();
        });
      });
    });
  };

  var updateTxHistory = function(cb) {
    if (!cb) cb = function() {};
    if ($scope.updatingTxHistory) return;

    $scope.updatingTxHistory = true;
    $scope.updateTxHistoryError = false;
    $scope.updatingTxHistoryProgress = 0;

    var progressFn = function(txs, newTxs) {
      $scope.updatingTxHistoryProgress = newTxs;
      $scope.completeTxHistory = txs;
      $scope.showHistory();
      $timeout(function() {
        $scope.$apply();
      });
    };

    $timeout(function() {
      walletService.getTxHistory($scope.wallet, {
        progressFn: progressFn,
      }, function(err, txHistory) {
        $scope.updatingTxHistory = false;
        if (err) {
          $scope.txHistory = null;
          $scope.updateTxHistoryError = true;
          return;
        }
        $scope.completeTxHistory = txHistory;
        $scope.showHistory();
        $scope.$apply();
        return cb();
      });
    });
  };

  $scope.showHistory = function() {
    if ($scope.completeTxHistory) {
      $scope.txHistory = $scope.completeTxHistory.slice(0, (currentTxHistoryPage + 1) * HISTORY_SHOW_LIMIT);
      $scope.txHistoryShowMore = $scope.completeTxHistory.length > $scope.txHistory.length;
    }
  };

  $scope.getDate = function(txCreated) {
    var date = new Date(txCreated * 1000);
    return date;
  };

  $scope.isFirstInGroup = function(index) {
    if (index === 0) {
      return true;
    }
    var curTx = $scope.txHistory[index];
    var prevTx = $scope.txHistory[index - 1];
    return !createdDuringSameMonth(curTx, prevTx);
  };

  $scope.isLastInGroup = function(index) {
    if (index === $scope.txHistory.length - 1) {
      return true;
    }
    return $scope.isFirstInGroup(index + 1);
  };

  function createdDuringSameMonth(tx1, tx2) {
    var date1 = new Date(tx1.time * 1000);
    var date2 = new Date(tx2.time * 1000);
    return getMonthYear(date1) === getMonthYear(date2);
  }

  $scope.createdWithinPastDay = function(time) {
    var now = new Date();
    var date = new Date(time * 1000);
    return (now.getTime() - date.getTime()) < (1000 * 60 * 60 * 24);
  };

  $scope.isDateInCurrentMonth = function(date) {
    var now = new Date();
    return getMonthYear(now) === getMonthYear(date);
  };

  function getMonthYear(date) {
    return date.getMonth() + date.getFullYear();
  }

  $scope.isUnconfirmed = function(tx) {
    return !tx.confirmations || tx.confirmations === 0;
  };

  $scope.showMore = function() {
    $timeout(function() {
      currentTxHistoryPage++;
      $scope.showHistory();
      $scope.$broadcast('scroll.infiniteScrollComplete');
    }, 100);
  };

  $scope.onRefresh = function() {
    $timeout(function() {
      $scope.$broadcast('scroll.refreshComplete');
    }, 300);
    $scope.updateAll(true);
  };

  $scope.updateAll = function(force, cb)  {
    updateStatus(force);
    updateTxHistory(cb);
  };

  $scope.hideToggle = function() {
    profileService.toggleHideBalanceFlag($scope.wallet.credentials.walletId, function(err) {
      if (err) $log.error(err);
    });
  };

  var prevPos;

  function getScrollPosition() {
    var scrollPosition = $ionicScrollDelegate.getScrollPosition();
    if (!scrollPosition) {
      $window.requestAnimationFrame(function() {
        getScrollPosition();
      });
      return;
    }
    var pos = scrollPosition.top;
    if (pos === prevPos) {
      $window.requestAnimationFrame(function() {
        getScrollPosition();
      });
      return;
    }
    prevPos = pos;
    refreshAmountSection(pos);
  };

  function refreshAmountSection(scrollPos) {
    $scope.showBalanceButton = false;
    if ($scope.wallet.status) {
      $scope.showBalanceButton = ($scope.status.totalBalanceSat != $scope.status.spendableAmount);
    }
    if (!$scope.amountIsCollapsible) {
      var t = ($scope.showBalanceButton ? 15 : 45);
      $scope.amountScale = 'translateY(' + t + 'px)';
      return;
    }

    scrollPos = scrollPos || 0;
    var amountHeight = 210 - scrollPos;
    if (amountHeight < 80) {
      amountHeight = 80;
    }
    var contentMargin = amountHeight;
    if (contentMargin > 210) {
      contentMargin = 210;
    }

    var amountScale = (amountHeight / 210);
    if (amountScale < 0.5) {
      amountScale = 0.5;
    }
    if (amountScale > 1.1) {
      amountScale = 1.1;
    }

    var s = amountScale;

    // Make space for the balance button when it needs to display.
    var TOP_NO_BALANCE_BUTTON = 115;
    var TOP_BALANCE_BUTTON = 30;
    var top = TOP_NO_BALANCE_BUTTON;
    if ($scope.showBalanceButton) {
      top = TOP_BALANCE_BUTTON;
    }

    var amountTop = ((amountScale - 0.7) / 0.7) * top;
    if (amountTop < -10) {
      amountTop = -10;
    }
    if (amountTop > top) {
      amountTop = top;
    }

    var t = amountTop;

    $scope.altAmountOpacity = (amountHeight - 100) / 80;
    $window.requestAnimationFrame(function() {
      $scope.amountHeight = amountHeight + 'px';
      $scope.contentMargin = contentMargin + 'px';
      $scope.amountScale = 'scale3d(' + s + ',' + s + ',' + s + ') translateY(' + t + 'px)';
      $scope.$digest();
      getScrollPosition();
    });
  }

  var scrollWatcherInitialized;

  $scope.$on("$ionicView.enter", function(event, data) {
    if ($scope.isCordova && $scope.isAndroid) setAndroidStatusBarColor();
    if (scrollWatcherInitialized || !$scope.amountIsCollapsible) {
      return;
    }
    scrollWatcherInitialized = true;
  });

  $scope.$on("$ionicView.beforeEnter", function(event, data) {
    $scope.walletId = data.stateParams.walletId;
    $scope.wallet = profileService.getWallet($scope.walletId);
    $scope.requiresMultipleSignatures = $scope.wallet.credentials.m > 1;

    addressbookService.list(function(err, ab) {
      if (err) $log.error(err);
      $scope.addressbook = ab || {};
    });

    $scope.updateAll();
    refreshAmountSection();

    listeners = [
      $rootScope.$on('bwsEvent', function(e, walletId) {
        if (walletId == $scope.wallet.id && e.type != 'NewAddress')
          $scope.updateAll();
      }),
      $rootScope.$on('Local/TxAction', function(e, walletId) {
        if (walletId == $scope.wallet.id)
          $scope.updateAll();
      }),
    ];
  });

  $scope.$on("$ionicView.beforeLeave", function(event, data) {
    if ($window.StatusBar) {
      $window.StatusBar.backgroundColorByHexString('#1e3186');
    }
  });

  $scope.$on("$ionicView.leave", function(event, data) {
    lodash.each(listeners, function(x) {
      x();
    });
  });

  function setAndroidStatusBarColor() {
    var SUBTRACT_AMOUNT = 15;
    var rgb = hexToRgb($scope.wallet.color);
    var keys = Object.keys(rgb);
    keys.forEach(function(k) {
      if (rgb[k] - SUBTRACT_AMOUNT < 0) {
        rgb[k] = 0;
      } else {
        rgb[k] -= SUBTRACT_AMOUNT;
      }
    });
    var statusBarColorHexString = rgbToHex(rgb.r, rgb.g, rgb.b);
    if ($window.StatusBar)
      $window.StatusBar.backgroundColorByHexString(statusBarColorHexString);
  }

  function hexToRgb(hex) {
    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
      return r + r + g + g + b + b;
    });

    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
      r: parseInt(result[1], 16),
      g: parseInt(result[2], 16),
      b: parseInt(result[3], 16)
    } : null;
  }

  function componentToHex(c) {
    var hex = c.toString(16);
    return hex.length == 1 ? "0" + hex : hex;
  }

  function rgbToHex(r, g, b) {
    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
  }
});
<commit_msg>fix propertie name<commit_after>'use strict';

angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, storageService, $ionicScrollDelegate, $window, bwcError, gettextCatalog) {

  var HISTORY_SHOW_LIMIT = 10;
  var currentTxHistoryPage = 0;
  var listeners = [];
  $scope.txps = [];
  $scope.completeTxHistory = [];
  $scope.openTxpModal = txpModalService.open;
  $scope.isCordova = platformInfo.isCordova;
  $scope.isAndroid = platformInfo.isAndroid;
  $scope.isIOS = platformInfo.isIOS;

  $scope.amountIsCollapsible = !$scope.isAndroid;

  $scope.openExternalLink = function(url, target) {
    externalLinkService.open(url, target);
  };

  var setPendingTxps = function(txps) {

    /* Uncomment to test multiple outputs */

    // var txp = {
    //   message: 'test multi-output',
    //   fee: 1000,
    //   createdOn: new Date() / 1000,
    //   outputs: [],
    //   wallet: $scope.wallet
    // };
    //
    // function addOutput(n) {
    //   txp.outputs.push({
    //     amount: 600,
    //     toAddress: '2N8bhEwbKtMvR2jqMRcTCQqzHP6zXGToXcK',
    //     message: 'output #' + (Number(n) + 1)
    //   });
    // };
    // lodash.times(15, addOutput);
    // txps.push(txp);

    if (!txps) {
      $scope.txps = [];
      return;
    }
    $scope.txps = lodash.sortBy(txps, 'createdOn').reverse();
  };

  var updateStatus = function(force) {
    $scope.updatingStatus = true;
    $scope.updateStatusError = null;
    $scope.walletNotRegistered = false;

    walletService.getStatus($scope.wallet, {
      force: !!force,
    }, function(err, status) {
      $scope.updatingStatus = false;
      if (err) {
        if (err === 'WALLET_NOT_REGISTERED') {
          $scope.walletNotRegistered = true;
        } else {
          $scope.updateStatusError = bwcError.msg(err, gettextCatalog.getString('Could not update wallet'));
        }
        $scope.status = null;
      } else {
        setPendingTxps(status.pendingTxps);
        $scope.status = status;
      }
      refreshAmountSection();
      $timeout(function() {
        $scope.$apply();
      });

    });
  };

  $scope.openSearchModal = function() {
    $scope.color = $scope.wallet.color;

    $ionicModal.fromTemplateUrl('views/modals/search.html', {
      scope: $scope,
      focusFirstInput: true
    }).then(function(modal) {
      $scope.searchModal = modal;
      $scope.searchModal.show();
    });

    $scope.close = function() {
      $scope.searchModal.hide();
    };

    $scope.openTx = function(tx) {
      $ionicHistory.nextViewOptions({
        disableAnimate: true
      });
      $scope.searchModal.hide();
      $scope.openTxModal(tx);
    };
  };

  $scope.openTxModal = function(btx) {
    $scope.btx = lodash.cloneDeep(btx);
    $scope.walletId = $scope.wallet.id;
    $state.transitionTo('tabs.wallet.tx-details', {
      txid: $scope.btx.txid,
      walletId: $scope.walletId
    });
  };

  $scope.openBalanceModal = function() {
    $ionicModal.fromTemplateUrl('views/modals/wallet-balance.html', {
      scope: $scope
    }).then(function(modal) {
      $scope.walletBalanceModal = modal;
      $scope.walletBalanceModal.show();
    });

    $scope.close = function() {
      $scope.walletBalanceModal.hide();
    };
  };

  $scope.recreate = function() {
    walletService.recreate($scope.wallet, function(err) {
      if (err) return;
      $timeout(function() {
        walletService.startScan($scope.wallet, function() {
          $scope.updateAll();
          $scope.$apply();
        });
      });
    });
  };

  var updateTxHistory = function(cb) {
    if (!cb) cb = function() {};
    if ($scope.updatingTxHistory) return;

    $scope.updatingTxHistory = true;
    $scope.updateTxHistoryError = false;
    $scope.updatingTxHistoryProgress = 0;

    var progressFn = function(txs, newTxs) {
      $scope.updatingTxHistoryProgress = newTxs;
      $scope.completeTxHistory = txs;
      $scope.showHistory();
      $timeout(function() {
        $scope.$apply();
      });
    };

    $timeout(function() {
      walletService.getTxHistory($scope.wallet, {
        progressFn: progressFn,
      }, function(err, txHistory) {
        $scope.updatingTxHistory = false;
        if (err) {
          $scope.txHistory = null;
          $scope.updateTxHistoryError = true;
          return;
        }
        $scope.completeTxHistory = txHistory;
        $scope.showHistory();
        $scope.$apply();
        return cb();
      });
    });
  };

  $scope.showHistory = function() {
    if ($scope.completeTxHistory) {
      $scope.txHistory = $scope.completeTxHistory.slice(0, (currentTxHistoryPage + 1) * HISTORY_SHOW_LIMIT);
      $scope.txHistoryShowMore = $scope.completeTxHistory.length > $scope.txHistory.length;
    }
  };

  $scope.getDate = function(txCreated) {
    var date = new Date(txCreated * 1000);
    return date;
  };

  $scope.isFirstInGroup = function(index) {
    if (index === 0) {
      return true;
    }
    var curTx = $scope.txHistory[index];
    var prevTx = $scope.txHistory[index - 1];
    return !createdDuringSameMonth(curTx, prevTx);
  };

  $scope.isLastInGroup = function(index) {
    if (index === $scope.txHistory.length - 1) {
      return true;
    }
    return $scope.isFirstInGroup(index + 1);
  };

  function createdDuringSameMonth(tx1, tx2) {
    var date1 = new Date(tx1.time * 1000);
    var date2 = new Date(tx2.time * 1000);
    return getMonthYear(date1) === getMonthYear(date2);
  }

  $scope.createdWithinPastDay = function(time) {
    var now = new Date();
    var date = new Date(time * 1000);
    return (now.getTime() - date.getTime()) < (1000 * 60 * 60 * 24);
  };

  $scope.isDateInCurrentMonth = function(date) {
    var now = new Date();
    return getMonthYear(now) === getMonthYear(date);
  };

  function getMonthYear(date) {
    return date.getMonth() + date.getFullYear();
  }

  $scope.isUnconfirmed = function(tx) {
    return !tx.confirmations || tx.confirmations === 0;
  };

  $scope.showMore = function() {
    $timeout(function() {
      currentTxHistoryPage++;
      $scope.showHistory();
      $scope.$broadcast('scroll.infiniteScrollComplete');
    }, 100);
  };

  $scope.onRefresh = function() {
    $timeout(function() {
      $scope.$broadcast('scroll.refreshComplete');
    }, 300);
    $scope.updateAll(true);
  };

  $scope.updateAll = function(force, cb)  {
    updateStatus(force);
    updateTxHistory(cb);
  };

  $scope.hideToggle = function() {
    profileService.toggleHideBalanceFlag($scope.wallet.credentials.walletId, function(err) {
      if (err) $log.error(err);
    });
  };

  var prevPos;

  function getScrollPosition() {
    var scrollPosition = $ionicScrollDelegate.getScrollPosition();
    if (!scrollPosition) {
      $window.requestAnimationFrame(function() {
        getScrollPosition();
      });
      return;
    }
    var pos = scrollPosition.top;
    if (pos === prevPos) {
      $window.requestAnimationFrame(function() {
        getScrollPosition();
      });
      return;
    }
    prevPos = pos;
    refreshAmountSection(pos);
  };

  function refreshAmountSection(scrollPos) {
    $scope.showBalanceButton = false;
    if ($scope.status) {
      $scope.showBalanceButton = ($scope.status.totalBalanceSat != $scope.status.spendableAmount);
    }
    if (!$scope.amountIsCollapsible) {
      var t = ($scope.showBalanceButton ? 15 : 45);
      $scope.amountScale = 'translateY(' + t + 'px)';
      return;
    }

    scrollPos = scrollPos || 0;
    var amountHeight = 210 - scrollPos;
    if (amountHeight < 80) {
      amountHeight = 80;
    }
    var contentMargin = amountHeight;
    if (contentMargin > 210) {
      contentMargin = 210;
    }

    var amountScale = (amountHeight / 210);
    if (amountScale < 0.5) {
      amountScale = 0.5;
    }
    if (amountScale > 1.1) {
      amountScale = 1.1;
    }

    var s = amountScale;

    // Make space for the balance button when it needs to display.
    var TOP_NO_BALANCE_BUTTON = 115;
    var TOP_BALANCE_BUTTON = 30;
    var top = TOP_NO_BALANCE_BUTTON;
    if ($scope.showBalanceButton) {
      top = TOP_BALANCE_BUTTON;
    }

    var amountTop = ((amountScale - 0.7) / 0.7) * top;
    if (amountTop < -10) {
      amountTop = -10;
    }
    if (amountTop > top) {
      amountTop = top;
    }

    var t = amountTop;

    $scope.altAmountOpacity = (amountHeight - 100) / 80;
    $window.requestAnimationFrame(function() {
      $scope.amountHeight = amountHeight + 'px';
      $scope.contentMargin = contentMargin + 'px';
      $scope.amountScale = 'scale3d(' + s + ',' + s + ',' + s + ') translateY(' + t + 'px)';
      $scope.$digest();
      getScrollPosition();
    });
  }

  var scrollWatcherInitialized;

  $scope.$on("$ionicView.enter", function(event, data) {
    if ($scope.isCordova && $scope.isAndroid) setAndroidStatusBarColor();
    if (scrollWatcherInitialized || !$scope.amountIsCollapsible) {
      return;
    }
    scrollWatcherInitialized = true;
  });

  $scope.$on("$ionicView.beforeEnter", function(event, data) {
    $scope.walletId = data.stateParams.walletId;
    $scope.wallet = profileService.getWallet($scope.walletId);
    $scope.requiresMultipleSignatures = $scope.wallet.credentials.m > 1;

    addressbookService.list(function(err, ab) {
      if (err) $log.error(err);
      $scope.addressbook = ab || {};
    });

    $scope.updateAll();
    refreshAmountSection();

    listeners = [
      $rootScope.$on('bwsEvent', function(e, walletId) {
        if (walletId == $scope.wallet.id && e.type != 'NewAddress')
          $scope.updateAll();
      }),
      $rootScope.$on('Local/TxAction', function(e, walletId) {
        if (walletId == $scope.wallet.id)
          $scope.updateAll();
      }),
    ];
  });

  $scope.$on("$ionicView.beforeLeave", function(event, data) {
    if ($window.StatusBar) {
      $window.StatusBar.backgroundColorByHexString('#1e3186');
    }
  });

  $scope.$on("$ionicView.leave", function(event, data) {
    lodash.each(listeners, function(x) {
      x();
    });
  });

  function setAndroidStatusBarColor() {
    var SUBTRACT_AMOUNT = 15;
    var rgb = hexToRgb($scope.wallet.color);
    var keys = Object.keys(rgb);
    keys.forEach(function(k) {
      if (rgb[k] - SUBTRACT_AMOUNT < 0) {
        rgb[k] = 0;
      } else {
        rgb[k] -= SUBTRACT_AMOUNT;
      }
    });
    var statusBarColorHexString = rgbToHex(rgb.r, rgb.g, rgb.b);
    if ($window.StatusBar)
      $window.StatusBar.backgroundColorByHexString(statusBarColorHexString);
  }

  function hexToRgb(hex) {
    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
      return r + r + g + g + b + b;
    });

    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
      r: parseInt(result[1], 16),
      g: parseInt(result[2], 16),
      b: parseInt(result[3], 16)
    } : null;
  }

  function componentToHex(c) {
    var hex = c.toString(16);
    return hex.length == 1 ? "0" + hex : hex;
  }

  function rgbToHex(r, g, b) {
    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
  }
});
<|endoftext|>


<commit_before>import * as utils from 'src/utils';
import {
  registerBidder
} from 'src/adapters/bidderFactory';
import {
  BANNER
} from 'src/mediaTypes';
import {
  config
} from 'src/config';

const BIDDER_CODE = 'emx_digital';
const ENDPOINT = 'hb.emxdgt.com';
export const spec = {
  code: BIDDER_CODE,
  supportedMediaTypes: [BANNER],
  isBidRequestValid: function (bid) {
    return !!(bid.params.tagid);
  },
  buildRequests: function (validBidRequests, bidRequests) {
    const {host, href, protocol} = utils.getTopWindowLocation();
    let emxData = {};
    let emxImps = [];
    const auctionId = bidRequests.auctionId;
    const timeout = config.getConfig('bidderTimeout');
    const timestamp = Date.now();
    const url = location.protocol + '//' + ENDPOINT + ('?t=' + timeout + '&ts=' + timestamp);

    utils._each(validBidRequests, function (bid) {
      let tagId = String(utils.getBidIdParameter('tagid', bid.params));
      let bidFloor = utils.getBidIdParameter('bidfloor', bid.params) || 0;
      let emxBid = {
        id: bid.bidId,
        tid: bid.transactionId,
        tagid: tagId,
        secure: protocol === 'https:' ? 1 : 0,
        banner: {
          format: bid.sizes.map(function (size) {
            return {
              w: size[0],
              h: size[1]
            };
          }),
          w: bid.sizes[0][0],
          h: bid.sizes[0][1]
        }
      }
      if (bidFloor > 0) {
        emxBid.bidfloor = bidFloor
      }
      emxImps.push(emxBid);
    });
    emxData = {
      id: auctionId,
      imp: emxImps,
      site: {
        domain: host,
        page: href
      }
    };
    if (bidRequests.gdprConsent) {
      emxData.regs = {
        ext: {
          gdpr: bidRequests.gdprConsent.gdprApplies === true ? 1 : 0
        }
      };
    }
    if (bidRequests.gdprConsent && bidRequests.gdprConsent.gdprApplies) {
      emxData.user = {
        ext: {
          consent: bidRequests.gdprConsent.consentString
        }
      };
    }
    return {
      method: 'POST',
      url: url,
      data: JSON.stringify(emxData),
      options: {
        withCredentials: true
      }
    };
  },
  interpretResponse: function (serverResponse) {
    let emxBidResponses = [];
    let response = serverResponse.body || {};
    if (response.seatbid && response.seatbid.length > 0 && response.seatbid[0].bid) {
      response.seatbid.forEach(function (emxBid) {
        emxBid = emxBid.bid[0];
        emxBidResponses.push({
          requestId: emxBid.id,
          cpm: emxBid.price,
          width: emxBid.w,
          height: emxBid.h,
          creativeId: emxBid.crid || emxBid.id,
          dealId: emxBid.dealid || null,
          currency: 'USD',
          netRevenue: true,
          mediaType: BANNER,
          ad: decodeURIComponent(emxBid.adm),
          ttl: emxBid.ttl
        });
      });
    }
    return emxBidResponses;
  }
};
registerBidder(spec);
<commit_msg>Adding user sync method for IFRAME and Pixel (#3232)<commit_after>import * as utils from 'src/utils';
import {
  registerBidder
} from 'src/adapters/bidderFactory';
import {
  BANNER
} from 'src/mediaTypes';
import {
  config
} from 'src/config';

const BIDDER_CODE = 'emx_digital';
const ENDPOINT = 'hb.emxdgt.com';
export const spec = {
  code: BIDDER_CODE,
  supportedMediaTypes: [BANNER],
  isBidRequestValid: function (bid) {
    return !!(bid.params.tagid);
  },
  buildRequests: function (validBidRequests, bidRequests) {
    const {host, href, protocol} = utils.getTopWindowLocation();
    let emxData = {};
    let emxImps = [];
    const auctionId = bidRequests.auctionId;
    const timeout = config.getConfig('bidderTimeout');
    const timestamp = Date.now();
    const url = location.protocol + '//' + ENDPOINT + ('?t=' + timeout + '&ts=' + timestamp);

    utils._each(validBidRequests, function (bid) {
      let tagId = String(utils.getBidIdParameter('tagid', bid.params));
      let bidFloor = utils.getBidIdParameter('bidfloor', bid.params) || 0;
      let emxBid = {
        id: bid.bidId,
        tid: bid.transactionId,
        tagid: tagId,
        secure: protocol === 'https:' ? 1 : 0,
        banner: {
          format: bid.sizes.map(function (size) {
            return {
              w: size[0],
              h: size[1]
            };
          }),
          w: bid.sizes[0][0],
          h: bid.sizes[0][1]
        }
      }
      if (bidFloor > 0) {
        emxBid.bidfloor = bidFloor
      }
      emxImps.push(emxBid);
    });
    emxData = {
      id: auctionId,
      imp: emxImps,
      site: {
        domain: host,
        page: href
      }
    };
    if (bidRequests.gdprConsent) {
      emxData.regs = {
        ext: {
          gdpr: bidRequests.gdprConsent.gdprApplies === true ? 1 : 0
        }
      };
    }
    if (bidRequests.gdprConsent && bidRequests.gdprConsent.gdprApplies) {
      emxData.user = {
        ext: {
          consent: bidRequests.gdprConsent.consentString
        }
      };
    }
    return {
      method: 'POST',
      url: url,
      data: JSON.stringify(emxData),
      options: {
        withCredentials: true
      }
    };
  },
  interpretResponse: function (serverResponse) {
    let emxBidResponses = [];
    let response = serverResponse.body || {};
    if (response.seatbid && response.seatbid.length > 0 && response.seatbid[0].bid) {
      response.seatbid.forEach(function (emxBid) {
        emxBid = emxBid.bid[0];
        emxBidResponses.push({
          requestId: emxBid.id,
          cpm: emxBid.price,
          width: emxBid.w,
          height: emxBid.h,
          creativeId: emxBid.crid || emxBid.id,
          dealId: emxBid.dealid || null,
          currency: 'USD',
          netRevenue: true,
          mediaType: BANNER,
          ad: decodeURIComponent(emxBid.adm),
          ttl: emxBid.ttl
        });
      });
    }
    return emxBidResponses;
  },
  getUserSyncs: function (syncOptions) {
    const syncs = [];
    if (syncOptions.iframeEnabled) {
      syncs.push({
        type: 'iframe',
        url: '//biddr.brealtime.com/check.html'
      });
    }
    if (syncOptions.pixelEnabled) {
      syncs.push({
        type: 'image',
        url: '//edba.brealtime.com/'
      });
    }
    return syncs;
  }
};
registerBidder(spec);
<|endoftext|>