<commit_before>//class
game.PlayerEntity = me.Entity.extend({
	//setting function
	init: function(x, y, settings) {
		//extending the function
		this._super(me.Entity, 'init', [x, y, {
			//setting the player image and its width and height
			image: "player",
			width: 64,
			height: 64,
			spritewidth: "64",
			spriteheight: "64",

			getShape: function(){
				//new shift
				//rectangle to make the character walk into it
				//setting it to the right size
				return (new me.Rect (0, 0, 64, 64)).toPolygon();
			}
		}]);
		//setting the velocity
		this.body.setVelocity(5, 20);
		//keeps track of which direction your character is going
		this.facing = "right";

		this.now = new Date().getTime();
		this.lastHit = this.now;
		this.lastAttack = new Date().getTime();
		//the camera follows the player
		me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH)
		//adding the pictures of the characters
		this.renderable.addAnimation("idle" , [78]);
		this.renderable.addAnimation("walk", [117, 118 , 119 , 120 , 121 , 122 , 123 , 124 , 125], 80);
		this.renderable.addAnimation("attack", [65, 66, 67, 68, 69, 70, 71, 72], 80);
		this.renderable.setCurrentAnimation("idle");
	},

	update: function(delta){
		this.now = new Date().getTime();
		//checking if the right key is pressed
		if (me.input.isKeyPressed("right")) {
			//adds to  the position of my x by the velocity defined above in
			//setVelocity() and multiplying it by me.timer.tick
			//me.timer.tick makes the movement look smooth
			this.body.vel.x += this.body.accel.x * me.timer.tick;

			//flipping the character
			this.facing = "right";
			this.flipX(true);

			//if other key is pressed it wont work
		}else if (me.input.isKeyPressed("left")){
			this.facing = "left";
			this.body.vel.x -=this.body.accel.x * me.timer.tick;
			this.flipX(false);
		}else{
			this.body.vel.x = 0;
		}
		//lets you jump except when you're already jumping or falling
if(me.input.isKeyPressed("jump") && !this.body.jumping && !this.body.falling) {
this.jumping = true;
this.body.vel.y -= this.body.accel.y * me.timer.tick;
}

if(me.input.isKeyPressed("attack")){

	if(!this.renderable.isCurrentAnimation("attack")){
		console.log(!this.renderable.isCurrentAnimation("attack"));
		//sets the current animation to attack and once that is over
	//goes back to the idle animation
	this.renderable.setCurrentAnimation("attack" , "idle");
	//makes it so that the next time we start this sequence we begin
	//from the first animation, not wherever we left off when we
	//switched to another animation
	this.renderable.setAnimationFrame();
	}
}

		else if(this.body.vel.x !== 0 && !this.renderable.isCurrentAnimation("attack")){
			//sets the animation of walking
			if(!this.renderable.isCurrentAnimation("walk")){
				this.renderable.setCurrentAnimation("walk");
			}
		}else if (!this.renderable.isCurrentAnimation("attack")){
			//when no keys are pressed the character sets to idle
			this.renderable.setCurrentAnimation("idle");
		}

		//checks the collision
	me.collision.check(this, true, this.collideHandler.bind(this), true);
		//updating the game
		this.body.update(delta);
		//reaches to the constructor of Entity
		this._super(me.Entity, "update", [delta]);
		return true;
	},
			//sets collision between tower and player it helps so the player wont go through the tower
		collideHandler: function(response) {
		if(response.b.type==='EnemyBaseEntity') {
			var ydif = this.pos.y - response.b.pos.y;
			var xdif = this.pos.x - response.b.pos.x;

if (ydif<-40 && xdif< 70 && xdif>-35){
this.body.falling = false;
this.body.vel.y = -1;
}

			else if(xdif>-35 && this.facing==='right' && (xdif<0 && ydif>-0)) {
				this.body.vel.x = 0;
				this.pos.x = this.pos.x -1;
			}else if(xdif<70 && this.facing==='left' && xdif>0) {
				this.body.vel.x = 0;
				this.pos.x = this.pos.x +1;

			}
			if(this.renderable.isCurrentAnimation("attack") && this.now-this.lastHit>= 1000){
				this.lastHit = this.now;
				response.b.loseHealth();
			}
		}
	}
});

game.EnemyBaseEntity = me.Entity.extend({
	init: function(x , y, settings) {
		this._super(me.Entity, 'init', [x, y, {

			//adding the tower image , and setting its size
			image: "tower",
			width: 100,
			height: 100,
			spritewidth: "100",
			spriteheight: "100",
			getShape: function() {
				//setting the rectangle thats for the tower
				return (new me.Rect(0, 0, 100, 80)).toPolygon();
			}
		}]);
		//the health of the power .. if you hit it more than 10 times , then it will blow up
		this.broken = false;
		this.health = 10;
		this.alwaysUpdate = true;
		this.body.onCollision = this.onCollision.bind(this);
		this.type = "EnemyBaseEntity";
		//adding the pictures of the tower
		this.renderable.addAnimation("idle" , [0]);
		this.renderable.addAnimation("broken" , [1]);
		//setting the picture
		this.renderable.setCurrentAnimation("idle");
	},

	update:function(delta){
		//the tower when it has no hits yet , (health is at 0 )
		if (this.health<=0) {
			this.broken = true;
			//sets the picture of the tower on fire when health is at 0
			this.renderable.setCurrentAnimation("broken");
		}
		this.body.update(delta);
		this._super(me.Entity, "update", [delta]);
		return true;
	},
	onCollision: function(){

	}
});

game.PlayerBaseEntity = me.Entity.extend({
	init: function(x , y, settings) {
		// the constructor of Entity
		this._super(me.Entity, 'init', [x, y, {
			//choosing the second tower and setting its size
			image: "tower",
			width: 100,
			height: 100,
			spritewidth: "100",
			spriteheight: "100",
			getShape: function() {
				//setting the rectangle that the tower is in
				return (new me.Rect(0, 0, 100, 80)).toPolygon();
			}
		}]);
		//the health of the tower
		this.broken = false;
		this.health = 10;
		this.alwaysUpdate = true;
		this.body.onCollision = this.onCollision.bind(this);
		this.type = "PlayerBaseEntity";
		//adding pictures of the second tower
		this.renderable.addAnimation("idle" , [0]);
		this.renderable.addAnimation("broken" , [1]);
		//setting the picture of the second tower
		this.renderable.setCurrentAnimation("idle");
	},

	update:function(delta){
		//towers health at 0
		if (this.health<=0) {
			this.broken = true;
			this.renderable.setCurrentAnimation("broken");
		}
		this.body.update(delta);
		this._super(me.Entity, "update", [delta]);
		return true;
	},
	onCollision: function(){

	},
	loseHealth: function(){
		this.health--;
	}
});

game.EnemyCreep = me.Entity.extend({
	init: function(x, y, settings){
		this._super(me.Entity, 'init', [x, y, {
			image: "creep1",
			width: 32,
			height: 64,
			spritewidth: "32",
			spriteheight: "64",
			getShape: function(){
				return (new me.Rect(0, 0, 32, 64)).toPolygon();
			}
		}]);
		this.health = 10;
		this.alwaysUpdate = true;

		this.body.setVelocity(3, 20);
		this.type = "EnemyCreep";
		this.renderable.addAnimation("walk", [3, 4, 5], 80);
		this.renderable.setCurrentAnimation("walk");
	},
	update: function(){

	}
})

game.GameManager = Object.extend({
init: function(x, y, settings){
this.now = new Date().getTime();
this.lastCreep = new Date().getTime();
this.alwaysUpdate = true;
},
update: function(){
this.now = new Date().getTime();

if(Math.round(this.now/1000)%10 ===0 && (this.now - this.lastCreep >= 1000)){
	this.lastCreep = this.now;
	var creepe = me.pool.pull("EnemyCreep", 1000, 0, {});
	me.game.world.addChild(Creepe, 5);
	}
	return true;
}
});<commit_msg>Commented video 16<commit_after>//class
game.PlayerEntity = me.Entity.extend({
	//setting function
	init: function(x, y, settings) {
		//extending the function
		this._super(me.Entity, 'init', [x, y, {
			//setting the player image and its width and height
			image: "player",
			width: 64,
			height: 64,
			spritewidth: "64",
			spriteheight: "64",

			getShape: function(){
				//new shift
				//rectangle to make the character walk into it
				//setting it to the right size
				return (new me.Rect (0, 0, 64, 64)).toPolygon();
			}
		}]);
		//setting the velocity
		this.body.setVelocity(5, 20);
		//keeps track of which direction your character is going
		this.facing = "right";

		this.now = new Date().getTime();
		this.lastHit = this.now;
		this.lastAttack = new Date().getTime();
		//the camera follows the player
		me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH)
		//adding the pictures of the characters
		this.renderable.addAnimation("idle" , [78]);
		this.renderable.addAnimation("walk", [117, 118 , 119 , 120 , 121 , 122 , 123 , 124 , 125], 80);
		this.renderable.addAnimation("attack", [65, 66, 67, 68, 69, 70, 71, 72], 80);
		this.renderable.setCurrentAnimation("idle");
	},

	update: function(delta){
		this.now = new Date().getTime();
		//checking if the right key is pressed
		if (me.input.isKeyPressed("right")) {
			//adds to  the position of my x by the velocity defined above in
			//setVelocity() and multiplying it by me.timer.tick
			//me.timer.tick makes the movement look smooth
			this.body.vel.x += this.body.accel.x * me.timer.tick;

			//flipping the character
			this.facing = "right";
			this.flipX(true);

			//if other key is pressed it wont work
		}else if (me.input.isKeyPressed("left")){
			this.facing = "left";
			this.body.vel.x -=this.body.accel.x * me.timer.tick;
			this.flipX(false);
		}else{
			this.body.vel.x = 0;
		}
		//lets you jump except when you're already jumping or falling
if(me.input.isKeyPressed("jump") && !this.body.jumping && !this.body.falling) {
this.jumping = true;
this.body.vel.y -= this.body.accel.y * me.timer.tick;
}

if(me.input.isKeyPressed("attack")){

	if(!this.renderable.isCurrentAnimation("attack")){
		console.log(!this.renderable.isCurrentAnimation("attack"));
		//sets the current animation to attack and once that is over
	//goes back to the idle animation
	this.renderable.setCurrentAnimation("attack" , "idle");
	//makes it so that the next time we start this sequence we begin
	//from the first animation, not wherever we left off when we
	//switched to another animation
	this.renderable.setAnimationFrame();
	}
}

		else if(this.body.vel.x !== 0 && !this.renderable.isCurrentAnimation("attack")){
			//sets the animation of walking
			if(!this.renderable.isCurrentAnimation("walk")){
				this.renderable.setCurrentAnimation("walk");
			}
		}else if (!this.renderable.isCurrentAnimation("attack")){
			//when no keys are pressed the character sets to idle
			this.renderable.setCurrentAnimation("idle");
		}

		//checks the collision
	me.collision.check(this, true, this.collideHandler.bind(this), true);
		//updating the game
		this.body.update(delta);
		//reaches to the constructor of Entity
		this._super(me.Entity, "update", [delta]);
		return true;
	},
			//sets collision between tower and player it helps so the player wont go through the tower
		collideHandler: function(response) {
		if(response.b.type==='EnemyBaseEntity') {
			var ydif = this.pos.y - response.b.pos.y;
			var xdif = this.pos.x - response.b.pos.x;

//helps the player step on the correct level of the floor .
if (ydif<-40 && xdif< 70 && xdif>-35){
this.body.falling = false;
this.body.vel.y = -1;
}

		//stops player from going through from the right
			else if(xdif>-35 && this.facing==='right' && (xdif<0 && ydif>-0)) {
				this.body.vel.x = 0;
				this.pos.x = this.pos.x -1;
				//stops player from going through from the left
			}else if(xdif<70 && this.facing==='left' && xdif>0) {
				this.body.vel.x = 0;
				this.pos.x = this.pos.x +1;

			}
			if(this.renderable.isCurrentAnimation("attack") && this.now-this.lastHit>= 1000){
				this.lastHit = this.now;
				response.b.loseHealth();
			}
		}
	}
});

