<commit_before>var exec = require('cordova/exec');

function createUUID() {
  // http://www.ietf.org/rfc/rfc4122.txt
  var s = [];
  var hexDigits = "0123456789abcdef";
  for (var i = 0; i < 36; i++) {
      s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  }
  s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
  s[8] = s[13] = s[18] = s[23] = "-";

  var uuid = s.join("");
  return uuid;
}

function Session(config) {
  if (typeof config !== 'object') {
    throw {
      name: 'PhoneRTC Error',
      message: 'The first argument must be an object.'
    };
  }

  if (typeof config.isInitiator === 'undefined') {
    throw {
      name: 'PhoneRTC Error',
      message: 'isInitiator is a required parameter.'
    };
  }

  var self = this;
  self.events = {};
  self.config = config;
  self.sessionKey = createUUID();

  function callEvent(eventName) {
    if (!self.events[eventName]) {
      return;
    }

    var args = Array.prototype.slice.call(arguments, 1);
    self.events[eventName].forEach(function (callback) {
      callback.apply(self, args);
    });
  }

  function onSendMessage(data) {
    callEvent('sendMessage', data);
  }

  exec(onSendMessage, null, 'PhoneRTCPlugin', 'createSession', [self.sessionKey, config]);
};

Session.prototype.on = function (eventName, fn) {
  // make sure that the second argument is a function
  if (typeof fn !== 'function') {
    throw {
      name: 'PhoneRTC Error',
      message: 'The second argument must be a function.'
    };
  }

  // create the event if it doesn't exist
  if (!this.events[eventName]) {
    this.events[eventName] = [];
  } else {
    // make sure that this callback doesn't exist already
    for (var i = 0, len = this.events[eventName].length; i < len; i++) {
      if (this.events[eventName][i] === fn) {
        throw {
          name: 'PhoneRTC Error',
          message: 'This callback function was already added.'
        };
      }
    }
  }

  // add the event
  this.events[eventName].push(fn);
};

Session.prototype.off = function (eventName, fn) {
  // make sure that the second argument is a function
  if (typeof fn !== 'function') {
    throw {
      name: 'PhoneRTC Error',
      message: 'The second argument must be a function.'
    };
  }

  if (!this.events[eventName]) {
    return;
  }

  var indexesToRemove = [];
  for (var i = 0, len = this.events[eventName].length; i < len; i++) {
    if (this.events[eventName][i] === fn) {
      indexesToRemove.push(i);
    }
  }

  indexesToRemove.forEach(function (index) {
    this.events.splice(index, 1);
  })
};

Session.prototype.close = function () {
  exec(null, null, 'PhoneRTCPlugin', 'disconnect', [{
    sessionKey: this.sessionKey
  }]);
};

Session.prototype.initialize = function () {
  exec(null, null, 'PhoneRTCPlugin', 'initialize', [{
    sessionKey: this.sessionKey
  }]);
};

Session.prototype.mute = function () {
  exec(null, null, 'PhoneRTCPlugin', 'toggleMute', [{
    sessionKey: this.sessionKey,
    mute: true
  }]);
};

Session.prototype.receive = function (data) {
  exec(null, null, 'PhoneRTCPlugin', 'receive', [{
    sessionKey: this.sessionKey,
    message: JSON.stringify(data)
  }]);
};

Session.prototype.unmute = function () {
  exec(null, null, 'PhoneRTCPlugin', 'toggleMute', [{
    sessionKey: this.sessionKey,
    mute: false
  }]);
};

exports.Session = Session;

function WebSocket(url, protocols) {
  var self = this;
  // Runtime state.
  this.binaryType = 'blob';
  this.bufferedAmount = 0;
  this.extensions = '';
  this.protocol = '';
  this.readyState = WebSocket.CONNECTING;
  this.sessionKey = createUUID();

  function setState(callback) {
    if(callback === 'onopen') {
      self.readyState = WebSocket.OPEN;
    } else if(callback === 'onclose' ||
              callback === 'onerror') {
      self.readyState = WebSocket.CLOSED;
    }
    window.console.log('State: ' + self.readyState);
  }

  function onMessage(data) {
    var name = data.name;
    setState(name);
    if(name === 'onmessage') { window.console.log('Type of Data: ' + (typeof data.parameters[0])) }
    if(self[name]) {
      if(typeof self[name] === 'function') {
        if(data.parameters) {
          self[name].apply(self, data.parameters);
        } else {
          self[name].apply(self);
        }
      } else {
        window.console.info(name + ' must be a function.');
      }
    }
  }

  // Make sure we don't cause grief.
  if(!url) {
    throw {
      'name': 'InvalidArgumentException',
      'message': 'Please specify a valid URL.'
    };
  }

  exec(onMessage, null, 'PhoneRTCPlugin', 'createWebSocket', [url, protocols, this.sessionKey]);
}

// Define static variables.
WebSocket.CONNECTING = 0;
WebSocket.OPEN = 1;
WebSocket.CLOSING = 2;
WebSocket.CLOSED = 3;

// Define object methods.
WebSocket.prototype.close = function (code, reason) {
  exec(null, null, 'PhoneRTCPlugin', 'close', [code, reason, this.sessionKey]);
  this.readyState = WebSocket.CLOSING;
};

WebSocket.prototype.send = function (data) {
  exec(null, null, 'PhoneRTCPlugin', 'send', [data, this.sessionKey]);
};

exports.WebSocket = WebSocket;<commit_msg>Working on native websocket.<commit_after>var exec = require('cordova/exec');

function createUUID() {
  // http://www.ietf.org/rfc/rfc4122.txt
  var s = [];
  var hexDigits = "0123456789abcdef";
  for (var i = 0; i < 36; i++) {
      s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  }
  s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
  s[8] = s[13] = s[18] = s[23] = "-";

  var uuid = s.join("");
  return uuid;
}

function Session(config) {
  if (typeof config !== 'object') {
    throw {
      name: 'PhoneRTC Error',
      message: 'The first argument must be an object.'
    };
  }

  if (typeof config.isInitiator === 'undefined') {
    throw {
      name: 'PhoneRTC Error',
      message: 'isInitiator is a required parameter.'
    };
  }

  var self = this;
  self.events = {};
  self.config = config;
  self.sessionKey = createUUID();

  function callEvent(eventName) {
    if (!self.events[eventName]) {
      return;
    }

    var args = Array.prototype.slice.call(arguments, 1);
    self.events[eventName].forEach(function (callback) {
      callback.apply(self, args);
    });
  }

  function onSendMessage(data) {
    callEvent('sendMessage', data);
  }

  exec(onSendMessage, null, 'PhoneRTCPlugin', 'createSession', [self.sessionKey, config]);
};

Session.prototype.on = function (eventName, fn) {
  // make sure that the second argument is a function
  if (typeof fn !== 'function') {
    throw {
      name: 'PhoneRTC Error',
      message: 'The second argument must be a function.'
    };
  }

  // create the event if it doesn't exist
  if (!this.events[eventName]) {
    this.events[eventName] = [];
  } else {
    // make sure that this callback doesn't exist already
    for (var i = 0, len = this.events[eventName].length; i < len; i++) {
      if (this.events[eventName][i] === fn) {
        throw {
          name: 'PhoneRTC Error',
          message: 'This callback function was already added.'
        };
      }
    }
  }

  // add the event
  this.events[eventName].push(fn);
};

Session.prototype.off = function (eventName, fn) {
  // make sure that the second argument is a function
  if (typeof fn !== 'function') {
    throw {
      name: 'PhoneRTC Error',
      message: 'The second argument must be a function.'
    };
  }

  if (!this.events[eventName]) {
    return;
  }

  var indexesToRemove = [];
  for (var i = 0, len = this.events[eventName].length; i < len; i++) {
    if (this.events[eventName][i] === fn) {
      indexesToRemove.push(i);
    }
  }

  indexesToRemove.forEach(function (index) {
    this.events.splice(index, 1);
  })
};

Session.prototype.close = function () {
  exec(null, null, 'PhoneRTCPlugin', 'disconnect', [{
    sessionKey: this.sessionKey
  }]);
};

Session.prototype.initialize = function () {
  exec(null, null, 'PhoneRTCPlugin', 'initialize', [{
    sessionKey: this.sessionKey
  }]);
};

Session.prototype.mute = function () {
  exec(null, null, 'PhoneRTCPlugin', 'toggleMute', [{
    sessionKey: this.sessionKey,
    mute: true
  }]);
};

Session.prototype.receive = function (data) {
  exec(null, null, 'PhoneRTCPlugin', 'receive', [{
    sessionKey: this.sessionKey,
    message: JSON.stringify(data)
  }]);
};

Session.prototype.unmute = function () {
  exec(null, null, 'PhoneRTCPlugin', 'toggleMute', [{
    sessionKey: this.sessionKey,
    mute: false
  }]);
};

exports.Session = Session;

function WebSocket(url, protocols) {
  var self = this;
  // Runtime state.
  this.binaryType = 'blob';
  this.bufferedAmount = 0;
  this.extensions = '';
  this.protocol = '';
  this.readyState = WebSocket.CONNECTING;
  this.sessionKey = createUUID();

  function setState(callback) {
    if(callback === 'onopen') {
      self.readyState = WebSocket.OPEN;
    } else if(callback === 'onclose' ||
              callback === 'onerror') {
      self.readyState = WebSocket.CLOSED;
    }
    window.console.log('State: ' + self.readyState);
  }

  function onMessage(data) {
    window.console.log(data);
    window.console.log('\\r\\n index: ' + data.parameters.indexOf('\r\n'));
    var name = data.name;
    setState(name);
    if(name === 'onmessage') { window.console.log('Type of Data: ' + (typeof data.parameters[0])) }
    if(self[name]) {
      if(typeof self[name] === 'function') {
        if(data.parameters) {
          self[name].apply(self, data.parameters);
        } else {
          self[name].apply(self);
        }
      } else {
        window.console.info(name + ' must be a function.');
      }
    }
  }

  // Make sure we don't cause grief.
  if(!url) {
    throw {
      'name': 'InvalidArgumentException',
      'message': 'Please specify a valid URL.'
    };
  }

  exec(onMessage, null, 'PhoneRTCPlugin', 'createWebSocket', [url, protocols, this.sessionKey]);
}

// Define static variables.
WebSocket.CONNECTING = 0;
WebSocket.OPEN = 1;
WebSocket.CLOSING = 2;
WebSocket.CLOSED = 3;

// Define object methods.
WebSocket.prototype.close = function (code, reason) {
  exec(null, null, 'PhoneRTCPlugin', 'close', [code, reason, this.sessionKey]);
  this.readyState = WebSocket.CLOSING;
};

WebSocket.prototype.send = function (data) {
  exec(null, null, 'PhoneRTCPlugin', 'send', [data, this.sessionKey]);
};

exports.WebSocket = WebSocket;<|endoftext|>


<commit_before>// Contains functions and variables used in the initiation of the game and game state.

