<commit_before>var horizon = 200;
var gameTime = 8;
var hourL = 60000;
var frameTime = 0;
var lastFrame = 0;
var drawFrame = false;
var lastHour = 0;
var sunrise,day,sunset,night,ground;
var orbAngle = 0;
var paused = false;
var lines;
var lastLine = 0;
var lineChance = 1/50;
var lineLife = 60;
var liveLines = Array();

function setup(){
  createCanvas(600,400);
  background(255);
  sunset = [color(0,150,200),color(224,153,255),color(255,224,224)];
  night = [color(0),color(0),color(128,0,64)];
  sunrise = [color(0,153,204),color(204,153,255),color(255,204,204)];
  day = [color(102,204,255),color(153,204,255),color(204,255,255)];
  ground = [color(200,255,200),color(64,255,64),color(64,255,64)];
  lines = ["...","CUBE GOOD HORSE?","CUBE GO FAST?","CUBE BAD","CUBE GET A PUSH?","CUBE NOT FAST","CUBE NO GO GOOD","OTHER HORSE PULL CUBE?","CUBE NEED A PUSH","CUBE WIN RACE?","OATS","NO OATS?","...","CUBE TRY CUBE'S BEST","CUBE TRY HARD THIS TIME","CUBE TRY HARDER","CUBE IN THE LEAD?","CUBE TIRED FROM TRYING"];
  textSize(16);
  textAlign(CENTER);
  drawSky();
  drawGround();
  drawCube(width/2-50,height-200,100,150,25,125);
  drawFence(height+15,120,60,8);
}

function draw(){
  if(!paused){
    if(millis()-lastHour > hourL){
	  lastHour = millis();
	  gameTime= (gameTime+1) % 24;
    }
  }

  if(millis()-lastFrame > 33){
    lastFrame = millis();
	frameTime = (frameTime + 1) % 24;
    drawSky();
	drawGround();
	drawCube(width/2-50,height-200,100,150,25,125);
	drawFence(height+15,120,60,8);
	if(random()<=lineChance && lastLine>=30){
      var curLine = {};
	  curLine.age = lineLife;
	  curLine.x = random(-100,100);
	  curLine.y = random(0,-200);
	  curLine.line = lines[floor(random(lines.length))];
	  liveLines.push(curLine);
	  lastLine = 0;
	}
	else if(liveLines.length>0){
	  for(var i = 0;i<liveLines.length;i++){
		  liveLines[i].age--;
		  if(liveLines[i].age>0){
		    drawLine(liveLines[i]);
		  }
	  }
	  while(liveLines.length>0 && liveLines[liveLines.length-1].age<0){
	    liveLines.pop();
	  }
	}
	lastLine++;
  }
}

function drawLine(aLine){
	push();
	  translate(width/2+aLine.x, height-50+aLine.y);
	  stroke(255,(aLine.age/lineLife)*255);
	  strokeWeight(2);
	  fill(0,0,200,(aLine.age/lineLife)*255);
	  rect(-(textWidth(aLine.line)/2)-5,0,textWidth(aLine.line)+10,32);
	  noStroke();
	  if(-100 - aLine.y >= 0){
	//    triangle(-aLine.x,-100 - aLine.y,-10,32,10,32);
	  }
	  else{
	 //   triangle(-aLine.x,-100 - aLine.y,-10,-2,10,-2);
	  }
	  fill(255,(aLine.age/lineLife)*255);
	  text(aLine.line,0,22);

	pop();
}

function drawCube(x,y,w1,w2,h1,h2){
	var sx = (w2-w1)/2;
	push();
	translate(x,y);
	noStroke();
	fill(240);
	quad(0,0,w1,0,w1+sx,h1,0-sx,h1);
	fill(128);
	rect(-sx,h1,w2,h2);
	pop();
}

function drawSky(){
  var curSky;
  if(gameTime<4 || gameTime>20){
    curSky = night;
  }
  else if(gameTime>8 && gameTime<16){
    curSky = day;
  }
  else if(gameTime<6){
    //sunrise
	var inter = ((gameTime-4)) + ((millis()-lastHour)/hourL);
	curSky = lerpGradient(night,sunrise,inter);
  }
  else if(gameTime<=8){
    //sunrise
	var inter = ((gameTime-6)) + ((millis()-lastHour)/hourL);
	curSky = lerpGradient(sunrise,day,inter);
  }
  else if(gameTime<18){
	var inter = ((gameTime-16)) + ((millis()-lastHour)/hourL);
	curSky = lerpGradient(day,sunset,inter);
    //sunset
  }
  else if(gameTime<=20){
	var inter = ((gameTime-18)) + ((millis()-lastHour)/hourL);
	curSky = lerpGradient(sunset,night,inter);
    //sunset
  }
  else{
  	curSky = night;
	console.log(gameTime);
  }
  drawGradient(0,0,width,horizon,curSky);
  var orbColor = (gameTime>=6 && gameTime<18) ? color(255,255,200) : color(255);
  var pastRise;
  if(gameTime>=6 && gameTime<18){
    pastRise = gameTime + ((millis()-lastHour)/hourL) - 5;
  }
  else{
    pastRise = (gameTime<6) ? gameTime + ((millis()-lastHour)/hourL) + 6 : gameTime + ((millis()-lastHour)/hourL) - 18;
  }

  push();
  orbAngle = map(pastRise,0,12,PI/8,-PI - (PI/8));
  fill(orbColor);
  stroke(color(255,32));
  strokeWeight(15 + (2*sin(frameTime/12*PI)));
  translate(width/2.0,horizon);
  rotate(orbAngle,0);
  translate((width/2)-100,0);
  ellipse(0,0,50,50);
  strokeWeight(1);
  pop();

}

function drawGround(){
  push();
  noStroke();

  if(gameTime>=8 && gameTime <=16){
 	 drawGradient(0,horizon,width,height-horizon,ground);
  }
  else if(gameTime<=4 || gameTime >=20){
	drawGradient(0,horizon,width,height-horizon,blendGradient(ground,color(100),0.75));
  }
  else if(gameTime<8){
	  var curTime = gameTime + ( (millis()-lastHour) / hourL) - 4;
	  drawGradient(0,horizon,width,height-horizon,blendGradient(ground,color(100),0.75 - (.75 * (curTime/4)) ));
  }
  else if(gameTime>16){
	  var curTime = gameTime + ( (millis()-lastHour) / hourL) - 16;
	  drawGradient(0,horizon,width,height-horizon,blendGradient(ground,color(100),(.75 * (curTime/4)) ));
  }
  pop();
  drawFence(horizon+5,30,10,2);
  drawTrack(horizon+10,20);
  drawFence(horizon+50,60,30,4);
  drawTrack(horizon+70,120);
}

function drawTrack(y,theight){
  push();
  translate(0,y);
  var tcolor = color(150,100,50);
  if(gameTime>=8 && gameTime <=16){
	  tcolor = color(150,100,50);
  }
  else if(gameTime<=4 || gameTime >=20){
	  tcolor = lerpColor(tcolor, color(100),0.75);
  }
  else if(gameTime<8){
	  var curTime = gameTime + ( (millis()-lastHour) / hourL) - 4;
	  tcolor = lerpColor(tcolor, color(100),0.75 - (0.75 * (curTime/4)));
  }
  else if(gameTime>16){
	  var curTime = gameTime + ( (millis()-lastHour) / hourL) - 16;
	  tcolor = lerpColor(tcolor, color(100),0.75 * (curTime/4));
  }

  fill(tcolor);
  noStroke();
  rect(0,0,width,theight);
  pop();
}

function drawFence(y,fdelta,fheight,fwidth){
  push();
   var fcolor = color(255,255,255);
   translate(0,y);
   noStroke();
   fill(fcolor);
   rect(0,-fheight,width,fwidth);
   for(var i = fdelta/2;i<width;i+=fdelta){
	 rect(i,0,fwidth/2,-fheight);
   }
  pop();
}

function blendGradient(c1,c2,inter){
  var c3 = Array();
  for( var i = 0;i<c1.length;i++){
    c3[i] = lerpColor(c1[i],c2,inter);
  }
  return c3;
}

function lerpGradient(c1,c2,inter){
  var c3 = Array();
  if(c1.length = c2.length){
    for(var i = 0;i<c1.length;i++){
		c3[i] = lerpColor(c1[i],c2[i],inter);
    }
  }
  else{

  }
  return c3;
}

function drawGradient(x,y,w,h,stops){
  var c1,c2,inter,delta;

  //how long until we switch to a new target color;
  delta = h/max(stops.length-1,1);
  c1 = 0;
  c2 = 1;

  push();
    translate(x,y);
    for(var i = 0;i<h;i++){
      c1 = floor(i/delta);
      c2 = c1+1;
      inter = (i%delta) / delta;
      stroke(lerpColor(stops[c1],stops[c2],inter));
      line(0,i,w,i);
    }
  pop();
}

function mousePressed(){
}<commit_msg>added in-game date and cubehorse birthday glue bonus<commit_after>var horizon = 200;
var gameTime = 8;
var hourL = 60000;
var frameTime = 0;
var lastFrame = 0;
var drawFrame = false;
var lastHour = 0;
var sunrise,day,sunset,night,ground;
var orbAngle = 0;
var paused = false;
var lines;
var lastLine = 0;
var lineChance = 1/50;
var lineLife = 60;
var liveLines = Array();
var gameDate = new Date();
var BDAY_MONTH = 11;
var BDAY_DATE = 1;

function setup(){
  createCanvas(600,400);
  background(255);
  sunset = [color(0,150,200),color(224,153,255),color(255,224,224)];
  night = [color(0),color(0),color(128,0,64)];
  sunrise = [color(0,153,204),color(204,153,255),color(255,204,204)];
  day = [color(102,204,255),color(153,204,255),color(204,255,255)];
  ground = [color(200,255,200),color(64,255,64),color(64,255,64)];
  lines = ["...","CUBE GOOD HORSE?","CUBE GO FAST?","CUBE BAD","CUBE GET A PUSH?","CUBE NOT FAST","CUBE NO GO GOOD","OTHER HORSE PULL CUBE?","CUBE NEED A PUSH","CUBE WIN RACE?","OATS","NO OATS?","...","CUBE TRY CUBE'S BEST","CUBE TRY HARD THIS TIME","CUBE TRY HARDER","CUBE IN THE LEAD?","CUBE TIRED FROM TRYING"];
  textSize(16);
  textAlign(CENTER);
  drawSky();
  drawGround();
  drawCube(width/2-50,height-200,100,150,25,125);
  drawFence(height+15,120,60,8);
}

function draw(){
  if(!paused){
    if(millis()-lastHour > hourL){
	  lastHour = millis();
	  gameTime= (gameTime+1) % 24;
	  gameDate.setDate(gameDate.getDate() + 1);
    }
  }

  if(millis()-lastFrame > 33){
    lastFrame = millis();
	frameTime = (frameTime + 1) % 24;
    drawSky();
	drawGround();
	drawCube(width/2-50,height-200,100,150,25,125);
	drawFence(height+15,120,60,8);
	if(random()<=lineChance && lastLine>=30){
      var curLine = {};
	  curLine.age = lineLife;
	  curLine.x = random(-100,100);
	  curLine.y = random(0,-200);
	  curLine.line = lines[floor(random(lines.length))];
	  if (gameDate.getMonth()==BDAY_MONTH && gameDate.getDate()==BDAY_DATE){
	      curLine.line += " (+GLUE BONUS)"
	  }
	  liveLines.push(curLine);
	  lastLine = 0;
	}
	else if(liveLines.length>0){
	  for(var i = 0;i<liveLines.length;i++){
		  liveLines[i].age--;
		  if(liveLines[i].age>0){
		    drawLine(liveLines[i]);
		  }
	  }
	  while(liveLines.length>0 && liveLines[liveLines.length-1].age<0){
	    liveLines.pop();
	  }
	}
	lastLine++;
  }
}