game.EnemyBaseEntity = me.Entity.extend({
	init: function(x , y, settings) {
		this._super(me.Entity, 'init', [x, y, {

			//adding the tower image , and setting its size
			image: "tower",
			width: 100,
			height: 100,
			spritewidth: "100",
			spriteheight: "100",
			getShape: function() {
				//setting the rectangle thats for the tower
				return (new me.Rect(0, 0, 100, 80)).toPolygon();
			}
		}]);
		//the health of the power .. if you hit it more than 10 times , then it will blow up
		this.broken = false;
		this.health = 10;
		this.alwaysUpdate = true;
		this.body.onCollision = this.onCollision.bind(this);
		this.type = "EnemyBaseEntity";
		//adding the pictures of the tower
		this.renderable.addAnimation("idle" , [0]);
		this.renderable.addAnimation("broken" , [1]);
		//setting the picture
		this.renderable.setCurrentAnimation("idle");
	},

	update:function(delta){
		//the tower when it has no hits yet , (health is at 0 )
		if (this.health<=0) {
			this.broken = true;
			//sets the picture of the tower on fire when health is at 0
			this.renderable.setCurrentAnimation("broken");
		}
		this.body.update(delta);
		this._super(me.Entity, "update", [delta]);
		return true;
	},
	onCollision: function(){

	}
});

game.PlayerBaseEntity = me.Entity.extend({
	init: function(x , y, settings) {
		// the constructor of Entity
		this._super(me.Entity, 'init', [x, y, {
			//choosing the second tower and setting its size
			image: "tower",
			width: 100,
			height: 100,
			spritewidth: "100",
			spriteheight: "100",
			getShape: function() {
				//setting the rectangle that the tower is in
				return (new me.Rect(0, 0, 100, 80)).toPolygon();
			}
		}]);
		//the health of the tower
		this.broken = false;
		this.health = 10;
		this.alwaysUpdate = true;
		this.body.onCollision = this.onCollision.bind(this);
		this.type = "PlayerBaseEntity";
		//adding pictures of the second tower
		this.renderable.addAnimation("idle" , [0]);
		this.renderable.addAnimation("broken" , [1]);
		//setting the picture of the second tower
		this.renderable.setCurrentAnimation("idle");
	},

	update:function(delta){
		//towers health at 0
		if (this.health<=0) {
			this.broken = true;
			this.renderable.setCurrentAnimation("broken");
		}
		this.body.update(delta);
		this._super(me.Entity, "update", [delta]);
		return true;
	},
	onCollision: function(){

	},
	loseHealth: function(){
		this.health--;
	}
});

game.EnemyCreep = me.Entity.extend({
	init: function(x, y, settings){
		this._super(me.Entity, 'init', [x, y, {
			image: "creep1",
			width: 32,
			height: 64,
			spritewidth: "32",
			spriteheight: "64",
			getShape: function(){
				return (new me.Rect(0, 0, 32, 64)).toPolygon();
			}
		}]);
		this.health = 10;
		this.alwaysUpdate = true;

		this.body.setVelocity(3, 20);
		this.type = "EnemyCreep";
		this.renderable.addAnimation("walk", [3, 4, 5], 80);
		this.renderable.setCurrentAnimation("walk");
	},
	update: function(){

	}
})

game.GameManager = Object.extend({
init: function(x, y, settings){
this.now = new Date().getTime();
this.lastCreep = new Date().getTime();
this.alwaysUpdate = true;
},
update: function(){
this.now = new Date().getTime();

if(Math.round(this.now/1000)%10 ===0 && (this.now - this.lastCreep >= 1000)){
	this.lastCreep = this.now;
	var creepe = me.pool.pull("EnemyCreep", 1000, 0, {});
	me.game.world.addChild(Creepe, 5);
	}
	return true;
}
});<|endoftext|>


<commit_before>// player's class
game.PlayerEntity = me.Entity.extend ({
	//constructor function
	init: function(x, y, settings){
		//reachers the constructor function for enitity
		this._super(me.Entity, 'init', [x, y, {
			//settings. shows the player
			image: "player",
			//sets aside a width of 64 pixels for the sprite
			width: 64,
			//sets aside a height of 64 pixels for the sprite
			height: 64,
			//gives the sprite a width of 64.
			spritewidth : "64",
			//gives the sprite a width of 64
			spriteheight: "64",
			getShape: function(){
				//returns a rectangle of what the player walks into
				return(new me.Rect(0, 0, 64, 64)).toPolygon();
			}
		}]);
		//sets movemet speed. allows player to move horizantally and vertically
		this.body.setVelocity(5, 20);
		//keeps track of what direction the character is facing
		this.facing = "right";
		//checks what time it is in the game
		this.now = new Date().getTime();
		this.lastHit = this.now;
		//sets delay on when the player can hit
		this.lastAttack = new Date().getTime();
		//makesit so the player is always on the screen
		me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH);
		//gives player animation while standing
		this.renderable.addAnimation("idle", [78]);
		//gives player animation while walking
		this.renderable.addAnimation("walk", [117, 118, 119, 120, 121, 122, 123, 124, 125], 80);
		//gives player animation while attacking
		this.renderable.addAnimation("attack", [65, 66, 67, 68, 69, 70, 71, 72], 80);
		//the player's start animation
		this.renderable.setCurrentAnimation("idle");
	},

	//delata is the change in time that's happening
	update: function(delta){
		this.now = new Date().getTime();
		if(me.input.isKeyPressed("right")){
			//when right key is pressed, adds to the position of my x by the velocity defined above in setVelocity and multiplying it by me.timer.tick
			//me.timer.tick makes the movement look smooth
			this.body.vel.x += this.body.accel.x * me.timer.tick;
			this.facing = "right";
			this.flipX(true);
		}

		else if(me.input.isKeyPressed("left")){
			//when left key is pressed, adds to the position of my x by the velocity defined above in setVelocity and multiplying it by me.timer.tick
			//me.timer.tick makes the movement look smooth
			this.facing = "left";
			this.body.vel.x -= this.body.accel.x * me.timer.tick;
			this.flipX(false);
		}

		//if the right key isn't being pressed, the player doesn't move
		else{
			this.body.vel.x = 0;
		}

		//when up key is pressed, player jumps
		if(me.input.isKeyPressed("jump")){
			if(!this.body.jumping && !this.body.falling){
				this.body.jumping = true;
				this.body.vel.y -= this.body.accel.y * me.timer.tick;
			}
		}
		//runs if the attack key is pressed
		if(me.input.isKeyPressed("attack")){
			if(!this.renderable.isCurrentAnimation("attack")){
				//sets current animation to attack. goes back to idle oncethe attack is over it goes back to idle
				this.renderable.setCurrentAnimation("attack", "idle")
				//makes it so that next time the button is pressed the player starts from the first animation, not where it left off
				this.renderable.setAnimationFrame();
			}
		}
		//runs if the player is moving horizantally
		else if(this.body.vel.x !== 0 && !this.renderable.isCurrentAnimation("attack")){
			//runs if the player isn't already running the walk animation
			if(!this.renderable.isCurrentAnimation("walk")){
				//gives the player the walking animation
				this.renderable.setCurrentAnimation("walk");
			}
		}
		//runs if player is standing still
		else if(!this.renderable.isCurrentAnimation("attack")){
			//gives the player the idle animation
			this.renderable.setCurrentAnimation("idle");
		}

		me.collision.check(this, true, this.collideHandler.bind(this), true);
		//tells above code to work
		this.body.update(delta);

		this._super(me.Entity, "update", [delta]);
		return true
	},

	collideHandler: function(response){
		if(response.b.type==='EnemyBaseEntity'){
			var ydif = this.pos.y - response.b.pos.y;
			var xdif = this.pos.x - response.b.pos.x;
		}
		//player will collide witht the top of the base
		if(ydif<-40 && xdif< 70 && xdif>-35){
			this.body.falling = false;
			this.body.vel.y = -1;
		}
		//player will colide with the base while facing to the right
		else if(xdif>-35 && this.facing==='right' && (xdif<0)){
			this.body.vel.x = 0;
			this.pos.x = this.pos.x -1;
		}
		//player will colide with the base while facing to the left
		else if(xdif<70 && this.facing==='left' && (ydif>0)){
			this.body.vel.x = 0;
			this.pos.x = this.pos.x +1;
		}

		//sets how long the base has to be hit before it will break
		if(this.renderable.isCurrentAnimation("attack") && this.now-this.lastHit >= 1000){
			this.lastHit = this.now;
			response.b.loseHealth();
		}
	}

});

//tower class
game.PlayerBaseEntity = me.Entity.extend({
	init: function(x, y, settings){
		//reachers the constructor function for tower
		this._super(me.Entity, 'init', [x, y, {
			//settings. shoes the tower
			image: "tower",
			//sets aside a width of 100 pixels for the tower
			width: 100,
			//sets aside a height of 100 pixels for the tower
			height: 100,
			//gives the tower a width of 100.
			spritewidth : "100",
			//gives the tower a width of 100
			spriteheight: "100",
			getShape: function(){
				//returns a rectangle of what the tower walks into
				return(new me.Rect(0, 0, 100, 200)).toPolygon();
			}
		}]);
		//says that tower hasn't been destroyed
		this.broken = false;
		//gives tower a "health" of ten
		this.health = 10;
		//makes sure the tower's status is always updating, eben when it isn't on the map
		this.alwaysUpdate = true;
		//makes teh tower collidable
		this.body.onCollision = this.onCollision.bind(this);
		//checks what player is running into
		this.type = "PlayerBaseEntity";
		//adds the defualt animatin for the game
		this.renderable.addAnimation("idle", [0]);
		//adds the animation for when the tower is broken
		this.renderable.addAnimation("broken", [1]);
		//sets the desfault animation
		this.renderable.setCurrentAnimation("idle");

	},

	update:function(delta){
		//runs if health is less than or equal to 0
		if(this.health<=0){
			//makes the tower "broken"
			this.broken = true;
			//sets animation for "broken"
			this.renderable.setCurrentAnimation("broken");
		}
		//updates tower status
		this.body.update(delta);

		this._super(me.Entity, "update", [delta]);
		return true;
	},
	//function that runs when base is touched
	onCollision: function(){

	}
});

//tower class
game.EnemyBaseEntity = me.Entity.extend({
	init: function(x, y, settings){
		//reachers the constructor function for tower
		this._super(me.Entity, 'init', [x, y, {
			//settings. shoes the tower
			image: "tower",
			//sets aside a width of 100 pixels for the tower
			width: 100,
			//sets aside a height of 100 pixels for the tower
			height: 100,
			//gives the tower a width of 100.
			spritewidth : "100",
			//gives the tower a width of 100
			spriteheight: "100",
			getShape: function(){
				//returns a rectangle of what the tower walks into
				return(new me.Rect(0, 0, 100, 70)).toPolygon();
			}
		}]);
		//says that tower hasn't been destroyed
		this.broken = false;
		//gives tower a "health" of ten
		this.health = 10;
		//makes sure the tower's status is always updating, eben when it isn't on the map
		this.alwaysUpdate = true;
		//makes teh tower collidable
		this.body.onCollision = this.onCollision.bind(this);
		//checks what player is running into
		this.type = "EnemyBaseEntity";
		//adds the defualt animatin for the game
		this.renderable.addAnimation("idle", [0]);
		//adds the animation for when the tower is broken
		this.renderable.addAnimation("broken", [1]);
		//sets the default animation
		this.renderable.setCurrentAnimation("idle");
	},

	update:function(delta){
		//runs if health is less than or equal to 0
		if(this.health<=0){
			//makes the tower "broken"
			this.broken = true;
			//sets animation for "broken"
			this.renderable.setCurrentAnimation("broken");
		}
		//updates tower status
		this.body.update(delta);

		this._super(me.Entity, "update", [delta]);
		return true;
	},
	//function that runs when base is touched
	onCollision: function(){

	},

	loseHealth: function(){
		this.health--;
	}
});