var refreshButton = document.getElementsByClassName("refresh")[0];
var upButton = document.getElementsByClassName("upButton")[0];
var levelGauge = document.getElementsByClassName("level")[0];
var downButton = document.getElementsByClassName("downButton")[0];

var refreshRate = 250; // How quickly the snake moves. (ms)
var intervalId; // Used to repeatedly call ai(level) and to stop calling same.
var gameIsStopped = true;
var highscores;

if (document.cookie !== null) {
  cookies = document.cookie.split(';');
  for (var c=0; c<cookies.length; c++) {
    var cookie = cookies[c].split('=');
    if (cookie[0] == 'speed') {
      var speed = parseInt(cookie[1]);
      var speedSlider = document.getElementById('speedSlider');
      speedSlider.value = speed;
      showValue(speedSlider);
    }
  }
}

// Takes a time array as [minutes, seconds, milliseconds] and returns a zero-padded MM:SS.msss
function formatTime(time) {
  return (
    time[0]
    + ':'
    + (time[1]<10?'0':'')
    + time[1]
    + '.'
    + (time[2]<100?'0':'')
    + (time[2]<10?'0':'')
    + time[2]);
}

function getScores() {
  var req = new XMLHttpRequest();
  req.open('GET', 'http://reverse-snake.cloudant.com/highscores/highscores', true); // METHOD, url, async
  req.onload = function() { // Asynchronous callback.
    highscores = JSON.parse(req.responseText);
    for (var i=0; i<5; i++) {
      document.getElementsByClassName("score"+i)[0].innerHTML = highscores["data"]["scores"][i];
      var time = highscores["data"]["times"][i];
      document.getElementsByClassName("time"+i)[0].innerHTML = formatTime(time);
    }
  }
  req.send();
}

getScores();

// Assume our scores are up-to-date. It should be possible to check for conflict by reading the response. I'll deal with this some other time.
function checkHighscore(kind, value, level) {
  if (kind == 'SCORE') {
    if (value < highscores["data"]["scores"][level]) {
      console.log("New highscore for level "+level+": "+value);
      highscores["data"]["scores"][level] = value;
      return true;
    }
  } else if (kind == 'TIME') {
    var newHighscore = false;
    if (value[0] < highscores["data"]["times"][level][0]) {
      newHighscore = true;
    } else if (value[0] == highscores["data"]["times"][level][0]) {
      if (value[1] < highscores["data"]["times"][level][1]) {
        newHighscore = true;
      } else if (value[1] == highscores["data"]["times"][level][1]) {
        if (value[2] < highscores["data"]["times"][level][2]) {
          newHighscore = true;
        }
      }
    }
    if (newHighscore) {
      console.log("New best time for level "+level+": "+formatTime(value));
      highscores["data"]["times"][level] = value;
      return true;
    }
  }
  return false;
}

function uploadHighscores() {
  var req = new XMLHttpRequest();
  req.open('PUT', 'http://reverse-snake.cloudant.com/highscores/highscores', true); // METHOD, url, async
  req.onload = function() { // Asynchronous callback.
    console.log(req.responseText);
  }
  req.setRequestHeader('Content-Type', 'application/json');
  console.log("Sending scores...");
  req.send(highscores);
}

// Clears board & stops AI
function stopGame() {
  console.log("Round ended! Advancing AI to level "+ (level + 1));
  getScores();
  var now = new Date();
  stopTime = [now.getMinutes(), now.getSeconds(), now.getMilliseconds()];
  var time = [0, 0, 0]
  time[0] = (stopTime[0] - startTime[0] + 60) % 60;
  time[1] = (stopTime[1] - startTime[1] + 60) % 60;
  time[2] = (stopTime[2] - startTime[2] + 1000) % 1000;
  console.log("Uploading scores...");
  if (checkHighscore('TIME', time, level) | checkHighscore('SCORE', score, level)) {
    uploadHighscores();
  }
  console.log("Scores uploaded");
  maxLevel++;
  upLevel();
  refreshButton.disabled = true;
  resetGame();
}

function resetGame() {
  console.log("Game reset");
  startTime = [];
  stopTime = [];
  followLeftEdge = false;
  moves = [];
  window.clearInterval(intervalId);
  upButton.disabled = (level == maxLevel || level == 4);
  downButton.disabled = (level === 0);
  gameIsStopped = true;
  board = []; // board[x][y]
  board.length = width;
  for (var i = 0; i < width; i++) {
    board[i] = [];
    board[i].length = height;
  }
  food = [-10, -10];
  snake = [];
  for (var i=0; i<level+3; i++) {
    snake.unshift([i, 0]);
  }
  dir = 'right';
  updateBoard();
  if (level == 5) {
    showVictory();
  }
}

function startGame() {
  if (!gameIsStopped) {
    return;
  }
  console.log("Game started");
  var now = new Date();
  startTime = [now.getMinutes(), now.getSeconds(), now.getMilliseconds()];
  refreshButton.disabled = false;
  upButton.disabled = true;
  downButton.disabled = true;
  // document.cookie = 'speed='+refreshRate+'; maxLevel='+maxLevel;
  gameIsStopped = false;
  intervalId = window.setInterval(ai, refreshRate, level); // calls ai(level) at refreshRate
  ai(level);
}

function changeSpeed(rate) {
  refreshRate = rate; // set to new value
  window.clearInterval(intervalId);
  if (!gameIsStopped) { // ensures only one interval going on at once
    intervalId = window.setInterval(ai, refreshRate, level); // calls ai(level) at refreshRate
    ai(level);
  }
}
<commit_msg>Move debug to correct location.<commit_after>// Contains functions and variables used in the initiation of the game and game state.

var refreshButton = document.getElementsByClassName("refresh")[0];
var upButton = document.getElementsByClassName("upButton")[0];
var levelGauge = document.getElementsByClassName("level")[0];
var downButton = document.getElementsByClassName("downButton")[0];

var refreshRate = 250; // How quickly the snake moves. (ms)
var intervalId; // Used to repeatedly call ai(level) and to stop calling same.
var gameIsStopped = true;
var highscores;

if (document.cookie !== null) {
  cookies = document.cookie.split(';');
  for (var c=0; c<cookies.length; c++) {
    var cookie = cookies[c].split('=');
    if (cookie[0] == 'speed') {
      var speed = parseInt(cookie[1]);
      var speedSlider = document.getElementById('speedSlider');
      speedSlider.value = speed;
      showValue(speedSlider);
    }
  }
}

// Takes a time array as [minutes, seconds, milliseconds] and returns a zero-padded MM:SS.msss
function formatTime(time) {
  return (
    time[0]
    + ':'
    + (time[1]<10?'0':'')
    + time[1]
    + '.'
    + (time[2]<100?'0':'')
    + (time[2]<10?'0':'')
    + time[2]);
}

function getScores() {
  var req = new XMLHttpRequest();
  req.open('GET', 'http://reverse-snake.cloudant.com/highscores/highscores', true); // METHOD, url, async
  req.onload = function() { // Asynchronous callback.
    highscores = JSON.parse(req.responseText);
    for (var i=0; i<5; i++) {
      document.getElementsByClassName("score"+i)[0].innerHTML = highscores["data"]["scores"][i];
      var time = highscores["data"]["times"][i];
      document.getElementsByClassName("time"+i)[0].innerHTML = formatTime(time);
    }
  }
  req.send();
}

getScores();

// Assume our scores are up-to-date. It should be possible to check for conflict by reading the response. I'll deal with this some other time.
function checkHighscore(kind, value, level) {
  if (kind == 'SCORE') {
    if (value < highscores["data"]["scores"][level]) {
      console.log("New highscore for level "+level+": "+value);
      highscores["data"]["scores"][level] = value;
      return true;
    }
  } else if (kind == 'TIME') {
    var newHighscore = false;
    if (value[0] < highscores["data"]["times"][level][0]) {
      newHighscore = true;
    } else if (value[0] == highscores["data"]["times"][level][0]) {
      if (value[1] < highscores["data"]["times"][level][1]) {
        newHighscore = true;
      } else if (value[1] == highscores["data"]["times"][level][1]) {
        if (value[2] < highscores["data"]["times"][level][2]) {
          newHighscore = true;
        }
      }
    }
    if (newHighscore) {
      console.log("New best time for level "+level+": "+formatTime(value));
      highscores["data"]["times"][level] = value;
      return true;
    }
  }
  return false;
}

function uploadHighscores() {
  var req = new XMLHttpRequest();
  req.open('PUT', 'http://reverse-snake.cloudant.com/highscores/highscores', true); // METHOD, url, async
  req.onload = function() { // Asynchronous callback.
    console.log(req.responseText);
    console.log("Scores uploaded");
  }
  req.setRequestHeader('Content-Type', 'application/json');
  console.log("Sending scores...");
  req.send(highscores);
}

// Clears board & stops AI
function stopGame() {
  console.log("Round ended! Advancing AI to level "+ (level + 1));
  getScores();
  var now = new Date();
  stopTime = [now.getMinutes(), now.getSeconds(), now.getMilliseconds()];
  var time = [0, 0, 0]
  time[0] = (stopTime[0] - startTime[0] + 60) % 60;
  time[1] = (stopTime[1] - startTime[1] + 60) % 60;
  time[2] = (stopTime[2] - startTime[2] + 1000) % 1000;
  console.log("Uploading scores...");
  if (checkHighscore('TIME', time, level) | checkHighscore('SCORE', score, level)) {
    uploadHighscores();
  }
  maxLevel++;
  upLevel();
  refreshButton.disabled = true;
  resetGame();
}

function resetGame() {
  console.log("Game reset");
  startTime = [];
  stopTime = [];
  followLeftEdge = false;
  moves = [];
  window.clearInterval(intervalId);
  upButton.disabled = (level == maxLevel || level == 4);
  downButton.disabled = (level === 0);
  gameIsStopped = true;
  board = []; // board[x][y]
  board.length = width;
  for (var i = 0; i < width; i++) {
    board[i] = [];
    board[i].length = height;
  }
  food = [-10, -10];
  snake = [];
  for (var i=0; i<level+3; i++) {
    snake.unshift([i, 0]);
  }
  dir = 'right';
  updateBoard();
  if (level == 5) {
    showVictory();
  }
}

function startGame() {
  if (!gameIsStopped) {
    return;
  }
  console.log("Game started");
  var now = new Date();
  startTime = [now.getMinutes(), now.getSeconds(), now.getMilliseconds()];
  refreshButton.disabled = false;
  upButton.disabled = true;
  downButton.disabled = true;
  // document.cookie = 'speed='+refreshRate+'; maxLevel='+maxLevel;
  gameIsStopped = false;
  intervalId = window.setInterval(ai, refreshRate, level); // calls ai(level) at refreshRate
  ai(level);
}

function changeSpeed(rate) {
  refreshRate = rate; // set to new value
  window.clearInterval(intervalId);
  if (!gameIsStopped) { // ensures only one interval going on at once
    intervalId = window.setInterval(ai, refreshRate, level); // calls ai(level) at refreshRate
    ai(level);
  }
}
<|endoftext|>