function drawLine(aLine){
	push();
	  translate(width/2+aLine.x, height-50+aLine.y);
	  stroke(255,(aLine.age/lineLife)*255);
	  strokeWeight(2);
	  fill(0,0,200,(aLine.age/lineLife)*255);
	  rect(-(textWidth(aLine.line)/2)-5,0,textWidth(aLine.line)+10,32);
	  noStroke();
	  if(-100 - aLine.y >= 0){
	//    triangle(-aLine.x,-100 - aLine.y,-10,32,10,32);
	  }
	  else{
	 //   triangle(-aLine.x,-100 - aLine.y,-10,-2,10,-2);
	  }
	  fill(255,(aLine.age/lineLife)*255);
	  text(aLine.line,0,22);

	pop();
}

function drawCube(x,y,w1,w2,h1,h2){
	var sx = (w2-w1)/2;
	push();
	translate(x,y);
	noStroke();
	fill(240);
	quad(0,0,w1,0,w1+sx,h1,0-sx,h1);
	fill(128);
	rect(-sx,h1,w2,h2);
	pop();
}

function drawSky(){
  var curSky;
  if(gameTime<4 || gameTime>20){
    curSky = night;
  }
  else if(gameTime>8 && gameTime<16){
    curSky = day;
  }
  else if(gameTime<6){
    //sunrise
	var inter = ((gameTime-4)) + ((millis()-lastHour)/hourL);
	curSky = lerpGradient(night,sunrise,inter);
  }
  else if(gameTime<=8){
    //sunrise
	var inter = ((gameTime-6)) + ((millis()-lastHour)/hourL);
	curSky = lerpGradient(sunrise,day,inter);
  }
  else if(gameTime<18){
	var inter = ((gameTime-16)) + ((millis()-lastHour)/hourL);
	curSky = lerpGradient(day,sunset,inter);
    //sunset
  }
  else if(gameTime<=20){
	var inter = ((gameTime-18)) + ((millis()-lastHour)/hourL);
	curSky = lerpGradient(sunset,night,inter);
    //sunset
  }
  else{
  	curSky = night;
	console.log(gameTime);
  }
  drawGradient(0,0,width,horizon,curSky);
  var orbColor = (gameTime>=6 && gameTime<18) ? color(255,255,200) : color(255);
  var pastRise;
  if(gameTime>=6 && gameTime<18){
    pastRise = gameTime + ((millis()-lastHour)/hourL) - 5;
  }
  else{
    pastRise = (gameTime<6) ? gameTime + ((millis()-lastHour)/hourL) + 6 : gameTime + ((millis()-lastHour)/hourL) - 18;
  }

  push();
  orbAngle = map(pastRise,0,12,PI/8,-PI - (PI/8));
  fill(orbColor);
  stroke(color(255,32));
  strokeWeight(15 + (2*sin(frameTime/12*PI)));
  translate(width/2.0,horizon);
  rotate(orbAngle,0);
  translate((width/2)-100,0);
  ellipse(0,0,50,50);
  strokeWeight(1);
  pop();

}

function drawGround(){
  push();
  noStroke();

  if(gameTime>=8 && gameTime <=16){
 	 drawGradient(0,horizon,width,height-horizon,ground);
  }
  else if(gameTime<=4 || gameTime >=20){
	drawGradient(0,horizon,width,height-horizon,blendGradient(ground,color(100),0.75));
  }
  else if(gameTime<8){
	  var curTime = gameTime + ( (millis()-lastHour) / hourL) - 4;
	  drawGradient(0,horizon,width,height-horizon,blendGradient(ground,color(100),0.75 - (.75 * (curTime/4)) ));
  }
  else if(gameTime>16){
	  var curTime = gameTime + ( (millis()-lastHour) / hourL) - 16;
	  drawGradient(0,horizon,width,height-horizon,blendGradient(ground,color(100),(.75 * (curTime/4)) ));
  }
  pop();
  drawFence(horizon+5,30,10,2);
  drawTrack(horizon+10,20);
  drawFence(horizon+50,60,30,4);
  drawTrack(horizon+70,120);
}

function drawTrack(y,theight){
  push();
  translate(0,y);
  var tcolor = color(150,100,50);
  if(gameTime>=8 && gameTime <=16){
	  tcolor = color(150,100,50);
  }
  else if(gameTime<=4 || gameTime >=20){
	  tcolor = lerpColor(tcolor, color(100),0.75);
  }
  else if(gameTime<8){
	  var curTime = gameTime + ( (millis()-lastHour) / hourL) - 4;
	  tcolor = lerpColor(tcolor, color(100),0.75 - (0.75 * (curTime/4)));
  }
  else if(gameTime>16){
	  var curTime = gameTime + ( (millis()-lastHour) / hourL) - 16;
	  tcolor = lerpColor(tcolor, color(100),0.75 * (curTime/4));
  }

  fill(tcolor);
  noStroke();
  rect(0,0,width,theight);
  pop();
}

function drawFence(y,fdelta,fheight,fwidth){
  push();
   var fcolor = color(255,255,255);
   translate(0,y);
   noStroke();
   fill(fcolor);
   rect(0,-fheight,width,fwidth);
   for(var i = fdelta/2;i<width;i+=fdelta){
	 rect(i,0,fwidth/2,-fheight);
   }
  pop();
}

function blendGradient(c1,c2,inter){
  var c3 = Array();
  for( var i = 0;i<c1.length;i++){
    c3[i] = lerpColor(c1[i],c2,inter);
  }
  return c3;
}

function lerpGradient(c1,c2,inter){
  var c3 = Array();
  if(c1.length = c2.length){
    for(var i = 0;i<c1.length;i++){
		c3[i] = lerpColor(c1[i],c2[i],inter);
    }
  }
  else{

  }
  return c3;
}

function drawGradient(x,y,w,h,stops){
  var c1,c2,inter,delta;

  //how long until we switch to a new target color;
  delta = h/max(stops.length-1,1);
  c1 = 0;
  c2 = 1;

  push();
    translate(x,y);
    for(var i = 0;i<h;i++){
      c1 = floor(i/delta);
      c2 = c1+1;
      inter = (i%delta) / delta;
      stroke(lerpColor(stops[c1],stops[c2],inter));
      line(0,i,w,i);
    }
  pop();
}

function mousePressed(){
}
<|endoftext|>


<commit_before>/**
 * @TODO - NLS, define strings in extenal file
 * @TODO - proper file structure (e.g. .html goes in /templates)
 * @TODO - common strcuture
 * @TODO - comment / doc
 * @TODO - settings
 * @TODO - add debugging
 * @TODO - add dialog for errors
 * @TODO - allow for automatically building of FTP command syntax and prompt user for usename and password
 * @TODO - error check handling, don't allow to execut a director as an ftp script for example
 * @TODO - add config file for default / editable transfer types (e.g. ascii, binary, ...)
 * @TODO - separate into multiple pieces
 * @TODO - clean dialog UI
 * @TODO - what goes in app init, can some things be done earlier?
 * @TODO - hide context menu for ineligible ftp(maybe?) perhaps allow for the ability to ftp a directory???
 * @TODO - generalize add context menu, t/f for devider, menu id to append after
 * @TODO - key bindings in dialog for each ftp, (i.e. set Ctrl + Alt + 1 to ftp to ca11?)
 */