game.EnemyCreep = me.Entity.extend({
	init: function(x, y, settings){
		this._super(me.Entity, 'init', [x, y, {
			//settings. shoes the player
			image: "player",
			//sets aside a width of 32 pixels for the sprite
			width: 32,
			//sets aside a height of 64 pixels for the sprite
			height: 64,
			//gives the sprite a width of 32
			spritewidth : "32",
			//gives the sprite a width of 64
			spriteheight: "64",
			getShape: function(){
				//returns a rectangle of what the player walks into
				return(new me.Rect(0, 0, 32, 64)).toPolygon();
			}
		}]);
		//sets health for enemy
		this.health = 10;
		this.alwaysUpdate = true;

		//sets speed for enemy
		this.body.setVelocity(3, 20);

		//sets enemy type
		this.type = "EnemyCreep";

		//creates walking animation for enemy
		this.renderable.addAnimation("walk", [3,4,5], 80);
		this.renderable.setCurrentAnimation("walk");
	},

	update: function(delta){
            //makes creep move
            this.body.vel.x -= this.body.accel.x * me.timer.tick;

            this.body.update(delta);

		this._super(me.Entity, "update", [delta]);
            return true;

	}
});

game.GameManager = Object.extend({
	init: function(x, y, settings){
		this.now = new Date().getTime();
		this.lastCreep = new Date().getTime();

		this.alwaysUpdate = true;
	},

	update: function(){
		this.now = new Date().getTime;

		if(Math.round(this.now/1000)%10 ===0 && (this.now - this.lastCreep >= 1000)){
			this.lastCreep = this.now;
			var creepe = me.pool.pull("EnemyCreep", 1000, 0 ());
			me.game.world.addChild(creepe, 5);
		}

		return true;

	}
});
<commit_msg>video 20 comments<commit_after>// player's class
game.PlayerEntity = me.Entity.extend ({
	//constructor function
	init: function(x, y, settings){
		//reachers the constructor function for enitity
		this._super(me.Entity, 'init', [x, y, {
			//settings. shows the player
			image: "player",
			//sets aside a width of 64 pixels for the sprite
			width: 64,
			//sets aside a height of 64 pixels for the sprite
			height: 64,
			//gives the sprite a width of 64.
			spritewidth : "64",
			//gives the sprite a width of 64
			spriteheight: "64",
			getShape: function(){
				//returns a rectangle of what the player walks into
				return(new me.Rect(0, 0, 64, 64)).toPolygon();
			}
		}]);
		//sets movemet speed. allows player to move horizantally and vertically
		this.body.setVelocity(5, 20);
		//keeps track of what direction the character is facing
		this.facing = "right";
		//checks what time it is in the game
		this.now = new Date().getTime();
		this.lastHit = this.now;
		//sets delay on when the player can hit
		this.lastAttack = new Date().getTime();
		//makesit so the player is always on the screen
		me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH);
		//gives player animation while standing
		this.renderable.addAnimation("idle", [78]);
		//gives player animation while walking
		this.renderable.addAnimation("walk", [117, 118, 119, 120, 121, 122, 123, 124, 125], 80);
		//gives player animation while attacking
		this.renderable.addAnimation("attack", [65, 66, 67, 68, 69, 70, 71, 72], 80);
		//the player's start animation
		this.renderable.setCurrentAnimation("idle");
	},

	//delata is the change in time that's happening
	update: function(delta){
		this.now = new Date().getTime();
		if(me.input.isKeyPressed("right")){
			//when right key is pressed, adds to the position of my x by the velocity defined above in setVelocity and multiplying it by me.timer.tick
			//me.timer.tick makes the movement look smooth
			this.body.vel.x += this.body.accel.x * me.timer.tick;
			this.facing = "right";
			this.flipX(true);
		}

		else if(me.input.isKeyPressed("left")){
			//when left key is pressed, adds to the position of my x by the velocity defined above in setVelocity and multiplying it by me.timer.tick
			//me.timer.tick makes the movement look smooth
			this.facing = "left";
			this.body.vel.x -= this.body.accel.x * me.timer.tick;
			this.flipX(false);
		}

		//if the right key isn't being pressed, the player doesn't move
		else{
			this.body.vel.x = 0;
		}

		//when up key is pressed, player jumps
		if(me.input.isKeyPressed("jump")){
			if(!this.body.jumping && !this.body.falling){
				this.body.jumping = true;
				this.body.vel.y -= this.body.accel.y * me.timer.tick;
			}
		}
		//runs if the attack key is pressed
		if(me.input.isKeyPressed("attack")){
			if(!this.renderable.isCurrentAnimation("attack")){
				//sets current animation to attack. goes back to idle oncethe attack is over it goes back to idle
				this.renderable.setCurrentAnimation("attack", "idle")
				//makes it so that next time the button is pressed the player starts from the first animation, not where it left off
				this.renderable.setAnimationFrame();
			}
		}
		//runs if the player is moving horizantally
		else if(this.body.vel.x !== 0 && !this.renderable.isCurrentAnimation("attack")){
			//runs if the player isn't already running the walk animation
			if(!this.renderable.isCurrentAnimation("walk")){
				//gives the player the walking animation
				this.renderable.setCurrentAnimation("walk");
			}
		}
		//runs if player is standing still
		else if(!this.renderable.isCurrentAnimation("attack")){
			//gives the player the idle animation
			this.renderable.setCurrentAnimation("idle");
		}

		me.collision.check(this, true, this.collideHandler.bind(this), true);
		//tells above code to work
		this.body.update(delta);

		this._super(me.Entity, "update", [delta]);
		return true
	},

	collideHandler: function(response){
		if(response.b.type==='EnemyBaseEntity'){
			var ydif = this.pos.y - response.b.pos.y;
			var xdif = this.pos.x - response.b.pos.x;
		}
		//player will collide witht the top of the base
		if(ydif<-40 && xdif< 70 && xdif>-35){
			this.body.falling = false;
			this.body.vel.y = -1;
		}
		//player will colide with the base while facing to the right
		else if(xdif>-35 && this.facing==='right' && (xdif<0)){
			this.body.vel.x = 0;
			this.pos.x = this.pos.x -1;
		}
		//player will colide with the base while facing to the left
		else if(xdif<70 && this.facing==='left' && (ydif>0)){
			this.body.vel.x = 0;
			this.pos.x = this.pos.x +1;
		}

		//sets how long the base has to be hit before it will break
		if(this.renderable.isCurrentAnimation("attack") && this.now-this.lastHit >= 1000){
			this.lastHit = this.now;
			response.b.loseHealth();
		}
	}

});

//tower class
game.PlayerBaseEntity = me.Entity.extend({
	init: function(x, y, settings){
		//reachers the constructor function for tower
		this._super(me.Entity, 'init', [x, y, {
			//settings. shoes the tower
			image: "tower",
			//sets aside a width of 100 pixels for the tower
			width: 100,
			//sets aside a height of 100 pixels for the tower
			height: 100,
			//gives the tower a width of 100.
			spritewidth : "100",
			//gives the tower a width of 100
			spriteheight: "100",
			getShape: function(){
				//returns a rectangle of what the tower walks into
				return(new me.Rect(0, 0, 100, 200)).toPolygon();
			}
		}]);
		//says that tower hasn't been destroyed
		this.broken = false;
		//gives tower a "health" of ten
		this.health = 10;
		//makes sure the tower's status is always updating, eben when it isn't on the map
		this.alwaysUpdate = true;
		//makes teh tower collidable
		this.body.onCollision = this.onCollision.bind(this);
		//checks what player is running into
		this.type = "PlayerBaseEntity";
		//adds the defualt animatin for the game
		this.renderable.addAnimation("idle", [0]);
		//adds the animation for when the tower is broken
		this.renderable.addAnimation("broken", [1]);
		//sets the desfault animation
		this.renderable.setCurrentAnimation("idle");

	},

	update:function(delta){
		//runs if health is less than or equal to 0
		if(this.health<=0){
			//makes the tower "broken"
			this.broken = true;
			//sets animation for "broken"
			this.renderable.setCurrentAnimation("broken");
		}
		//updates tower status
		this.body.update(delta);

		this._super(me.Entity, "update", [delta]);
		return true;
	},
	//function that runs when base is touched
	onCollision: function(){

	}
});

//tower class
game.EnemyBaseEntity = me.Entity.extend({
	init: function(x, y, settings){
		//reachers the constructor function for tower
		this._super(me.Entity, 'init', [x, y, {
			//settings. shoes the tower
			image: "tower",
			//sets aside a width of 100 pixels for the tower
			width: 100,
			//sets aside a height of 100 pixels for the tower
			height: 100,
			//gives the tower a width of 100.
			spritewidth : "100",
			//gives the tower a width of 100
			spriteheight: "100",
			getShape: function(){
				//returns a rectangle of what the tower walks into
				return(new me.Rect(0, 0, 100, 70)).toPolygon();
			}
		}]);
		//says that tower hasn't been destroyed
		this.broken = false;
		//gives tower a "health" of ten
		this.health = 10;
		//makes sure the tower's status is always updating, eben when it isn't on the map
		this.alwaysUpdate = true;
		//makes teh tower collidable
		this.body.onCollision = this.onCollision.bind(this);
		//checks what player is running into
		this.type = "EnemyBaseEntity";
		//adds the defualt animatin for the game
		this.renderable.addAnimation("idle", [0]);
		//adds the animation for when the tower is broken
		this.renderable.addAnimation("broken", [1]);
		//sets the default animation
		this.renderable.setCurrentAnimation("idle");
	},

	update:function(delta){
		//runs if health is less than or equal to 0
		if(this.health<=0){
			//makes the tower "broken"
			this.broken = true;
			//sets animation for "broken"
			this.renderable.setCurrentAnimation("broken");
		}
		//updates tower status
		this.body.update(delta);

		this._super(me.Entity, "update", [delta]);
		return true;
	},
	//function that runs when base is touched
	onCollision: function(){

	},

	loseHealth: function(){
		this.health--;
	}
});

game.EnemyCreep = me.Entity.extend({
	init: function(x, y, settings){
		this._super(me.Entity, 'init', [x, y, {
			//settings. shoes the player
			image: "player",
			//sets aside a width of 32 pixels for the sprite
			width: 32,
			//sets aside a height of 64 pixels for the sprite
			height: 64,
		 	//gives the sprite a width of 32
			spritewidth : "32",
			//gives the sprite a width of 64
			spriteheight: "64",
			getShape: function(){
				//returns a rectangle of what the player walks into
				return(new me.Rect(0, 0, 32, 64)).toPolygon();
			}
		}]);
		//sets health for enemy
		this.health = 10;
		this.alwaysUpdate = true;

		//sets speed for enemy
		this.body.setVelocity(3, 20);

		//sets enemy type
		this.type = "EnemyCreep";

		//creates walking animation for enemy
		this.renderable.addAnimation("walk", [3,4,5], 80);
		this.renderable.setCurrentAnimation("walk");
	},

	update: function(delta){
            //makes creep move
            this.body.vel.x -= this.body.accel.x * me.timer.tick;

            this.body.update(delta);

		this._super(me.Entity, "update", [delta]);
            return true;

	}
});