<commit_before>var JS_GAME = {};

JS_GAME.game = (function () {
  var isKeyDown = [];
  var context;
  var userData = [];
  var enemies = [];
  var frameLength = 1;// in milliseconds
  var socket;
  var connected = false;
  var user = "";
  var pass = "";

  function init() {
    user = document.getElementById("loginInfo").user.value;
    pass = document.getElementById("loginInfo").pass.value;
    $("#user").blur();
    $("#pass").blur();
    $("#loginInfo").remove();
    if (user.indexOf(",") >= 0 || user.indexOf(":") >= 0){
      document.getElementById("loginInfo").user.value = "INVALID INPUT";
      return;
    }
    socket = new WebSocket("ws:167.88.120.57:38734");

    socket.onopen = function() {
      connected = true;
      socket.send("login:" + user + "," + pass);
    };

socket.onmessage = function(message) {
  if (message.data.indexOf("pos") == 0){
  userData = message.data.split(":")[1].split(",");

} else if (message.data.indexOf("dat") == 0){
  enemies = message.data.split(":")[1].split(",");
}
};

socket.onclose = function() {
  window.location.reload(false);
};

socket.onerror = function() {
};

document.body.innerHTML = "";
for (i = 0; i < 256; i++){
  isKeyDown[i] = false;
}
$('body').append('<canvas id="GameCanvas">');
var canvasElement = $('#GameCanvas');
canvasElement.select().focus().click();
canvasElement.attr('width', $(window).innerWidth());
canvasElement.attr('height', $(window).innerHeight());
canvasElement.attr('tabIndex', 1);
document.getElementById("GameCanvas").focus();
var canvas = canvasElement[0];
window.addEventListener( "keydown", keyPress, false);
window.addEventListener( "keyup", keyRelease, false);
context = canvas.getContext('2d');
gameLoop();
}

function gameLoop() {
  var keyData = "";
  for (i = 0; i < 256; i++){
    keyData += isKeyDown[i] ? 1 : 0;
  }
  try {
    socket.send("keys:" + keyData);
  } catch (err) {
  }
  context.clearRect(0, 0, document.body.clientWidth, document.body.clientHeight);
  //draw enemies
  for (i = 0; i < enemies.length; i += 4){
  context.fillStyle = enemies[i+2];
  context.fillRect(enemies[i], enemies[i+1], 30, 50);
  }
  //draw player
  context.fillStyle = userData[2];
  context.fillRect(userData[0], userData[1], 30, 50);
  //draw enemy names
  for (i = 0; i < enemies.length; i += 4){
  context.fillStyle = enemies[i+2];
  context.fillText(enemies[i+3],(enemies[i] - (context.measureText(enemies[i+3]).width / 2)) + 15,enemies[i+1] - 5);
  }
  //draw player name
  context.fillStyle = userData[2];
  context.font = "15px Arial";
  context.fillText(userData[3],(userData[0] - (context.measureText(userData[3]).width / 2)) + 15,userData[1] - 5);

  setTimeout(gameLoop, frameLength);
}

function keyPress(e){
  isKeyDown[e.keyCode] = true;
}
function keyRelease(e){
  isKeyDown[e.keyCode] = false;
}
function isKeyPressed(c){
  return isKeyDown[c.charCodeAt(0)];
}

return {
  init: init
};
})();

$(document).ready(function() {
  $("#loginInfo").submit(function(event){
    event.preventDefault();
    JS_GAME.game.init();
    return false;
  });
});
<commit_msg>Page dimensions make sense now<commit_after>var JS_GAME = {};

JS_GAME.game = (function () {
  var isKeyDown = [];
  var context;
  var userData = [];
  var enemies = [];
  var frameLength = 1;// in milliseconds
  var socket;
  var connected = false;
  var user = "";
  var pass = "";
  var windowWidth = $(window).innerWidth();
  var windowHeight = $(window).innerHeight();

  function init() {
    user = document.getElementById("loginInfo").user.value;
    pass = document.getElementById("loginInfo").pass.value;
    $("#user").blur();
    $("#pass").blur();
    $("#loginInfo").remove();
    if (user.indexOf(",") >= 0 || user.indexOf(":") >= 0){
      document.getElementById("loginInfo").user.value = "INVALID INPUT";
      return;
    }
    socket = new WebSocket("ws:167.88.120.57:38734");

    socket.onopen = function() {
      connected = true;
      socket.send("login:" + user + "," + pass);
    };

socket.onmessage = function(message) {
  if (message.data.indexOf("pos") == 0){
  userData = message.data.split(":")[1].split(",");

} else if (message.data.indexOf("dat") == 0){
  enemies = message.data.split(":")[1].split(",");
}
};

socket.onclose = function() {
  window.location.reload(false);
};

socket.onerror = function() {
};

document.body.innerHTML = "";
for (i = 0; i < 256; i++){
  isKeyDown[i] = false;
}
$('body').append('<canvas id="GameCanvas">');
var canvasElement = $('#GameCanvas');
canvasElement.select().focus().click();
canvasElement.attr('width', windowWidth);
canvasElement.attr('height', windowHeight);
canvasElement.attr('tabIndex', 1);
document.getElementById("GameCanvas").focus();
var canvas = canvasElement[0];
window.addEventListener( "keydown", keyPress, false);
window.addEventListener( "keyup", keyRelease, false);
context = canvas.getContext('2d');
gameLoop();
}

function gameLoop() {
  var keyData = "";
  for (i = 0; i < 256; i++){
    keyData += isKeyDown[i] ? 1 : 0;
  }
  try {
    socket.send("keys:" + keyData);
  } catch (err) {
  }
  context.clearRect(0, 0, windowWidth, windowHeight);
  //draw enemies
  for (i = 0; i < enemies.length; i += 4){
  context.fillStyle = enemies[i+2];
  context.fillRect(enemies[i], enemies[i+1], 30, 50);
  }
  //draw player
  context.fillStyle = userData[2];
  context.fillRect(userData[0], userData[1], 30, 50);
  //draw enemy names
  for (i = 0; i < enemies.length; i += 4){
  context.fillStyle = enemies[i+2];
  context.fillText(enemies[i+3],(enemies[i] - (context.measureText(enemies[i+3]).width / 2)) + 15,enemies[i+1] - 5);
  }
  //draw player name
  context.fillStyle = userData[2];
  context.font = "15px Arial";
  context.fillText(userData[3],(userData[0] - (context.measureText(userData[3]).width / 2)) + 15,userData[1] - 5);

  setTimeout(gameLoop, frameLength);
}

function keyPress(e){
  isKeyDown[e.keyCode] = true;
}
function keyRelease(e){
  isKeyDown[e.keyCode] = false;
}
function isKeyPressed(c){
  return isKeyDown[c.charCodeAt(0)];
}

return {
  init: init
};
})();

$(document).ready(function() {
  $("#loginInfo").submit(function(event){
    event.preventDefault();
    JS_GAME.game.init();
    return false;
  });
});
<|endoftext|>


<commit_before>var app = angular.module('8ball', ['ionic'])

app.run(function ($ionicPlatform) {
	$ionicPlatform.ready(function () {
		// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
		// for form inputs)
		if (window.cordova && window.cordova.plugins.Keyboard) {
			cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
		}
		if (window.StatusBar) {
			StatusBar.styleDefault();
		}
	});
});

app.controller('PredictionController', function ($scope, $timeout) {

	var predictionList = [
		"Signs point to yes",
		"Yes",
		"Reply hazy, try again",
		"Without a doubt",
		"My sources say no",
		"As I see it, yes",
		"You may rely on it",
		"Concentrate and ask again",
		"Outlook not so good",
		"It is decidedly so",
		"Better not tell you now",
		"Very doubtful",
		"Yes - definitely",
		"It is certain",
		"Cannot predict now",
		"Most likely",
		"Ask again later",
		"My reply is no",
		"Outlook good",
		"Don't count on it"
	];

	$scope.prediction = "Tap 8ball for an answer";

	$scope.doThis = function(){
		$scope.prediction = "Thinking....";
		$timeout(function(){
			$scope.prediction = predictionList[Math.floor(Math.random() * predictionList.length)];
		},2000);
	};

});
<commit_msg>minor changes<commit_after>var app = angular.module('8ball', ['ionic'])

app.run(function ($ionicPlatform) {
	$ionicPlatform.ready(function () {
		// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
		// for form inputs)
		if (window.cordova && window.cordova.plugins.Keyboard) {
			cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
		}
		if (window.StatusBar) {
			StatusBar.styleDefault();
		}
	});
});

app.controller('PredictionController', function ($scope, $timeout) {

	var predictionList = [
		"Signs point to yes",
		"Yes",
		"Reply hazy, try again",
		"Without a doubt",
		"My sources say no",
		"As I see it, yes",
		"You may rely on it",
		"Concentrate and ask again",
		"Outlook not so good",
		"It is decidedly so",
		"Better not tell you now",
		"Very doubtful",
		"Yes - definitely",
		"It is certain",
		"Cannot predict now",
		"Most likely",
		"Ask again later",
		"My reply is no",
		"Outlook good",
		"Don't count on it"
	];

	$scope.prediction = "Tap 8ball for an answer";

	$scope.doThis = function(){
		$scope.prediction = "Thinking";
		$timeout(function(){
			$scope.prediction = "Thinking.";
			console.log("first");
		},500);
		$timeout(function(){
			$scope.prediction = "Thinking..";
			console.log("second");
		},1000);
		$timeout(function(){
			$scope.prediction = "Thinking...";
			console.log("third");
		},1500);
		$timeout(function(){
			$scope.prediction = predictionList[Math.floor(Math.random() * predictionList.length)];
		},2000);
	};

});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import assign from 'object-assign';

import { showMenu, hideMenu } from './actions';
import { callIfExists, cssClasses } from './helpers';

export default class ContextMenuTrigger extends Component {
    static propTypes = {
        id: PropTypes.string.isRequired,
        children: PropTypes.node.isRequired,
        attributes: PropTypes.object,
        collect: PropTypes.func,
        disable: PropTypes.bool,
        holdToDisplay: PropTypes.number,
        renderTag: PropTypes.oneOfType([
            PropTypes.node,
            PropTypes.func
        ])
    };

    static defaultProps = {
        attributes: {},
        collect() { return null; },
        disable: false,
        holdToDisplay: 1000,
        renderTag: 'div'
    };

    touchHandled = false;

    handleMouseDown = (event) => {
        if (this.props.holdToDisplay >= 0 && event.button === 0) {
            event.persist();

            this.mouseDownTimeoutId = setTimeout(
                () => this.handleContextClick(event),
                this.props.holdToDisplay
            );
        }
    }

    handleMouseUp = (event) => {
        if (event.button === 0) {
            clearTimeout(this.mouseDownTimeoutId);
        }
    }

    handleTouchstart = (event) => {
        if (this.props.holdToDisplay >= 0) {
            event.persist();

            this.touchstartTimeoutId = setTimeout(
                () => {
                    this.handleContextClick(event);
                    this.touchHandled = true;
                },
                this.props.holdToDisplay
            );
        }
    }