define(function (require, exports, module) {
  'use strict';

  //these map to folders in http://brackets.io/docs (e.g. see utils/NodeDomain)
  var NodeDomain = brackets.getModule('utils/NodeDomain');
  var ExtensionUtils = brackets.getModule('utils/ExtensionUtils');
  var osFtpDomain = new NodeDomain('ftp', ExtensionUtils.getModulePath(module, 'node/FtpDomain'));

  var CommandManager = brackets.getModule('command/CommandManager');
  var Menus = brackets.getModule('command/Menus');

  var AppInit = brackets.getModule('utils/AppInit');
  var File = brackets.getModule('file/FileUtils');

  var Project = brackets.getModule('project/ProjectManager');

  var PreferencesManager = brackets.getModule('preferences/PreferencesManager');

  var Dialog = brackets.getModule('widgets/Dialogs');

  var COMMAND_RUN_SCRIPT_LABEL            = 'Run as FTP Script';
  var COMMAND_RUN_SCRIPT_ID               = 'osftp_run_script';

  var COMMAND_NEW_SITE_LABEL            = 'New FTP Site...';
  var COMMAND_NEW_SITE_ID               = 'osftp_new_site';

  var PREF = 'osftp';
  var PREF_SESSION = 'session_'

  var osFtpPreferences = PreferencesManager.getExtensionPrefs(PREF);

  var EXECUTE = '_execute';

  /**
   * Initialization complete
   */
  AppInit.appReady(function () {

    //add context menu to run a script
    regCommandAndAddToContextMenus(COMMAND_RUN_SCRIPT_LABEL, COMMAND_RUN_SCRIPT_ID, handleRunScript, true);

    //add a context menu to create a site
    regCommandAndAddToContextMenus(COMMAND_NEW_SITE_LABEL, COMMAND_NEW_SITE_ID, handleNewSite, false);

  });

function regCommandAndAddToContextMenus(label, id, handler, addMenuDivider, afterId) {

  var contextMenu;

  var COMMAND_RUN_SCRIPT_LABEL = 'Run as FTP Script';
  var COMMAND_RUN_SCRIPT_ID = 'osftp_run_script';
  var ID_EXECUTE = id + EXECUTE;

  /**
   * Register the command
   */

  //register working set command
  CommandManager.register(label, ID_EXECUTE, handler);

  /**
   * Add to working set
   */

  //get menu item for working set
  contextMenu = Menus.getContextMenu(Menus.ContextMenuIds.WORKING_SET_CONTEXT_MENU);

  //add menu divider if requested
  if (addMenuDivider)
    contextMenu.addMenuDivider();

  //add menu item for working set
  addContextMenuItem(contextMenu, ID_EXECUTE, afterId);

  /**
   * Add to project set
   */

  //get menu item for project set
  contextMenu = Menus.getContextMenu(Menus.ContextMenuIds.PROJECT_MENU);

  //add menu divider if requested
  if (addMenuDivider)
    contextMenu.addMenuDivider();

  //add menu item for project set
  addContextMenuItem(contextMenu, ID_EXECUTE, afterId);

}

function addContextMenuItem(contextMenu, id, afterId) {

  //if we don't have an afterId
  if (!isSet(afterId)) {

    //add to menu with defaults
    contextMenu.addMenuItem(id);

  //else we were given an afterId
  } else {

    //orient to id we want to add after
    var AFTER_ID_EXECUTE = afterId + EXECUTE;

    //add to menu after afterId
    contextMenu.addMenuItem(
      id,               //new id
      null,             //no key binding
      Menus.AFTER,      //position
      AFTER_ID_EXECUTE  //after this id
    );
  }

}

function isSet(variable) {
  if (variable != 'undefined' && variable != null && variable != '')
    return true;
  return false;
}

function handleNewSite() {

  var escapeKey = 27;

  var buttons = [
    {
    className: Dialog.DIALOG_BTN_CLASS_LEFT,
    id: Dialog.DIALOG_BTN_CANCEL,
    text: 'CANCEL'
  },
    {
    className: Dialog.DIALOG_BTN_CLASS_PRIMARY,
    id: Dialog.DIALOG_BTN_OK,
    text: 'OK'
  }
  ];

  var inputDialog = Dialog.showModalDialog(null, //class
    'Add New Site', //title
    'Name:' +
    '
' +
    '<input id="input-name" type="text">' +
    '
' +
    'Host:' +
    '
' +
    '<input id="input-host" type="text">' +
    '
' +
    'Root:' +
    '
' +
    '<input id="input-root" type="text">' +
    '
' +
    '<form>' +
    'User:' +
    '
' +
    '<input id="input-user" type="text">' +
    '
' +
    'Password:' +
    '
' +
    '<input id="input-pass" type="password">' +
    '</form>',
    buttons,
    false); //disable auto dismiss

  //listen for escape key
  $(document).keyup(function (event) {

    if (event.which == escapeKey)

      //close if escape
      inputDialog.close();

  });

  //listen for cancel (modal doesnt have standard id= attribute, it's data-button-id
  $('button[data-button-id="' + Dialog.DIALOG_BTN_CANCEL + '"').click(function () {

    console.log('Dialog closed without save');

    inputDialog.close();

  });

  //listen for ok
  $('button[data-button-id="' + Dialog.DIALOG_BTN_OK + '"').click(function () {

    var name = $('#input-name').val();
    var host = $('#input-host').val();
    var root = $('#input-root').val();
    var user = $('#input-user').val();
    var pass = $('#input-pass').val();

    console.log('Dialog inputs are: ' +
      'name - ' + name + ', ' +
      'host - ' + host + ', ' +
      'root - ' + root + ', ' +
      'user - ' + user + ', ' +
      'pass - ' + pass
    );

    //@TODO, validate name is not already used

    //@TODO, save preferences

    var session = {
      name: name,
      host: host,
      root: root,
      user: user,
      pass: pass
    };

    osFtpPreferences.set(PREF_SESSION + name, session);

    //@TODO, allow for edit of previous site names

    var COMMAND_RUN_SITE_LABEL            = name;
    var COMMAND_RUN_SITE_ID               = 'osftp_run_' + name;

    //add a context menu to create a site
    regCommandAndAddToContextMenus(COMMAND_RUN_SITE_LABEL, COMMAND_RUN_SITE_ID, handleRunSite, false, COMMAND_NEW_SITE_ID);

    console.log('Dialog closed with save');

    inputDialog.close();

  });

  //listen for dialog done
  inputDialog.done(function () {

    console.log('Dialog modal is dismissed');

  });

}

  function handleRunSite() {

    //like 'C:' is two characters
    var WINDOWS_DRIVE_LETTER_OFFSET = 0;
    var WINDOWS_DRIVE_LETTER_LEN = 2;
    var WINDOWS_DRIVE_SEPERATOR_OFFSET = 1;
    var WINDOWS_DRIVE_SEPERATOR = ':';
    var WINDOWS_DRIVE_DIRECTORY_CHAR= '\\';

    var name = this.getName();

    var session = osFtpPreferences.get(PREF_SESSION + name);

    if (File.getDirectoryPath(Project.getSelectedItem().fullPath) == Project.getSelectedItem().fullPath) {

      console.log('Select FTP script file - not a directory');

    }

    else {

      var ftpStdin = '';

      ftpStdin += 'op ';
      ftpStdin += session.host;
      ftpStdin += '\n';

      ftpStdin += 'user\n';

      ftpStdin += session.user;
      ftpStdin += '\n';
      ftpStdin += session.pass;
      ftpStdin += '\n';

      ftpStdin += 'cd ';
      ftpStdin += session.root;
      ftpStdin += '\n';

      var directory = File.getDirectoryPath(Project.getSelectedItem().fullPath).split('/');

      if (directory[WINDOWS_DRIVE_LETTER_OFFSET].length == WINDOWS_DRIVE_LETTER_LEN) {

        if (directory[WINDOWS_DRIVE_LETTER_OFFSET].charAt(WINDOWS_DRIVE_SEPERATOR_OFFSET) == WINDOWS_DRIVE_SEPERATOR)
          directory[WINDOWS_DRIVE_LETTER_OFFSET] += WINDOWS_DRIVE_DIRECTORY_CHAR;

      }

      directory.forEach(function(dir) {

        if (dir != null && dir != '')     {

          ftpStdin += 'lcd ';
          ftpStdin += dir;
          ftpStdin += '\n';
        }

      });

      var extension = File.getFileExtension(Project.getSelectedItem().fullPath);

      if (extension == 'class')
        ftpStdin += 'binary\n';

      ftpStdin += 'put ';
      ftpStdin += File.getBaseName(Project.getSelectedItem().fullPath);
      ftpStdin += '\n';

      ftpStdin += 'quit \n';

      runFtpCommandStdin(File.getDirectoryPath(Project.getSelectedItem().fullPath) + '/node/' + session.host + '.txt', ftpStdin);
    }

  }

  function handleRunScript() {

    if (File.getDirectoryPath(Project.getSelectedItem().fullPath) == Project.getSelectedItem().fullPath)
      console.log('Select FTP script file - not a directory');
    else
      runFtpCommand(Project.getSelectedItem().fullPath);
  }

  /**
   * Function wrapper to invoke our domain function
   * @param {string} scriptFile File to use as an ftp script file
   */
  function runFtpCommand(scriptFile) {

    //invoke domain function
    osFtpDomain.exec('doFtp', scriptFile)

    //listen for done
    .done(
      function () {
        console.log('Completed: doFtp(' + scriptFile + ');');
      }
    )

    //listen for faile
    .fail(
      function () {
        console.error('Error in: doFtp(' + scriptFile + ');');
      }
    )
  }

  /**
   * Function wrapper to invoke our domain function
   * @param {string} scriptFile File to use as an ftp script file
   */
  function runFtpCommandStdin(file, data) {

    //invoke domain function
    osFtpDomain.exec('doFtpStdin', file, data)

    //listen for done
    .done(
      function () {
        console.log('Completed: doFtpStdin(' + file + ', ' + data + ');');
      }
    )

    //listen for faile
    .fail(
      function () {
        console.error('Error in: doFtpStdin(' + file + ', ' + data + ');');
      }
    )
  }

});
<commit_msg>Function cleanup and add doc<commit_after>/**
 * @TODO - Package and publish
 * @TODO - NLS, define strings in extenal file
 * @TODO - proper file structure (e.g. .html goes in /templates)
 * @TODO - common strcuture
 * @TODO - comment / doc
 * @TODO - error reporting
 * @TODO - settings
 * @TODO - add debugging
 * @TODO - add dialog for errors
 * @TODO - allow for automatically building of FTP command syntax and prompt user for usename and password
 * @TODO - error check handling, don't allow to execut a director as an ftp script for example
 * @TODO - add config file for default / editable transfer types (e.g. ascii, binary, ...)
 * @TODO - separate into multiple pieces
 * @TODO - clean dialog UI
 * @TODO - what goes in app init, can some things be done earlier?
 * @TODO - hide context menu for ineligible ftp(maybe?) perhaps allow for the ability to ftp a directory???
 * @TODO - generalize add context menu, t/f for devider, menu id to append after
 * @TODO - key bindings in dialog for each ftp, (i.e. set Ctrl + Alt + 1 to ftp to ca11?)
 */