game.GameManager = Object.extend({
	init: function(x, y, settings){
		this.now = new Date().getTime();
		this.lastCreep = new Date().getTime();

		this.alwaysUpdate = true;
	},

	update: function(){
		this.now = new Date().getTime;

		if(Math.round(this.now/1000)%10 ===0 && (this.now - this.lastCreep >= 1000)){
			this.lastCreep = this.now;
			var creepe = me.pool.pull("EnemyCreep", 1000, 0 ());
			me.game.world.addChild(creepe, 5);
		}

		return true;

	}
});
<|endoftext|>


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

// TODO: Add datalist support.

CLASS({
  package: 'foam.u2',
  name: 'DateInput',
  extends: 'foam.u2.Input',

  methods: [
    function initE() {
      this.SUPER();
      this.setAttribute('type', 'date');
    },
    function link() {
      Events.relate(
        this.data$,
        this.attrValue(null, this.onKey ? 'input' : null),
        function(date) { debugger; return date ? date.toISOString().substring(0,10) : date; },
        function(value) { debugger; return new Date(value); }
      );
    }
  ]
});
<commit_msg>Removed stale debugger statements.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// TODO: Add datalist support.

CLASS({
  package: 'foam.u2',
  name: 'DateInput',
  extends: 'foam.u2.Input',

  methods: [
    function initE() {
      this.SUPER();
      this.setAttribute('type', 'date');
    },
    function link() {
      Events.relate(
        this.data$,
        this.attrValue(null, this.onKey ? 'input' : null),
        function(date) { return date ? date.toISOString().substring(0,10) : date; },
        function(value) { return new Date(value); }
      );
    }
  ]
});
<|endoftext|>


<commit_before>// Generated by LispyScript v0.2.1
var List = function(head, tail) {
  this.head = head;
  this.tail = tail;
  this.length = ((tail).length + 1);
  return this;
};

List.prototype.length = 0;

List.prototype.tail = Object.create(List.prototype);

List.prototype.toString = function() {
  return (function loop(result, list) {
    var recur = loop;
    while ((recur === loop)) {
      recur = isEmpty(list) ?
        ''.concat("(", result.substr(1), ")") :
        (result = ''.concat(result, " ", (Object.prototype.toString.call(first(list)) === '[object Array]') ?
          ''.concat("[", first(list).join(" "), "]") :
          (first(list) == null) ?
            "nil" :
            (Object.prototype.toString.call(first(list)) === '[object String]') ?
              JSON.stringify(first(list)) :
              (Object.prototype.toString.call(first(list)) === '[object Number]') ?
                JSON.stringify(first(list)) :
                first(list)),
         list = rest(list),
         loop)
    };
    return recur;
  })("", this);
};

var isList = function(value) {
  return List.prototype.isPrototypeOf(value);
};

var count = function(sequence) {
  return (sequence).length;
};

var isEmpty = function(sequence) {
  return (count(sequence) == 0);
};

var first = function(sequence) {
  return isList(sequence) ?
    (sequence).head :
    sequence[0];
};

var second = function(sequence) {
  return isList(sequence) ?
    first(rest(sequence)) :
    sequence[1];
};

var third = function(sequence) {
  return isList(sequence) ?
    first(rest(rest(sequence))) :
    sequence[2];
};

var rest = function(sequence) {
  return isList(sequence) ?
    (sequence).tail :
    sequence.slice(1);
};

var cons = function(head, tail) {
  return isList(tail) ?
    new List(head, tail) :
    Array(head).concat(tail);
};

var list = function() {
  return ((arguments).length == 0) ?
    Object.create(List.prototype) :
    Array.prototype.slice.call(arguments).reduceRight(function(tail, head) {
      return cons(head, tail);
    }, list());
};

var reverse = function(sequence) {
  return isList(sequence) ?
    (function loop(items, source) {
      var recur = loop;
      while ((recur === loop)) {
        recur = isEmpty(source) ?
          list.apply(list, items) :
          (items = [ first(source) ].concat(items),
           source = rest(source),
           loop)
      };
      return recur;
    })([], sequence) :
    sequence.reverse();
};

var mapList = function(source, f) {
  return isEmpty(source) ?
    source :
    cons(f(first(source)), mapList(rest(source), f));
};

var reduceList = function(form, f, initial) {
  return (function loop(result, items) {
    var recur = loop;
    while ((recur === loop)) {
      recur = isEmpty(items) ?
        result :
        (result = f(result, first(items)),
         items = rest(items),
         loop)
    };
    return recur;
  })((initial == null) ?
    first(form) :
    initial, (initial == null) ?
    rest(form) :
    form);
};

var concatList = function(left, right) {
  return (function loop(result, prefix) {
    var recur = loop;
    while ((recur === loop)) {
      recur = isEmpty(prefix) ?
        result :
        (result = cons(first(prefix), result),
         prefix = rest(prefix),
         loop)
    };
    return recur;
  })(right, reverse(left));
};

var listToVector = function(source) {
  return (function loop(result, list) {
    var recur = loop;
    while ((recur === loop)) {
      recur = isEmpty(list) ?
        result :
        (result = (function() {
          result.push(first(list));
          return result;
        })(),
         list = rest(list),
         loop)
    };
    return recur;
  })(Array(), source);
};

var sortList = function(items, f) {
  return list.apply(list, listToVector(items).sort((f == null) ?
    f :
    function(a, b) {
      return f(a, b) ?
        0 :
        1;
    }));
};

exports.isEmpty = isEmpty;
exports.count = count;
exports.isList = isList;
exports.first = first;
exports.second = second;
exports.third = third;
exports.rest = rest;
exports.cons = cons;
exports.list = list;
exports.reverse = reverse;
exports.reduceList = reduceList;
exports.mapList = mapList;
exports.listToVector = listToVector;
exports.concatList = concatList;
exports.sortList = sortList;

<commit_msg>Recompile list with new compiler.<commit_after>var List = function List(head, tail) {
  this.head = head;
  this.tail = tail;
  this.length = (tail.length) + 1;
  return this;
};

List.prototype.length = 0;

List.prototype.tail = Object.create(List.prototype);

List.prototype.toString = function() {
  return (function loop() {
    var result = "";
    var list = this;

    var recur = loop;
    while (recur === loop) {
      recur = isEmpty(list) ?
      "(" + (result.substr(1)) + ")" :
      (result = result + " " + (isVector(first(list)) ?
        "[" + (first(list).join(" ")) + "]" :
        typeof(first(list)) === "undefined" ?
          "nil" :
          isString(first(list)) ?
            JSON.stringify(first(list)) :
            isNumber(first(list)) ?
              JSON.stringify(first(list)) :
              first(list)), list = rest(list), loop);
    };
    return recur;
  })();
};

var isList = function isList(value) {
  return List.prototype.isPrototypeOf(value);
};

var count = function count(sequence) {
  return sequence.length;
};

var isEmpty = function isEmpty(sequence) {
  return count(sequence) == 0;
};

var first = function first(sequence) {
  return isList(sequence) ?
    sequence.head :
    sequence[0];
};

var second = function second(sequence) {
  return isList(sequence) ?
    first(rest(sequence)) :
    sequence[1];
};

var third = function third(sequence) {
  return isList(sequence) ?
    first(rest(rest(sequence))) :
    sequence[2];
};

var rest = function rest(sequence) {
  return isList(sequence) ?
    sequence.tail :
    sequence.slice(1);
};

var cons = function cons(head, tail) {
  return isList(tail) ?
    new List(head, tail) :
    Array(head).concat(tail);
};

var list = function list() {
  return arguments.length == 0 ?
    Object.create(List.prototype) :
    Array.prototype.slice.call(arguments).reduceRight(function(tail, head) {
      return cons(head, tail);
    }, list());
};

var reverse = function reverse(sequence) {
  return isList(sequence) ?
    (function loop() {
      var items = [];
      var source = sequence;

      var recur = loop;
      while (recur === loop) {
        recur = isEmpty(source) ?
        list.apply(list, items) :
        (items = [first(source)].concat(items), source = rest(source), loop);
      };
      return recur;
    })() :
    sequence.reverse();
};

var mapList = function mapList(source, f) {
  return isEmpty(source) ?
    source :
    cons(f(first(source)), mapList(rest(source), f));
};

var reduceList = function reduceList(form, f, initial) {
  return (function loop() {
    var result = typeof(initial) === "undefined" ?
      first(form) :
      initial;
    var items = typeof(initial) === "undefined" ?
      rest(form) :
      form;

    var recur = loop;
    while (recur === loop) {
      recur = isEmpty(items) ?
      result :
      (result = f(result, first(items)), items = rest(items), loop);
    };
    return recur;
  })();
};

var concatList = function concatList(left, right) {
  return (function loop() {
    var result = right;
    var prefix = reverse(left);

    var recur = loop;
    while (recur === loop) {
      recur = isEmpty(prefix) ?
      result :
      (result = cons(first(prefix), result), prefix = rest(prefix), loop);
    };
    return recur;
  })();
};

var listToVector = function listToVector(source) {
  return (function loop() {
    var result = Array();
    var list = source;

    var recur = loop;
    while (recur === loop) {
      recur = isEmpty(list) ?
      result :
      (result = (function() {
        result.push(first(list));
        return result;
      })(), list = rest(list), loop);
    };
    return recur;
  })();
};

var sortList = function sortList(items, f) {
  return list.apply(list, listToVector(items).sort(typeof(f) === "undefined" ?
    f :
    function(a, b) {
      return f(a, b) ?
        0 :
        1;
    }));
};

exports.sortList = sortList;
exports.concatList = concatList;
exports.listToVector = listToVector;
exports.mapList = mapList;
exports.reduceList = reduceList;
exports.reverse = reverse;
exports.list = list;
exports.cons = cons;
exports.rest = rest;
exports.third = third;
exports.second = second;
exports.first = first;
exports.isList = isList;
exports.count = count;
exports.isEmpty = isEmpty;
<|endoftext|>


<commit_before>/**
 * Created by nagamai on 9/9/2016.
 */
import {
    cardFromNumber,
    schemeFromNumber,
    getAppData,
    addListener,
    postMessageWrapper,
    setAppData,
    isIOS
} from "./utils";
import {getConfigValue} from "./hosted-field-config";
import {validateCreditCard, isValidCvv, isValidExpiry} from "./validation/custom-validations";

let _paymentField;
let field;
//todo:change its name later
let digit;
let parentUrl = getAppData('parentUrl');
const addField = () => {
    let fieldType = document.location.href.split("#");
    if(fieldType.length<2)
        return;
    field = fieldType[1].split("-");
    _paymentField = document.createElement("input");
    _paymentField.setAttribute("id", field[0] + "citrusInput");
    document.body.appendChild(_paymentField);
    //addEventListenersForHostedFields();
};

const postPaymentData = () => {
    //Send value of the field to the cardnumber iframe
    let message = {messageType:'cardData'};
    let cardData = {};
    cardData.value = _paymentField.value;
    cardData.key = field[0];
    message.cardType = field[1];
    message.cardData = cardData;
    //todo:IMPORTANT, change * to citrus server url,
    //also if possible use name instead of index as index will be unreliable
    //if there are other iframes on merchant's page

    for(var i=0;i<parent.window.frames.length;i++)
    {
        postMessageWrapper(parent.window.frames[i], message, getConfigValue('hostedFieldDomain'));
    }
};