    handleTouchEnd = (event) => {
        if (this.touchHandled) {
            event.preventDefault();
        }
        clearTimeout(this.touchstartTimeoutId);
    }

    handleContextClick = (event) => {
        if (this.props.disable) return;

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

        const x = event.clientX || (event.touches && event.touches[0].pageX);
        const y = event.clientY || (event.touches && event.touches[0].pageY);

        hideMenu();

        showMenu({
            position: { x, y },
            target: this.elem,
            id: this.props.id,
            data: callIfExists(this.props.collect, this.props)
        });
    }

    elemRef = (c) => {
        this.elem = c;
    }

    render() {
        const { renderTag, attributes, children } = this.props;
        const newAttrs = assign({}, attributes, {
            className: cx(cssClasses.menuWrapper, attributes.className),
            onContextMenu: this.handleContextClick,
            onMouseDown: this.handleMouseDown,
            onMouseUp: this.handleMouseUp,
            onTouchStart: this.handleTouchstart,
            onTouchEnd: this.handleTouchEnd,
            onMouseOut: this.handleMouseUp,
            ref: this.elemRef
        });

        return React.createElement(renderTag, newAttrs, children);
    }
}
<commit_msg>Set touchHandled = false<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import assign from 'object-assign';

import { showMenu, hideMenu } from './actions';
import { callIfExists, cssClasses } from './helpers';

export default class ContextMenuTrigger extends Component {
    static propTypes = {
        id: PropTypes.string.isRequired,
        children: PropTypes.node.isRequired,
        attributes: PropTypes.object,
        collect: PropTypes.func,
        disable: PropTypes.bool,
        holdToDisplay: PropTypes.number,
        renderTag: PropTypes.oneOfType([
            PropTypes.node,
            PropTypes.func
        ])
    };

    static defaultProps = {
        attributes: {},
        collect() { return null; },
        disable: false,
        holdToDisplay: 1000,
        renderTag: 'div'
    };

    touchHandled = false;

    handleMouseDown = (event) => {
        if (this.props.holdToDisplay >= 0 && event.button === 0) {
            event.persist();

            this.mouseDownTimeoutId = setTimeout(
                () => this.handleContextClick(event),
                this.props.holdToDisplay
            );
        }
    }

    handleMouseUp = (event) => {
        if (event.button === 0) {
            clearTimeout(this.mouseDownTimeoutId);
        }
    }

    handleTouchstart = (event) => {
        this.touchHandled = false;

        if (this.props.holdToDisplay >= 0) {
            event.persist();

            this.touchstartTimeoutId = setTimeout(
                () => {
                    this.handleContextClick(event);
                    this.touchHandled = true;
                },
                this.props.holdToDisplay
            );
        }
    }

    handleTouchEnd = (event) => {
        if (this.touchHandled) {
            event.preventDefault();
        }
        clearTimeout(this.touchstartTimeoutId);
    }

    handleContextClick = (event) => {
        if (this.props.disable) return;

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

        const x = event.clientX || (event.touches && event.touches[0].pageX);
        const y = event.clientY || (event.touches && event.touches[0].pageY);

        hideMenu();

        showMenu({
            position: { x, y },
            target: this.elem,
            id: this.props.id,
            data: callIfExists(this.props.collect, this.props)
        });
    }

    elemRef = (c) => {
        this.elem = c;
    }

    render() {
        const { renderTag, attributes, children } = this.props;
        const newAttrs = assign({}, attributes, {
            className: cx(cssClasses.menuWrapper, attributes.className),
            onContextMenu: this.handleContextClick,
            onMouseDown: this.handleMouseDown,
            onMouseUp: this.handleMouseUp,
            onTouchStart: this.handleTouchstart,
            onTouchEnd: this.handleTouchEnd,
            onMouseOut: this.handleMouseUp,
            ref: this.elemRef
        });

        return React.createElement(renderTag, newAttrs, children);
    }
}
<|endoftext|>


<commit_before>/**
 * # ResurrectJS
 * @version 1.0.0
 *
 * ResurrectJS preserves object behavior (prototypes) and reference
 * circularity with a special JSON encoding. Unlike regular JSON,
 * Date, RegExp, DOM objects, and `undefined` are also properly
 * preserved.
 *
 * ## Examples
 *
 * function Foo() {}
 * Foo.prototype.greet = function() { return "hello"; };
 *
 * // Behavior is preserved:
 * var necromancer = new Resurrect();
 * var json = necromancer.stringify(new Foo());
 * var foo = necromancer.resurrect(json);
 * foo.greet();  // => "hello"
 *
 * // References to the same object are preserved:
 * json = necromancer.stringify([foo, foo]);
 * var array = necromancer.resurrect(json);
 * array[0] === array[1];  // => true
 * array[1].greet();  // => "hello"
 *
 * // Dates are restored properly
 * json = necromancer.stringify(new Date());
 * var date = necromancer.resurrect(json);
 * Object.prototype.toString.call(date);  // => "[object Date]"
 *
 * ## Options
 *
 * Options are provided to the constructor as an object with these
 * properties:
 *
 *   prefix ('#'): A prefix string used for temporary properties added
 *     to objects during serialization and deserialization. It is
 *     important that you don't use any properties beginning with this
 *     string. This option must be consistent between both
 *     serialization and deserialization.
 *
 *   cleanup (false): Perform full property cleanup after both
 *     serialization and deserialization using the `delete`
 *     operator. This may cause performance penalties (breaking hidden
 *     classes in V8) on objects that ResurrectJS touches, so enable
 *     with care.
 *
 *   revive (true): Restore behavior (__proto__) to objects that have
 *     been resurrected. If this is set to false during serialization,
 *     resurrection information will not be encoded. You still get
 *     circularity and Date support.
 *
 *   resolver (Resurrect.NamespaceResolver(window)): Converts between
 *     a name and a prototype. Create a custom resolver if your
 *     constructors are not stored in global variables. The resolver
 *     has two methods: getName(object) and getPrototype(string).
 *
 * For example,
 *
 * var necromancer = new Resurrect({
 *     prefix: '__#',
 *     cleanup: true
 * });
 *
 * ## Caveats
 *
 *   * With the default resolver, all constructors must be named and
 *   stored in the global variable under that name. This is required
 *   so that the prototypes can be looked up and reconnected at
 *   resurrection time.
 *
 *   * The wrapper objects Boolean, String, and Number will be
 *   unwrapped. This means extra properties added to these objects
 *   will not be preserved.
 *
 *   * Functions cannot ever be serialized. Resurrect will throw an
 *   error if a function is found when traversing a data structure.
 *
 * @see http://nullprogram.com/blog/2013/03/28/
 */

/**
 * @namespace
 * @constructor
 */
function Resurrect(options) {
    this.table = null;
    this.prefix = '#';
    this.cleanup = false;
    this.revive = true;
    for (var option in options) {
        if (options.hasOwnProperty(option)) {
            this[option] = options[option];
        }
    }
    this.refcode = this.prefix + 'id';
    this.origcode = this.prefix + 'original';
    this.buildcode = this.prefix + '.';
    this.valuecode = this.prefix + 'v';
}

/**
 * Portable access to the global object (window, global).
 * Uses indirect eval.
 * @constant
 */
Resurrect.GLOBAL = (0, eval)('this');

/* Helper Objects */

/**
 * @constructor
 */
Resurrect.prototype.Error = function ResurrectError(message) {
    this.message = message || '';
    this.stack = new Error().stack;
};
Resurrect.prototype.Error.prototype = Object.create(Error.prototype);
Resurrect.prototype.Error.prototype.name = 'ResurrectError';

/**
 * Resolves prototypes through the properties on an object and
 * constructor names.
 * @constructor
 */
Resurrect.NamespaceResolver = function(scope) {
    this.scope = scope;
};

/**
 * Gets the prototype of the given property name from an object. If
 * not found, it throws an error.
 * @param {string} name
 * @method
 */
Resurrect.NamespaceResolver.prototype.getPrototype = function(name) {
    var constructor = this.scope[name];
    if (constructor) {
        return constructor.prototype;
    } else {
        throw new Resurrect.prototype.Error('Unknown constructor: ' + name);
    }
};

/**
 * Get the prototype name for an object, to be fetched later with
 * getPrototype.
 * @returns {string} Null if the constructor is Object.
 * @method
 */
Resurrect.NamespaceResolver.prototype.getName = function(object) {
    var constructor = object.constructor.name;
    if (constructor == null) { // IE
        var funcPattern = /^\s*function\s*([A-Za-z0-9_$]*)/;
        constructor = funcPattern.exec(object.constructor)[1];
    }

    if (constructor === '') {
        var msg = "Can't serialize objects with anonymous constructors.";
        throw new Resurrect.prototype.Error(msg);
    } else if (constructor === 'Object' || constructor === 'Array') {
        return null;
    } else {
        return constructor;
    }
};

/* Set the default resolver searches the global object. */
Resurrect.prototype.resolver =
    new Resurrect.NamespaceResolver(Resurrect.GLOBAL);

/**
 * Create a DOM node from HTML source; behaves like a constructor.
 * @constructor
 */
Resurrect.Node = function(html) {
    var div = document.createElement('div');
    div.innerHTML = html;
    return div.firstChild;
};

/* Type Tests */

/**
 * @param {string} type
 * @returns {Function} A function that tests for type.
 */
Resurrect.is = function(type) {
    var string = '[object ' + type + ']';
    return function(object) {
        return Object.prototype.toString.call(object) === string;
    };
};

Resurrect.isArray = Resurrect.is('Array');
Resurrect.isString = Resurrect.is('String');
Resurrect.isBoolean = Resurrect.is('Boolean');
Resurrect.isNumber = Resurrect.is('Number');
Resurrect.isFunction = Resurrect.is('Function');
Resurrect.isDate = Resurrect.is('Date');
Resurrect.isRegExp = Resurrect.is('RegExp');
Resurrect.isObject = Resurrect.is('Object');

Resurrect.isAtom = function(object) {
    return !Resurrect.isObject(object) && !Resurrect.isArray(object);
};

/* Methods */

/**
 * Create a reference (encoding) to an object.
 * @method
 */
Resurrect.prototype.ref = function(object) {
    var ref = {};
    if (object === undefined) {
        ref[this.prefix] = -1;
    } else {
        ref[this.prefix] = object[this.refcode];
    }
    return ref;
};

/**
 * Lookup an object in the table by reference object.
 * @method
 */
Resurrect.prototype.deref = function(ref) {
    return this.table[ref[this.prefix]];
};

/**
 * Put a temporary identifier on an object and store it in the table.
 * @returns {number} The unique identifier number.
 * @method
 */
Resurrect.prototype.tag = function(object) {
    if (this.revive) {
        var constructor = this.resolver.getName(object);
        if (constructor) {
            var proto = Object.getPrototypeOf(object);
            if (this.resolver.getPrototype(constructor) !== proto) {
                throw new this.Error('Constructor mismatch!');
            } else {
                object[this.prefix] = constructor;
            }
        }
    }
    object[this.refcode] = this.table.length;
    this.table.push(object);
    return object[this.refcode];
};