define(function (require, exports, module) {
  'use strict';

  //these map to folders in http://brackets.io/docs (e.g. see utils/NodeDomain)
  var NodeDomain = brackets.getModule('utils/NodeDomain');
  var ExtensionUtils = brackets.getModule('utils/ExtensionUtils');
  var osFtpDomain = new NodeDomain('ftp', ExtensionUtils.getModulePath(module, 'node/FtpDomain'));

  var CommandManager = brackets.getModule('command/CommandManager');
  var Menus = brackets.getModule('command/Menus');

  var AppInit = brackets.getModule('utils/AppInit');
  var File = brackets.getModule('file/FileUtils');

  var Project = brackets.getModule('project/ProjectManager');

  var PreferencesManager = brackets.getModule('preferences/PreferencesManager');

  var Dialog = brackets.getModule('widgets/Dialogs');

  var COMMAND_RUN_SCRIPT_LABEL = 'Run as FTP Script';
  var COMMAND_RUN_SCRIPT_ID = 'osftp_run_script';

  var COMMAND_NEW_SITE_LABEL = 'New FTP Site...';
  var COMMAND_NEW_SITE_ID = 'osftp_new_site';

  var PREF = 'osftp';
  var PREF_SESSION = 'session_'

  var osFtpPreferences = PreferencesManager.getExtensionPrefs(PREF);

  var EXECUTE = '_execute';

  var NODE_DIRECTORY = '/node/';

  var FTP_SCRIPT_FILE_EXTENSION = '.txt';

  var FTP_BINARY_EXTENSIONS = ['class']

  /**
   * Initialization complete
   */
  AppInit.appReady(function () {

    //register command and add context menu to run a script
    regCommandAndAddToContextMenus(COMMAND_RUN_SCRIPT_LABEL, COMMAND_RUN_SCRIPT_ID, handleRunScript, true);

    //register command and add a context menu to create a site
    regCommandAndAddToContextMenus(COMMAND_NEW_SITE_LABEL, COMMAND_NEW_SITE_ID, handleNewSite, false);

  });

  /**
   * Register a command and add to the two context menus
   * @param {String}   label          Label to appear in the menu
   * @param {String}   id             Base id for this command, registered by appending EXECUTE constant
   * @param {Function} handler        Function to be called when the command is clicked
   * @param {Boolean}  addMenuDivider Indicator of whether or not a menu divider should be added
   * @param {String}   afterId        Previouslly added menu where we want to place the new item after
   */
  function regCommandAndAddToContextMenus(label, id, handler, addMenuDivider, afterId) {

    //function vars
    var contextMenu;
    var ID_EXECUTE = id + EXECUTE;

    /**
     * Register the command
     */

    //register working set command
    CommandManager.register(label, ID_EXECUTE, handler);

    /**
     * Add to working set
     */

    //get menu item for working set
    contextMenu = Menus.getContextMenu(Menus.ContextMenuIds.WORKING_SET_CONTEXT_MENU);

    //add menu divider if requested
    if (addMenuDivider)
      contextMenu.addMenuDivider();

    //add menu item for working set
    addContextMenuItem(contextMenu, ID_EXECUTE, afterId);

    /**
     * Add to project set
     */

    //get menu item for project set
    contextMenu = Menus.getContextMenu(Menus.ContextMenuIds.PROJECT_MENU);

    //add menu divider if requested
    if (addMenuDivider)
      contextMenu.addMenuDivider();

    //add menu item for project set
    addContextMenuItem(contextMenu, ID_EXECUTE, afterId);

  }

  /**
   * Add an item to a context menu
   * @param {Object} contextMenu Project or working set context menu object
   * @param {String} id          Identifier of command to be added
   * @param {String} afterId     Id where the menu item will be added after
   */
  function addContextMenuItem(contextMenu, id, afterId) {

    //if we don't have an afterId
    if (!isSet(afterId)) {

      //add to menu with defaults
      contextMenu.addMenuItem(id);

      //else we were given an afterId
    } else {

      //orient to id we want to add after
      var AFTER_ID_EXECUTE = afterId + EXECUTE;

      //add to menu after afterId
      contextMenu.addMenuItem(
        id, //new id
        null, //no key binding
        Menus.AFTER, //position
        AFTER_ID_EXECUTE //after this id
      );
    }

  }

  /**
   * Determines whether or not a variable exists, is null, or contains no data
   * @param   {String} variable Any variable type
   * @returns {Boolean}  Returns true if the variable is defined
   */
  function isSet(variable) {
    if (variable != 'undefined' && variable != null && variable != '')
      return true;
    return false;
  }

  function handleNewSite() {

    var escapeKey = 27;

    var buttons = [
      {
        className: Dialog.DIALOG_BTN_CLASS_LEFT,
        id: Dialog.DIALOG_BTN_CANCEL,
        text: 'CANCEL'
  },
      {
        className: Dialog.DIALOG_BTN_CLASS_PRIMARY,
        id: Dialog.DIALOG_BTN_OK,
        text: 'OK'
  }
  ];

    var inputDialog = Dialog.showModalDialog(null, //class
      'Add New Site', //title
      'Name:' +
      '
' +
      '<input id="input-name" type="text">' +
      '
' +
      'Host:' +
      '
' +
      '<input id="input-host" type="text">' +
      '
' +
      'Root:' +
      '
' +
      '<input id="input-root" type="text">' +
      '
' +
      '<form>' +
      'User:' +
      '
' +
      '<input id="input-user" type="text">' +
      '
' +
      'Password:' +
      '
' +
      '<input id="input-pass" type="password">' +
      '</form>',
      buttons,
      false); //disable auto dismiss

    //listen for escape key
    $(document).keyup(function (event) {

      if (event.which == escapeKey)

      //close if escape
        inputDialog.close();

    });

    //listen for cancel (modal doesnt have standard id= attribute, it's data-button-id
    $('button[data-button-id="' + Dialog.DIALOG_BTN_CANCEL + '"').click(function () {

      console.log('Dialog closed without save');

      inputDialog.close();

    });

    //listen for ok
    $('button[data-button-id="' + Dialog.DIALOG_BTN_OK + '"').click(function () {

      var name = $('#input-name').val();
      var host = $('#input-host').val();
      var root = $('#input-root').val();
      var user = $('#input-user').val();
      var pass = $('#input-pass').val();

      console.log('Dialog inputs are: ' +
        'name - ' + name + ', ' +
        'host - ' + host + ', ' +
        'root - ' + root + ', ' +
        'user - ' + user + ', ' +
        'pass - ' + pass
      );

      //@TODO, validate name is not already used

      //@TODO, save preferences

      var session = {
        name: name,
        host: host,
        root: root,
        user: user,
        pass: pass
      };

      osFtpPreferences.set(PREF_SESSION + name, session);

      //@TODO, allow for edit of previous site names

      var COMMAND_RUN_SITE_LABEL = name;
      var COMMAND_RUN_SITE_ID = 'osftp_run_' + name;

      //add a context menu to create a site
      regCommandAndAddToContextMenus(COMMAND_RUN_SITE_LABEL, COMMAND_RUN_SITE_ID, handleRunSite, false, COMMAND_NEW_SITE_ID);

      console.log('Dialog closed with save');

      inputDialog.close();

    });

    //listen for dialog done
    inputDialog.done(function () {

      console.log('Dialog modal is dismissed');

    });

  }

  /**
   * Handler for executing an added site
   */
  function handleRunSite() {

    //get the command name
    var name = this.getName();

    //get the session object preference associated with this command name
    var session = osFtpPreferences.get(PREF_SESSION + name);

    //get the full path to the item that was selected
    var itemFullPath = Project.getSelectedItem().fullPath;

    //determine if the file choosen is a directory or an individual file
    if (File.getDirectoryPath(itemFullPath) == itemFullPath) {

      //@TODO all for processing and ftp'ing an entire directory
      //for now, log message if an attempt is made to ftp a directory
      console.log('Select FTP script file - not a directory');

    //an individual file was choose, build a script string and invoke node to run FTP and this script
    } else {

      //build our ftp script
      var ftpScript = buildFtpScriptForFile(itemFullPath, session);

      //select the file name we want to create
      var scriptFileName = File.getDirectoryPath(itemFullPath) + NODE_DIRECTORY + session.host + FTP_SCRIPT_FILE_EXTENSION

      //invoke node js to build and run our ftp script file
      runFtpCommandStdin(scriptFileName, ftpScript);

    }

  }

  function buildFtpScriptForFile(itemFullPath, session) {

    //like 'C:' is two characters
    var WINDOWS_DRIVE_LETTER_OFFSET = 0;
    var WINDOWS_DRIVE_LETTER_LEN = 2;
    var WINDOWS_DRIVE_SEPERATOR_OFFSET = 1;
    var WINDOWS_DRIVE_SEPERATOR = ':';
    var WINDOWS_DRIVE_DIRECTORY_CHAR = '\\';

    //initialize script
    var ftpStdin = '';

    //open the host
    ftpStdin += 'op ';
    ftpStdin += session.host;
    ftpStdin += '\n';

    //we no that auto-login will be disabled so specify 'user'
    ftpStdin += 'user\n';

    //provide user name and password to script file
    ftpStdin += session.user;
    ftpStdin += '\n';
    ftpStdin += session.pass;
    ftpStdin += '\n';

    //switch to requested root directory
    ftpStdin += 'cd ';
    ftpStdin += session.root;
    ftpStdin += '\n';

    //directory path with always have forward slash seperators, so parse each directory
    var directory = File.getDirectoryPath(itemFullPath).split('/');

    //if the first directory is a windows type drive
    if (directory[WINDOWS_DRIVE_LETTER_OFFSET].length == WINDOWS_DRIVE_LETTER_LEN) {

      //if the second character after the drive letter is a colon, this should be windows directories
      if (directory[WINDOWS_DRIVE_LETTER_OFFSET].charAt(WINDOWS_DRIVE_SEPERATOR_OFFSET) == WINDOWS_DRIVE_SEPERATOR)

        //append a backlash to the drive letter and colon
        directory[WINDOWS_DRIVE_LETTER_OFFSET] += WINDOWS_DRIVE_DIRECTORY_CHAR;

    }

    //iterate through directories
    directory.forEach(function (dir) {

      //while the directory appears valid
      if (isSet(dir)) {

        //alter local directory to the file we are ftp'ing
        ftpStdin += 'lcd ';
        ftpStdin += dir;
        ftpStdin += '\n';
      }

    });

    var extension = File.getFileExtension(itemFullPath);

    if (extension == 'class')
      ftpStdin += 'binary\n';

    ftpStdin += 'put ';
    ftpStdin += File.getBaseName(itemFullPath);
    ftpStdin += '\n';

    ftpStdin += 'quit \n';

    return ftpStdin;

  }

  /**
   * Check known extensions to see whether ftp should be done in binary
   * @param   {String} extension extension (without '.') to validate against known extensions
   * @returns {Boolean}  Returns true if this extension should be ftp'ed as binary
   */
  function ftpAsBinary(extension) {

    //if the extension is in our predefined list of things to ftp, return true
    for (var i = 0; i < FTP_BINARY_EXTENSIONS.length; i++)
      if (FTP_BINARY_EXTENSIONS[i] == extension)
        return true

    //no need to ftp this as binary
    return false;

  }

  /**
   * Function driven when a file is called to be executed as an FTP script
   */
  function handleRunScript() {

    //get the full path to the item that was selected
    var itemFullPath = Project.getSelectedItem().fullPath;

    //determine if the file choosen is a directory or an individual file
    if (File.getDirectoryPath(itemFullPath) == itemFullPath) {

      //@TODO all for processing and ftp'ing an entire directory
      //for now, log message if an attempt is made to ftp a directory
      console.log('Select FTP script file - not a directory');

    //an individual file was choose, build a script string and invoke node to run FTP and this script
    } else {

      //invoke node js to run our ftp script file
      runFtpCommand(Project.getSelectedItem().fullPath);

    }
  }

  /**
   * Function wrapper to invoke our domain function
   * @param {string} scriptFile File to use as an ftp script file
   */
  function runFtpCommand(scriptFile) {

    //invoke domain function
    osFtpDomain.exec('doFtp', scriptFile)

    //listen for done
    .done(
      function () {
        console.log('Completed: doFtp(' + scriptFile + ');');
      }
    )

    //listen for faile
    .fail(
      function () {
        console.error('Error in: doFtp(' + scriptFile + ');');
      }
    )
  }

  /**
   * Function wrapper to invoke our domain function
   * @param {string} scriptFile File to use as an ftp script file
   */
  function runFtpCommandStdin(file, data) {

    //invoke domain function
    osFtpDomain.exec('doFtpStdin', file, data)

    //listen for done
    .done(
      function () {
        console.log('Completed: doFtpStdin(' + file + ', ' + data + ');');
      }
    )

    //listen for faile
    .fail(
      function () {
        console.error('Error in: doFtpStdin(' + file + ', ' + data + ');');
      }
    )
  }

});
<|endoftext|>


<commit_before>var app = require('app'),
    BrowserWindow = require('browser-window'),
    Menu = require('menu'),
    noble = require('noble'),
    metadata = require('./metadata.js'),
    urldecode = require('./urldecode.js'),
    mainWindow = null,
    counter = 0;

// Quit when all windows are closed.
app.on('window-all-closed', function() {
  app.quit();
});

noble.on('scanStart', function() {
  console.log('Scan started...');
  mainWindow.webContents.send('status', 'Scanning for Physical Web beacons. Press ⌘ + T to stop.', true);
  counter = 0;
  app.dock.setBadge('');
});

noble.on('scanStop', function() {
  console.log('Scan stopped...');
  mainWindow.webContents.send('status', 'Scanning stopped. Press ⌘ + S to restart scan.');
});

noble.on('discover', function(peripheral) {
  var serviceData = peripheral.advertisement.serviceData;
  if (serviceData && serviceData.length) {
    var objects = [];
    for (var i in serviceData) {

      // check if Eddystone-URL
      if (serviceData[i].data.toString('hex').substr(0,2) === '10') {
        var url = urldecode(serviceData[i].data.toString('hex'));
        objects.push({url: url});
      }
    }
    if (objects.length) {
      metadata(objects, function(message) {
        mainWindow.webContents.send('url', message);
        if (!mainWindow.isFocused()) {
          counter ++;
          app.dock.setBadge('' + counter + '');
        }
      });
    }
  }
});

app.on('ready', function() {

  var menuTemplate = [
    {
      label: 'Physical Web Scan',
      submenu: [
        {
          label: 'Scan for beacons',
          accelerator: 'Command+S',
          click: function() {
            if (noble.state === 'poweredOn') {
              noble.startScanning(['feaa']);
            } else {
              mainWindow.webContents.send('status', 'Bluetooth not ready or turned on. Press ⌘ + S to retry.');
            }
          }
        },
        {
          label: 'Stop scanning',
          accelerator: 'Command+T',
          click: function() {
            noble.stopScanning();
          }
        },
        {
          label: 'Quit',
          accelerator: 'Command+Q',
          click: function() { app.quit(); }
        }
      ]
    }
  ];

  menu = Menu.buildFromTemplate(menuTemplate);
  Menu.setApplicationMenu(menu);

  mainWindow = new BrowserWindow({width: 480, height: 600});

  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  mainWindow.on('closed', function() {
    mainWindow = null;
  });

  mainWindow.webContents.on('did-finish-load', function() {
    console.log(noble.state);
    if (noble.state === 'poweredOn') {
      noble.startScanning(['feaa']);
    }

  });

});

app.on('browser-window-focus', function() {
  counter = 0;
  app.dock.setBadge('');
});<commit_msg>use basic es2015 syntax<commit_after>'use strict';
let app = require('app'),
  BrowserWindow = require('browser-window'),
  Menu = require('menu'),
  noble = require('noble'),
  metadata = require('./metadata.js'),
  urldecode = require('./urldecode.js'),
  mainWindow = null,
  counter = 0;

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  app.quit();
});