const addEventListenersForHostedFields = (cardSetupType) => {
    //detect the ios user agent, since ios devices don't listen to blur events. ignore the microsoft user agent which also contains the ios keyword.
    let iOS = isIOS();
    let eventStr;
    iOS ? eventStr = "input" : eventStr = "blur";
        //add the event listeners for ui validations of those fields.
        if(cardSetupType==="credit"||cardSetupType==="debit"||cardSetupType==="card")
            addListener(_paymentField,eventStr, postPaymentData, false);
        addListener(_paymentField,"focus", addFocusAttributes, false);
        addListener(_paymentField,"blur", removeFocusAttributes, false);
        addListener(_paymentField,'paste', restrictPaste, false);
        switch (field[0]) {
            case "number" :
                addListener(_paymentField,eventStr, validateCardEventListener, false);
                addListener(_paymentField,'input',detectScheme);
                addListener(_paymentField,'keypress', restrictNumeric, false);
                addListener(_paymentField,'keypress', restrictCardNumber, false);
                addListener(_paymentField,'keypress', formatCardNumber, false);
                addListener(_paymentField,'input', reFormatCardNumber, false);
                break;
            case "expiry" :
                addListener(_paymentField,eventStr, validateExpiryEventListener, false);
                addListener(_paymentField,'keypress', restrictNumeric, false);
                addListener(_paymentField,'keypress', formatExpiry, false);
                addListener(_paymentField,'input', reformatExpiry, false);
                break;
            case "cvv"    :
                addListener(_paymentField,eventStr, validateCvvEventListener, false);
                _paymentField.setAttribute("type", "password");
                addListener(_paymentField,'keypress', restrictNumeric, false);
                addListener(_paymentField,'keypress', restrictCVC, false);
                break;
        }
};

const detectScheme = ()=>{
    const num = _paymentField.value.replace(/\s+/g, '');
    const scheme = schemeFromNumber(num);
    var setupType = getAppData('cardType');
    var hostedField = getAppData('hostedField');
    if(!scheme)
        return;
    var lastDetectedScheme = getAppData(setupType+'scheme');
    let schemeChangeMessage = {messageType:'schemeChange',scheme:scheme,hostedField, cardType:setupType};
    if(lastDetectedScheme!==scheme)
    {
        setAppData(setupType+'scheme',scheme);
        postMessageWrapper(parent,schemeChangeMessage,getParentUrl());
    }
};

const addFocusAttributes=()=>{
    var hostedField = getAppData('hostedField');
    let focusReceivedMessage = {messageType:'focusReceived',fieldType:field[0],hostedField};
    postMessageWrapper(parent, focusReceivedMessage, getParentUrl());
};

const removeFocusAttributes =()=>{
     var hostedField = getAppData('hostedField');
    let focusLostMessage = {messageType:'focusLost',fieldType:field[0],hostedField};
    postMessageWrapper(parent, focusLostMessage, getParentUrl());
};
const formatCardNumber = () => {
    let num = _paymentField.value;
    num = num.replace(/\D/g, '');

    var card, groups, upperLength, _ref;
    var parts = num.match(/^\d{1,19}$/);
    if (!parts) {
        _paymentField.value = '';
        return;
    }
    card = cardFromNumber(num);
    if (!card) {
        return num;
    }
    upperLength = card.length[card.length.length - 1];
    num = num.replace(/\D/g, '');
    num = num.slice(0, upperLength);
    if (card.groupingFormat.global) {
        _paymentField.value = (_ref = num.match(card.groupingFormat)) != null ? _ref.join(' ') : void 0;
    } else {
        groups = card.groupingFormat.exec(num);
        if (groups == null) {
            return;
        }
        groups.shift();
        groups = groups.filter(function (n) {
            return n;
        });
        _paymentField.value = groups.join(' ');
    }
};

const hasTextSelected = (target) => {
    var _ref;
    if ((target.selectionStart != null) && target.selectionStart !== target.selectionEnd) {
        return true;
    }
    return !!(typeof document !== "undefined" && document !== null ? ( _ref = document.selection) != null ? typeof _ref.createRange === "function" ? _ref.createRange().text :
        void 0 :
        void 0 :
        void 0);

};

const formatExpiry = (e) => {
    let expiry = _paymentField.value;
    var mon,
        parts,
        sep,
        year;
    parts = expiry.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/);
    if (!parts) {
        _paymentField.value = '';
        return;
    }
    mon = parts[1] || '';
    sep = parts[2] || '';
    year = parts[3] || '';
    if (year.length > 0 || (sep.length > 0 && !(/\ \/?\ ?/.test(sep)))) {
        sep = ' / ';
    }
    if (mon.length === 1 && (mon !== '0' && mon !== '1')) {
        mon = "0" + mon;
        sep = ' / ';
    }
    //check added for backspace key
    if(e.which<57) digit = e.which;
    if (digit< 57 && mon.length === 2)
    {
         sep = ' / ';
        digit = 60;
    }
    _paymentField.value = mon + sep + year;
};

const restrictNumeric = (e) => {
    var input;
    if (e.metaKey || e.ctrlKey) {
        return true;
    }
    if (e.which === 32) {
        return false;
    }
    if (e.which === 0) {
        return true;
    }
    if (e.which < 33) {
        return true;
    }
    input = String.fromCharCode(e.which);
    if(!/[\d\s]/.test(input)) e.preventDefault();
    //return !!/[\d\s]/.test(input);
};

//to avoid the acceptance of one extra digit in the field,
//and also formats the card number while pasting the number directly inside the field
const reFormatCardNumber = () => {
    return setTimeout(function () {
        formatCardNumber(_paymentField.value);
    });
};
//to avoid the acceptance of one extra digit in the field
//and also formats the card number while pasting the number directly inside the field
const reformatExpiry = () => {
    return setTimeout(function () {
        formatExpiry(_paymentField.value);
    });
};

const restrictCardNumber = function(e) {
    let card,
        digit,
        value;
    digit = String.fromCharCode(e.which);
    if (!/^\d+$/.test(digit)) {
        return;
    }
    if (hasTextSelected(_paymentField)) {
        return;
    }
    value = (_paymentField.value + digit).replace(/\D/g, '');
    card = cardFromNumber(value);
    if (card) {
        if(value.length > card.length[card.length.length - 1]) e.preventDefault();
    } else {
        if(value.length > 16) e.preventDefault();
    }
};

//todo: change the value of these two fields
//if the card number does not require cvv or field;

const validateCardEventListener=()=>{
    validateCard();
};
const validateCard = () => {
    const num = _paymentField.value.replace(/\s+/g, '');
    var cardType = getAppData('cardType');
    var hostedField = getAppData('hostedField');
    let validationResult = {fieldType:'number',messageType:'validation',hostedField,cardType};
    if(!num){
        validationResult.cardValidationResult = {"txMsg": 'Card nubmer can not be empty.',isValid:false};
        toggleValidity(false);
        postMessageWrapper(parent, validationResult, getParentUrl());
        return;
    }
    const scheme = schemeFromNumber(num);
    //todo : add check for maestro and rupay
    const isValidCard = validateCreditCard(num, scheme);
    let txMsg = "";
    if(!isValidCard) txMsg = "Invalid card number";
    validationResult.cardValidationResult = {"txMsg": txMsg,isValid:isValidCard,scheme:scheme};
    parentUrl = getAppData('parentUrl');
    toggleValidity(isValidCard);
    postMessageWrapper(parent, validationResult, parentUrl);
};

const validateExpiryEventListener=()=>{
    validateExpiry(false);
};
const validateExpiry = (isCascadeFromNumberField) => {
    var hostedField = getAppData('hostedField');
    var cardType = getAppData('cardType');
    var scheme = getAppData(cardType+'scheme');
    const exp = _paymentField.value.replace(/\s+/g, '');
    //console.log(scheme,exp,'test');
    let isEmpty = !exp;
    let isValid;
    var ignoreValidationBroadcast =isCascadeFromNumberField;

    let validationResult = {fieldType:'expiry',messageType:'validation',hostedField,cardType,ignoreValidationBroadcast};
    if(!scheme&&isEmpty)
    {
        validationResult.cardValidationResult = { "txMsg": 'Expiry date can not be empty.',isValid:false,isEmpty:true};
        isValid = false;
    }
    else if(isValidExpiry(exp,scheme)){
        validationResult.cardValidationResult = {txMsg:"",isValid:true};
        isValid = true;
    }
    else{
        let txMsg = 'Invalid Expiry date.';
        if(!exp){
            txMsg = 'Expiry date can not be empty.'
        }
        validationResult.cardValidationResult = {txMsg:txMsg,isValid:false};
        isValid = false;

    }
    parentUrl = getAppData('parentUrl');
    if(!isCascadeFromNumberField)
    {
        toggleValidity(isValid);
    }
    postMessageWrapper(parent,validationResult,getParentUrl());
};

const toggleValidity = (isValid)=>{
    let classNameToAdd = ' invalid',classNameToRemove = ' valid';
    if(isValid)
    {
        classNameToAdd=' valid';
        classNameToRemove = ' invalid';
    }
    _paymentField.className = _paymentField.className.replace(classNameToRemove,'');
    if(_paymentField.className.indexOf(classNameToAdd)===-1)
        _paymentField.className += classNameToAdd;
};
const validateCvvEventListener = () =>{
    validateCvv(false);
};

const validateCvv = (isCascadeFromNumberField) =>{
    var hostedField = getAppData('hostedField');
    var cardType = getAppData('cardType');
    var scheme = getAppData(cardType+'scheme');
    const cvv = _paymentField.value.replace(/\s+/g, '');
    //console.log(scheme,cvv,'inside validateCvv');
    var isValid = true;
     var isEmpty = !cvv;
     var ignoreValidationBroadcast =isCascadeFromNumberField;
     //console.log('cardType',cardType);
     let validationResult = {fieldType:'cvv',messageType:'validation',hostedField,cardType,ignoreValidationBroadcast};
     if(!scheme&&isEmpty&& cardType!=="savedCard")
    {
        validationResult.cardValidationResult = {"txMsg": 'Cvv can not be empty.',isValid:false,isEmpty:true};
        isValid = false;
    }
    else if(isValidCvv(cvv.length,scheme))
    {
        validationResult.cardValidationResult = { "txMsg": '',isValid:true,length:cvv.length};
        isValid = true;
    }
    else{
         let txMsg = 'Cvv can not be empty.';
        if(!isEmpty)
            txMsg = 'Cvv is invalid.';
        validationResult.cardValidationResult = {"txMsg": txMsg,isValid:false,length:cvv.length};
        isValid = false;
    }
    if(!isCascadeFromNumberField)
    {
        toggleValidity(isValid);
    }
    postMessageWrapper(parent, validationResult, getParentUrl());

};

const restrictCVC = (e) => {
    var digit, val;
    digit = String.fromCharCode(e.which);
    if (!/^\d+$/.test(digit)) {
        return;
    }
    if (hasTextSelected(_paymentField)) {
        return;
    }
    val = _paymentField.value + digit;
    if(val.length > 4)  e.preventDefault();
};

const getParentUrl = ()=>{
  let url =  (window.location != window.parent.location)
            ? document.referrer
      : document.location.protocol + '//' + document.location.host;
  return url;
};

const restrictPaste = (e) => {
    e.preventDefault();
};

export {addField, formatExpiry,validateCvv,validateExpiry,validateCard,addEventListenersForHostedFields}<commit_msg>saving mcp related changes<commit_after>/**
 * Created by nagamai on 9/9/2016.
 */