/**
 * Create a builder object (encoding) for serialization.
 * @param {string} name The name of the constructor.
 * @param value The value to pass to the constructor.
 * @method
 */
Resurrect.prototype.builder = function(name, value) {
    var builder = {};
    builder[this.buildcode] = name;
    builder[this.valuecode] = value;
    return builder;
};

/**
 * Build a value from a deserialized builder.
 * @method
 * @see http://stackoverflow.com/a/14378462
 * @see http://nullprogram.com/blog/2013/03/24/
 */
Resurrect.prototype.build = function(ref) {
    var type = ref[this.buildcode].split(/\./).reduce(function(object, name) {
        return object[name];
    }, Resurrect.GLOBAL);
    /* Brilliant hack by kybernetikos: */
    var args = [null].concat(ref[this.valuecode]);
    var factory = type.bind.apply(type, args);
    return new factory();
};

/**
 * Dereference or build an object or value from an encoding.
 * @method
 */
Resurrect.prototype.decode = function(ref) {
    if (this.prefix in ref) {
        return this.deref(ref);
    } else if (this.buildcode in ref) {
        return this.build(ref);
    } else {
        throw new this.Error('Unknown encoding.');
    }
};

/**
 * @returns True if the provided object is already tagged for serialization.
 * @method
 */
Resurrect.prototype.isTagged = function(object) {
    return (this.refcode in object) && (object[this.refcode] != null);
};

/**
 * Visit root and all its ancestors, visiting atoms with f.
 * @param {Function} f
 * @returns A fresh copy of root to be serialized.
 * @method
 */
Resurrect.prototype.visit = function(root, f) {
    if (Resurrect.isAtom(root)) {
        return f(root);
    } else if (!this.isTagged(root)) {
        var copy = null;
        if (Resurrect.isArray(root)) {
            copy = [];
            root[this.refcode] = this.tag(copy);
            for (var i = 0; i < root.length; i++) {
                copy.push(this.visit(root[i], f));
            }
        } else { /* Object */
            copy = Object.create(Object.getPrototypeOf(root));
            root[this.refcode] = this.tag(copy);
            for (var key in root) {
                if (root.hasOwnProperty(key)) {
                    copy[key] = this.visit(root[key], f);
                }
            }
        }
        copy[this.origcode] = root;
        return this.ref(copy);
    } else {
        return this.ref(root);
    }
};

/**
 * Manage special atom values, possibly returning an encoding.
 */
Resurrect.prototype.handleAtom = function(atom) {
    var Node = Resurrect.GLOBAL.Node || function() {};
    if (Resurrect.isFunction(atom)) {
        throw new this.Error("Can't serialize functions.");
    } else if (atom instanceof Node) {
        var xmls = new XMLSerializer();
        return this.builder('Resurrect.Node', [xmls.serializeToString(atom)]);
    } else if (Resurrect.isDate(atom)) {
        return this.builder('Date', [atom.toISOString()]);
    } else if (Resurrect.isRegExp(atom)) {
        var args = atom.toString().match(/\/(.+)\/([gimy]*)/).slice(1);
        return this.builder('RegExp', args);
    } else if (atom === undefined) {
        return this.ref(undefined);
    } else {
        return atom;
    }
};

/**
 * Serialize an arbitrary JavaScript object, carefully preserving it.
 * @method
 */
Resurrect.prototype.stringify = function(object) {
    if (Resurrect.isAtom(object)) {
        return JSON.stringify(this.handleAtom(object));
    } else {
        this.table = [];
        this.visit(object, this.handleAtom.bind(this));
        for (var i = 0; i < this.table.length; i++) {
            if (this.cleanup) {
                delete this.table[i][this.origcode][this.refcode];
            } else {
                this.table[i][this.origcode][this.refcode] = null;
            }
            delete this.table[i][this.refcode];
            delete this.table[i][this.origcode];
        }
        var table = this.table;
        this.table = null;
        return JSON.stringify(table);
    }
};

/**
 * Restore the __proto__ of the given object to the proper value.
 * @returns The object.
 */
Resurrect.prototype.fixPrototype = function(object) {
    if (this.prefix in object) {
        var name = object[this.prefix];
        var prototype = this.resolver.getPrototype(name);
        if ('__proto__' in object) {
            object.__proto__ = prototype;
            if (this.cleanup) {
                delete object[this.prefix];
            }
            return object;
        } else { // IE
            var copy = Object.create(prototype);
            for (var key in object) {
                if (object.hasOwnProperty(key) && key !== this.prefix) {
                    copy[key] = object[key];
                }
            }
            return copy;
        }
    } else {
        return object;
    }
};

/**
 * Deserialize an encoded object, restoring circularity and behavior.
 * @param {string} string
 * @returns The decoded object or value.
 * @method
 */
Resurrect.prototype.resurrect = function(string) {
    var result = null;
    var data = JSON.parse(string);
    if (Resurrect.isArray(data)) {
        this.table = data;
        /* Restore __proto__. */
        if (this.revive) {
            for (var i = 0; i < this.table.length; i++) {
                this.table[i] = this.fixPrototype(this.table[i]);
            }
        }
        /* Re-establish object references and construct atoms. */
        for (i = 0; i < this.table.length; i++) {
            var object = this.table[i];
            for (var key in object) {
                if (object.hasOwnProperty(key)) {
                    if (!(Resurrect.isAtom(object[key]))) {
                        object[key] = this.decode(object[key]);
                    }
                }
            }
        }
        result = this.table[0];
    } else if (Resurrect.isObject(data)) {
        this.table = [];
        result = this.decode(data);
    } else {
        result = data;
    }
    this.table = null;
    return result;
};
<commit_msg>Pass through JSON.stringify optional arguments<commit_after>/**
 * # ResurrectJS
 * @version 1.0.0
 *
 * ResurrectJS preserves object behavior (prototypes) and reference
 * circularity with a special JSON encoding. Unlike regular JSON,
 * Date, RegExp, DOM objects, and `undefined` are also properly
 * preserved.
 *
 * ## Examples
 *
 * function Foo() {}
 * Foo.prototype.greet = function() { return "hello"; };
 *
 * // Behavior is preserved:
 * var necromancer = new Resurrect();
 * var json = necromancer.stringify(new Foo());
 * var foo = necromancer.resurrect(json);
 * foo.greet();  // => "hello"
 *
 * // References to the same object are preserved:
 * json = necromancer.stringify([foo, foo]);
 * var array = necromancer.resurrect(json);
 * array[0] === array[1];  // => true
 * array[1].greet();  // => "hello"
 *
 * // Dates are restored properly
 * json = necromancer.stringify(new Date());
 * var date = necromancer.resurrect(json);
 * Object.prototype.toString.call(date);  // => "[object Date]"
 *
 * ## Options
 *
 * Options are provided to the constructor as an object with these
 * properties:
 *
 *   prefix ('#'): A prefix string used for temporary properties added
 *     to objects during serialization and deserialization. It is
 *     important that you don't use any properties beginning with this
 *     string. This option must be consistent between both
 *     serialization and deserialization.
 *
 *   cleanup (false): Perform full property cleanup after both
 *     serialization and deserialization using the `delete`
 *     operator. This may cause performance penalties (breaking hidden
 *     classes in V8) on objects that ResurrectJS touches, so enable
 *     with care.
 *
 *   revive (true): Restore behavior (__proto__) to objects that have
 *     been resurrected. If this is set to false during serialization,
 *     resurrection information will not be encoded. You still get
 *     circularity and Date support.
 *
 *   resolver (Resurrect.NamespaceResolver(window)): Converts between
 *     a name and a prototype. Create a custom resolver if your
 *     constructors are not stored in global variables. The resolver
 *     has two methods: getName(object) and getPrototype(string).
 *
 * For example,
 *
 * var necromancer = new Resurrect({
 *     prefix: '__#',
 *     cleanup: true
 * });
 *
 * ## Caveats
 *
 *   * With the default resolver, all constructors must be named and
 *   stored in the global variable under that name. This is required
 *   so that the prototypes can be looked up and reconnected at
 *   resurrection time.
 *
 *   * The wrapper objects Boolean, String, and Number will be
 *   unwrapped. This means extra properties added to these objects
 *   will not be preserved.
 *
 *   * Functions cannot ever be serialized. Resurrect will throw an
 *   error if a function is found when traversing a data structure.
 *
 * @see http://nullprogram.com/blog/2013/03/28/
 */

/**
 * @namespace
 * @constructor
 */
function Resurrect(options) {
    this.table = null;
    this.prefix = '#';
    this.cleanup = false;
    this.revive = true;
    for (var option in options) {
        if (options.hasOwnProperty(option)) {
            this[option] = options[option];
        }
    }
    this.refcode = this.prefix + 'id';
    this.origcode = this.prefix + 'original';
    this.buildcode = this.prefix + '.';
    this.valuecode = this.prefix + 'v';
}

/**
 * Portable access to the global object (window, global).
 * Uses indirect eval.
 * @constant
 */
Resurrect.GLOBAL = (0, eval)('this');

/* Helper Objects */

/**
 * @constructor
 */
Resurrect.prototype.Error = function ResurrectError(message) {
    this.message = message || '';
    this.stack = new Error().stack;
};
Resurrect.prototype.Error.prototype = Object.create(Error.prototype);
Resurrect.prototype.Error.prototype.name = 'ResurrectError';

/**
 * Resolves prototypes through the properties on an object and
 * constructor names.
 * @constructor
 */
Resurrect.NamespaceResolver = function(scope) {
    this.scope = scope;
};

/**
 * Gets the prototype of the given property name from an object. If
 * not found, it throws an error.
 * @param {string} name
 * @method
 */
Resurrect.NamespaceResolver.prototype.getPrototype = function(name) {
    var constructor = this.scope[name];
    if (constructor) {
        return constructor.prototype;
    } else {
        throw new Resurrect.prototype.Error('Unknown constructor: ' + name);
    }
};

/**
 * Get the prototype name for an object, to be fetched later with
 * getPrototype.
 * @returns {string} Null if the constructor is Object.
 * @method
 */
Resurrect.NamespaceResolver.prototype.getName = function(object) {
    var constructor = object.constructor.name;
    if (constructor == null) { // IE
        var funcPattern = /^\s*function\s*([A-Za-z0-9_$]*)/;
        constructor = funcPattern.exec(object.constructor)[1];
    }

    if (constructor === '') {
        var msg = "Can't serialize objects with anonymous constructors.";
        throw new Resurrect.prototype.Error(msg);
    } else if (constructor === 'Object' || constructor === 'Array') {
        return null;
    } else {
        return constructor;
    }
};

/* Set the default resolver searches the global object. */
Resurrect.prototype.resolver =
    new Resurrect.NamespaceResolver(Resurrect.GLOBAL);

/**
 * Create a DOM node from HTML source; behaves like a constructor.
 * @constructor
 */