noble.on('scanStart', () => {
  console.log('Scan started...');
  mainWindow.webContents.send('status', 'Scanning for Physical Web beacons. Press ⌘ + T to stop.', true);
  counter = 0;
  app.dock.setBadge('');
});

noble.on('scanStop', () => {
  console.log('Scan stopped...');
  mainWindow.webContents.send('status', 'Scanning stopped. Press ⌘ + S to restart scan.');
});

noble.on('discover', peripheral => {
  let serviceData = peripheral.advertisement.serviceData;
  if (serviceData && serviceData.length) {
    let objects = [];
    for (let i in serviceData) {
      // check if Eddystone-URL
      if (serviceData[i].data.toString('hex').substr(0, 2) === '10') {
        let url = urldecode(serviceData[i].data.toString('hex'));
        objects.push({'url': url});
      }
    }
    if (objects.length) {
      metadata(objects, message => {
        mainWindow.webContents.send('url', message);
        if (!mainWindow.isFocused()) {
          counter ++;
          app.dock.setBadge('' + counter + '');
        }
      });
    }
  }
});

app.on('ready', () => {
  const menuTemplate = [
    {
      'label': 'Physical Web Scan',
      'submenu': [
        {
          'label': 'Scan for beacons',
          'accelerator': 'Command+S',
          'click': () => {
            if (noble.state === 'poweredOn') {
              noble.startScanning(['feaa']);
            } else {
              mainWindow.webContents.send('status', 'Bluetooth not ready or turned on. Press ⌘ + S to retry.');
            }
          }
        },
        {
          'label': 'Stop scanning',
          'accelerator': 'Command+T',
          'click': () => {
            noble.stopScanning();
          }
        },
        {
          'label': 'Quit',
          'accelerator': 'Command+Q',
          'click': () => { app.quit(); }
        }
      ]
    }
  ];

  let menu = Menu.buildFromTemplate(menuTemplate);
  Menu.setApplicationMenu(menu);

  mainWindow = new BrowserWindow({'width': 480, 'height': 600});

  mainWindow.loadURL('file://' + __dirname + '/index.html');

  mainWindow.on('closed', () => {
    mainWindow = null;
  });

  mainWindow.webContents.on('did-finish-load', () => {
    console.log(noble.state);
    if (noble.state === 'poweredOn') {
      noble.startScanning(['feaa']);
    }
  });
});

app.on('browser-window-focus', () => {
  counter = 0;
  app.dock.setBadge('');
});
<|endoftext|>


<commit_before>if (window.location.host != "www.probux.com") {
alert("You can only use ProAlert on probux.com... (DUH)")}

var doAlert = false
var timeOut = 60
var oldTitle = document.title
var flashVar = true

var div = document.createElement("div");
div.style.width = screen.availWidth + "px";
div.style.height = "21px";
div.style.background = "#b30000";
div.style.color = "#ffffff";
div.style.textAlign = "center";
div.style.fontSize = "15px";
div.style.paddingTop = "5px"
div.style.position = "relative";
div.style.borderBottom = "3px solid #960000";
div.id = "ProAlertbar"
div.style.cursor = "pointer";
div.innerHTML = "Loading ProAlert code...";

document.getElementById("header-menu").insertBefore(div, document.getElementById("header-menu").childNodes[0]);

function getName() {
getHttp(true)
var xmlhttp = new XMLHttpRequest()
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
xmlhttp.responseText.indexOf("My Account Details")
var done = false
var num = 0
while (done == false) {
var num = num + 1
if (xmlhttp.responseText.slice(xmlhttp.responseText.indexOf("My Account Details") + 21, xmlhttp.responseText.indexOf("My Account Details") + 21 + num).indexOf("<") != -1) {
var num = num - 1
var done = true}}
div.onclick = function () {openOptions()};
div.innerHTML = "Welcome back " + xmlhttp.responseText.slice(xmlhttp.responseText.indexOf("My Account Details") + 21, xmlhttp.responseText.indexOf("My Account Details") + 21 + num) + "! The ProAlert forum topic has been shutdown. You guys will be the only ones to have ProAlert for now."
timeSet = setTimeout(function () {time(timeOut + 1)}, 4500)}}
xmlhttp.open("GET", "http://www.probux.com/account.php", true);
xmlhttp.send()}

function openOptions() {
if (typeof timeSet !== "undefined") {
clearTimeout(timeSet)}
div.style.height = "82px"
if (doAlert == true) {
var temp = "checked='checked'"}
else {var temp = ""}
div.innerHTML = "<form action='' method='post' onsubmit='return closeOptions();'>Change your tab to Probux when new ads are available. <input type='checkbox' id='checkform' " + temp + " >
Refresh data after <input type='text' id='textform' value='" + timeOut + "' maxlength='3' style='width: 25px;text-align: center;height:17px;border:none;box-shadow:none;'> seconds
github <input type='submit' value='Save & close' style='margin-top:9px;border:none;box-shadow:none;height:27px;width:auto;'> forum</form>"
div.onclick = ""
div.style.cursor = "default";}

function cancelOptions() {
div.style.height = "21px";
div.style.cursor = "pointer";
div.onclick = function () {openOptions()};
time(timeOut + 1)
return false;}

function closeOptions() {
if (document.getElementById("textform").value == "") {
error("That text field can't be empty!")
return false;}
if (parseInt(document.getElementById("textform").value) < 20) {
error("The minimum is 20 seconds!")
return false;}
if (parseInt(document.getElementById("textform").value) > 600) {
error("The maximum is 10 minutes!")
return false;}
if (parseInt(document.getElementById("textform").value) == "NaN") {
error("You can only enter numbers!")
return false;}
window.doAlert = document.getElementById('checkform').checked
window.timeOut = parseInt(document.getElementById("textform").value)
div.innerHTML = "Your settings have been saved!"
div.style.height = "21px";
div.onclick = function () {openOptions()};
div.style.cursor = "pointer";
timeSet = setTimeout(function () {time(window.timeOut + 1)}, 3000)
return false;}

function error(e) {
div.innerHTML = "Error: " + e
setTimeout(function () {openOptions()}, 3000);
div.style.height = "21px";
div.onclick = function () {openOptions()};}

function getHttp(g) {
var xmlhttp = new XMLHttpRequest()
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var purple = getNumbers(xmlhttp.responseText, "ballon-purple", 33)
var green = getNumbers(xmlhttp.responseText, "ballon-green", 32)
var orange = getNumbers(xmlhttp.responseText, "ballon-orange", 33)
if (purple != 0 || green != 0 || orange != 0) {
document.title = purple + " " + green + " " + orange + " - " + oldTitle;
if (g == false) {
if (doAlert == true) {
if (typeof timeSet !== "undefined") {
clearTimeout(timeSet)}
div.style.height = "30px";
div.innerHTML = "New ads have been detected and ProAlert is now disabled <button onclick='div.style.height = '21px';time(timeOut + 1)' style='margin-top:0px;border:none;box-shadow:none;height:27px;width:100px;'>Reanable</button>"
alert("New ads have been detected! \n" + purple + " daily, " + green + " extra and " + orange + " fixed ads have been found.");}
else {
flash(purple, green, orange)
time(timeOut + 1)}}}
else {
if (g == false) {
time(timeOut + 1)}
document.title = "0 0 0 - " + oldTitle;}}}
xmlhttp.open("GET", "http://www.probux.com/viewads.php", true);
xmlhttp.send();}

function flash(p, g, o) {
if (window.flashVar == true) {
document.title = p + " " + g + " " + o + " ! " + oldTitle;
window.flashVar = false
doFlash = setTimeout(function () {flash(p, g, o)}, 300)}
else {
document.title = p + " " + g + " " + o + " - " + oldTitle;
window.flashVar = true
doFlash = setTimeout(function () {flash(p, g, o)}, 600)}}

function getNumbers(response, id, space) {
if (response.indexOf(id) != -1) {
var temp = response.slice(response.indexOf(id) + space, response.indexOf(id) + space + 2)
if (temp.indexOf("<") != -1) {
var temp = response.slice(response.indexOf(id) + space, response.indexOf(id) + space + 1)}}
else {
var temp = "0"}
return temp}

function time(tempTime) {
var tempTime = tempTime - 1;
if (tempTime == -1) {
if (typeof doFlash !== "undefined") {
clearTimeout(doFlash);}
div.innerHTML = "Refreshing now."
document.title = "? ? ? - " + oldTitle
getHttp(false)} else {
div.innerHTML = "Next refresh in " + tempTime + " seconds."
timeSet = setTimeout(function () {
time(tempTime)}, 1000);}}

div.innerHTML = "Preparing ProAlert...";
getName()
<commit_msg>Final v1.1 main.js<commit_after>if (window.location.host != "www.probux.com") {
alert("You can only use ProAlert on probux.com... (DUH)")}

var doAlert = false
var timeOut = 60
var oldTitle = document.title
var flashVar = true

var div = document.createElement("div");
div.style.width = screen.availWidth + "px";
div.style.height = "21px";
div.style.background = "#b30000";
div.style.color = "#ffffff";
div.style.textAlign = "center";
div.style.fontSize = "15px";
div.style.paddingTop = "5px"
div.style.position = "relative";
div.style.borderBottom = "3px solid #960000";
div.id = "ProAlertbar"
div.style.cursor = "pointer";
div.innerHTML = "Loading ProAlert code...";

document.getElementById("header-menu").insertBefore(div, document.getElementById("header-menu").childNodes[0]);

function getName() {
getHttp(true)
var xmlhttp = new XMLHttpRequest()
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
xmlhttp.responseText.indexOf("My Account Details")
var done = false
var num = 0
while (done == false) {
var num = num + 1
if (xmlhttp.responseText.slice(xmlhttp.responseText.indexOf("My Account Details") + 21, xmlhttp.responseText.indexOf("My Account Details") + 21 + num).indexOf("<") != -1) {
var num = num - 1
var done = true}}
div.onclick = function () {openOptions()};
div.innerHTML = "Welcome back " + xmlhttp.responseText.slice(xmlhttp.responseText.indexOf("My Account Details") + 21, xmlhttp.responseText.indexOf("My Account Details") + 21 + num) + "! The ProAlert forum topic has been shutdown. You guys will be the only ones to have ProAlert for now."
timeSet = setTimeout(function () {time(timeOut + 1)}, 6000)}}
xmlhttp.open("GET", "http://www.probux.com/account.php", true);
xmlhttp.send()}

function openOptions() {
if (typeof timeSet !== "undefined") {
clearTimeout(timeSet)}
div.style.height = "82px"
if (doAlert == true) {
var temp = "checked='checked'"}
else {var temp = ""}
div.innerHTML = "<form action='' method='post' onsubmit='return closeOptions();'>Change your tab to Probux when new ads are available. <input type='checkbox' id='checkform' " + temp + " >
Refresh data after <input type='text' id='textform' value='" + timeOut + "' maxlength='3' style='width: 25px;text-align: center;height:17px;border:none;box-shadow:none;'> seconds
github <input type='submit' value='Save & close' style='margin-top:9px;border:none;box-shadow:none;height:27px;width:auto;'> forum</form>"
div.onclick = ""
div.style.cursor = "default";}

function cancelOptions() {
div.style.height = "21px";
div.style.cursor = "pointer";
div.onclick = function () {openOptions()};
time(timeOut + 1)
return false;}