import {
    cardFromNumber,
    schemeFromNumber,
    getAppData,
    addListener,
    postMessageWrapper,
    setAppData,
    isIOS
} from "./utils";
import {getConfigValue} from "./hosted-field-config";
import {validateCreditCard, isValidCvv, isValidExpiry} from "./validation/custom-validations";

let _paymentField;
let field;
let cvvLen = 4;
//todo:change its name later
let digit;
let parentUrl = getAppData('parentUrl');
const addField = () => {
    let fieldType = document.location.href.split("#");
    if(fieldType.length<2)
        return;
    field = fieldType[1].split("-");
    _paymentField = document.createElement("input");
    _paymentField.setAttribute("id", field[0] + "citrusInput");
    document.body.appendChild(_paymentField);
    //addEventListenersForHostedFields();
};

const postPaymentData = () => {
    //Send value of the field to the cardnumber iframe
    let message = {messageType:'cardData'};
    let cardData = {};
    cardData.value = _paymentField.value;
    cardData.key = field[0];
    message.cardType = field[1];
    message.cardData = cardData;
    //todo:IMPORTANT, change * to citrus server url,
    //also if possible use name instead of index as index will be unreliable
    //if there are other iframes on merchant's page

    for(var i=0;i<parent.window.frames.length;i++)
    {
        postMessageWrapper(parent.window.frames[i], message, getConfigValue('hostedFieldDomain'));
    }
};

//in android browsers keypress does not fire
//keydown fires but the charCode is not usable
//so the input event is the one which prevent invalid entry in the case of android
//for all input fields.
const addEventListenersForHostedFields = (cardSetupType) => {
    //detect the ios user agent, since ios devices don't listen to blur events. ignore the microsoft user agent which also contains the ios keyword.
    let iOS = isIOS();
    let eventStr;
    iOS ? eventStr = "input" : eventStr = "blur";
        //add the event listeners for ui validations of those fields.
        if(cardSetupType==="credit"||cardSetupType==="debit"||cardSetupType==="card")
            addListener(_paymentField,eventStr, postPaymentData, false);
        addListener(_paymentField,"focus", addFocusAttributes, false);
        addListener(_paymentField,"blur", removeFocusAttributes, false);
        addListener(_paymentField,'paste', restrictPaste, false);
        switch (field[0]) {
            case "number" :
                addListener(_paymentField,eventStr, validateCardEventListener, false);
                addListener(_paymentField,'input',detectScheme);
                addListener(_paymentField,'keypress', restrictNumeric, false);
                addListener(_paymentField,'keypress', restrictCardNumber, false);
                addListener(_paymentField,'keypress', formatCardNumber, false);
                addListener(_paymentField,'input', reFormatCardNumber, false);
                break;
            case "expiry" :
                addListener(_paymentField,eventStr, validateExpiryEventListener, false);
                addListener(_paymentField,'keypress', restrictNumeric, false);
                addListener(_paymentField,'keypress', formatExpiry, false);
                addListener(_paymentField,'input', reformatExpiry, false);
                break;
            case "cvv"    :
                addListener(_paymentField,eventStr, validateCvvEventListener, false);
                _paymentField.setAttribute("type", "password");
                addListener(_paymentField,'keypress', restrictNumeric, false);
                addListener(_paymentField,'keypress', restrictCVC, false);
                //this is specifically for android, as keypress does not fire
                //on android
                addListener(_paymentField,'input',formatCvv,false);
                break;
        }
};

const detectScheme = ()=>{
    const num = _paymentField.value.replace(/\s+/g, '');
    const scheme = schemeFromNumber(num);
    var setupType = getAppData('cardType');
    var hostedField = getAppData('hostedField');
    if(!scheme)
        return;
    var lastDetectedScheme = getAppData(setupType+'scheme');
    let schemeChangeMessage = {messageType:'schemeChange',scheme:scheme,hostedField, cardType:setupType};
    if(lastDetectedScheme!==scheme)
    {
        setAppData(setupType+'scheme',scheme);
        postMessageWrapper(parent,schemeChangeMessage,getParentUrl());
    }
};

const addFocusAttributes=()=>{
    var hostedField = getAppData('hostedField');
    let focusReceivedMessage = {messageType:'focusReceived',fieldType:field[0],hostedField};
    postMessageWrapper(parent, focusReceivedMessage, getParentUrl());
};

const removeFocusAttributes =()=>{
     var hostedField = getAppData('hostedField');
    let focusLostMessage = {messageType:'focusLost',fieldType:field[0],hostedField};
    postMessageWrapper(parent, focusLostMessage, getParentUrl());
};
const formatCardNumber = () => {
    let num = _paymentField.value;
    num = num.replace(/\D/g, '');
     var parts = num.match(/^\d{1,19}/);
    if (!parts) {
        _paymentField.value = '';
        return;
    }
    var card, groups, upperLength, _ref;
    card = cardFromNumber(num);
    if (!card) {
        return num;
    }
    upperLength = card.length[card.length.length - 1];
    num = num.replace(/\D/g, '');
    num = num.slice(0, upperLength);
    if (card.groupingFormat.global) {
        _paymentField.value = (_ref = num.match(card.groupingFormat)) != null ? _ref.join(' ') : void 0;
    } else {
        groups = card.groupingFormat.exec(num);
        if (groups == null) {
            return;
        }
        groups.shift();
        groups = groups.filter(function (n) {
            return n;
        });
        _paymentField.value = groups.join(' ');
    }
};

const hasTextSelected = (target) => {
    var _ref;
    if ((target.selectionStart != null) && target.selectionStart !== target.selectionEnd) {
        return true;
    }
    return !!(typeof document !== "undefined" && document !== null ? ( _ref = document.selection) != null ? typeof _ref.createRange === "function" ? _ref.createRange().text :
        void 0 :
        void 0 :
        void 0);

};

const formatExpiry = (e) => {
    let expiry = _paymentField.value;
    var mon,
        parts,
        sep,
        year;
    parts = expiry.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/);
    if (!parts) {
        _paymentField.value = '';
        return;
    }
    mon = parts[1] || '';
    sep = parts[2] || '';
    year = parts[3] || '';
    if (year.length > 0 || (sep.length > 0 && !(/\ \/?\ ?/.test(sep)))) {
        sep = ' / ';
    }
    if (mon.length === 1 && (mon !== '0' && mon !== '1')) {
        mon = "0" + mon;
        sep = ' / ';
    }
    //check added for backspace key
    if(e.which<57) digit = e.which;
    if (digit< 57 && mon.length === 2)
    {
         sep = ' / ';
        digit = 60;
    }
    _paymentField.value = mon + sep + year;
};

const restrictNumeric = (e) => {
    var input;
    if (e.metaKey || e.ctrlKey) {
        return true;
    }
    if (e.which === 32) {

        return false;
    }
    if (e.which === 0) {
        return true;
    }
    if (e.which < 33) {
        return true;
    }
    input = String.fromCharCode(e.which);
    if(!/[\d\s]/.test(input)) e.preventDefault();
    //return !!/[\d\s]/.test(input);
};

const formatCvv = ()=>{
   let cvv = _paymentField.value;
   cvv = cvv.replace(/\D/g, '');
    let parts = cvv.match(/^\d{1,4}/);
    if (!parts) {
        _paymentField.value = '';
        return;
    }
}

//to avoid the acceptance of one extra digit in the field,
//and also formats the card number while pasting the number directly inside the field
const reFormatCardNumber = () => {
    return setTimeout(function () {
        formatCardNumber(_paymentField.value);
    });
};
//to avoid the acceptance of one extra digit in the field
//and also formats the card number while pasting the number directly inside the field
const reformatExpiry = () => {
    return setTimeout(function () {
        formatExpiry(_paymentField.value);
    });
};

const restrictCardNumber = function(e) {
    let card,
        digit,
        value;
    digit = String.fromCharCode(e.which);
    if (!/^\d+$/.test(digit)) {
        return;
    }
    if (hasTextSelected(_paymentField)) {
        return;
    }
    value = (_paymentField.value + digit).replace(/\D/g, '');
    card = cardFromNumber(value);
    if (card) {
        if(value.length > card.length[card.length.length - 1]) e.preventDefault();
    } else {
        if(value.length > 16) e.preventDefault();
    }
};

//todo: change the value of these two fields
//if the card number does not require cvv or field;

const validateCardEventListener=()=>{
    validateCard();
};
const validateCard = () => {
    const num = _paymentField.value.replace(/\s+/g, '');
    var cardType = getAppData('cardType');
    var hostedField = getAppData('hostedField');
    let validationResult = {fieldType:'number',messageType:'validation',hostedField,cardType};
    if(!num){
        validationResult.cardValidationResult = {"txMsg": 'Card nubmer can not be empty.',isValid:false};
        toggleValidity(false);
        postMessageWrapper(parent, validationResult, getParentUrl());
        return;
    }
    const scheme = schemeFromNumber(num);
    //todo : add check for maestro and rupay
    const isValidCard = validateCreditCard(num, scheme);
    let txMsg = "";
    if(!isValidCard) txMsg = "Invalid card number";
    validationResult.cardValidationResult = {"txMsg": txMsg,isValid:isValidCard,scheme:scheme};
    parentUrl = getAppData('parentUrl');
    toggleValidity(isValidCard);
    postMessageWrapper(parent, validationResult, parentUrl);
};

const validateExpiryEventListener=()=>{
    validateExpiry(false);
};
const validateExpiry = (isCascadeFromNumberField) => {
    var hostedField = getAppData('hostedField');
    var cardType = getAppData('cardType');
    var scheme = getAppData(cardType+'scheme');
    const exp = _paymentField.value.replace(/\s+/g, '');
    //console.log(scheme,exp,'test');
    let isEmpty = !exp;
    let isValid;
    var ignoreValidationBroadcast =isCascadeFromNumberField;

    let validationResult = {fieldType:'expiry',messageType:'validation',hostedField,cardType,ignoreValidationBroadcast};
    if(!scheme&&isEmpty)
    {
        validationResult.cardValidationResult = { "txMsg": 'Expiry date can not be empty.',isValid:false,isEmpty:true};
        isValid = false;
    }
    else if(isValidExpiry(exp,scheme)){
        validationResult.cardValidationResult = {txMsg:"",isValid:true};
        isValid = true;
    }
    else{
        let txMsg = 'Invalid Expiry date.';
        if(!exp){
            txMsg = 'Expiry date can not be empty.'
        }
        validationResult.cardValidationResult = {txMsg:txMsg,isValid:false};
        isValid = false;

    }
    parentUrl = getAppData('parentUrl');
    if(!isCascadeFromNumberField)
    {
        toggleValidity(isValid);
    }
    postMessageWrapper(parent,validationResult,getParentUrl());
};

const toggleValidity = (isValid)=>{
    let classNameToAdd = ' invalid',classNameToRemove = ' valid';
    if(isValid)
    {
        classNameToAdd=' valid';
        classNameToRemove = ' invalid';
    }
    _paymentField.className = _paymentField.className.replace(classNameToRemove,'');
    if(_paymentField.className.indexOf(classNameToAdd)===-1)
        _paymentField.className += classNameToAdd;
};
const validateCvvEventListener = () =>{
    validateCvv(false);
};