Resurrect.Node = function(html) {
    var div = document.createElement('div');
    div.innerHTML = html;
    return div.firstChild;
};

/* Type Tests */

/**
 * @param {string} type
 * @returns {Function} A function that tests for type.
 */
Resurrect.is = function(type) {
    var string = '[object ' + type + ']';
    return function(object) {
        return Object.prototype.toString.call(object) === string;
    };
};

Resurrect.isArray = Resurrect.is('Array');
Resurrect.isString = Resurrect.is('String');
Resurrect.isBoolean = Resurrect.is('Boolean');
Resurrect.isNumber = Resurrect.is('Number');
Resurrect.isFunction = Resurrect.is('Function');
Resurrect.isDate = Resurrect.is('Date');
Resurrect.isRegExp = Resurrect.is('RegExp');
Resurrect.isObject = Resurrect.is('Object');

Resurrect.isAtom = function(object) {
    return !Resurrect.isObject(object) && !Resurrect.isArray(object);
};

/* Methods */

/**
 * Create a reference (encoding) to an object.
 * @method
 */
Resurrect.prototype.ref = function(object) {
    var ref = {};
    if (object === undefined) {
        ref[this.prefix] = -1;
    } else {
        ref[this.prefix] = object[this.refcode];
    }
    return ref;
};

/**
 * Lookup an object in the table by reference object.
 * @method
 */
Resurrect.prototype.deref = function(ref) {
    return this.table[ref[this.prefix]];
};

/**
 * Put a temporary identifier on an object and store it in the table.
 * @returns {number} The unique identifier number.
 * @method
 */
Resurrect.prototype.tag = function(object) {
    if (this.revive) {
        var constructor = this.resolver.getName(object);
        if (constructor) {
            var proto = Object.getPrototypeOf(object);
            if (this.resolver.getPrototype(constructor) !== proto) {
                throw new this.Error('Constructor mismatch!');
            } else {
                object[this.prefix] = constructor;
            }
        }
    }
    object[this.refcode] = this.table.length;
    this.table.push(object);
    return object[this.refcode];
};

/**
 * Create a builder object (encoding) for serialization.
 * @param {string} name The name of the constructor.
 * @param value The value to pass to the constructor.
 * @method
 */
Resurrect.prototype.builder = function(name, value) {
    var builder = {};
    builder[this.buildcode] = name;
    builder[this.valuecode] = value;
    return builder;
};

/**
 * Build a value from a deserialized builder.
 * @method
 * @see http://stackoverflow.com/a/14378462
 * @see http://nullprogram.com/blog/2013/03/24/
 */
Resurrect.prototype.build = function(ref) {
    var type = ref[this.buildcode].split(/\./).reduce(function(object, name) {
        return object[name];
    }, Resurrect.GLOBAL);
    /* Brilliant hack by kybernetikos: */
    var args = [null].concat(ref[this.valuecode]);
    var factory = type.bind.apply(type, args);
    return new factory();
};

/**
 * Dereference or build an object or value from an encoding.
 * @method
 */
Resurrect.prototype.decode = function(ref) {
    if (this.prefix in ref) {
        return this.deref(ref);
    } else if (this.buildcode in ref) {
        return this.build(ref);
    } else {
        throw new this.Error('Unknown encoding.');
    }
};

/**
 * @returns True if the provided object is already tagged for serialization.
 * @method
 */
Resurrect.prototype.isTagged = function(object) {
    return (this.refcode in object) && (object[this.refcode] != null);
};

/**
 * Visit root and all its ancestors, visiting atoms with f.
 * @param {Function} f
 * @returns A fresh copy of root to be serialized.
 * @method
 */
Resurrect.prototype.visit = function(root, f) {
    if (Resurrect.isAtom(root)) {
        return f(root);
    } else if (!this.isTagged(root)) {
        var copy = null;
        if (Resurrect.isArray(root)) {
            copy = [];
            root[this.refcode] = this.tag(copy);
            for (var i = 0; i < root.length; i++) {
                copy.push(this.visit(root[i], f));
            }
        } else { /* Object */
            copy = Object.create(Object.getPrototypeOf(root));
            root[this.refcode] = this.tag(copy);
            for (var key in root) {
                if (root.hasOwnProperty(key)) {
                    copy[key] = this.visit(root[key], f);
                }
            }
        }
        copy[this.origcode] = root;
        return this.ref(copy);
    } else {
        return this.ref(root);
    }
};

/**
 * Manage special atom values, possibly returning an encoding.
 */
Resurrect.prototype.handleAtom = function(atom) {
    var Node = Resurrect.GLOBAL.Node || function() {};
    if (Resurrect.isFunction(atom)) {
        throw new this.Error("Can't serialize functions.");
    } else if (atom instanceof Node) {
        var xmls = new XMLSerializer();
        return this.builder('Resurrect.Node', [xmls.serializeToString(atom)]);
    } else if (Resurrect.isDate(atom)) {
        return this.builder('Date', [atom.toISOString()]);
    } else if (Resurrect.isRegExp(atom)) {
        var args = atom.toString().match(/\/(.+)\/([gimy]*)/).slice(1);
        return this.builder('RegExp', args);
    } else if (atom === undefined) {
        return this.ref(undefined);
    } else {
        return atom;
    }
};

/**
 * Serialize an arbitrary JavaScript object, carefully preserving it.
 * @method
 */
Resurrect.prototype.stringify = function(object, replacer, space) {
    if (Resurrect.isAtom(object)) {
        return JSON.stringify(this.handleAtom(object), replacer, space);
    } else {
        this.table = [];
        this.visit(object, this.handleAtom.bind(this));
        for (var i = 0; i < this.table.length; i++) {
            if (this.cleanup) {
                delete this.table[i][this.origcode][this.refcode];
            } else {
                this.table[i][this.origcode][this.refcode] = null;
            }
            delete this.table[i][this.refcode];
            delete this.table[i][this.origcode];
        }
        var table = this.table;
        this.table = null;
        return JSON.stringify(table, replacer, space);
    }
};

/**
 * Restore the __proto__ of the given object to the proper value.
 * @returns The object.
 */
Resurrect.prototype.fixPrototype = function(object) {
    if (this.prefix in object) {
        var name = object[this.prefix];
        var prototype = this.resolver.getPrototype(name);
        if ('__proto__' in object) {
            object.__proto__ = prototype;
            if (this.cleanup) {
                delete object[this.prefix];
            }
            return object;
        } else { // IE
            var copy = Object.create(prototype);
            for (var key in object) {
                if (object.hasOwnProperty(key) && key !== this.prefix) {
                    copy[key] = object[key];
                }
            }
            return copy;
        }
    } else {
        return object;
    }
};

/**
 * Deserialize an encoded object, restoring circularity and behavior.
 * @param {string} string
 * @returns The decoded object or value.
 * @method
 */
Resurrect.prototype.resurrect = function(string) {
    var result = null;
    var data = JSON.parse(string);
    if (Resurrect.isArray(data)) {
        this.table = data;
        /* Restore __proto__. */
        if (this.revive) {
            for (var i = 0; i < this.table.length; i++) {
                this.table[i] = this.fixPrototype(this.table[i]);
            }
        }
        /* Re-establish object references and construct atoms. */
        for (i = 0; i < this.table.length; i++) {
            var object = this.table[i];
            for (var key in object) {
                if (object.hasOwnProperty(key)) {
                    if (!(Resurrect.isAtom(object[key]))) {
                        object[key] = this.decode(object[key]);
                    }
                }
            }
        }
        result = this.table[0];
    } else if (Resurrect.isObject(data)) {
        this.table = [];
        result = this.decode(data);
    } else {
        result = data;
    }
    this.table = null;
    return result;
};
<|endoftext|>


<commit_before>const electron = require('electron')
const os = require('os')

// Module to control application life.
const { Menu, app, shell, dialog } = electron;

const buildMenu = (mainWindow, loadInit) => {
    let menu = []

    // On Windows, both the forward slash `/` and the backward slash `\` are accepted as path delimiters.
    // The node APIs only return the backward slash, ie: `C:\\oni\\README.md`, but this causes problems
    // for VIM as it sees escape keys.
    const normalizePath = (fileName) => fileName.split("\\").join("/")

    const executeVimCommand = (command) => mainWindow.webContents.send("menu-item-click", command)

    const executeVimCommandForMultipleFiles = (command, files) => mainWindow.webContents.send("open-files", command, files)

    const executeOniCommand = (command) => mainWindow.webContents.send("execute-command", command)

    const executeVimCommandForFiles = (command, files) => {
        if (!files || !files.length)
            return

        files.forEach((fileName) => executeVimCommand(`${command} ${normalizePath(fileName)}`))
    }

    let preferences = {
        label: 'Preferences',
        submenu: [
            {
                label: "Edit Oni config",
                click: () => executeOniCommand("oni.config.openConfigJs")
            },
        ]
    }

    if (loadInit) {
        preferences.submenu.push(
        {
            label: "Edit Neovim config",
            click: () => executeOniCommand("oni.config.openInitVim")
        })
    }

    let firstMenu = os.platform() == "win32" ? 'File' : 'Oni';
    menu.unshift({
        label: firstMenu,
        submenu: [
            {
                label: 'Open File...',
                click: (item, focusedWindow) => {
                    dialog.showOpenDialog(mainWindow, { properties: ['openFile', 'multiSelections'] }, (files) => {
                        executeVimCommandForMultipleFiles(":tabnew", files)
                    })
                }
            },
            {
                label: 'Open Folder...',
                click: (item, focusedWindow) => {
                    executeOniCommand("oni.openFolder")
                }
            },
            {
                label: 'Split Open...',
                click: (item, focusedWindow) => {
                    dialog.showOpenDialog(mainWindow, 'openFile', (files) => {
                        executeVimCommandForFiles(":sp", files)
                    })
                }
            },
            {
                label: 'New',
                click: (item, focusedWindow) => executeVimCommand(":enew")
            },
            {
                label: 'Close',
                click: (item, focusedWindow) => executeVimCommand(":close")
            },
            {
                type: 'separator'
            },
            preferences,
            {
                type: 'separator'
            },
            {
                label: 'Save',
                click: (item, focusedWindow) => executeVimCommand(":w")
            },
            {
                label: 'Save As...',
                click: (item, focusedWindow) => {
                    dialog.showSaveDialog(mainWindow, {}, (name) => {
                        if (name) {
                            executeVimCommand(":save " + name)
                        }
                    })
                }
            },
            {
                label: 'Save All',
                click: (item, focusedWindow) => executeVimCommand(":wall")
            },
            {
                type: 'separator'
            },
            {
                label: 'Quit',
                click: (item, focusedWindow) => {
                    app.quit()
                }
            }
        ]
    })

    // Edit menu
    menu.push({
        label: "Edit",
        submenu:  [

       {
           label: 'Undo',
           click: (item, focusedWindow) => executeVimCommand("u")
       },
       {
           label: 'Redo',
           click: (item, focusedWindow) => executeVimCommand("\\<C-r>")
       },
       {
           label: 'Repeat',
           click: (item, focusedWindow) => executeVimCommand(".")
       },
       {
           type: 'separator'
       },
       {
           label: 'Cut',
           click: (item, focusedWindow) => executeVimCommand('\\"+x')
       },
       {
           label: 'Copy',
           click: (item, focusedWindow) => executeVimCommand('\\"+y')
       },
       {
           label: 'Paste',
           click: (item, focusedWindow) => executeVimCommand('\\"+gP')
       },
       {
           label: 'Paste Line Before',
           click: (item, focusedWindow) => executeVimCommand("[p")
       },
       {
           label: 'Paste Line After',
           click: (item, focusedWindow) => executeVimCommand("]p")
       },
       {
           label: 'Select All',
           click: (item, focusedWindow) => executeVimCommand("ggVG")
       }
    ]})

    // Window menu
    menu.push({

        label:  'Split',
    submenu : [
        {
           label: 'New Horizontal Split',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>n")
        },
        {
           label: 'Split File Horizontally',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>s")
        },
        {
           label: 'Split File Vertically',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>v")
        },
        {
           label: 'File Explorer Split',
           click: (item, focusedWindow) => executeVimCommand(":Lexplore | vertical resize 30")
        },
        {
            type: 'separator'
        },
        {
           label: 'Close',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>c")
        },
        {
           label: 'Close Other Split(s)',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>o")
        },
        {
            type: 'separator'
        },
        {
           label: 'Move To',
           submenu: [
           {
                label: 'Top',
                click: (item, focusedWindow) => executeVimCommand("\\<C-w>K")
            },
            {
                label: 'Bottom',
                click: (item, focusedWindow) => executeVimCommand("\\<C-w>J")
            },
            {
                label: 'Left Side',
                click: (item, focusedWindow) => executeVimCommand("\\<C-w>H")
            },
            {
                label: 'Right Side',
                click: (item, focusedWindow) => executeVimCommand("\\<C-w>L")
            }]
        },
        {
           label: 'Rotate Up',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>R")
        },
        {
           label: 'Rotate Down',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>r")
        },
        {
            type: 'separator'
        },
        {
           label: 'Equal Size',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>=")
        },
        {
           label: 'Max Height',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>_")
        },
        {
           label: 'Min Height',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>1_")
        },
        {
           label: 'Max Width',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>|")
        },
        {
           label: 'Min Width',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>1|")
        }
    ]})

    // Help menu
    menu.push({
        label: "Help",
        submenu: [
        {
            label: 'Learn more',
            click: (item, focusedWindow) => {
                shell.openExternal('https://github.com/extr0py/oni#introduction');
            }
        },
        {
            label: 'Issues',
            click: (item, focusedWindow) => {
                shell.openExternal('https://github.com/extr0py/oni/issues');
            }
        },
        {
            label: 'Github',
            click: (item, focusedWindow) => {
                shell.openExternal('https://github.com/extr0py/oni');
            }
        },
        {
            type: 'separator'
        },
        {
            label: 'Developer Tools',
            click: () => executeOniCommand('oni.debug.openDevTools')
        }
    ]})

    return Menu.buildFromTemplate(menu)
}