function closeOptions() {
if (document.getElementById("textform").value == "") {
error("That text field can't be empty!")
return false;}
if (parseInt(document.getElementById("textform").value) < 20) {
error("The minimum is 20 seconds!")
return false;}
if (parseInt(document.getElementById("textform").value) > 600) {
error("The maximum is 10 minutes!")
return false;}
if (parseInt(document.getElementById("textform").value) == "NaN") {
error("You can only enter numbers!")
return false;}
window.doAlert = document.getElementById('checkform').checked
window.timeOut = parseInt(document.getElementById("textform").value)
div.innerHTML = "Your settings have been saved!"
div.style.height = "21px";
div.onclick = function () {openOptions()};
div.style.cursor = "pointer";
timeSet = setTimeout(function () {time(window.timeOut + 1)}, 3000)
return false;}

function error(e) {
div.innerHTML = "Error: " + e
setTimeout(function () {openOptions()}, 3000);
div.style.height = "21px";
div.onclick = function () {openOptions()};}

function getHttp(g) {
var xmlhttp = new XMLHttpRequest()
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var purple = getNumbers(xmlhttp.responseText, "ballon-purple", 33)
var green = getNumbers(xmlhttp.responseText, "ballon-green", 32)
var orange = getNumbers(xmlhttp.responseText, "ballon-orange", 33)
if (purple != 0 || green != 0 || orange != 0) {
document.title = purple + " " + green + " " + orange + " - " + oldTitle;
if (g == false) {
if (doAlert == true) {
if (typeof timeSet !== "undefined") {
clearTimeout(timeSet)}
div.style.height = "30px";
div.innerHTML = "New ads have been detected and ProAlert is now disabled <button onclick='div.style.height = '21px';time(timeOut + 1)' style='margin-top:0px;border:none;box-shadow:none;height:27px;width:100px;'>Reanable</button>"
alert("New ads have been detected! \n" + purple + " daily, " + green + " extra and " + orange + " fixed ads have been found.");}
else {
flash(purple, green, orange)
time(timeOut + 1)}}}
else {
if (g == false) {
time(timeOut + 1)}
document.title = "0 0 0 - " + oldTitle;}}}
xmlhttp.open("GET", "http://www.probux.com/viewads.php", true);
xmlhttp.send();}

function flash(p, g, o) {
if (window.flashVar == true) {
document.title = p + " " + g + " " + o + " ! " + oldTitle;
window.flashVar = false
doFlash = setTimeout(function () {flash(p, g, o)}, 300)}
else {
document.title = p + " " + g + " " + o + " - " + oldTitle;
window.flashVar = true
doFlash = setTimeout(function () {flash(p, g, o)}, 600)}}

function getNumbers(response, id, space) {
if (response.indexOf(id) != -1) {
var temp = response.slice(response.indexOf(id) + space, response.indexOf(id) + space + 2)
if (temp.indexOf("<") != -1) {
var temp = response.slice(response.indexOf(id) + space, response.indexOf(id) + space + 1)}}
else {
var temp = "0"}
return temp}

function time(tempTime) {
var tempTime = tempTime - 1;
if (tempTime == -1) {
if (typeof doFlash !== "undefined") {
clearTimeout(doFlash);}
div.innerHTML = "Refreshing now."
document.title = "? ? ? - " + oldTitle
getHttp(false)} else {
div.innerHTML = "Next refresh in " + tempTime + " seconds."
timeSet = setTimeout(function () {
time(tempTime)}, 1000);}}

div.innerHTML = "Preparing ProAlert...";
getName()
<|endoftext|>


<commit_before>var GRAVITY = [0, 10]; //m/s^2
var SCALE = 1; // pixels/m
var PI = 3.14159265359;
var SCREEN_WIDTH = 1024;
var SCREEN_HEIGHT = 760;
var COLLISION_TYPES = {
    CIRCLE: 'circle' //has radius
};

//google fonts
WebFontConfig = {
    google: {
        families: ['Snippet', 'Podkova:700']
    },

    active: function () {
        // do something
        //init();
    }

};
(function () {
    var wf = document.createElement('script');
    wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
        '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
    wf.type = 'text/javascript';
    wf.async = 'true';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(wf, s);
})();

//game engine stuff

function makePlayer() {
    // create a new Sprite using the texture
    var player = new PIXI.Container();

    var body = new PIXI.Text("COPTER", {
        font: "bold 20px Podkova",
        fill: "#cc00ff",
        align: "center",
        stroke: "#FFFFFF",
        strokeThickness: 6
    });

    var leftRotor = new PIXI.Text("QWOP", {
        font: "bold 20px Podkova",
        fill: "#000000",
        align: "center",
        stroke: "#FFFFFF",
        strokeThickness: 6
    });
    var rightRotor = new PIXI.Text("QWOP", {
        font: "bold 20px Podkova",
        fill: "#000000",
        align: "center",
        stroke: "#FFFFFF",
        strokeThickness: 6
    });

    body.anchor.x = 0.5;
    body.anchor.y = 1;
    leftRotor.anchor.x = 0.5;
    leftRotor.anchor.y = 0.5;
    rightRotor.anchor.x = 0.5;
    rightRotor.anchor.y = 0.5;
    body.x = 0;
    body.y = 0;
    leftRotor.x = -35;
    leftRotor.y = -25;
    rightRotor.x = 35;
    rightRotor.y = -25;

    player.addChild(body);
    player.addChild(leftRotor);
    player.addChild(rightRotor);

    // set position
    player.x = 200;
    player.y = 150;

    //makes the object be effected by physics
    player.physics = {
        mass: 1,
        appliedForce: [0, 0],
        gravity: true,
        speed: [0, 0]
    };

    //gives custom animation/render
    player.animate = function (frameTime) {
        //animate
        leftRotor.rotation += 0.2;
        rightRotor.rotation -= 0.2;

        renderer.render(player);
    };

    //collision attributes
    player.collision = {
        type: COLLISION_TYPES.CIRCLE,
        radius: body.width / 2
    };

    return player;
}

function makePoint(x, y) {
    var point = new PIXI.Text("POI\nNT", {
        font: "bold 20px Podkova",
        fill: "#ff0000",
        align: "center",
        stroke: "#FFFFFF",
        strokeThickness: 6
    });
    point.anchor.x = point.anchor.y = 0.5;
    point.x = x;
    point.y = y;

    point.collision = {
        type: COLLISION_TYPES.CIRCLE,
        radius: point.width / 2,
        onCollision: function (other) {
            if (other == player) {
                score++;
                removeFromStage.push(point);
            }
        }
    };

    return point;
}

function makeKeyboardTrigger(keyCode) {
    var key = {};
    key.code = keyCode;
    key.isDown = false;
    key.isUp = true;
    key.press = undefined;
    key.release = undefined;
    //The `downHandler`
    key.downHandler = function (event) {
        if (event.keyCode === key.code) {
            if (key.isUp && key.press) key.press();
            key.isDown = true;
            key.isUp = false;
        }
        event.preventDefault();
    };

    //The `upHandler`
    key.upHandler = function (event) {
        if (event.keyCode === key.code) {
            if (key.isDown && key.release) key.release();
            key.isDown = false;
            key.isUp = true;
        }
        event.preventDefault();
    };

    //Attach event listeners
    window.addEventListener(
        "keydown", key.downHandler.bind(key), false
    );
    window.addEventListener(
        "keyup", key.upHandler.bind(key), false
    );
    return key;
}

function add2D(a, b) {
    return [a[0] + b[0], a[1] + b[1]];
}

function mul2D(v, s) {
    return [v[0] * s, v[1] * s];
}

function size2D(v) {
    return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
}

function div2D(v, s) {
    return [v[0] / s, v[1] / s];
}

function init2D(rotation, size) {
    return [Math.sin(rotation) * size, Math.cos(rotation) * size];
}

function mirrorHorizontal2D(v) {
    return [v[0], v[1] * -1];
}

function mirrorVertical2D(v) {
    return [v[0] * -1, v[1]];
}

function doPhysics(object, time) {
    var acceleration = div2D(object.physics.appliedForce, object.physics.mass);

    if (object.physics.gravity) {
        acceleration = add2D(acceleration, GRAVITY);
    }
    object.physics.speed = add2D(object.physics.speed, mul2D(acceleration, time));

    object.physics.appliedForce = [0, 0];
    //F = m a
    //a = F/m
    //v = t a

    object.x += object.physics.speed[0] * SCALE;
    object.y += object.physics.speed[1] * SCALE;
}

function doCollision(first, second) {
    var didCollide = false;

    //currently we only have circular bounding boxes
    var xDiff = first.x - second.x;
    var yDiff = first.y - second.y;
    var squareDistance = xDiff * xDiff + yDiff * yDiff;
    var radiusSum = first.collision.radius + second.collision.radius;
    if (squareDistance <= radiusSum * radiusSum) {
        didCollide = true;
    }

    if (didCollide) {
        if (first.collision.onCollision) {
            first.collision.onCollision(second);
        }
        if (second.collision.onCollision) {
            second.collision.onCollision(first);
        }
    }
}

var ACTION_UP_FORCE = -100;
var ACTION_UP_ROTATION = 0.15;
var ACTION_SIDE_ROTATION = 0.3; //this is radians btw, so 2*PI RAD == 360 DEG

var leftUpAction = function () {
    player.rotation += ACTION_UP_ROTATION;
    player.physics.appliedForce = add2D(player.physics.appliedForce, init2D(-player.rotation, ACTION_UP_FORCE));
};
var rightUpAction = function () {
    player.rotation -= ACTION_UP_ROTATION;
    player.physics.appliedForce = add2D(player.physics.appliedForce, init2D(-player.rotation, ACTION_UP_FORCE));
};
var leftAction = function () {
    player.rotation += ACTION_SIDE_ROTATION;
};
var rightAction = function () {
    player.rotation -= ACTION_SIDE_ROTATION;
};

function addActions() {
//key codes http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000520.html
    var leftKey = makeKeyboardTrigger(81); //q
    var leftUpKey = makeKeyboardTrigger(87); //w
    var rightUpKey = makeKeyboardTrigger(79); //o
    var rightKey = makeKeyboardTrigger(80); //p
    var altLeftKey = makeKeyboardTrigger(222); //'
    var altLeftUpKey = makeKeyboardTrigger(188); //,
    var altRightUpKey = makeKeyboardTrigger(82); //r
    var altRightKey = makeKeyboardTrigger(76); //l

    leftKey.press = leftAction;
    altLeftKey.press = leftAction;
    leftUpKey.press = leftUpAction;
    altLeftUpKey.press = leftUpAction;
    rightUpKey.press = rightUpAction;
    altRightUpKey.press = rightUpAction;
    rightKey.press = rightAction;
    altRightKey.press = rightAction;
}

//TODO get this executed after the fonts are loaded
//gameplay
var score = 0;

//create world
var renderer = PIXI.autoDetectRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, {backgroundColor: 0x1099bb});
document.body.appendChild(renderer.view);
var stage = new PIXI.Container();
var player = makePlayer();

stage.addChild(player);

stage.addChild(makePoint(100, 100));
stage.addChild(makePoint(100, SCREEN_HEIGHT - 100));
stage.addChild(makePoint(SCREEN_WIDTH - 100, 100));
stage.addChild(makePoint(SCREEN_WIDTH - 100, SCREEN_HEIGHT - 100));

addActions();
//create HUD
var scoreText = new PIXI.Text('Score: 9001 (just kidding)', {
    font: "35px Snippet",
    fill: "white",
    align: "left"
});
scoreText.updateHud = function () {
    scoreText.text = "Score: " + score;
};
scoreText.x = 20;
scoreText.y = 20;