const validateCvv = (isCascadeFromNumberField) =>{
    var hostedField = getAppData('hostedField');
    var cardType = getAppData('cardType');
    var scheme = getAppData(cardType+'scheme');
    const cvv = _paymentField.value.replace(/\s+/g, '');
    //console.log(scheme,cvv,'inside validateCvv');
    var isValid = true;
     var isEmpty = !cvv;
     var ignoreValidationBroadcast =isCascadeFromNumberField;
     //console.log('cardType',cardType);
     let validationResult = {fieldType:'cvv',messageType:'validation',hostedField,cardType,ignoreValidationBroadcast};
     if(!scheme&&isEmpty&& cardType!=="savedCard")
    {
        validationResult.cardValidationResult = {"txMsg": 'Cvv can not be empty.',isValid:false,isEmpty:true};
        isValid = false;
    }
    else if(isValidCvv(cvv.length,scheme))
    {
        validationResult.cardValidationResult = { "txMsg": '',isValid:true,length:cvv.length};
        isValid = true;
    }
    else{
         let txMsg = 'Cvv can not be empty.';
        if(!isEmpty)
            txMsg = 'Cvv is invalid.';
        validationResult.cardValidationResult = {"txMsg": txMsg,isValid:false,length:cvv.length};
        isValid = false;
    }
    if(!isCascadeFromNumberField)
    {
        toggleValidity(isValid);
    }
    postMessageWrapper(parent, validationResult, getParentUrl());

};

const restrictCVC = (e) => {
    var digit, val;
    digit = String.fromCharCode(e.which);
    if (!/^\d+$/.test(digit)) {
        return;
    }
    if (hasTextSelected(_paymentField)) {
        return;
    }
    val = _paymentField.value + digit;
    if(val.length > 4)  e.preventDefault();
};

const getParentUrl = ()=>{
  let url =  (window.location != window.parent.location)
            ? document.referrer
      : document.location.protocol + '//' + document.location.host;
  return url;
};

const restrictPaste = (e) => {
    e.preventDefault();
};

export {addField, formatExpiry,validateCvv,validateExpiry,validateCard,addEventListenersForHostedFields}<|endoftext|>


<commit_before>iD.behavior.Lasso = function(context) {

    var behavior = function(selection) {

        var timeout = null,
            // the position of the first mousedown
            pos = null,
            lasso;

        function mousedown() {
            if (d3.event.shiftKey === true) {

                lasso = iD.ui.lasso().a(d3.mouse(context.surface().node()));

                context.surface().call(lasso);

                selection
                    .on('mousemove.lasso', mousemove)
                    .on('mouseup.lasso', mouseup);

                d3.event.stopPropagation();
                d3.event.preventDefault();

            }
        }

        function mousemove() {
            lasso.b(d3.mouse(context.surface().node()));
        }

        function mouseup() {
            var extent = iD.geo.Extent(
                context.projection.invert(lasso.a()),
                context.projection.invert(lasso.b()));

            lasso.close();

            var selected = context.graph().intersects(extent);

            if (selected.length) {
                context.enter(iD.modes.Select(context, _.pluck(selected, 'id')));
            }

            selection
                .on('mousemove.lasso', null);
        }

        selection
            .on('mousedown.select', mousedown);
    };

    behavior.off = function(selection) {
        selection.on('mousedown.lasso', null);
    };

    return behavior;
};
<commit_msg>Normalize coordinates so that lasso can be dragged in any direction<commit_after>iD.behavior.Lasso = function(context) {

    var behavior = function(selection) {

        var timeout = null,
            // the position of the first mousedown
            pos = null,
            lasso;

        function mousedown() {
            if (d3.event.shiftKey === true) {

                lasso = iD.ui.lasso().a(d3.mouse(context.surface().node()));

                context.surface().call(lasso);

                selection
                    .on('mousemove.lasso', mousemove)
                    .on('mouseup.lasso', mouseup);

                d3.event.stopPropagation();
                d3.event.preventDefault();

            }
        }

        function mousemove() {
            lasso.b(d3.mouse(context.surface().node()));
        }

        function normalize(a, b) {
            return [
                [Math.min(a[0], b[0]), Math.min(a[1], b[1])],
                [Math.max(a[0], b[0]), Math.max(a[1], b[1])]];
        }

        function mouseup() {
            var extent = iD.geo.Extent(
                normalize(context.projection.invert(lasso.a()),
                context.projection.invert(lasso.b())));

            lasso.close();

            var selected = context.graph().intersects(extent);

            selection
                .on('mousemove.lasso', null)
                .on('mouseup.lasso', null);

            if (selected.length) {
                context.enter(iD.modes.Select(context, _.pluck(selected, 'id')));
            }
        }

        selection
            .on('mousedown.lasso', mousedown);
    };

    behavior.off = function(selection) {
        selection.on('mousedown.lasso', null);
    };

    return behavior;
};
<|endoftext|>


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

const logger = require('./logger');
const sqldb = require('./sqldb');
const config = require('./config');
const sql = require('./sql-loader').loadSqlEquiv(__filename);

class LoadEstimator {
    constructor(jobType, maxJobCount) {
        this.jobType = jobType;
        const nowMS = Date.now();
        this.lastEstimateTimeMS = nowMS;
        this.lastIncrementTimeMS = nowMS;
        this.integratedLoad = 0;
        this.currentJobs = {};
        this.maxJobCount = maxJobCount || 1;
        this.timeoutID = null;
        this._reportLoad();
    }

    startJob(id) {
        this._addIntegratedLoad();
        if (_.has(this.currentJobs, id)) {
            logger.error(`load.startJob(): ${this.jobType} id already running: ${id}`);
        }
        this.currentJobs[id] = Date.now();
    }

    endJob(id) {
        this._addIntegratedLoad();
        if (_.has(this.currentJobs, id)) {
            delete this.currentJobs[id];
        } else {
            logger.error(`load.endJob(): ${this.jobType} no such id: ${id}`);
        }
    }

    close() {
        if (this.timeoutID != null) {
            clearTimeout(this.timeoutID);
        } else {
            console.log(this.jobType, 'no timeout to clear');
        }
    }

    _getAndResetLoadEstimate() {
        this._addIntegratedLoad();
        const nowMS = Date.now();
        const deltaSeconds = Math.max(1, nowMS - this.lastEstimateTimeMS) / 1000;
        const loadEstimate = this.integratedLoad / deltaSeconds;

        // reset stats
        this.lastEstimateTimeMS = nowMS;
        this.lastIncrementTimeMS = nowMS;
        this.integratedLoad = 0;

        return loadEstimate;
    }

    _addIntegratedLoad() {
        const currentJobCount = _.size(this.currentJobs);
        const nowMS = Date.now();
        const delta = Math.max(1, nowMS - this.lastIncrementTimeMS) / 1000;
        this.integratedLoad += delta * currentJobCount;
        this.lastIncrementTimeMS = nowMS;
    }

    _reportLoad() {
        this._warnOldJobs();
        var params = {
            instance_id: config.instanceId,
            group_name: config.groupName,
            job_type: this.jobType,
            average_jobs: this._getAndResetLoadEstimate(),
            max_jobs: this.maxJobCount,
        };
        sqldb.query(sql.insert_load, params, (err) => {
            if (err) logger.error('Error reporting load', {err});
            this.timeoutID = setTimeout(this._reportLoad.bind(this), config.reportIntervalSec * 1000);
        });
    }

    _warnOldJobs() {
        const nowMS = Date.now();
        _.forEach(this.currentJobs, (startMS, id) => {
            if (nowMS - startMS > config.maxResponseTimeSec * 1000) {
                logger.error(`load._warnOldJobs(): ${this.jobType} id ${id} has age ${nowMS - startMS} ms`);
            }
        });
    }
}

const estimators = {};

module.exports = {
    initEstimator(jobType, maxJobCount) {
        if (_.has(estimators, jobType)) throw new Error(`duplicate jobType: ${jobType}`);
        estimators[jobType] = new LoadEstimator(jobType, maxJobCount);
    },

    startJob(jobType, id, maxJobCount) {
        if (!_.has(estimators, jobType)) {
            // lazy estimator creation, needed for unit tests
            estimators[jobType] = new LoadEstimator(jobType, maxJobCount);
        }
        estimators[jobType].startJob(id);
    },

    endJob(jobType, id) {
        if (!_.has(estimators, jobType)) throw new Error(`endJob(): no such estimator: ${jobType}`);
        estimators[jobType].endJob(id);
    },

    close() {
        for (const jobType in estimators) {
            estimators[jobType].close();
            delete estimators[jobType];
        }
    },
};
<commit_msg>remove leftover debugging code<commit_after>const _ = require('lodash');

const logger = require('./logger');
const sqldb = require('./sqldb');
const config = require('./config');
const sql = require('./sql-loader').loadSqlEquiv(__filename);

class LoadEstimator {
    constructor(jobType, maxJobCount) {
        this.jobType = jobType;
        const nowMS = Date.now();
        this.lastEstimateTimeMS = nowMS;
        this.lastIncrementTimeMS = nowMS;
        this.integratedLoad = 0;
        this.currentJobs = {};
        this.maxJobCount = maxJobCount || 1;
        this.timeoutID = null;
        this._reportLoad();
    }

    startJob(id) {
        this._addIntegratedLoad();
        if (_.has(this.currentJobs, id)) {
            logger.error(`load.startJob(): ${this.jobType} id already running: ${id}`);
        }
        this.currentJobs[id] = Date.now();
    }

    endJob(id) {
        this._addIntegratedLoad();
        if (_.has(this.currentJobs, id)) {
            delete this.currentJobs[id];
        } else {
            logger.error(`load.endJob(): ${this.jobType} no such id: ${id}`);
        }
    }

    close() {
        if (this.timeoutID != null) {
            clearTimeout(this.timeoutID);
        }
    }

    _getAndResetLoadEstimate() {
        this._addIntegratedLoad();
        const nowMS = Date.now();
        const deltaSeconds = Math.max(1, nowMS - this.lastEstimateTimeMS) / 1000;
        const loadEstimate = this.integratedLoad / deltaSeconds;

        // reset stats
        this.lastEstimateTimeMS = nowMS;
        this.lastIncrementTimeMS = nowMS;
        this.integratedLoad = 0;

        return loadEstimate;
    }

    _addIntegratedLoad() {
        const currentJobCount = _.size(this.currentJobs);
        const nowMS = Date.now();
        const delta = Math.max(1, nowMS - this.lastIncrementTimeMS) / 1000;
        this.integratedLoad += delta * currentJobCount;
        this.lastIncrementTimeMS = nowMS;
    }

    _reportLoad() {
        this._warnOldJobs();
        var params = {
            instance_id: config.instanceId,
            group_name: config.groupName,
            job_type: this.jobType,
            average_jobs: this._getAndResetLoadEstimate(),
            max_jobs: this.maxJobCount,
        };
        sqldb.query(sql.insert_load, params, (err) => {
            if (err) logger.error('Error reporting load', {err});
            this.timeoutID = setTimeout(this._reportLoad.bind(this), config.reportIntervalSec * 1000);
        });
    }

    _warnOldJobs() {
        const nowMS = Date.now();
        _.forEach(this.currentJobs, (startMS, id) => {
            if (nowMS - startMS > config.maxResponseTimeSec * 1000) {
                logger.error(`load._warnOldJobs(): ${this.jobType} id ${id} has age ${nowMS - startMS} ms`);
            }
        });
    }
}

const estimators = {};

module.exports = {
    initEstimator(jobType, maxJobCount) {
        if (_.has(estimators, jobType)) throw new Error(`duplicate jobType: ${jobType}`);
        estimators[jobType] = new LoadEstimator(jobType, maxJobCount);
    },

    startJob(jobType, id, maxJobCount) {
        if (!_.has(estimators, jobType)) {
            // lazy estimator creation, needed for unit tests
            estimators[jobType] = new LoadEstimator(jobType, maxJobCount);
        }
        estimators[jobType].startJob(id);
    },

    endJob(jobType, id) {
        if (!_.has(estimators, jobType)) throw new Error(`endJob(): no such estimator: ${jobType}`);
        estimators[jobType].endJob(id);
    },

    close() {
        for (const jobType in estimators) {
            estimators[jobType].close();
            delete estimators[jobType];
        }
    },
};
<|endoftext|>