module.exports = {
    buildMenu: buildMenu
}
<commit_msg>Add space back for tabnew, in order fix issue when opening multiple files after a first file has been opened (#621)<commit_after>const electron = require('electron')
const os = require('os')

// Module to control application life.
const { Menu, app, shell, dialog } = electron;

const buildMenu = (mainWindow, loadInit) => {
    let menu = []

    // On Windows, both the forward slash `/` and the backward slash `\` are accepted as path delimiters.
    // The node APIs only return the backward slash, ie: `C:\\oni\\README.md`, but this causes problems
    // for VIM as it sees escape keys.
    const normalizePath = (fileName) => fileName.split("\\").join("/")

    const executeVimCommand = (command) => mainWindow.webContents.send("menu-item-click", command)

    const executeVimCommandForMultipleFiles = (command, files) => mainWindow.webContents.send("open-files", command, files)

    const executeOniCommand = (command) => mainWindow.webContents.send("execute-command", command)

    const executeVimCommandForFiles = (command, files) => {
        if (!files || !files.length)
            return

        files.forEach((fileName) => executeVimCommand(`${command} ${normalizePath(fileName)}`))
    }

    let preferences = {
        label: 'Preferences',
        submenu: [
            {
                label: "Edit Oni config",
                click: () => executeOniCommand("oni.config.openConfigJs")
            },
        ]
    }

    if (loadInit) {
        preferences.submenu.push(
        {
            label: "Edit Neovim config",
            click: () => executeOniCommand("oni.config.openInitVim")
        })
    }

    let firstMenu = os.platform() == "win32" ? 'File' : 'Oni';
    menu.unshift({
        label: firstMenu,
        submenu: [
            {
                label: 'Open File...',
                click: (item, focusedWindow) => {
                    dialog.showOpenDialog(mainWindow, { properties: ['openFile', 'multiSelections'] }, (files) => {
                        executeVimCommandForMultipleFiles(":tabnew ", files)
                    })
                }
            },
            {
                label: 'Open Folder...',
                click: (item, focusedWindow) => {
                    executeOniCommand("oni.openFolder")
                }
            },
            {
                label: 'Split Open...',
                click: (item, focusedWindow) => {
                    dialog.showOpenDialog(mainWindow, 'openFile', (files) => {
                        executeVimCommandForFiles(":sp", files)
                    })
                }
            },
            {
                label: 'New',
                click: (item, focusedWindow) => executeVimCommand(":enew")
            },
            {
                label: 'Close',
                click: (item, focusedWindow) => executeVimCommand(":close")
            },
            {
                type: 'separator'
            },
            preferences,
            {
                type: 'separator'
            },
            {
                label: 'Save',
                click: (item, focusedWindow) => executeVimCommand(":w")
            },
            {
                label: 'Save As...',
                click: (item, focusedWindow) => {
                    dialog.showSaveDialog(mainWindow, {}, (name) => {
                        if (name) {
                            executeVimCommand(":save " + name)
                        }
                    })
                }
            },
            {
                label: 'Save All',
                click: (item, focusedWindow) => executeVimCommand(":wall")
            },
            {
                type: 'separator'
            },
            {
                label: 'Quit',
                click: (item, focusedWindow) => {
                    app.quit()
                }
            }
        ]
    })

    // Edit menu
    menu.push({
        label: "Edit",
        submenu:  [

       {
           label: 'Undo',
           click: (item, focusedWindow) => executeVimCommand("u")
       },
       {
           label: 'Redo',
           click: (item, focusedWindow) => executeVimCommand("\\<C-r>")
       },
       {
           label: 'Repeat',
           click: (item, focusedWindow) => executeVimCommand(".")
       },
       {
           type: 'separator'
       },
       {
           label: 'Cut',
           click: (item, focusedWindow) => executeVimCommand('\\"+x')
       },
       {
           label: 'Copy',
           click: (item, focusedWindow) => executeVimCommand('\\"+y')
       },
       {
           label: 'Paste',
           click: (item, focusedWindow) => executeVimCommand('\\"+gP')
       },
       {
           label: 'Paste Line Before',
           click: (item, focusedWindow) => executeVimCommand("[p")
       },
       {
           label: 'Paste Line After',
           click: (item, focusedWindow) => executeVimCommand("]p")
       },
       {
           label: 'Select All',
           click: (item, focusedWindow) => executeVimCommand("ggVG")
       }
    ]})

    // Window menu
    menu.push({

        label:  'Split',
    submenu : [
        {
           label: 'New Horizontal Split',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>n")
        },
        {
           label: 'Split File Horizontally',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>s")
        },
        {
           label: 'Split File Vertically',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>v")
        },
        {
           label: 'File Explorer Split',
           click: (item, focusedWindow) => executeVimCommand(":Lexplore | vertical resize 30")
        },
        {
            type: 'separator'
        },
        {
           label: 'Close',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>c")
        },
        {
           label: 'Close Other Split(s)',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>o")
        },
        {
            type: 'separator'
        },
        {
           label: 'Move To',
           submenu: [
           {
                label: 'Top',
                click: (item, focusedWindow) => executeVimCommand("\\<C-w>K")
            },
            {
                label: 'Bottom',
                click: (item, focusedWindow) => executeVimCommand("\\<C-w>J")
            },
            {
                label: 'Left Side',
                click: (item, focusedWindow) => executeVimCommand("\\<C-w>H")
            },
            {
                label: 'Right Side',
                click: (item, focusedWindow) => executeVimCommand("\\<C-w>L")
            }]
        },
        {
           label: 'Rotate Up',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>R")
        },
        {
           label: 'Rotate Down',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>r")
        },
        {
            type: 'separator'
        },
        {
           label: 'Equal Size',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>=")
        },
        {
           label: 'Max Height',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>_")
        },
        {
           label: 'Min Height',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>1_")
        },
        {
           label: 'Max Width',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>|")
        },
        {
           label: 'Min Width',
           click: (item, focusedWindow) => executeVimCommand("\\<C-w>1|")
        }
    ]})

    // Help menu
    menu.push({
        label: "Help",
        submenu: [
        {
            label: 'Learn more',
            click: (item, focusedWindow) => {
                shell.openExternal('https://github.com/extr0py/oni#introduction');
            }
        },
        {
            label: 'Issues',
            click: (item, focusedWindow) => {
                shell.openExternal('https://github.com/extr0py/oni/issues');
            }
        },
        {
            label: 'Github',
            click: (item, focusedWindow) => {
                shell.openExternal('https://github.com/extr0py/oni');
            }
        },
        {
            type: 'separator'
        },
        {
            label: 'Developer Tools',
            click: () => executeOniCommand('oni.debug.openDevTools')
        }
    ]})

    return Menu.buildFromTemplate(menu)
}

module.exports = {
    buildMenu: buildMenu
}
<|endoftext|>


<commit_before>'use strict';

function rule(analyzer) {
	analyzer.setMetric('redundantBodySelectors');

	analyzer.on('selector', function(rule, selector, expressions) {
		var noExpressions = expressions.length;

		// check more complex selectors only
		if (noExpressions < 2) {
			return;
		}

		var firstTag = expressions[0].tag,
			lastTag = expressions[noExpressions-1].tag,
			isDescendantCombinator = (expressions[1].combinator === '>'),
			isRedundant = false;

		// matches "html > body" fixes
		if (firstTag === 'html' && isDescendantCombinator && expressions[1].tag === 'body') {
			isRedundant = false;
		}
		// matches html.modal-popup-mode body (issue #44)
		else if (firstTag === 'html' && lastTag === 'body' && noExpressions === 2) {
			isRedundant = false;
		}
		// matches "body .foo", but not "body > .bar' nor "body.foo .bar"
		else if (firstTag === 'body' && !isDescendantCombinator && !expressions[0].classList) {
			isRedundant = true;
		}
		// matches ".foo body > h2"
		else {
			expressions.slice(1).forEach(function(expr) {
				if (expr.tag === 'body') {
					isRedundant = true;
				}
			});
		}

		if (isRedundant) {
			analyzer.incrMetric('redundantBodySelectors');
			analyzer.addOffender('redundantBodySelectors', selector);
		}
	});
}

rule.description = 'Reports redundant body selectors';
module.exports = rule;
<commit_msg>`body` not always redundant<commit_after>'use strict';

function rule(analyzer) {
	analyzer.setMetric('redundantBodySelectors');

	analyzer.on('selector', function(rule, selector, expressions) {
		var noExpressions = expressions.length;

		// check more complex selectors only
		if (noExpressions < 2) {
			return;
		}

		var firstTag = expressions[0].tag,
			firstHasClass = !!expressions[0].classList,
			isDescendantCombinator = (expressions[1].combinator === '>'),
			isShortExpression = (expressions.length === 2),
			isRedundant = true; // always expect the worst ;)

		// first, let's find the body tag selector in the expression
		var bodyIndex = expressions.
			map(function(item) {
				return item.tag;
			}).
			indexOf('body');

		// body selector not found - skip the rules that follow
		if (bodyIndex < 0) {
			return;
		}

		// matches "html > body"
		// matches "html.modal-popup-mode body" (issue #44)
		if ( (firstTag === 'html') && (bodyIndex === 1) && (isDescendantCombinator || isShortExpression) ) {
			isRedundant = false;
		}
		// matches "body .foo", but not "body > .bar' nor "body.foo .bar"
		else if ( (bodyIndex === 0) && isDescendantCombinator && isShortExpression ) {
			isRedundant = false;
		}
		// matches "body.foo ul li a"
		else if ( (bodyIndex === 0) && firstHasClass) {
			isRedundant = false;
		}
		// matches ".has-modal > body" (issue #49)
		else if ( firstHasClass && (bodyIndex === 1) && isDescendantCombinator) {
			isRedundant = false;
		}

		// report he redundant body selector
		if (isRedundant) {
			analyzer.incrMetric('redundantBodySelectors');
			analyzer.addOffender('redundantBodySelectors', selector);
		}
	});
}

rule.description = 'Reports redundant body selectors';
module.exports = rule;
<|endoftext|>


<commit_before>var app = angular.module('app', ['ngSanitize', 'ui.bootstrap', 'LocalStorageModule',]);

app.controller('HomeController',
  function($scope, $uibModal, localStorageService)
  {

    var recreateIds = function() {
      _.map($scope.tree, function(node, idx) {
        node.id = idx.toString();
      });
    };

    $scope.btnDeleteNodeClicked = function() {
      $scope.tree.splice($scope.selectedNode.id, 1);
      recreateIds();
      $scope.selectedNode = null;
    };

    $scope.btnDeletePathClicked = function(key) {
      delete $scope.selectedNode.parentsPaths[key];
    };

    $scope.btnMoveDownClicked = function(path, $index) {
      var point = path.splice($index, 1)[0];
      path.splice($index + 1, 0, point);
    };

    $scope.btnMoveUpClicked = function(path, $index) {
      var point = path.splice($index, 1)[0];
      path.splice($index - 1, 0, point);
    };

    $scope.btnRemovePointClicked = function(path, $index) {
      path.splice($index, 1);
    };

    $scope.btnAddPointClicked = function(path) {
      var point = [0, 0, 0];
      path.push(point);
    };

    $scope.btnSaveClicked = function() {
      var modalInstance = $uibModal.open({
        animation: true,
        template:
          '
' +
          '
' +
          '    <button type="button" class="close" ng-click="cancel()">x</button>' +
          '
Save
' +
          '
' +
          '
' +
          '    <input ng-model="input.name" type="text" class="form-control" ng-enter="btnSaveClicked()" focus-me required />' +
          '
' +
          '
' +
          '    <input type="button" value="Save" class="btn btn-primary" ng-click="btnSaveClicked()" />' +
          '    <input type="button" value="Close" class="btn btn-default" ng-click="cancel()" />' +
          '
' +
          '
',
        controller: function($scope, tree, $uibModalInstance, projectName) {
          $scope.input = {};
          $scope.input.name = projectName;
          $scope.btnSaveClicked = function() {
            if (_.isEmpty($scope.input.name)) {
              return;
            }
            var names = localStorageService.get('names') || {};
            names[$scope.input.name] = tree;
            localStorageService.set('names', names);
            $uibModalInstance.close();
          };
          $scope.cancel = function() {
            $uibModalInstance.dismiss('cancel');
          };
        },
        size: 'sm',
        resolve: {
          projectName: function() { return $scope.input.projectName; },
          tree: function() { return $scope.tree; }
        },
      });
    };

    $scope.btnLoadClicked = function() {
      var modalInstance = $uibModal.open({
        animation: true,
        template:
          '
' +
          '
' +
          '    <button type="button" class="close" ng-click="cancel()">x</button>' +
          '
Load
' +
          '
' +
          '
' +
          '    <select ng-model="input.name" ng-options="name for name in names" class="form-control" ng-enter="btnLoadClicked()" focus-me></select>' +
          '
' +
          '
' +
          '    <input type="button" value="Load" class="btn btn-primary" ng-click="btnLoadClicked()" />' +
          '    <input type="button" value="Close" class="btn btn-default" ng-click="cancel()" />' +
          '
' +
          '
',
        controller: 'LoadModalController',
        size: 'sm',
      }).result.then(function(res) {
        if (res) {
          $scope.input.projectName = res.projectName;
          $scope.tree = res.data;
        }
      });
    };

    $scope.toJson = function(tree) {
      return angular.toJson(tree, true);
    };

    (function constructor() {
      $scope.selectedNode = null;
      $scope.inputFile = '';
      $scope.testFile = '';
      $scope.shellFile = '';
      $scope.tree = [];
      $scope.input = {};

      $scope.colors = [
        '#5aa1be',
        '#c065b8',
        '#c0ab5f',
        '#59bc95',
        '#7a63be',
        '#c0615b',
        '#73bb5e',
        '#6ee585',
        '#7088e8',
        '#eb77a3',
        '#c2e675',
      ];

    })();

  }
);
<commit_msg>Deleting a node will move all children and paths and shits<commit_after>var app = angular.module('app', ['ngSanitize', 'ui.bootstrap', 'LocalStorageModule',]);

app.controller('HomeController',
  function($scope, $uibModal, localStorageService)
  {

    var recreateIds = function() {
      _.map($scope.tree, function(node, idx) {
        node.id = idx.toString();
      });
    };

    var removeFromChildrenParents = function(parentId) {
      _.each($scope.tree, function(node) {
        delete node.parentsPaths[parentId];
      });
      var nbNodes = $scope.tree.length;
      _.each($scope.tree, function(node) {
        _.each(node.parentsPaths, function(path, key) {
          if (key > parentId) {
            node.parentsPaths[key-1] = path;
          }
        });
        delete node.parentsPaths[nbNodes];
      });
    };

    $scope.btnDeleteNodeClicked = function() {
      var idToRemove = $scope.selectedNode.id;
      $scope.tree.splice(idToRemove, 1);
      recreateIds();
      removeFromChildrenParents(idToRemove);
      _.each($scope.tree, function(node) {
        _.each(node.parents, function(nodeParent, idx) {
          if (nodeParent == idToRemove) {
            node.parents.splice(idx, 1);
          } else if (nodeParent > idToRemove) {
            node.parents[idx]--;
          }
        });
        _.each(node.parentsPaths, function(path, parentId) {
          _.each(path.path, function(point, idx) {
            if (point[1] > idToRemove) {
              node.parentsPaths[parentId].path[idx][1]--;
            }
          });
        });
      });
      $scope.selectedNode = null;
    };

    $scope.btnDeletePathClicked = function(key) {
      delete $scope.selectedNode.parentsPaths[key];
    };

    $scope.btnMoveDownClicked = function(path, $index) {
      var point = path.splice($index, 1)[0];
      path.splice($index + 1, 0, point);
    };

    $scope.btnMoveUpClicked = function(path, $index) {
      var point = path.splice($index, 1)[0];
      path.splice($index - 1, 0, point);
    };

    $scope.btnRemovePointClicked = function(path, $index) {
      path.splice($index, 1);
    };

    $scope.btnAddPointClicked = function(path) {
      var point = [0, 0, 0];
      path.push(point);
    };

    $scope.btnSaveClicked = function() {
      var modalInstance = $uibModal.open({
        animation: true,
        template:
          '
' +
          '
' +
          '    <button type="button" class="close" ng-click="cancel()">x</button>' +
          '
Save
' +
          '
' +
          '
' +
          '    <input ng-model="input.name" type="text" class="form-control" ng-enter="btnSaveClicked()" focus-me required />' +
          '
' +
          '
' +
          '    <input type="button" value="Save" class="btn btn-primary" ng-click="btnSaveClicked()" />' +
          '    <input type="button" value="Close" class="btn btn-default" ng-click="cancel()" />' +
          '
' +
          '
',
        controller: function($scope, tree, $uibModalInstance, projectName) {
          $scope.input = {};
          $scope.input.name = projectName;
          $scope.btnSaveClicked = function() {
            if (_.isEmpty($scope.input.name)) {
              return;
            }
            var names = localStorageService.get('names') || {};
            names[$scope.input.name] = tree;
            localStorageService.set('names', names);
            $uibModalInstance.close();
          };
          $scope.cancel = function() {
            $uibModalInstance.dismiss('cancel');
          };
        },
        size: 'sm',
        resolve: {
          projectName: function() { return $scope.input.projectName; },
          tree: function() { return $scope.tree; }
        },
      });
    };

    $scope.btnLoadClicked = function() {
      var modalInstance = $uibModal.open({
        animation: true,
        template:
          '
' +
          '
' +
          '    <button type="button" class="close" ng-click="cancel()">x</button>' +
          '
Load
' +
          '
' +
          '
' +
          '    <select ng-model="input.name" ng-options="name for name in names" class="form-control" ng-enter="btnLoadClicked()" focus-me></select>' +
          '
' +
          '
' +
          '    <input type="button" value="Load" class="btn btn-primary" ng-click="btnLoadClicked()" />' +
          '    <input type="button" value="Close" class="btn btn-default" ng-click="cancel()" />' +
          '
' +
          '
',
        controller: 'LoadModalController',
        size: 'sm',
      }).result.then(function(res) {
        if (res) {
          $scope.input.projectName = res.projectName;
          $scope.tree = res.data;
        }
      });
    };

    $scope.toJson = function(tree) {
      return angular.toJson(tree, true);
    };

    (function constructor() {
      $scope.selectedNode = null;
      $scope.inputFile = '';
      $scope.testFile = '';
      $scope.shellFile = '';
      $scope.tree = [];
      $scope.input = {};

      $scope.colors = [
        '#5aa1be',
        '#c065b8',
        '#c0ab5f',
        '#59bc95',
        '#7a63be',
        '#c0615b',
        '#73bb5e',
        '#6ee585',
        '#7088e8',
        '#eb77a3',
        '#c2e675',
      ];

    })();

  }
);
<|endoftext|>