var hud = [scoreText];
stage.addChild(scoreText);

var fps = 60;
var frameTime = 1000 / fps;
var physicsTime = 1 / fps;
var removeFromStage = [];

gameLoop();

function gameLoop() {
    setTimeout(function () {
        requestAnimationFrame(gameLoop);
        //TODO keyboad/action processing step?

        //move
        _.forEach(stage.children, function (child) {
            if (child.physics) {
                doPhysics(child, physicsTime);
            }
        });

        //collision resolution
        for (var i = 0; i < stage.children.length; i++) {
            var child = stage.children[i];
            if (child.collision) {
                for (var j = i + 1; j < stage.children.length; j++) {
                    var other = stage.children[j];
                    if (other.collision) {
                        doCollision(child, other);
                    }
                }
            }

            //stage walls
            if (child == player) {
                //fix collisions
                if (child.y > SCREEN_HEIGHT) {
                    child.y = SCREEN_HEIGHT;
                    child.physics.speed = mirrorHorizontal2D(mul2D(player.physics.speed, 0.7));
                }
                if (child.x > SCREEN_WIDTH) {
                    child.x = SCREEN_WIDTH;
                    child.physics.speed = mirrorVertical2D(mul2D(player.physics.speed, 0.7));
                }
                if (child.x < 0) {
                    child.x = 0;
                    child.physics.speed = mirrorVertical2D(mul2D(player.physics.speed, 0.7));
                }
            }
        }

        //remove things
        _.forEach(removeFromStage, function (childToRemove) {
            stage.removeChild(childToRemove);
        });
        removeFromStage = [];

        _.forEach(stage.children, function (child) {
            //animate
            if (child.animate) {
                player.animate(frameTime);
            }
        });

        //update HUD
        _.forEach(hud, function (hudElemet) {
            hudElemet.updateHud();
        });

        //render everything
        renderer.render(stage);
    }, frameTime);
}
<commit_msg>make player start from the ground<commit_after>var GRAVITY = [0, 10]; //m/s^2
var SCALE = 1; // pixels/m
var PI = 3.14159265359;
var SCREEN_WIDTH = 1024;
var SCREEN_HEIGHT = 760;
var COLLISION_TYPES = {
    CIRCLE: 'circle' //has radius
};

//google fonts
WebFontConfig = {
    google: {
        families: ['Snippet', 'Podkova:700']
    },

    active: function () {
        // do something
        //init();
    }

};
(function () {
    var wf = document.createElement('script');
    wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
        '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
    wf.type = 'text/javascript';
    wf.async = 'true';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(wf, s);
})();

//game engine stuff

function makePlayer(x, y) {
    // create a new Sprite using the texture
    var player = new PIXI.Container();

    var body = new PIXI.Text("COPTER", {
        font: "bold 20px Podkova",
        fill: "#cc00ff",
        align: "center",
        stroke: "#FFFFFF",
        strokeThickness: 6
    });

    var leftRotor = new PIXI.Text("QWOP", {
        font: "bold 20px Podkova",
        fill: "#000000",
        align: "center",
        stroke: "#FFFFFF",
        strokeThickness: 6
    });
    var rightRotor = new PIXI.Text("QWOP", {
        font: "bold 20px Podkova",
        fill: "#000000",
        align: "center",
        stroke: "#FFFFFF",
        strokeThickness: 6
    });

    body.anchor.x = 0.5;
    body.anchor.y = 1;
    leftRotor.anchor.x = 0.5;
    leftRotor.anchor.y = 0.5;
    rightRotor.anchor.x = 0.5;
    rightRotor.anchor.y = 0.5;
    body.x = 0;
    body.y = 0;
    leftRotor.x = -35;
    leftRotor.y = -25;
    rightRotor.x = 35;
    rightRotor.y = -25;

    player.addChild(body);
    player.addChild(leftRotor);
    player.addChild(rightRotor);

    // set position
    player.x = x;
    player.y = y;

    //makes the object be effected by physics
    player.physics = {
        mass: 1,
        appliedForce: [0, 0],
        gravity: true,
        speed: [0, 0]
    };

    //gives custom animation/render
    player.animate = function (frameTime) {
        //animate
        leftRotor.rotation += 0.2;
        rightRotor.rotation -= 0.2;

        renderer.render(player);
    };

    //collision attributes
    player.collision = {
        type: COLLISION_TYPES.CIRCLE,
        radius: body.width / 2
    };

    return player;
}

function makePoint(x, y) {
    var point = new PIXI.Text("POI\nNT", {
        font: "bold 20px Podkova",
        fill: "#ff0000",
        align: "center",
        stroke: "#FFFFFF",
        strokeThickness: 6
    });
    point.anchor.x = point.anchor.y = 0.5;
    point.x = x;
    point.y = y;

    point.collision = {
        type: COLLISION_TYPES.CIRCLE,
        radius: point.width / 2,
        onCollision: function (other) {
            if (other == player) {
                score++;
                removeFromStage.push(point);
            }
        }
    };

    return point;
}

function makeKeyboardTrigger(keyCode) {
    var key = {};
    key.code = keyCode;
    key.isDown = false;
    key.isUp = true;
    key.press = undefined;
    key.release = undefined;
    //The `downHandler`
    key.downHandler = function (event) {
        if (event.keyCode === key.code) {
            if (key.isUp && key.press) key.press();
            key.isDown = true;
            key.isUp = false;
        }
        event.preventDefault();
    };

    //The `upHandler`
    key.upHandler = function (event) {
        if (event.keyCode === key.code) {
            if (key.isDown && key.release) key.release();
            key.isDown = false;
            key.isUp = true;
        }
        event.preventDefault();
    };

    //Attach event listeners
    window.addEventListener(
        "keydown", key.downHandler.bind(key), false
    );
    window.addEventListener(
        "keyup", key.upHandler.bind(key), false
    );
    return key;
}

function add2D(a, b) {
    return [a[0] + b[0], a[1] + b[1]];
}

function mul2D(v, s) {
    return [v[0] * s, v[1] * s];
}

function size2D(v) {
    return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
}

function div2D(v, s) {
    return [v[0] / s, v[1] / s];
}

function init2D(rotation, size) {
    return [Math.sin(rotation) * size, Math.cos(rotation) * size];
}

function mirrorHorizontal2D(v) {
    return [v[0], v[1] * -1];
}

function mirrorVertical2D(v) {
    return [v[0] * -1, v[1]];
}

function doPhysics(object, time) {
    var acceleration = div2D(object.physics.appliedForce, object.physics.mass);

    if (object.physics.gravity) {
        acceleration = add2D(acceleration, GRAVITY);
    }
    object.physics.speed = add2D(object.physics.speed, mul2D(acceleration, time));

    object.physics.appliedForce = [0, 0];
    //F = m a
    //a = F/m
    //v = t a

    object.x += object.physics.speed[0] * SCALE;
    object.y += object.physics.speed[1] * SCALE;
}

function doCollision(first, second) {
    var didCollide = false;

    //currently we only have circular bounding boxes
    var xDiff = first.x - second.x;
    var yDiff = first.y - second.y;
    var squareDistance = xDiff * xDiff + yDiff * yDiff;
    var radiusSum = first.collision.radius + second.collision.radius;
    if (squareDistance <= radiusSum * radiusSum) {
        didCollide = true;
    }

    if (didCollide) {
        if (first.collision.onCollision) {
            first.collision.onCollision(second);
        }
        if (second.collision.onCollision) {
            second.collision.onCollision(first);
        }
    }
}

var ACTION_UP_FORCE = -100;
var ACTION_UP_ROTATION = 0.15;
var ACTION_SIDE_ROTATION = 0.3; //this is radians btw, so 2*PI RAD == 360 DEG

var leftUpAction = function () {
    player.rotation += ACTION_UP_ROTATION;
    player.physics.appliedForce = add2D(player.physics.appliedForce, init2D(-player.rotation, ACTION_UP_FORCE));
};
var rightUpAction = function () {
    player.rotation -= ACTION_UP_ROTATION;
    player.physics.appliedForce = add2D(player.physics.appliedForce, init2D(-player.rotation, ACTION_UP_FORCE));
};
var leftAction = function () {
    player.rotation += ACTION_SIDE_ROTATION;
};
var rightAction = function () {
    player.rotation -= ACTION_SIDE_ROTATION;
};

function addActions() {
//key codes http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000520.html
    var leftKey = makeKeyboardTrigger(81); //q
    var leftUpKey = makeKeyboardTrigger(87); //w
    var rightUpKey = makeKeyboardTrigger(79); //o
    var rightKey = makeKeyboardTrigger(80); //p
    var altLeftKey = makeKeyboardTrigger(222); //'
    var altLeftUpKey = makeKeyboardTrigger(188); //,
    var altRightUpKey = makeKeyboardTrigger(82); //r
    var altRightKey = makeKeyboardTrigger(76); //l

    leftKey.press = leftAction;
    altLeftKey.press = leftAction;
    leftUpKey.press = leftUpAction;
    altLeftUpKey.press = leftUpAction;
    rightUpKey.press = rightUpAction;
    altRightUpKey.press = rightUpAction;
    rightKey.press = rightAction;
    altRightKey.press = rightAction;
}

//TODO get this executed after the fonts are loaded
//gameplay
var score = 0;

//create world
var renderer = PIXI.autoDetectRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, {backgroundColor: 0x1099bb});
document.body.appendChild(renderer.view);
var stage = new PIXI.Container();
var player = makePlayer(SCREEN_WIDTH / 2, SCREEN_HEIGHT);

stage.addChild(player);

stage.addChild(makePoint(100, 100));
stage.addChild(makePoint(100, SCREEN_HEIGHT - 100));
stage.addChild(makePoint(SCREEN_WIDTH - 100, 100));
stage.addChild(makePoint(SCREEN_WIDTH - 100, SCREEN_HEIGHT - 100));

addActions();
//create HUD
var scoreText = new PIXI.Text('Score: 9001 (just kidding)', {
    font: "35px Snippet",
    fill: "white",
    align: "left"
});
scoreText.updateHud = function () {
    scoreText.text = "Score: " + score;
};
scoreText.x = 20;
scoreText.y = 20;

var hud = [scoreText];
stage.addChild(scoreText);

var fps = 60;
var frameTime = 1000 / fps;
var physicsTime = 1 / fps;
var removeFromStage = [];

gameLoop();

function gameLoop() {
    setTimeout(function () {
        requestAnimationFrame(gameLoop);
        //TODO keyboad/action processing step?

        //move
        _.forEach(stage.children, function (child) {
            if (child.physics) {
                doPhysics(child, physicsTime);
            }
        });

        //collision resolution
        for (var i = 0; i < stage.children.length; i++) {
            var child = stage.children[i];
            if (child.collision) {
                for (var j = i + 1; j < stage.children.length; j++) {
                    var other = stage.children[j];
                    if (other.collision) {
                        doCollision(child, other);
                    }
                }
            }

            //stage walls
            if (child == player) {
                //fix collisions
                if (child.y > SCREEN_HEIGHT) {
                    child.y = SCREEN_HEIGHT;
                    child.physics.speed = mirrorHorizontal2D(mul2D(player.physics.speed, 0.7));
                }
                if (child.x > SCREEN_WIDTH) {
                    child.x = SCREEN_WIDTH;
                    child.physics.speed = mirrorVertical2D(mul2D(player.physics.speed, 0.7));
                }
                if (child.x < 0) {
                    child.x = 0;
                    child.physics.speed = mirrorVertical2D(mul2D(player.physics.speed, 0.7));
                }
            }
        }

        //remove things
        _.forEach(removeFromStage, function (childToRemove) {
            stage.removeChild(childToRemove);
        });
        removeFromStage = [];

        _.forEach(stage.children, function (child) {
            //animate
            if (child.animate) {
                player.animate(frameTime);
            }
        });

        //update HUD
        _.forEach(hud, function (hudElemet) {
            hudElemet.updateHud();
        });

        //render everything
        renderer.render(stage);
    }, frameTime);
}
<|endoftext|>