<commit_before>iD.modes.MoveWay = function(context, wayId) {
    var mode = {
        id: 'move-way'
    };

    var keybinding = d3.keybinding('move-way');

    mode.enter = function() {
        var origin = point(),
            annotation = t('operations.move.annotation.' + context.geometry(wayId));

        // If intiated via keyboard
        if (!origin[0] && !origin[1]) origin = null;

        context.perform(
            iD.actions.Noop(),
            annotation);

        function point() {
            return d3.mouse(context.surface().node());
        }

        function move() {
            var p = point(),
                delta = origin ?
                    [p[0] - origin[0], p[1] - origin[1]] :
                    [0, 0];

            origin = p;

            context.replace(
                iD.actions.MoveWay(wayId, delta, context.projection),
                annotation);
        }

        function finish() {
            d3.event.stopPropagation();
            context.enter(iD.modes.Select(context, [wayId], true));
        }

        function cancel() {
            context.pop();
            context.enter(iD.modes.Select(context, [wayId], true));
        }

        function undone() {
            context.enter(iD.modes.Browse(context));
        }

        context.selection()
            .on('mousemove.move-way', move)
            .on('click.move-way', finish);

        context.history()
            .on('undone.move-way', undone);

        keybinding
            .on('⎋', cancel)
            .on('↩', finish);

        d3.select(document)
            .call(keybinding);
    };

    mode.exit = function() {
        context.selection()
            .on('mousemove.move-way', null)
            .on('click.move-way', null);

        context.history()
            .on('undone.move-way', null);

        keybinding.off();
    };

    return mode;
};
<commit_msg>Fix MoveWay mode (fixes #602)<commit_after>iD.modes.MoveWay = function(context, wayId) {
    var mode = {
        id: 'move-way'
    };

    var keybinding = d3.keybinding('move-way');

    mode.enter = function() {
        var origin = point(),
            annotation = t('operations.move.annotation.' + context.geometry(wayId));

        // If intiated via keyboard
        if (!origin[0] && !origin[1]) origin = null;

        context.perform(
            iD.actions.Noop(),
            annotation);

        function point() {
            return d3.mouse(context.surface().node());
        }

        function move() {
            var p = point(),
                delta = origin ?
                    [p[0] - origin[0], p[1] - origin[1]] :
                    [0, 0];

            origin = p;

            context.replace(
                iD.actions.MoveWay(wayId, delta, context.projection),
                annotation);
        }

        function finish() {
            d3.event.stopPropagation();
            context.enter(iD.modes.Select(context, [wayId], true));
        }

        function cancel() {
            context.pop();
            context.enter(iD.modes.Select(context, [wayId], true));
        }

        function undone() {
            context.enter(iD.modes.Browse(context));
        }

        context.surface()
            .on('mousemove.move-way', move)
            .on('click.move-way', finish);

        context.history()
            .on('undone.move-way', undone);

        keybinding
            .on('⎋', cancel)
            .on('↩', finish);

        d3.select(document)
            .call(keybinding);
    };

    mode.exit = function() {
        context.surface()
            .on('mousemove.move-way', null)
            .on('click.move-way', null);

        context.history()
            .on('undone.move-way', null);

        keybinding.off();
    };

    return mode;
};
<|endoftext|>


<commit_before>import uniqueId from 'lodash/utility/uniqueId'
import loadArea from './load-area'
import getStudentData from './get-student-data'

import Worker from './check-student-against-area.worker.js'
const worker = new Worker()
// worker.onmessage = msg => console.log('[main] received message from check-student worker:', msg)
worker.addEventListener('error', msg => console.log('[main] received error from check-student worker:', msg))

function onMessage({sourceId, resolve, reject}, {data}) {
	const [resultId, type, contents] = JSON.parse(data)

	if (resultId === sourceId) {
		worker.removeEventListener('message', onMessage)

		if (type === 'result') {
			resolve(contents)
		}
		else if (type === 'error') {
			reject({_error: contents.message})
		}
	}
}

/**
 * Checks a student object against an area of study.
 *
 * @param {Object} student - the student to check
 * @param {Object} area - the area to check against
 * @returns {Promise} - the promise for a result
 * @promise ResultsPromise
 * @fulfill {Object} - The details of the area check.
 */
export default async function checkStudentAgainstArea(student, area) {
	const sourceId = uniqueId()

	return new Promise(async (resolve, reject) => {
		worker.addEventListener('message', onMessage.bind(null, {sourceId, resolve, reject}))

		const areaData = {
			...area,
		}
		try {
			areaData.data = await loadArea(area)
		}
		catch (err) {
			console.error(err)
			return
		}

		let studentData
		try {
			studentData = await getStudentData(student)
		}
		catch (err) {
			console.error(err)
			return
		}

		/* why stringify? from https://code.google.com/p/chromium/issues/detail?id=536620#c11:
		 > We know that serialization/deserialization is slow. It's actually faster to
		 > JSON.stringify() then postMessage() a string than to postMessage() an object. :(
		 */
		worker.postMessage(JSON.stringify([sourceId, studentData, areaData]))
	})
}
<commit_msg>use "reject" in checkStudentAgainstArea<commit_after>import uniqueId from 'lodash/utility/uniqueId'
import loadArea from './load-area'
import getStudentData from './get-student-data'

import Worker from './check-student-against-area.worker.js'
const worker = new Worker()
// worker.onmessage = msg => console.log('[main] received message from check-student worker:', msg)
worker.addEventListener('error', msg => console.log('[main] received error from check-student worker:', msg))

function onMessage({sourceId, resolve, reject}, {data}) {
	const [resultId, type, contents] = JSON.parse(data)

	if (resultId === sourceId) {
		worker.removeEventListener('message', onMessage)

		if (type === 'result') {
			resolve(contents)
		}
		else if (type === 'error') {
			reject({_error: contents.message})
		}
	}
}

/**
 * Checks a student object against an area of study.
 *
 * @param {Object} student - the student to check
 * @param {Object} area - the area to check against
 * @returns {Promise} - the promise for a result
 * @promise ResultsPromise
 * @fulfill {Object} - The details of the area check.
 */
export default async function checkStudentAgainstArea(student, area) {
	const sourceId = uniqueId()

	return new Promise(async (resolve, reject) => {
		worker.addEventListener('message', onMessage.bind(null, {sourceId, resolve, reject}))

		const areaData = {
			...area,
		}
		try {
			areaData.data = await loadArea(area)
		}
		catch (err) {
			reject(err)
		}

		let studentData
		try {
			studentData = await getStudentData(student)
		}
		catch (err) {
			reject(err)
		}

		/* why stringify? from https://code.google.com/p/chromium/issues/detail?id=536620#c11:
		 > We know that serialization/deserialization is slow. It's actually faster to
		 > JSON.stringify() then postMessage() a string than to postMessage() an object. :(
		 */
		worker.postMessage(JSON.stringify([sourceId, studentData, areaData]))
	})
}
<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014-2016 Ruslan Sagitov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
'use strict';

/**
 * @module loud
 */

var getWordsFromRole = require('./words-from-role'),
    getWordsFromAttributes = require('./words-from-attributes'),
    getAccessibleName = require('./accessible-name'),
    A11yNode = require('./a11y-node'),
    UTIL = require('./util');

var flatten = UTIL.flatten;

function Loud() {
    return this;
}

Loud.prototype.say = function(node) {
    if (!node || !node.length) {
        node = [node];
    }

    var res = [];

    for (var i = 0; i < node.length; i++) {
        if (!node[i]) {
            continue;
        }

        this.elementById = {};

        this.root = new A11yNode(node[i], this);
        this.root.parse().setIds(this).setRole(this).fixRole(this);

        res.push(this.handleNode(this.root));

        this.root.free();
        delete this.root;
        delete this.elementById;
    }

    return flatten(res);
};

Loud.prototype.setElementId = function(id, node) {
    this.elementById[id] = node;
};

Loud.prototype.getElementById = function(id) {
    return this.elementById[id];
};

Loud.prototype.getElementsByTagName = function(name) {
    return this.root.getElementsByTagName(name);
};

Loud.prototype.traverse = function(node) {
    var iter = node.firstChild,
        value = [],
        val;
    for (; iter; iter = iter.nextSibling) {
        val = this.handleNode(iter);
        if (val) {
            value.push(val);
        }
    }

    return flatten(value);
};

Loud.prototype.handleNode = function(node) {
    switch (node.nodeType) {
        case 1: /* ELEMENT */
            break;
        case 3: /* TEXTNODE */
            return node.nodeValue.trim();
    }

    if (node.hidden) {
        return '';
    }

    return this.getWordsFromRole(node);
};

Loud.prototype.getAccessibleName = getAccessibleName;
Loud.prototype.getWordsFromRole = getWordsFromRole;
Loud.prototype.getWordsFromAttributes = getWordsFromAttributes;

module.exports = {
    /**
     * @type {String}
     */
    VERSION: '0.8.4',

    /**
     * Transform a DOM element to words.
     *
     * @param {Object|Object[]} node - DOM element or array of
     *                                 DOM elements
     * @returns {String[]} Words
     */
    say: function(node) {
        return (new Loud()).say(node);
    }
};
<commit_msg>Refactor for better clarity<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014-2016 Ruslan Sagitov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
'use strict';

/**
 * @module loud
 */

var getWordsFromRole = require('./words-from-role'),
    getWordsFromAttributes = require('./words-from-attributes'),
    getAccessibleName = require('./accessible-name'),
    A11yNode = require('./a11y-node'),
    UTIL = require('./util');

var flatten = UTIL.flatten;

function Loud() {
    return this;
}

Loud.prototype.say = function(node) {
    if (!node || !node.length) {
        node = [node];
    }

    var res = [];

    for (var i = 0; i < node.length; i++) {
        if (!node[i]) {
            continue;
        }

        this.elementById = {};

        this.root = new A11yNode(node[i], this);
        this.root.parse().setIds(this).setRole(this).fixRole(this);

        res.push(this.handleNode(this.root));

        this.root.free();
        delete this.root;
        delete this.elementById;
    }

    return flatten(res);
};

Loud.prototype.setElementId = function(id, node) {
    this.elementById[id] = node;
};

Loud.prototype.getElementById = function(id) {
    return this.elementById[id];
};

Loud.prototype.getElementsByTagName = function(name) {
    return this.root.getElementsByTagName(name);
};

Loud.prototype.traverse = function(node) {
    var iter = node.firstChild,
        value = [],
        val;
    for (; iter; iter = iter.nextSibling) {
        val = this.handleNode(iter);
        if (val) {
            value.push(val);
        }
    }

    return flatten(value);
};

Loud.prototype.handleNode = function(node) {
    if (node.nodeType === 3) {
        return node.nodeValue.trim();
    }

    if (node.hidden) {
        return '';
    }

    return this.getWordsFromRole(node);
};

Loud.prototype.getAccessibleName = getAccessibleName;
Loud.prototype.getWordsFromRole = getWordsFromRole;
Loud.prototype.getWordsFromAttributes = getWordsFromAttributes;

module.exports = {
    /**
     * @type {String}
     */
    VERSION: '0.8.4',

    /**
     * Transform a DOM element to words.
     *
     * @param {Object|Object[]} node - DOM element or array of
     *                                 DOM elements
     * @returns {String[]} Words
     */
    say: function(node) {
        return (new Loud()).say(node);
    }
};
<|endoftext|>