<commit_before>/**
 *
 * @author Janus Tøndering <janus@toendering.dk>
 * @license MIT
 */

/*jslint white: true, vars: true, node: true, nomen: true */
/*global define,brackets,$*/

define(function(require, exports, module) {
    "use strict";

    var CommandManager = brackets.getModule("command/CommandManager"),
        Commands = brackets.getModule("command/Commands"),
        KeyBindingManager = brackets.getModule("command/KeyBindingManager"),
        ModalBar = brackets.getModule("widgets/ModalBar"),
        FileUtils = brackets.getModule("file/FileUtils"),
        FileSystem = brackets.getModule("filesystem/FileSystem"),
        ProjectManager = brackets.getModule("project/ProjectManager"),
        Dialogs = brackets.getModule("widgets/Dialogs"),
        DefaultDialogs = brackets.getModule("widgets/DefaultDialogs"),
        AppInit = brackets.getModule("utils/AppInit");

    var html = "
<input type='text' autocomplete='off' id='advancedNewFile' placeholder='Enter new filename\u2026' style='width: 30em'>
";

    var panel;

    function mkdir(dir)
    {
        var promise = $.Deferred();
        dir.create(function(err, stat){
            if(err) { promise.reject(err); }
            else    { promise.resolve(); }
        });
        return promise;
    }

    function mkdirp(path)
    {
        var dir = FileSystem.getDirectoryForPath(path);
        var promise = $.Deferred();

        dir.exists(function(err, exists){
            if(!exists)
            {
                var parentFolder = path.replace(/\/+\s*$/, "").split('/').slice(0, -1).join('/');
                mkdirp(parentFolder).then(function(){
                    dir.create(function(err, stat){
                        if(err) { promise.reject(err); }
                        else    { promise.resolve(); }
                    });
                })
                .fail(function(err){
                    promise.reject(err);
                });
            }
            else {
                promise.resolve();
            }
        });

        return promise;
    }

    function createEmptyFile(file)
    {
        var promise = $.Deferred();
        file.write("", {}, function(err, stat){
            if(err) { promise.reject(err); }
            else    { promise.resolve(); }
        });
        return promise;
    }

    function tryOpenExistingFile(file)
    {
        var promise = $.Deferred();
        file.exists(function(err, exists){
            if(!err && exists)
            {
                return CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: file.fullPath});
            }
            promise.reject();
        });
        return promise;
    }

    function createNewFile(filename)
    {
        var basePath = ProjectManager.getProjectRoot().fullPath;
        var file = FileSystem.getFileForPath(basePath + "/" + filename);
        var dir = FileUtils.getDirectoryPath(file.fullPath);

        // TODO - Don't overwrite existing files
        tryOpenExistingFile(file)
            .then(function(){ panel.close(); })
            .fail(function(){
                mkdirp(dir)
                    .then(function(){
                        return createEmptyFile(file);
                    })
                    .then(function(){
                        return CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: file.fullPath});
                    })
                    .always(function(){
                        panel.close();
                    })
                    .fail(function(err){
                        Dialogs.showModalDialog(DefaultDialogs.DIALOG_ID_ERROR, "Error", err);
                    });
            });
    }

    function handleKeyDown(e)
    {
        if(e.keyCode === 13)
        {
            createNewFile(e.target.value.trim());
            e.preventDefault();
        }
    }

    function openModalBar()
    {
        panel = new ModalBar.ModalBar(html, true);
        var input = panel.getRoot().find("input").first();
        input.on('keydown', handleKeyDown);
        $(panel).on("close", function(){
            input.off("keydown", handleKeyDown);
        });
    }

    AppInit.appReady(function(){
        var NEW_FILE_EXECUTE = "toendering.advanced_new_file.newFile";
        CommandManager.register("Create new file", NEW_FILE_EXECUTE,openModalBar);
        KeyBindingManager.addBinding(NEW_FILE_EXECUTE, { key: "Opt-Alt-N" });
    });
});
<commit_msg>Add code documentation and improve readability<commit_after>/**
 *
 * @author Janus Tøndering <janus@toendering.dk>
 * @license MIT
 */

/*jslint white: true, vars: true, node: true, nomen: true */
/*global define,brackets,$*/

define(function(require, exports, module) {
    "use strict";

    var CommandManager = brackets.getModule("command/CommandManager"),
        Commands = brackets.getModule("command/Commands"),
        KeyBindingManager = brackets.getModule("command/KeyBindingManager"),
        ModalBar = brackets.getModule("widgets/ModalBar"),
        FileUtils = brackets.getModule("file/FileUtils"),
        FileSystem = brackets.getModule("filesystem/FileSystem"),
        ProjectManager = brackets.getModule("project/ProjectManager"),
        Dialogs = brackets.getModule("widgets/Dialogs"),
        DefaultDialogs = brackets.getModule("widgets/DefaultDialogs"),
        AppInit = brackets.getModule("utils/AppInit");

    var html = "
<input type='text' autocomplete='off' id='advancedNewFile' placeholder='Enter new filename\u2026' style='width: 30em'>
";

    var panel;

    function mkdir(dir)
    {
        var promise = $.Deferred();
        dir.create(function(err, stat){
            if(err) { promise.reject(err); }
            else    { promise.resolve(); }
        });
        return promise;
    }

    /**
     * Implementation of "mkdir -p" unix command
     * @param {string} path
     * @returns {jQuery.Deferred}
     */
    function mkdirp(path)
    {
        var dir = FileSystem.getDirectoryForPath(path);
        var promise = $.Deferred();

        dir.exists(function(err, exists){
            if(!exists)
            {
                var parentFolder = path.replace(/\/+\s*$/, "").split('/').slice(0, -1).join('/');
                mkdirp(parentFolder).then(function(){
                    dir.create(function(err, stat){
                        if(err) { promise.reject(err); }
                        else    { promise.resolve(); }
                    });
                })
                .fail(function(err){
                    promise.reject(err);
                });
            }
            else {
                promise.resolve();
            }
        });

        return promise;
    }

    /**
     * Creates a new empty file (will truncate existing files)
     * @param {File} file
     * @returns {jQuery.Deferred}
     */
    function createEmptyFile(file)
    {
        var promise = $.Deferred();
        file.write("", {}, function(err, stat){
            if(err) { promise.reject(err); }
            else    { promise.resolve(); }
        });
        return promise;
    }

    /**
     * Open file in brackets
     * @param {File} file
     * @returns {jQuery.Deferred}
     */
    function addFileToWorkingSet(file)
    {
        return CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: file.fullPath});
    }

    /**
     * Open file in brackets if it exists.
     * @param {File} file
     * @returns {jQuery.Deferred} promise that is resolved if found, rejected otherwise
     */
    function tryOpenExistingFile(file)
    {
        var promise = $.Deferred();
        file.exists(function(err, exists){
            if(!err && exists)
            {
                return addFileToWorkingSet(file);
            }
            promise.reject();
        });
        return promise;
    }

    /**
     * Create filename if it doesn't exist, opens it otherwise
     * @param {string} filename
     */
    function createNewFile(filename)
    {
        var basePath = ProjectManager.getProjectRoot().fullPath;
        var file = FileSystem.getFileForPath(basePath + "/" + filename);
        var dir = FileUtils.getDirectoryPath(file.fullPath);

        tryOpenExistingFile(file)
            .then(function(){ panel.close(); })
            .fail(function(){
                mkdirp(dir)
                    .then(function()   { return createEmptyFile(file); })
                    .then(function()   { return addFileToWorkingSet(file); })
                    .always(function() { panel.close(); })
                    .fail(function(err){
                        Dialogs.showModalDialog(DefaultDialogs.DIALOG_ID_ERROR, "Error", err);
                    });
            });
    }

    function handleKeyDown(e)
    {
        if(e.keyCode === 13)
        {
            createNewFile(e.target.value.trim());
            e.preventDefault();
        }
    }

    function openModalBar()
    {
        panel = new ModalBar.ModalBar(html, true);
        var input = panel.getRoot().find("input").first();
        input.on('keydown', handleKeyDown);
        $(panel).on("close", function(){
            input.off("keydown", handleKeyDown);
        });
    }

    AppInit.appReady(function(){
        var NEW_FILE_EXECUTE = "toendering.advanced_new_file.newFile";
        CommandManager.register("Create new file", NEW_FILE_EXECUTE,openModalBar);
        KeyBindingManager.addBinding(NEW_FILE_EXECUTE, { key: "Opt-Alt-N" });
    });
});
<|endoftext|>


<commit_before>const parse = require('./parse')
const error = require('./error')
const help = require('./help')

module.exports = function sergeant (name, description, define) {
  if (define == null) {
    define = description

    description = null
  }

  const definitions = {}
  const commands = {}

  option('help', {
    type: Boolean,
    aliases: ['h'],
    description: 'get help'
  })

  let i = 0
  const action = define({option, parameter, command})

  return (argv) => {
    if (argv[0] != null && commands[argv[0]] != null) {
      commands[argv[0]].action(argv.slice(1))
    } else {
      const args = parse(argv, definitions)

      try {
        if (args != null) {
          if (args.help === true || action == null) {
            help(name, description, definitions, commands)
          } else if (action != null) {
            const result = action(args)

            if (typeof result === 'object' && result instanceof Promise) {
              result.catch(error)
            }
          }
        }
      } catch (e) {
        error(e)
      }
    }
  }

  function command (subname, description, define) {
    if (define == null) {
      define = description

      description = null
    }

    commands[subname] = {
      action: sergeant(name + ' ' + subname, description, define),
      description
    }
  }

  function option (key, definition) {
    definitions[key] = definition
  }

  function parameter (key, definition) {
    definitions[i++] = Object.assign(definition, {key})
  }
}
<commit_msg>Sub-commands can appear after options<commit_after>const parse = require('./parse')
const error = require('./error')
const help = require('./help')

module.exports = function sergeant (name, description, define) {
  if (define == null) {
    define = description

    description = null
  }

  const definitions = {}
  const commands = {}

  option('help', {
    type: Boolean,
    aliases: ['h'],
    description: 'get help'
  })

  let i = 0
  const action = define({option, parameter, command})

  return (argv) => {
    const filtered = argv.filter((arg) => arg !== '-' && !arg.startsWith('-'))

    if (filtered[0] != null && commands[filtered[0]] != null) {
      commands[filtered[0]].action(filtered.slice(1))
    } else {
      const args = parse(argv, definitions)

      try {
        if (args != null) {
          if (args.help === true || action == null) {
            help(name, description, definitions, commands)
          } else if (action != null) {
            const result = action(args)

            if (typeof result === 'object' && result instanceof Promise) {
              result.catch(error)
            }
          }
        }
      } catch (e) {
        error(e)
      }
    }
  }

  function command (subname, description, define) {
    if (define == null) {
      define = description

      description = null
    }

    commands[subname] = {
      action: sergeant(name + ' ' + subname, description, define),
      description
    }
  }

  function option (key, definition) {
    definitions[key] = definition
  }

  function parameter (key, definition) {
    definitions[i++] = Object.assign(definition, {key})
  }
}
<|endoftext|>