<commit_before>var http = require('http');
var url = require('url');
var Stream = require('stream');
var Frame = require('./frame');
var Builder = require('./builder');
var runner = require('./runner');

var Argo = function(_http) {
  this._router = {};
  this._routerKeys = [];
  this.builder = new Builder();
  this._http = _http || http;

  var that = this;
  var incoming = this._http.IncomingMessage.prototype;

  if (!incoming._argoModified) {
    var _addHeaderLine = incoming._addHeaderLine;

    incoming._addHeaderLine = function(field, value) {
      this._rawHeaderNames = this._rawHeaderNames || {};
      this._rawHeaderNames[field.toLowerCase()] = field;

      _addHeaderLine.call(this, field, value);
    };

    incoming.body = null;
    incoming.getBody = that._getBody();
    incoming._argoModified = true;
  }

  var serverResponse = this._http.ServerResponse.prototype;
  if (!serverResponse._argoModified) {
    serverResponse.body = null;
    serverResponse.getBody = that._getBody();

    serverResponse._argoModified = true;
  }
};

Argo.prototype._getBody = function() {
  var that = this;
  return function(callback) {
    if (this.body) {
      callback(null, this.body);
      return;
    }
    var buf = [];
    var len = 0;

    this.on('data', function(chunk) {
      buf.push(chunk);
      len += chunk.length;
    });

    this.on('end', function() {
      var body;
      if (buf.length && Buffer.isBuffer(buf[0])) {
        body = new Buffer(len);
        var i = 0;
        buf.forEach(function(chunk) {
          chunk.copy(body, i, 0, chunk.length);
          i += chunk.length;
        });
      } else if (buf.length) {
        body = buf.join('');
      }

      this.body = body;

      callback(null, body);
    });
  };
};

Argo.prototype.include = function(mod) {
  var p = mod.package(this);
  p.install();
  return this;
};

Argo.prototype.listen = function(port) {
  runner.listen(this, port);
  return this;
};

Argo.prototype.use = function(middleware) {
  if (middleware.package) {
    return this.include(middleware);
  }
  this.builder.use(middleware);
  return this;
};

Argo.prototype.target = function(url) {
  return this.use(function(addHandler) {
    addHandler('request', function(env, next) {
      env.target.url = url + (env.request.url || '');
      next(env);
    });
  });
};

Argo.prototype.embed = function() {
  this.buildCore();

  this.builder.run(this._target);
  this.builder.use(function(addHandler) {
    addHandler('response', { affinity: 'sink' }, function(env) {
      if (env.argo.oncomplete) {
        env.argo.oncomplete(env);
      };
    });
  });

  return this.builder.build();
}

Argo.prototype.buildCore = function() {
  var that = this;

  that.builder.use(function(addHandler) {
    addHandler('request', function(env, next) {
      env.argo._http = that._http;
      next(env);
    });
  });

  var hasRoutes = false;
  for (var prop in that._router) {
    if (!hasRoutes && that._router.hasOwnProperty(prop)) {
      hasRoutes = true;
    }
  }

  if (hasRoutes) {
    that.builder.use(function addRouteHandlers(handlers) {
     that._route(that._router, handlers);
    });
  }
};

Argo.prototype.build = function() {
  var that = this;

  that.buildCore();

  that.builder.run(that._target);

  // response ender
  that.builder.use(function(handle) {
    handle('response', { affinity: 'sink' }, function(env, next) {
      if (env.response.body) {
        var body = env.response.body;
        if (typeof body === 'string') {
          env.response.setHeader('Content-Length', body ? body.length : 0);
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end(body);
        } else if (body instanceof Stream) {
          env.response.writeHead(env.response.statusCode, env.response.headers);
          body.pipe(env.response);
        } else if (typeof body === 'object') {
          body = new Buffer(JSON.stringify(body), 'utf-8');
          if (!env.response.getHeader('Content-Type')) {
            env.response.setHeader('Content-Type', 'application/json; charset=UTF-8');
          }
          env.response.setHeader('Content-Length', body ? body.length : 0);
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end(body.toString('utf-8'));
        }
      } else {
        var contentLength = env.response.getHeader('Content-Length');
        if (contentLength == '0') {
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end();
        } else if (env.target.response) {
          env.target.response.getBody(function(err, body) {
            env.response.setHeader('Content-Length', body ? body.length : 0);
            env.response.writeHead(env.response.statusCode, env.response.headers);
            env.response.end(body);
          });
        } else {
          env.response.setHeader('Content-Length', '0');
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end();
        }
      }
    });
  });

  return that.builder.build();
};

Argo.prototype.call = function(env) {
  var app = this.build();
  return app.flow(env);
}

Argo.prototype.route = function(path, options, handlers) {
  if (typeof(options) === 'function') {
    handlers = options;
    options = {};
  }

  options.methods = options.methods || ['*'];
  if (!this._router[path]) {
    this._router[path] = {};
  }

  var that = this;
  options.methods.forEach(function(method) {
    that._router[path][method.toLowerCase()] = handlers;
  });

  that._routerKeys.push(path);
  that._routerKeys.sort(function(a, b) {
    if (a.length > b.length) {
      return -1;
    } else if (a.length < b.length) {
      return 1;
    }

    return 0;
  });

  return this;
};

var methods = {
  'get': 'GET',
  'post': 'POST',
  'put': 'PUT',
  'del': 'DELETE',
  'head': 'HEAD',
  'options': 'OPTIONS',
  'trace': 'TRACE'
};

Object.keys(methods).forEach(function(method) {
  Argo.prototype[method] = function(path, options, handlers) {
    if (typeof(options) === 'function') {
      handlers = options;
      options = {};
    }
    options.methods = [methods[method]];
    return this.route(path, options, handlers);
  };
});

Argo.prototype.map = function(path, options, handler) {
  if (typeof(options) === 'function') {
    handler = options;
    options = {};
  }

  options.methods = options.methods || ['*'];
  if (!this._router[path]) {
    this._router[path] = {};
  }

  function generateHandler(path, handler) {
    var argo = new Argo();
    handler(argo);

    var app = argo.embed();

    return function(addHandler) {
      addHandler('request', function mapHandler(env, next) {
        env.argo.frames = env.argo.frames || [];

        var frame = new Frame();
        frame.routed = env.argo._routed;
        frame.routedResponseHandler = env.argo._routedResponseHandler;

        env.argo._routed = false;
        env.argo._routedResponseHandler = null;

        if (env.request.url[env.request.url.length - 1] === '/') {
          env.request.url = env.request.url.substr(0, env.request.url.length - 1);
        }

        if (env.argo.frames.length) {
          pathLength = 0;
          env.argo.frames.forEach(function(frame) {
            pathLength += frame.routeUri.length;
          });
        }

        frame.routeUri = path || '/';

        env.request.url = env.request.url.substr(frame.routeUri.length);
        env.request.url = env.request.url || '/';

        // TODO: See if this can work in a response handler here.

        if (env.argo.oncomplete) {
          frame.oncomplete = env.argo.oncomplete;
        }

        env.argo.currentFrame = frame;
        env.argo.frames.push(frame);

        env.argo.oncomplete = function(env) {
          var frame = env.argo.frames.pop();

          env.argo._routed = frame.routed;
          env.argo._routedResponseHandler = frame.routedResponseHandler;
          env.request.url = frame.routeUri + env.request.url;
          env.argo.oncomplete = frame.oncomplete;

          next(env);
        };

        app.flow(env);
      });
    };
  };

  return this.route(path, options, generateHandler(path, handler));
};

Argo.prototype._pipeline = function(name) {
  return this.builder.pipelineMap[name];
};

Argo.prototype._addRouteHandlers = function(handlers) {
  return function add(name, opts, cb) {
    if (typeof opts === 'function') {
      cb = opts;
      opts = null;
    }

    if (name === 'request') {
      handlers.request = cb;
    } else if (name === 'response') {
      handlers.response = cb;
    }
  };
};

function RouteHandlers() {
  this.request = null;
  this.response = null;
}

Argo.prototype._routeRequestHandler = function(router) {
  var that = this;
  return function routeRequestHandler(env, next) {
    env.argo._routed = false;

    var search = env.request.url;

    var routerKey;
    if (search === '/' && that._router['/']) {
      routerKey = '/';
    } else {
      that._routerKeys.forEach(function(key) {
        if (!routerKey && key !== '*' && search.search(key) !== -1 && key !== '/') {
          routerKey = key;
        }
      });
    }

    if (!routerKey && that._router['*']) {
      routerKey = '*';
    }

    if (routerKey &&
        (!router[routerKey][env.request.method.toLowerCase()] &&
         !router[routerKey]['*'])) {
      env.response.statusCode = 405;
      next(env);
      return;
    }

    if (routerKey &&
        (router[routerKey][env.request.method.toLowerCase()] ||
         router[routerKey]['*'])) {
      env.argo._routed = true;

      var method = env.request.method.toLowerCase();
      var fn = router[routerKey][method] ? router[routerKey][method]
        : router[routerKey]['*'];

      var handlers = new RouteHandlers();
      fn(that._addRouteHandlers(handlers));

      env.argo._routedResponseHandler = handlers.response || null;

      if (handlers.request) {
        handlers.request(env, next);
      } else {
        next(env);
        return;
      }
    }

    if (!env.argo._routed) {
      next(env);
    }
  };
};

Argo.prototype._routeResponseHandler = function(router) {
  var that = this;
  return function routeResponseHandler(env, next) {
    if (!env.argo._routed) {
      if (env.response.statusCode !== 405) {
        env.response.statusCode = 404;
      }

      next(env);
      return;
    }

    if (env.argo._routedResponseHandler) {
      env.argo._routedResponseHandler(env, next);
      return;
    } else {
      next(env);
      return;
    }
  };
};

Argo.prototype._route = function(router, handle) {
  handle('request', this._routeRequestHandler(router));
  handle('response', { affinity: 'hoist' }, this._routeResponseHandler(router));
};

Argo.prototype._target = function(env, next) {
  if (env.response._headerSent || env.target.skip) {
    next(env);
    return;
  }
  var start = +Date.now();

  if (env.target && env.target.url) {
    var options = {};
    options.method = env.request.method || 'GET';

    // TODO: Make Agent configurable.
    options.agent = new env.argo._http.Agent();
    options.agent.maxSockets = 1024;

    var parsed = url.parse(env.target.url);
    options.hostname = parsed.hostname;
    options.port = parsed.port || 80;
    options.path = parsed.path;

    options.headers = env.request.headers;
    options.headers['Connection'] = 'keep-alive';
    options.headers['Host'] = options.hostname;

    if (parsed.auth) {
      options.auth = parsed.auth;
    }

    var req = env.argo._http.request(options, function(res) {
      for (var key in res.headers) {
        var headerName = res._rawHeaderNames[key] || key;
        env.response.setHeader(headerName, res.headers[key]);
      }

      env.target.response = res;

      if (next) {
        var duration = (+Date.now() - start);
        next(env);
      }
    });

    env.request.getBody(function(err, body) {
      if (body) {
        req.write(body);
      }

      req.end();
    });
  } else {
    next(env);
  }
};

module.exports = function(_http) { return new Argo(_http) };
<commit_msg>Adding a parameter to a function; killing a bug introduced by Pipeworks.<commit_after>var http = require('http');
var url = require('url');
var Stream = require('stream');
var Frame = require('./frame');
var Builder = require('./builder');
var runner = require('./runner');

var Argo = function(_http) {
  this._router = {};
  this._routerKeys = [];
  this.builder = new Builder();
  this._http = _http || http;

  var that = this;
  var incoming = this._http.IncomingMessage.prototype;

  if (!incoming._argoModified) {
    var _addHeaderLine = incoming._addHeaderLine;

    incoming._addHeaderLine = function(field, value) {
      this._rawHeaderNames = this._rawHeaderNames || {};
      this._rawHeaderNames[field.toLowerCase()] = field;

      _addHeaderLine.call(this, field, value);
    };

    incoming.body = null;
    incoming.getBody = that._getBody();
    incoming._argoModified = true;
  }

  var serverResponse = this._http.ServerResponse.prototype;
  if (!serverResponse._argoModified) {
    serverResponse.body = null;
    serverResponse.getBody = that._getBody();

    serverResponse._argoModified = true;
  }
};

Argo.prototype._getBody = function() {
  var that = this;
  return function(callback) {
    if (this.body) {
      callback(null, this.body);
      return;
    }
    var buf = [];
    var len = 0;

    this.on('data', function(chunk) {
      buf.push(chunk);
      len += chunk.length;
    });

    this.on('end', function() {
      var body;
      if (buf.length && Buffer.isBuffer(buf[0])) {
        body = new Buffer(len);
        var i = 0;
        buf.forEach(function(chunk) {
          chunk.copy(body, i, 0, chunk.length);
          i += chunk.length;
        });
      } else if (buf.length) {
        body = buf.join('');
      }

      this.body = body;

      callback(null, body);
    });
  };
};

Argo.prototype.include = function(mod) {
  var p = mod.package(this);
  p.install();
  return this;
};

Argo.prototype.listen = function(port) {
  runner.listen(this, port);
  return this;
};

Argo.prototype.use = function(middleware) {
  if (middleware.package) {
    return this.include(middleware);
  }
  this.builder.use(middleware);
  return this;
};

Argo.prototype.target = function(url) {
  return this.use(function(addHandler) {
    addHandler('request', function(env, next) {
      env.target.url = url + (env.request.url || '');
      next(env);
    });
  });
};

Argo.prototype.embed = function() {
  this.buildCore();

  this.builder.run(this._target);
  this.builder.use(function(addHandler) {
    addHandler('response', { affinity: 'sink' }, function(env, next) {
      console.log(env.toString());
      if (env.argo.oncomplete) {
        env.argo.oncomplete(env);
      };
    });
  });

  return this.builder.build();
}

Argo.prototype.buildCore = function() {
  var that = this;

  that.builder.use(function(addHandler) {
    addHandler('request', function(env, next) {
      env.argo._http = that._http;
      next(env);
    });
  });

  var hasRoutes = false;
  for (var prop in that._router) {
    if (!hasRoutes && that._router.hasOwnProperty(prop)) {
      hasRoutes = true;
    }
  }

  if (hasRoutes) {
    that.builder.use(function addRouteHandlers(handlers) {
     that._route(that._router, handlers);
    });
  }
};

Argo.prototype.build = function() {
  var that = this;

  that.buildCore();

  that.builder.run(that._target);

  // response ender
  that.builder.use(function(handle) {
    handle('response', { affinity: 'sink' }, function(env, next) {
      if (env.response.body) {
        var body = env.response.body;
        if (typeof body === 'string') {
          env.response.setHeader('Content-Length', body ? body.length : 0);
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end(body);
        } else if (body instanceof Stream) {
          env.response.writeHead(env.response.statusCode, env.response.headers);
          body.pipe(env.response);
        } else if (typeof body === 'object') {
          body = new Buffer(JSON.stringify(body), 'utf-8');
          if (!env.response.getHeader('Content-Type')) {
            env.response.setHeader('Content-Type', 'application/json; charset=UTF-8');
          }
          env.response.setHeader('Content-Length', body ? body.length : 0);
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end(body.toString('utf-8'));
        }
      } else {
        var contentLength = env.response.getHeader('Content-Length');
        if (contentLength == '0') {
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end();
        } else if (env.target.response) {
          env.target.response.getBody(function(err, body) {
            env.response.setHeader('Content-Length', body ? body.length : 0);
            env.response.writeHead(env.response.statusCode, env.response.headers);
            env.response.end(body);
          });
        } else {
          env.response.setHeader('Content-Length', '0');
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end();
        }
      }
    });
  });

  return that.builder.build();
};

Argo.prototype.call = function(env) {
  var app = this.build();
  return app.flow(env);
}

Argo.prototype.route = function(path, options, handlers) {
  if (typeof(options) === 'function') {
    handlers = options;
    options = {};
  }

  options.methods = options.methods || ['*'];
  if (!this._router[path]) {
    this._router[path] = {};
  }

  var that = this;
  options.methods.forEach(function(method) {
    that._router[path][method.toLowerCase()] = handlers;
  });

  that._routerKeys.push(path);
  that._routerKeys.sort(function(a, b) {
    if (a.length > b.length) {
      return -1;
    } else if (a.length < b.length) {
      return 1;
    }

    return 0;
  });

  return this;
};

var methods = {
  'get': 'GET',
  'post': 'POST',
  'put': 'PUT',
  'del': 'DELETE',
  'head': 'HEAD',
  'options': 'OPTIONS',
  'trace': 'TRACE'
};

Object.keys(methods).forEach(function(method) {
  Argo.prototype[method] = function(path, options, handlers) {
    if (typeof(options) === 'function') {
      handlers = options;
      options = {};
    }
    options.methods = [methods[method]];
    return this.route(path, options, handlers);
  };
});

Argo.prototype.map = function(path, options, handler) {
  if (typeof(options) === 'function') {
    handler = options;
    options = {};
  }

  options.methods = options.methods || ['*'];
  if (!this._router[path]) {
    this._router[path] = {};
  }

  function generateHandler(path, handler) {
    var argo = new Argo();
    handler(argo);

    var app = argo.embed();

    return function(addHandler) {
      addHandler('request', function mapHandler(env, next) {
        env.argo.frames = env.argo.frames || [];

        var frame = new Frame();
        frame.routed = env.argo._routed;
        frame.routedResponseHandler = env.argo._routedResponseHandler;

        env.argo._routed = false;
        env.argo._routedResponseHandler = null;

        if (env.request.url[env.request.url.length - 1] === '/') {
          env.request.url = env.request.url.substr(0, env.request.url.length - 1);
        }

        if (env.argo.frames.length) {
          pathLength = 0;
          env.argo.frames.forEach(function(frame) {
            pathLength += frame.routeUri.length;
          });
        }

        frame.routeUri = path || '/';

        env.request.url = env.request.url.substr(frame.routeUri.length);
        env.request.url = env.request.url || '/';

        // TODO: See if this can work in a response handler here.

        if (env.argo.oncomplete) {
          frame.oncomplete = env.argo.oncomplete;
        }

        env.argo.currentFrame = frame;
        env.argo.frames.push(frame);

        env.argo.oncomplete = function(env) {
          var frame = env.argo.frames.pop();

          env.argo._routed = frame.routed;
          env.argo._routedResponseHandler = frame.routedResponseHandler;
          env.request.url = frame.routeUri + env.request.url;
          env.argo.oncomplete = frame.oncomplete;

          next(env);
        };

        app.flow(env);
      });
    };
  };

  return this.route(path, options, generateHandler(path, handler));
};

Argo.prototype._pipeline = function(name) {
  return this.builder.pipelineMap[name];
};

Argo.prototype._addRouteHandlers = function(handlers) {
  return function add(name, opts, cb) {
    if (typeof opts === 'function') {
      cb = opts;
      opts = null;
    }

    if (name === 'request') {
      handlers.request = cb;
    } else if (name === 'response') {
      handlers.response = cb;
    }
  };
};

function RouteHandlers() {
  this.request = null;
  this.response = null;
}

Argo.prototype._routeRequestHandler = function(router) {
  var that = this;
  return function routeRequestHandler(env, next) {
    env.argo._routed = false;

    var search = env.request.url;

    var routerKey;
    if (search === '/' && that._router['/']) {
      routerKey = '/';
    } else {
      that._routerKeys.forEach(function(key) {
        if (!routerKey && key !== '*' && search.search(key) !== -1 && key !== '/') {
          routerKey = key;
        }
      });
    }

    if (!routerKey && that._router['*']) {
      routerKey = '*';
    }

    if (routerKey &&
        (!router[routerKey][env.request.method.toLowerCase()] &&
         !router[routerKey]['*'])) {
      env.response.statusCode = 405;
      next(env);
      return;
    }

    if (routerKey &&
        (router[routerKey][env.request.method.toLowerCase()] ||
         router[routerKey]['*'])) {
      env.argo._routed = true;

      var method = env.request.method.toLowerCase();
      var fn = router[routerKey][method] ? router[routerKey][method]
        : router[routerKey]['*'];

      var handlers = new RouteHandlers();
      fn(that._addRouteHandlers(handlers));

      env.argo._routedResponseHandler = handlers.response || null;

      if (handlers.request) {
        handlers.request(env, next);
      } else {
        next(env);
        return;
      }
    }

    if (!env.argo._routed) {
      next(env);
    }
  };
};

Argo.prototype._routeResponseHandler = function(router) {
  var that = this;
  return function routeResponseHandler(env, next) {
    if (!env.argo._routed) {
      if (env.response.statusCode !== 405) {
        env.response.statusCode = 404;
      }

      next(env);
      return;
    }

    if (env.argo._routedResponseHandler) {
      env.argo._routedResponseHandler(env, next);
      return;
    } else {
      next(env);
      return;
    }
  };
};

Argo.prototype._route = function(router, handle) {
  handle('request', this._routeRequestHandler(router));
  handle('response', { affinity: 'hoist' }, this._routeResponseHandler(router));
};

Argo.prototype._target = function(env, next) {
  if (env.response._headerSent || env.target.skip) {
    next(env);
    return;
  }
  var start = +Date.now();

  if (env.target && env.target.url) {
    var options = {};
    options.method = env.request.method || 'GET';

    // TODO: Make Agent configurable.
    options.agent = new env.argo._http.Agent();
    options.agent.maxSockets = 1024;

    var parsed = url.parse(env.target.url);
    options.hostname = parsed.hostname;
    options.port = parsed.port || 80;
    options.path = parsed.path;

    options.headers = env.request.headers;
    options.headers['Connection'] = 'keep-alive';
    options.headers['Host'] = options.hostname;

    if (parsed.auth) {
      options.auth = parsed.auth;
    }

    var req = env.argo._http.request(options, function(res) {
      for (var key in res.headers) {
        var headerName = res._rawHeaderNames[key] || key;
        env.response.setHeader(headerName, res.headers[key]);
      }

      env.target.response = res;

      if (next) {
        var duration = (+Date.now() - start);
        next(env);
      }
    });

    env.request.getBody(function(err, body) {
      if (body) {
        req.write(body);
      }

      req.end();
    });
  } else {
    next(env);
  }
};

module.exports = function(_http) { return new Argo(_http) };
<|endoftext|>


<commit_before>let app;
let listing = null;
let isAutomated = false;
let block = false;
let waiting = false;
let hackProgress = 0;
let wordLoop = null;
let minerLoop = null;
let upgradeLoop = null;
let myBT = 0;
let minerStatus = [
	{
		name: "shop-basic-miner",
		value: 0
	},
	{
		name: "shop-advanced-miner",
		value: 0
	},
	{
		name: "shop-mining-drill",
		value: 0
	},
	{
		name: "shop-data-center",
		value: 0
	},
	{
		name: "shop-bot-net",
		value: 0
	},
	{
		name: "shop-quantum-server",
		value: 0
	}
];
let maxStats = {
	charge: 30,
	strength: 4,
	regen: 10
};
const firewalls = ["1", "2", "3"];
const ocrApiKey = "e3b7e80ac588957";
const db = "https://raw.githubusercontent.com/snollygolly/sourceio-automation/master/db.json";
let message = "papa bless, one love /r/javascript";
let wordFreq = 1250;
let mineFreq = 3000;
let blockFreq = 5000;
let upgradeFreq = 7500;
let minerLevel = 20;
let playerToAttack = 0;

app = {
	start: () => {
		$.get(db).done((data) => {
			listing = JSON.parse(data);
			app.automate();
		});
	},

	exportListing: () => {
		log(JSON.stringify(listing, null, 2));
	},

	automate: () => {
		// first check the windows are open, and open them if they aren't
		if ($("#player-list").is(":visible") === false) {
			log("* Target list must be open");
			$("#desktop-list").children("img").click();
		}
		if ($("#window-shop").is(":visible") === false) {
			log("* Black market must be open");
			$("#desktop-shop").children("img").click();
			$("#desktop-miner").children("img").click();
		}
		if ($("#window-computer").is(":visible") === false) {
			log("* My computer must be open");
			$("#desktop-computer").children("img").click();
		}
		isAutomated = true;
		// start by getting the first target in the list
		const targetName = $("#player-list").children("tr").eq(playerToAttack)[0].innerText;
		log(`. Now attacking ${targetName}`);
		// click it, and then hack, and then port b
		$("#player-list").children("tr").eq(playerToAttack)[0].click();
		$("#window-other-button").click();
		// do a check for money
		const portStyle = $(`#window-other-port${firewalls[0]}`).attr("style");
		if (portStyle.indexOf("opacity: 1") === -1) {
			// this port costs too much, let's wait a bit
			log("* Hack too expensive, waiting");
			setTimeout(app.automate, blockFreq);
			return;
		}
		$("#window-other-port2").click();
		// handle upgrades
		app.loops.upgrade();
		// start the loop that does the guessing
		wordLoop = setInterval(app.loops.word, wordFreq);
		// start the loop for btc monitoring
		minerLoop = setInterval(app.loops.miner, mineFreq);
		// start the loop for upgrades
		//upgradeLoop = setInterval(app.loops.upgrade, upgradeFreq);
	},

	loops: {
		word: () => {
			if (block === true) {
				return;
			}
			if ($("#targetmessage-input").is(":visible") === true) {
				// we're done!
				$("#targetmessage-input").val(message);
				$("#targetmessage-button-send").click();
				app.restart();
				return;
			}
			// if we're waiting on the progress bar to move...
			if (waiting === true) {
				const newHackProgress = parseHackProgress($("#progressbar-firewall-amount").attr("style"));
				// check to see if it's new
				if (hackProgress === newHackProgress) {
					// the bar hasn't moved
					log("* Progress bar hasn't moved, waiting");
					// TODO: make this an automatic process
					return;
				} else {
					// the bar has moved
					hackProgress = newHackProgress;
					waiting = false;
				}
			}
			// actually do the word stuff
			waiting = true;
			app.go();
		},
		miner: () => {
			// first, get the status of our miners
			for (const miner of minerStatus) {
				// set value
				miner.value = parseInt($(`#${miner.name}-amount`).text());
				// this is available to buy
				if ($(`#${miner.name}`).attr("style") === "opacity: 1;") {
					if (miner.value < minerLevel) {
						// we should buy this
						$(`#${miner.name}`).click();
					}
				}
			}
		},
		upgrade: () => {
			myBT = parseInt($("#window-my-coinamount").text());
			// if the back button is visible, we're on a page, let's back out
			if ($("#window-firewall-pagebutton").is(":visible") === true) {
				$("#window-firewall-pagebutton").click();
			}
			// take it off the top
			const firewall = firewalls.shift()
			firewalls.push(firewall);
			// select the firewall
			log(`. Handling upgrades to firewall ${firewall}`);
			$(`#window-firewall-part${firewall}`).click();
			// get stats
			const stats = {
				charge: parseInt($("#shop-max-charges").text()),
				strength: parseInt($("#shop-strength").text()),
				regen: parseInt($("#shop-regen").text()),
			};
			// start checking prices, start with strength
			if (stats.strength < maxStats.strength) {
				log(". Strength isn't maxed");
				const strengthPrice = parseInt($("#shop-firewall-difficulty-value").text());
				if (strengthPrice < myBT) {
					log(". Buying strength");
					$("#shop-firewall-difficulty").click();
					return;
				}
			}
			// check max charges
			if (stats.charge < maxStats.charge) {
				log(". Charge isn't maxed");
				const chargePrice = parseInt($("#shop-firewall-max_charge10-value").text());
				if (chargePrice < myBT) {
					$("#shop-firewall-max_charge10").click();
					log(". Buying charge");
					return;
				}
			}
			// check regen
			if (stats.regen < maxStats.regen) {
				log(". Regen isn't maxed");
				const regenPrice = parseInt($("#shop-firewall-regen-value").text());
				if (regenPrice < myBT) {
					$("#shop-firewall-regen").click();
					log(". Buying regen");
					return;
				}
			}
			// nothing matched, let's go back
			if ($("#window-firewall-pagebutton").is(":visible") === true) {
				$("#window-firewall-pagebutton").click();
			}
		}
	},

	restart: () => {
		app.stop();
		app.automate();
	},

	stop: () => {
		if (wordLoop === null && minerLoop === null && upgradeLoop === null) {
			log("! No loops to stop");
			return;
		}
		isAutomated = false;
		block = false;
		waiting = false;
		clearInterval(wordLoop);
		wordLoop = null;
		clearInterval(minerLoop);
		minerLoop = null;
		clearInterval(upgradeLoop);
		upgradeLoop = null;
		log("* Stopped loops");
	},

	exportListing: () => {
		log(JSON.stringify(listing, null, 2));
	},

	go: () => {
		const wordLink = $(".tool-type-img").prop("src");
		if (listing.hasOwnProperty(wordLink) === true) {
			const word = listing[wordLink];
			log(`. Found word: [${word}]`);
			app.submit(word);
			return;
		}
		log("* Not seen, trying OCR...");
		app.ocr(wordLink);
	},

	submit: (word) => {
		$("#tool-type-word").val(word);
		$("#tool-type-word").submit();
	},

	learn: (word) => {
		const wordLink = $(".tool-type-img").prop("src");
		listing[wordLink] = word;
		app.submit(word);
	},

	ocr: (url) => {
		block = true;
		$.post("http://api.ocr.space/parse/image", {
			apikey: ocrApiKey,
			language: "eng",
			url: url
		}).done((data) => {
			const word = String(data["ParsedResults"][0]["ParsedText"]).trim().toLowerCase();
			if (word.length > 3) {
				log(`. Got data: [${word}]`);
				$("#tool-type-word").val(word);
				if (isAutomated === true) {
					app.learn(word);
					block = false;
				}
			} else {
				log("* OCR failed");
				app.restart();
			}
		});
	}
};

function parseHackProgress(progress) {
	// remove the %;
	const newProgress = progress.slice(0, -2);
	const newProgressParts = newProgress.split("width: ");
	return parseInt(newProgressParts.pop());
}

function log(message) {
	console.log(`:: ${message}`);
}
<commit_msg>Fix wrong guesses using OCR<commit_after>let app;
let listing = null;
let isAutomated = false;
let block = false;
let waiting = false;
let hackProgress = 0;
let wordLoop = null;
let minerLoop = null;
let upgradeLoop = null;
let myBT = 0;
let minerStatus = [
	{
		name: "shop-basic-miner",
		value: 0
	},
	{
		name: "shop-advanced-miner",
		value: 0
	},
	{
		name: "shop-mining-drill",
		value: 0
	},
	{
		name: "shop-data-center",
		value: 0
	},
	{
		name: "shop-bot-net",
		value: 0
	},
	{
		name: "shop-quantum-server",
		value: 0
	}
];
let maxStats = {
	charge: 30,
	strength: 4,
	regen: 10
};
const firewalls = ["1", "2", "3"];
const ocrApiKey = "e3b7e80ac588957";
const db = "https://raw.githubusercontent.com/snollygolly/sourceio-automation/master/db.json";
let message = "papa bless, one love /r/javascript";
let wordFreq = 1250;
let mineFreq = 3000;
let blockFreq = 5000;
let upgradeFreq = 7500;
let minerLevel = 20;
let playerToAttack = 0;

app = {
	start: () => {
		$.get(db).done((data) => {
			listing = JSON.parse(data);
			app.automate();
		});
	},

	exportListing: () => {
		log(JSON.stringify(listing, null, 2));
	},

	automate: () => {
		// first check the windows are open, and open them if they aren't
		if ($("#player-list").is(":visible") === false) {
			log("* Target list must be open");
			$("#desktop-list").children("img").click();
		}
		if ($("#window-shop").is(":visible") === false) {
			log("* Black market must be open");
			$("#desktop-shop").children("img").click();
			$("#desktop-miner").children("img").click();
		}
		if ($("#window-computer").is(":visible") === false) {
			log("* My computer must be open");
			$("#desktop-computer").children("img").click();
		}
		isAutomated = true;
		// start by getting the first target in the list
		const targetName = $("#player-list").children("tr").eq(playerToAttack)[0].innerText;
		log(`. Now attacking ${targetName}`);
		// click it, and then hack, and then port b
		$("#player-list").children("tr").eq(playerToAttack)[0].click();
		$("#window-other-button").click();
		// do a check for money
		const portStyle = $(`#window-other-port${firewalls[0]}`).attr("style");
		if (portStyle.indexOf("opacity: 1") === -1) {
			// this port costs too much, let's wait a bit
			log("* Hack too expensive, waiting");
			setTimeout(app.automate, blockFreq);
			return;
		}
		$("#window-other-port2").click();
		// handle upgrades
		app.loops.upgrade();
		// start the loop that does the guessing
		wordLoop = setInterval(app.loops.word, wordFreq);
		// start the loop for btc monitoring
		minerLoop = setInterval(app.loops.miner, mineFreq);
		// start the loop for upgrades
		//upgradeLoop = setInterval(app.loops.upgrade, upgradeFreq);
	},

	loops: {
		word: () => {
			if (block === true) {
				return;
			}
			if ($("#targetmessage-input").is(":visible") === true) {
				// we're done!
				$("#targetmessage-input").val(message);
				$("#targetmessage-button-send").click();
				app.restart();
				return;
			}
			// if we're waiting on the progress bar to move...
			if (waiting === true) {
				const newHackProgress = parseHackProgress($("#progressbar-firewall-amount").attr("style"));
				// check to see if it's new
				if (hackProgress === newHackProgress) {
					// the bar hasn't moved
					log("* Progress bar hasn't moved, waiting");
					// TODO: make this an automatic process
					return;
				} else {
					// the bar has moved
					hackProgress = newHackProgress;
					waiting = false;
				}
			}
			// actually do the word stuff
			waiting = true;
			app.go();
		},
		miner: () => {
			// first, get the status of our miners
			for (const miner of minerStatus) {
				// set value
				miner.value = parseInt($(`#${miner.name}-amount`).text());
				// this is available to buy
				if ($(`#${miner.name}`).attr("style") === "opacity: 1;") {
					if (miner.value < minerLevel) {
						// we should buy this
						$(`#${miner.name}`).click();
					}
				}
			}
		},
		upgrade: () => {
			myBT = parseInt($("#window-my-coinamount").text());
			// if the back button is visible, we're on a page, let's back out
			if ($("#window-firewall-pagebutton").is(":visible") === true) {
				$("#window-firewall-pagebutton").click();
			}
			// take it off the top
			const firewall = firewalls.shift()
			firewalls.push(firewall);
			// select the firewall
			log(`. Handling upgrades to firewall ${firewall}`);
			$(`#window-firewall-part${firewall}`).click();
			// get stats
			const stats = {
				charge: parseInt($("#shop-max-charges").text()),
				strength: parseInt($("#shop-strength").text()),
				regen: parseInt($("#shop-regen").text()),
			};
			// start checking prices, start with strength
			if (stats.strength < maxStats.strength) {
				log(". Strength isn't maxed");
				const strengthPrice = parseInt($("#shop-firewall-difficulty-value").text());
				if (strengthPrice < myBT) {
					log(". Buying strength");
					$("#shop-firewall-difficulty").click();
					return;
				}
			}
			// check max charges
			if (stats.charge < maxStats.charge) {
				log(". Charge isn't maxed");
				const chargePrice = parseInt($("#shop-firewall-max_charge10-value").text());
				if (chargePrice < myBT) {
					$("#shop-firewall-max_charge10").click();
					log(". Buying charge");
					return;
				}
			}
			// check regen
			if (stats.regen < maxStats.regen) {
				log(". Regen isn't maxed");
				const regenPrice = parseInt($("#shop-firewall-regen-value").text());
				if (regenPrice < myBT) {
					$("#shop-firewall-regen").click();
					log(". Buying regen");
					return;
				}
			}
			// nothing matched, let's go back
			if ($("#window-firewall-pagebutton").is(":visible") === true) {
				$("#window-firewall-pagebutton").click();
			}
		}
	},

	restart: () => {
		app.stop();
		app.automate();
	},

	stop: () => {
		if (wordLoop === null && minerLoop === null && upgradeLoop === null) {
			log("! No loops to stop");
			return;
		}
		isAutomated = false;
		block = false;
		waiting = false;
		clearInterval(wordLoop);
		wordLoop = null;
		clearInterval(minerLoop);
		minerLoop = null;
		clearInterval(upgradeLoop);
		upgradeLoop = null;
		log("* Stopped loops");
	},

	exportListing: () => {
		log(JSON.stringify(listing, null, 2));
	},

	go: () => {
		const wordLink = $(".tool-type-img").prop("src");
		if (listing.hasOwnProperty(wordLink) === true) {
			const word = listing[wordLink];
			log(`. Found word: [${word}]`);
			app.submit(word);
			return;
		}
		log("* Not seen, trying OCR...");
		app.ocr(wordLink);
	},

	submit: (word) => {
		$("#tool-type-word").val(word);
		$("#tool-type-word").submit();
	},

	learn: (word) => {
		const wordLink = $(".tool-type-img").prop("src");
		listing[wordLink] = word;
		app.submit(word);
	},

	ocr: (url) => {
		block = true;
		$.post("http://api.ocr.space/parse/image", {
			apikey: ocrApiKey,
			language: "eng",
			url: url
		}).done((data) => {
			const word = String(data["ParsedResults"][0]["ParsedText"]).trim().toLowerCase().split(" ").join("");
			if (word.length > 3) {
				log(`. Got data: [${word}]`);
				$("#tool-type-word").val(word);
				if (isAutomated === true) {
					app.learn(word);
					block = false;
				}
			} else {
				log("* OCR failed");
				app.restart();
			}
		});
	}
};

function parseHackProgress(progress) {
	// remove the %;
	const newProgress = progress.slice(0, -2);
	const newProgressParts = newProgress.split("width: ");
	return parseInt(newProgressParts.pop());
}

function log(message) {
	console.log(`:: ${message}`);
}
<|endoftext|>


<commit_before>var day = 0;
var morning;
var homeroom;
var warmup;
var classmate;
var homeroom;
var laugh;
var damanserve;
var arshserve;
var sleep;
var gameover = false;
function arshsim() {
	while (!gameover) {
		day += 1;
		alert("Day " + day);
		alert("*alarm rings*");
		morning = prompt("Would you like to [sleep in] or [wake up]?").toLowerCase();
		switch (morning) {
			case "sleep in":
				if (!gameover) {
					alert("Your dad comes and wakes you up.");
					alert("RUN RUN RUN");
					alert("You quickly brush your teeth and get ready. You run out the door.");
					if (Math.random() < 0.25) {
						alert("The bus has long gone.");
						alert("You come back inside and explain to your mom what happened.");
						alert("Your mom gives you a beating.");
						alert("GAME OVER");
						gameover = true;
					} else {
						alert("You reach the bus just in time.");
						alert("You are at school. It was a boring bus ride.");
					}
				}
				break;
			case "wake up":
				if (!gameover) {
					alert("You wake up and slowly walk to the washroom, to brush your teeth and get ready.");
					alert("You walk downstairs.");
					breakfast = prompt("What do you eat for breakfast?\n[cereal]\n[bagel]\n[pancakes]\n[waffles]\n[bacon]\n[nothing]").toLowerCase();
					if (breakfast === "nothing") {
						alert("You skip breakfast.");
					} else if (breakfast === "cereal" || breakfast === "bagel" || breakfast === "pancakes" || breakfast === "waffles" || breakfast === "bacon") {
						alert("You finish your " + breakfast + " and go back upstairs to brush again.");
					} else {
						gameover = true;
					}
					if (!gameover) {
						alert("You walk outside and wait about five minutes.");
						alert("The bus arrives.");
						alert("You are at school. It was a boring bus ride.");
					}
				}
				break;
			default:
				gameover = true;
		}
		if (!gameover) {
			switch (day) {
				case 1:
					alert("You put your stuff in a shared locker with your best friend. You walk inside to see the first two periods are math: your favourie subject!");
					alert("You easily finish the math and do some work on your laptop.");
					alert("*bell rings*");
					alert("Second period, gym!");
					alert("You walk inside the boys changeroom and quickly get dressed for gym.");
					alert("\"LET'S GET INTO A LINE ON THE WALL! WE'RE DOING OUR WARMUP!\" says the gym teacher.");
					alert("During the warmup, do you...");
					warmup = prompt("[Skip a few laps] or [do it all]?").toLowerCase();
					switch (warmup) {
					case "skip a few laps":
						if (Math.random() < 0.75) {
							alert("Your teacher notices and yells at you for cheating. You now have to do 700 more laps.");
							alert("GAME OVER");
							gameover = true;
						} else {
							alert("You get away with skipping a few laps.");
						}
						break;
					case "do it all":
						if (breakfast !== "nothing") {
							alert("You do all of the warmup.");
							alert("HUFF PUFF HUFF PUFF HUFF PUFF");
						} else {
							alert("Not having any food, you die of exhaustion.");
							gameover = true;
						}
						break;
					default:
						gameover = true;
					}
					if (!gameover) {
						alert("The class plays a game of volleyball and you were the top player!");
						alert("Just kidding, you suck at volleyball.");
						alert("You go back and put your normal clothes back on.");
						alert("*bell rings*");
						alert("Ah, lunch time.");
						alert("You eat your food and play outside.");
						alert("The rest of the day goes on as usual, until you noticed the most hilarious thing.");
						alert("A girl called Ameeta steals tries taking a chair from Kulshan.");
						alert("Kulshan fails to save his chair, so he takes a chair from a boy named Tejas.");
						alert("Tejas pushes Kulshan off the chair, and gets his chair back.");
						alert("At that moment, Kulshan knew, he was chairless.");
						alert("When you went home, you watched some TV and played outside a bit.");
					}
					break;
				case 2:
					alert("It's Halloween. You put on your brilliant costume, a fedora and call yourself Winston Churchill.");
					classmate = prompt("As you walk to the school building, you see some of your classmates. [Cameron] the Demon, [Daman] the Schoolkid, [Connor] the Leprechaun, and [Harshan] the Zombie.\nDo you greet them or [ignore] them? If you did greet them, which one do you greet?").toLowerCase();
					switch (classmate) {
					case "daman":
						alert("You say, \"Hey Daman. Nice costume.\"");
						alert("He responds, \"I'm not wearing a costume, retard.\" He proceeds to lightly tap your shoulder in a joking way. Being Arshneet, this kills you.");
						alert("THE END");
						gameover = true;
						break;
					case "connor":
						alert("You say, \"Hey Connor. Nice costume.\"");
						alert("Connor responds \"WOW, OF COURSE YOU THINK THE LEPRECHAUN COSTUME IS GOOD: BECAUSE LEPRECHAUNS ARE SHORT AND I'M SHORT!\"");
						alert("In his fit of height-insecure induced rage, Connor kills you.");
						gameover = true;
						break;
					case "cameron":
						alert("You say, \"Hey Cameron. Nice costume.\"");
						alert("Cameron responds, \"Thanks Arshneet, what are you supposed to...be...\"");
						alert("He then has an asthma attack on the spot.");
						alert("The stress of Cameron's death kills you.");
						alert("GAME OVER");
						gameover = true;
						break;
					case "harshan":
						alert("You say, \"Hey Harshan. Wow, cool costume.\"");
						alert("He responds, \"Thanks fam. What are you going as when you trick or tre-\"");
						alert("He faints on the spot.");
						alert("The stress kills you.");
						alert("GAME OVER");
						gameover = true;
						break;
					case "ignore":
						alert("You ignore them. Good, since you're a loner anyway.");
						alert("You continue on your merry way to school.");
						alert("As you get to school, the bell rings. Made it just in time!");
						alert("Walking into homeroom, you look around at the assortment of colors and unique costumes.");
						alert("Regardless, you think your costume is the best. Good on you.");
						homeroom = prompt("In homeroom, for the next two periods, do you [work], [fool around], or [play games]?").toLowerCase();
						switch (homeroom) {
						case "fool around":
							alert("Rather than working, you fool around.");
							alert("You play catch with Arash but you drop the ball multiple times and arash makes a joke about it.");
							laugh = prompt("Do you laugh at the joke? ([yes] or [no])").toLowerCase();
							switch (laugh) {
							case "yes":
								alert("Your satanic demon laugh invokes the rage of your classmates. They kill you.");
								alert("GAME OVER");
								gameover = true;
								break;
							case "no":
								alert("Arash gives you a look for not laughing, but you still continue on to third period.");
								break;
							}
							break;
						case "work":
							alert("You decide to actually work, like usual. Good.");
							alert("Class flies by, and all of a sudden it's third period.");
							break;
						case "play games":
							alert("You decide to play some Minecraft.");
							alert("What could go wrong?");
							alert("Suddenly, because you were so immersed in your Minecraft game, you realize your teacher was watching the whole time.");
							alert("Your teacher sends you home as punishment, and your mom grounds you.");
							alert("GAME OVER");
							gameover = true;
							break;
						default:
							gameover = true;
						}
						if (!gameover) {
							alert("You enter the gymnasium once again. Warmup was skipped because the volleyball net was up.");
							alert("A game of volleyball begins. Daman's legendary overhand serve makes it over the net, with the ball coming straight at you.");
							damanserve = prompt("Will you [try to return it], [get out of the way] or [stand in the way]?").toLowerCase();
							switch (damanserve) {
							case "try to return it":
								alert("You wish. This is Daman's serve we're talking about.");
								alert("The ball dunks you with the force of 10,000 Shaqille O'Neals.");
								alert("GAME OVER");
								gameover = true;
								break;
							case "stand in the way":
								alert("Well, that wasn't a smart decision.");
								alert("The ball dunks you with the force of 10,000 Shaqille O'Neals.");
								alert("GAME OVER");
								gameover = true;
								break;
							case "get out of the way":
								alert("You try your very best to dodge.");
								alert("You fail though.");
								alert("Luckily, Harshan, thirsty for redemption after being out-served by Daman, jumps in the way and takes the full force of the hit.");
								alert("Point Daman's team.");
								alert("Daman serves again, but Aryaman returns it and scores your team a point.");
								alert("Your turn to serve.");
								alert("What technique do you use for your serve?");
								arshserve = prompt("The [Arshneet Sidewinder], [traditional], or the [Daman Punch]?").toLowerCase();
								switch (arshserve) {
								case "daman punch":
									alert("You try Daman's serve.");
									alert("You can't pull it off.");
									alert("You have been shamed and must commit seppuku.");
									alert("GAME OVER");
									gameover = true;
									break;
								case "traditional":
									alert("Arshneet? Doing traditional sports?");
									alert("Hah, good one.");
									alert("GAME OVER");
									gameover = true;
									break;
								case "arshneet sidewinder":
									alert("You use your signature technique, and get a ball over the net.");
									alert("Doesn't matter though, you still lose.");
									alert("You head home after some more boring work periods, but to you, it's just your normal every day life.");
									alert("You eat dinner as usual. No skipping it becuase your parents are watching. After all, you're starving. Boy, is volleyball tiring.");
								}
								break;
							default:
								gameover = true;
							}
						}
						break;
					default:
						gameover = true;
					}
					break;
				case 3:
					alert("This is when day three is supposed to happen, but since it hasn't been coded, well...");
					alert("GAME OVER");
					gameover = true;
					break;
				}
			}
			if (!gameover) {
				alert("After eating dinner, do you...");
				sleep = prompt("...[stay up] or [go to sleep]?").toLowerCase();
				switch (sleep) {
				case "stay up":
					alert("You stay up and play video games.");
					while (!gameover) {
						alert("You hear your mother coming.");
						if (Math.random() < 0.75) {
							alert("You pretend to sleep.");
							alert("Your mother passes by without blinking an eye. You continue to play video games.");
						} else {
							alert("Your mother came before you could pretend to sleep.");
							alert("You get caught (obviously).");
							alert("GAME OVER");
							gameover = true;
						}
					}
					break;
				case "go to sleep":
					alert("You brush you bathe, brush your teeth, and finally lie down in bed after a long day.");
					break;
				default:
					gameover = true;
				}
			}
	}
	gameover = false;
	day = 0;
}<commit_msg>Sleep in now sets breakfast to "nothing"<commit_after>var day = 0;
var morning;
var homeroom;
var warmup;
var classmate;
var homeroom;
var laugh;
var damanserve;
var arshserve;
var sleep;
var gameover = false;
function arshsim() {
	while (!gameover) {
		day += 1;
		alert("Day " + day);
		alert("*alarm rings*");
		morning = prompt("Would you like to [sleep in] or [wake up]?").toLowerCase();
		switch (morning) {
			case "sleep in":
				breakfast = "nothing";
				if (!gameover) {
					alert("Your dad comes and wakes you up.");
					alert("RUN RUN RUN");
					alert("You quickly brush your teeth and get ready. You run out the door.");
					if (Math.random() < 0.25) {
						alert("The bus has long gone.");
						alert("You come back inside and explain to your mom what happened.");
						alert("Your mom gives you a beating.");
						alert("GAME OVER");
						gameover = true;
					} else {
						alert("You reach the bus just in time.");
						alert("You are at school. It was a boring bus ride.");
					}
				}
				break;
			case "wake up":
				if (!gameover) {
					alert("You wake up and slowly walk to the washroom, to brush your teeth and get ready.");
					alert("You walk downstairs.");
					breakfast = prompt("What do you eat for breakfast?\n[cereal]\n[bagel]\n[pancakes]\n[waffles]\n[bacon]\n[nothing]").toLowerCase();
					if (breakfast === "nothing") {
						alert("You skip breakfast.");
					} else if (breakfast === "cereal" || breakfast === "bagel" || breakfast === "pancakes" || breakfast === "waffles" || breakfast === "bacon") {
						alert("You finish your " + breakfast + " and go back upstairs to brush again.");
					} else {
						gameover = true;
					}
					if (!gameover) {
						alert("You walk outside and wait about five minutes.");
						alert("The bus arrives.");
						alert("You are at school. It was a boring bus ride.");
					}
				}
				break;
			default:
				gameover = true;
		}
		if (!gameover) {
			switch (day) {
				case 1:
					alert("You put your stuff in a shared locker with your best friend. You walk inside to see the first two periods are math: your favourie subject!");
					alert("You easily finish the math and do some work on your laptop.");
					alert("*bell rings*");
					alert("Second period, gym!");
					alert("You walk inside the boys changeroom and quickly get dressed for gym.");
					alert("\"LET'S GET INTO A LINE ON THE WALL! WE'RE DOING OUR WARMUP!\" says the gym teacher.");
					alert("During the warmup, do you...");
					warmup = prompt("[Skip a few laps] or [do it all]?").toLowerCase();
					switch (warmup) {
					case "skip a few laps":
						if (Math.random() < 0.75) {
							alert("Your teacher notices and yells at you for cheating. You now have to do 700 more laps.");
							alert("GAME OVER");
							gameover = true;
						} else {
							alert("You get away with skipping a few laps.");
						}
						break;
					case "do it all":
						if (breakfast !== "nothing") {
							alert("You do all of the warmup.");
							alert("HUFF PUFF HUFF PUFF HUFF PUFF");
						} else {
							alert("Not having any food, you die of exhaustion.");
							gameover = true;
						}
						break;
					default:
						gameover = true;
					}
					if (!gameover) {
						alert("The class plays a game of volleyball and you were the top player!");
						alert("Just kidding, you suck at volleyball.");
						alert("You go back and put your normal clothes back on.");
						alert("*bell rings*");
						alert("Ah, lunch time.");
						alert("You eat your food and play outside.");
						alert("The rest of the day goes on as usual, until you noticed the most hilarious thing.");
						alert("A girl called Ameeta steals tries taking a chair from Kulshan.");
						alert("Kulshan fails to save his chair, so he takes a chair from a boy named Tejas.");
						alert("Tejas pushes Kulshan off the chair, and gets his chair back.");
						alert("At that moment, Kulshan knew, he was chairless.");
						alert("When you went home, you watched some TV and played outside a bit.");
					}
					break;
				case 2:
					alert("It's Halloween. You put on your brilliant costume, a fedora and call yourself Winston Churchill.");
					classmate = prompt("As you walk to the school building, you see some of your classmates. [Cameron] the Demon, [Daman] the Schoolkid, [Connor] the Leprechaun, and [Harshan] the Zombie.\nDo you greet them or [ignore] them? If you did greet them, which one do you greet?").toLowerCase();
					switch (classmate) {
					case "daman":
						alert("You say, \"Hey Daman. Nice costume.\"");
						alert("He responds, \"I'm not wearing a costume, retard.\" He proceeds to lightly tap your shoulder in a joking way. Being Arshneet, this kills you.");
						alert("THE END");
						gameover = true;
						break;
					case "connor":
						alert("You say, \"Hey Connor. Nice costume.\"");
						alert("Connor responds \"WOW, OF COURSE YOU THINK THE LEPRECHAUN COSTUME IS GOOD: BECAUSE LEPRECHAUNS ARE SHORT AND I'M SHORT!\"");
						alert("In his fit of height-insecure induced rage, Connor kills you.");
						gameover = true;
						break;
					case "cameron":
						alert("You say, \"Hey Cameron. Nice costume.\"");
						alert("Cameron responds, \"Thanks Arshneet, what are you supposed to...be...\"");
						alert("He then has an asthma attack on the spot.");
						alert("The stress of Cameron's death kills you.");
						alert("GAME OVER");
						gameover = true;
						break;
					case "harshan":
						alert("You say, \"Hey Harshan. Wow, cool costume.\"");
						alert("He responds, \"Thanks fam. What are you going as when you trick or tre-\"");
						alert("He faints on the spot.");
						alert("The stress kills you.");
						alert("GAME OVER");
						gameover = true;
						break;
					case "ignore":
						alert("You ignore them. Good, since you're a loner anyway.");
						alert("You continue on your merry way to school.");
						alert("As you get to school, the bell rings. Made it just in time!");
						alert("Walking into homeroom, you look around at the assortment of colors and unique costumes.");
						alert("Regardless, you think your costume is the best. Good on you.");
						homeroom = prompt("In homeroom, for the next two periods, do you [work], [fool around], or [play games]?").toLowerCase();
						switch (homeroom) {
						case "fool around":
							alert("Rather than working, you fool around.");
							alert("You play catch with Arash but you drop the ball multiple times and arash makes a joke about it.");
							laugh = prompt("Do you laugh at the joke? ([yes] or [no])").toLowerCase();
							switch (laugh) {
							case "yes":
								alert("Your satanic demon laugh invokes the rage of your classmates. They kill you.");
								alert("GAME OVER");
								gameover = true;
								break;
							case "no":
								alert("Arash gives you a look for not laughing, but you still continue on to third period.");
								break;
							}
							break;
						case "work":
							alert("You decide to actually work, like usual. Good.");
							alert("Class flies by, and all of a sudden it's third period.");
							break;
						case "play games":
							alert("You decide to play some Minecraft.");
							alert("What could go wrong?");
							alert("Suddenly, because you were so immersed in your Minecraft game, you realize your teacher was watching the whole time.");
							alert("Your teacher sends you home as punishment, and your mom grounds you.");
							alert("GAME OVER");
							gameover = true;
							break;
						default:
							gameover = true;
						}
						if (!gameover) {
							alert("You enter the gymnasium once again. Warmup was skipped because the volleyball net was up.");
							alert("A game of volleyball begins. Daman's legendary overhand serve makes it over the net, with the ball coming straight at you.");
							damanserve = prompt("Will you [try to return it], [get out of the way] or [stand in the way]?").toLowerCase();
							switch (damanserve) {
							case "try to return it":
								alert("You wish. This is Daman's serve we're talking about.");
								alert("The ball dunks you with the force of 10,000 Shaqille O'Neals.");
								alert("GAME OVER");
								gameover = true;
								break;
							case "stand in the way":
								alert("Well, that wasn't a smart decision.");
								alert("The ball dunks you with the force of 10,000 Shaqille O'Neals.");
								alert("GAME OVER");
								gameover = true;
								break;
							case "get out of the way":
								alert("You try your very best to dodge.");
								alert("You fail though.");
								alert("Luckily, Harshan, thirsty for redemption after being out-served by Daman, jumps in the way and takes the full force of the hit.");
								alert("Point Daman's team.");
								alert("Daman serves again, but Aryaman returns it and scores your team a point.");
								alert("Your turn to serve.");
								alert("What technique do you use for your serve?");
								arshserve = prompt("The [Arshneet Sidewinder], [traditional], or the [Daman Punch]?").toLowerCase();
								switch (arshserve) {
								case "daman punch":
									alert("You try Daman's serve.");
									alert("You can't pull it off.");
									alert("You have been shamed and must commit seppuku.");
									alert("GAME OVER");
									gameover = true;
									break;
								case "traditional":
									alert("Arshneet? Doing traditional sports?");
									alert("Hah, good one.");
									alert("GAME OVER");
									gameover = true;
									break;
								case "arshneet sidewinder":
									alert("You use your signature technique, and get a ball over the net.");
									alert("Doesn't matter though, you still lose.");
									alert("You head home after some more boring work periods, but to you, it's just your normal every day life.");
									alert("You eat dinner as usual. No skipping it becuase your parents are watching. After all, you're starving. Boy, is volleyball tiring.");
								}
								break;
							default:
								gameover = true;
							}
						}
						break;
					default:
						gameover = true;
					}
					break;
				case 3:
					alert("This is when day three is supposed to happen, but since it hasn't been coded, well...");
					alert("GAME OVER");
					gameover = true;
					break;
				}
			}
			if (!gameover) {
				alert("After eating dinner, do you...");
				sleep = prompt("...[stay up] or [go to sleep]?").toLowerCase();
				switch (sleep) {
				case "stay up":
					alert("You stay up and play video games.");
					while (!gameover) {
						alert("You hear your mother coming.");
						if (Math.random() < 0.75) {
							alert("You pretend to sleep.");
							alert("Your mother passes by without blinking an eye. You continue to play video games.");
						} else {
							alert("Your mother came before you could pretend to sleep.");
							alert("You get caught (obviously).");
							alert("GAME OVER");
							gameover = true;
						}
					}
					break;
				case "go to sleep":
					alert("You brush you bathe, brush your teeth, and finally lie down in bed after a long day.");
					break;
				default:
					gameover = true;
				}
			}
	}
	gameover = false;
	day = 0;
}<|endoftext|>


<commit_before>/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4,
maxerr: 50, node: true */
/*global */

// NOTE : changes in here are only updated when brackets is fully closed
// and opened again.  F5 isn't enough.  Something to do with domainManager
// not clearing out names like the name in registerDomain function

(function () {
    "use strict";

    var fs = require("fs");
    var path = require("path");
    var exec = require('child_process').exec;

    /**
     * @private
     * Handler function to start node-webkit using another process
     * @param {string} nwpath Absolute path to nw.exe.
     * @param {string} basepath Current brackets project path.
     * @return {string} An error message if there is one.
     */
	function startnw(nwpath, basepath, callback) {
        console.log("Running: " + basepath + ", using: " + nwpath);

        // some validation to prevent starting node-webkit with invalid inputs
        // otherwise it fails silently and leaves a few nw.exe processes running

        // node-webkit projects need a package.json
        var packagePath = path.join(basepath, "package.json");
        if (!fs.existsSync(packagePath)) {
            return callback("package.json missing from currently open Bracekts project");
        }

        // node-webkit missing main property in package.json
        var packageJson = fs.readFileSync(packagePath, "utf8");
        if (!packageJson) {
            return callback("Error loading package.json.  File was empty or invalid");
        }

        // parse the package.json file if there was one
        try {
            packageJson = JSON.parse(packageJson);
        } catch (ex) {
            return callback("Error parsing package.json");
        }

        if (!packageJson.main) {
            return callback("Missing 'main' property from package.json");
        }

        // node-webkit invalid main value in package.json
        if (!fs.existsSync(path.join(basepath, packageJson.main))) {
            return callback("Invalid 'main' property of package.json: file not found");
        }

        // run node-webkit
        exec(nwpath + " " + basepath, function (error, stdout, stderr) {
            if (error) {
                console.log(error)
                return callback(
                    "
Error running project
" + basepath + "
    using
" + nwpath +
                    "

There may be a problem with your nw.exe path or you may not have " +
                    "a node-webkit project currently open in Brackets
");
            }

            return callback();
        });
	}

    // Init
    function init(domainManager) {
        if (!domainManager.hasDomain("run-node-webkit")) {
            domainManager.registerDomain("run-node-webkit", {major: 0, minor: 1});
        }

		domainManager.registerCommand("run-node-webkit", "startnw", startnw, true,
            "Returns a message if started otherwise an error (err, message)", [
                { name: "nwpath", type: "string", description: "Absolute path to nw.exe" },
                { name: "basepath", type: "string", description: "Current brackets open project path" },
                { name: "callback", type: "function", description: "Callback (err, result)" }
            ], [
                { name: "message", type: "string", description: "Error message on start failure" }
            ], []);
    }

    exports.init = init;

}());

<commit_msg>Another process check<commit_after>/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4,
maxerr: 50, node: true */
/*global */

// NOTE : changes in here are only updated when brackets is fully closed
// and opened again.  F5 isn't enough.  Something to do with domainManager
// not clearing out names like the name in registerDomain function

(function () {
    "use strict";

    var fs = require("fs");
    var path = require("path");
    var exec = require('child_process').exec;

    /**
     * @private
     * Handler function to start node-webkit using another process
     * @param {string} nwpath Absolute path to nw.exe.
     * @param {string} basepath Current brackets project path.
     * @return {string} An error message if there is one.
     */
	function startnw(nwpath, basepath, callback) {
        console.log("Running: " + basepath + ", using: " + nwpath);

//         some validation to prevent starting node-webkit with invalid inputs
//         otherwise it fails silently and leaves a few nw.exe processes running

        // node-webkit projects need a package.json
        var packagePath = path.join(basepath, "package.json");
        if (!fs.existsSync(packagePath)) {
            return callback("package.json missing from currently open Bracekts project");
        }

        // node-webkit missing main property in package.json
        var packageJson = fs.readFileSync(packagePath, "utf8");
        if (!packageJson) {
            return callback("Error loading package.json.  File was empty or invalid");
        }

        // parse the package.json file
        try {
            packageJson = JSON.parse(packageJson);
        } catch (ex) {
            return callback("Error parsing package.json");
        }

        // missing main in package.json
        if (!packageJson.main) {
            return callback("Missing 'main' property from package.json");
        }

        // node-webkit invalid main value in package.json
        if (!fs.existsSync(path.join(basepath, packageJson.main))) {
            return callback("Invalid 'main' property of package.json: file not found");
        }

        // run node-webkit
        exec(nwpath + " " + basepath, function (error, stdout, stderr) {
            if (error && error.killed !== false) {
                console.log(error)
                return callback(
                    "
Error running project
" + basepath + "
    using
" + nwpath +
                    "

There may be a problem with your nw.exe path or you may not have " +
                    "a node-webkit project currently open in Brackets
");
            } else {
                return callback();
            }
        });

        setTimeout(function () {
            return callback();
        }, 3000);
	}

    // Init
    function init(domainManager) {
        if (!domainManager.hasDomain("run-node-webkit")) {
            domainManager.registerDomain("run-node-webkit", {major: 0, minor: 1});
        }

		domainManager.registerCommand("run-node-webkit", "startnw", startnw, true,
            "Returns a message if started otherwise an error (err, message)", [
                { name: "nwpath", type: "string", description: "Absolute path to nw.exe" },
                { name: "basepath", type: "string", description: "Current brackets open project path" },
                { name: "callback", type: "function", description: "Callback (err, result)" }
            ], [
                { name: "message", type: "string", description: "Error message on start failure" }
            ], []);
    }

    exports.init = init;

}());

<|endoftext|>


<commit_before>(function() {

var gui = require('nw.gui');
var fs = require('fs');
var path = require('path');
var exec = require('child_process').exec;
var clj_fuzzy = require('clj-fuzzy');
var xdg = require('./xdg');
var win = gui.Window.get();

// Useful DOM objects:
var results = document.getElementById("results");

// Execute arbitrary command, removing the XDG .desktop file specific stuff
// until we figure out what to do with them.
function executeCommand(path) {
	path = path.replace(/%[UufF]/g, "");
	console.log("Executing: " + path);
	exec(path);  // dun dun dun
	win.close();
}

// Reads a desktop file. Returns an object with an "exists" attribute as false
// if not found (because screw the idea of null!)
function fileToEntry(filename) {
	if (filename.indexOf(".desktop") != -1) {
		var contents = fs.readFileSync(filename).toString();
		var executable = xdg.extractKey(contents, "Exec");
		var title = xdg.extractKey(contents, "Name");
		var icon = xdg.extractKey(contents, "Icon");
		return {
			"title": title,
			"icon": xdg.iconToPath(icon),
			"path": executable,
			"exists": true
		}
	}
	return {"exists": false};
}

// Searches applciations directory under the data for .desktop files, and adds
// entry objects for each of them.
function getEntriesFromApplications(dataDir) {
	var entries = [];
	var dir = path.join(dataDir, 'applications');
	if (fs.existsSync(dir)) {
		var desktopFiles = fs.readdirSync(dir);
		for (var j= 0, len = desktopFiles.length; j < len; j++) {
			entries.push(fileToEntry(path.join(dir, desktopFiles[j])));
		}
	}
	return entries;
}

// Filters out the first 5 entries that match the query.
function getQueryResults(entries, query) {
	if (query === "") {""
		return [];
	}
	var lowerQuery = query.toLowerCase();

	function addScore(entry) {
		var lowerTitle = entry.title.toLowerCase();
		entry.score = clj_fuzzy.metrics.jaccard(lowerTitle, lowerQuery);
		return entry;
	}

	function entryMatches(entry) {
		if (!entry.exists) {
			return false;
		}
		var lowerTitle = entry.title.toLowerCase();
		var contains = lowerQuery.indexOf(lowerTitle) != -1;
		var wildcardRegex = new RegExp(lowerQuery.split("").join(".*"), "i");
		var wildcardMatch = wildcardRegex.test(lowerTitle);
		return contains || wildcardMatch;
	}

	return entries.filter(entryMatches)
	              .map(addScore)
	              .sort(function (a, b) { return a.score - b.score; })
	              .slice(0, 5);
}

// Converts an entry number into a display string for the  appropriate shortcut.
// Currently hardcoded as "Return" for the first entry, and Alt+n for the nth
// entry. Should be configurable in the future.
function getShortcut(entryNumber) {
	if (entryNumber == 0) {
		return "\u23CE";  // return symbol
	} else {
		return "Alt+" + (entryNumber + 1);
	}
}

// Converts an entry object to HTML for display purposes
function entryToHTML(queryResult, entryNumber) {
	var elem = document.createElement("li");
	elem.className = "menu-item";

	var icon = document.createElement("img");
	icon.className = "icon";
	icon.src = queryResult.icon;

	var text = document.createElement("div");
	text.className = "text";

	var title = document.createElement("span");
	title.className = "title";
	title.appendChild(document.createTextNode(queryResult.title));
	text.appendChild(title);

	var path = document.createElement("span");
	path.className = "path";
	path.appendChild(document.createTextNode(queryResult.path));
	text.appendChild(path);

	var shortcut = document.createElement("span");
	shortcut.className = "shortcut";
	shortcut.appendChild(document.createTextNode(getShortcut(entryNumber)));

	elem.appendChild(icon);
	elem.appendChild(text);
	elem.appendChild(shortcut);

	elem.addEventListener('click', function (e) {
		executeCommand(queryResult.path);
	}, true);
	return elem;

}

// Updates the DOM with the entry objects
function updateResults(queryResults) {
	// Change elements
	while (results.hasChildNodes()) {
		results.removeChild(results.lastChild);
	}
	for (var i = 0, len = queryResults.length; i < len; i++) {
		var queryResult = queryResults[i];
		results.appendChild(entryToHTML(queryResult, i));
	}

	// Don't display footer if 1 or fewer elements.
	var footer = document.getElementById("footer");
	if (queryResults.length > 1) {
		footer.style.display = "block";
	} else {
		footer.style.display = "none";
	}
}

// Value to use as "negative"
function clearSelect() {
	return -1;
}

// User hit down, so increase the index value (maxing out at # of results)
function selectDown(highlighted) {
	return Math.min(highlighted + 1, results.childNodes.length - 1);
}

// User hit up, so decrease the index value (stopping at 0)
function selectUp(highlighted) {
	return Math.max(highlighted - 1, 0);
}

// Gets the selected application to run. If the user hit enter and something was
// highlighted via arrow keys, use that one. Otherwise, use the firs tone.
// If the user hit Alt+n, return n.
function getNumSelected(highlighted, e) {
	var selected = clearSelect();
	// Enter
	if (e.keyCode == 13) {
		selected = highlighted == clearSelect() ? 1 : highlighted + 1;
	}
	// Alt + number
	var numPressed = parseInt(String.fromCharCode(e.keyCode), 10);
	if (e.altKey && !isNaN(numPressed)) {
		selected = numPressed;
	}
	return selected;
}

// Updates the DOM to reflect the current highlighted entry.
function updateHighlighted(highlighted) {
	var numEntries = results.childNodes.length;
	for (var i = 0; i < numEntries; i++) {
		results.childNodes[i].className = 'menu-item';
		if (i == highlighted) {
			results.childNodes[i].className += ' selected';
		}
	}
}

function listenForEscapeToClose() {
	document.addEventListener('keyup', function (e) {
		if (e.keyCode == 27) {  // escape
			var win = gui.Window.get();
			win.close();
		}
	}, true);
}

function main() {
	listenForEscapeToClose();

	var highlighted = -1;  // none
	var entries = [];
	xdg.forEachDataDir(function (dataDir) {
		entries = entries.concat(getEntriesFromApplications(dataDir));
	});

	var searchTextbox = document.getElementById("search");
	searchTextbox.addEventListener('keyup', function (e) {
		var query = e.target.value;
		var queryResults = getQueryResults(entries, query);
		updateResults(queryResults);

		if (e.keyCode == 40) {  // down arrow
			highlighted = selectDown(highlighted);
		} else if (e.keyCode == 38) {  // up arrow
			highlighted = selectUp(highlighted);
		} else if (e.keyCode != 13) {  // anything but Enter clears the selected
			highlighted = clearSelect();
		}
		updateHighlighted(highlighted);

		var numSelected = getNumSelected(highlighted, e);  // 1-based
		if (numSelected != -1 && queryResults.length >= numSelected) {
			var selectedEntry = queryResults[numSelected - 1];
			var path = selectedEntry.path;
			executeCommand(path);
		}
	}, true);

	win.on('blur', function () {
		win.close();
	}, true);
}

main();

})();<commit_msg>Refactor keyboard shortcut handling<commit_after>(function() {

var gui = require('nw.gui');
var fs = require('fs');
var path = require('path');
var exec = require('child_process').exec;
var clj_fuzzy = require('clj-fuzzy');
var xdg = require('./xdg');
var win = gui.Window.get();

var CLEAR_SELECT = -1;
var results = document.getElementById("results");

// Execute arbitrary command, removing the XDG .desktop file specific stuff
// until we figure out what to do with them.
function executeCommand(path) {
	path = path.replace(/%[UufF]/g, "");
	console.log("Executing: " + path);
	exec(path);  // dun dun dun
	win.close();
}

// Reads a desktop file. Returns an object with an "exists" attribute as false
// if not found (because screw the idea of null!)
function fileToEntry(filename) {
	if (filename.indexOf(".desktop") != -1) {
		var contents = fs.readFileSync(filename).toString();
		var executable = xdg.extractKey(contents, "Exec");
		var title = xdg.extractKey(contents, "Name");
		var icon = xdg.extractKey(contents, "Icon");
		return {
			"title": title,
			"icon": xdg.iconToPath(icon),
			"path": executable,
			"exists": true
		}
	}
	return {"exists": false};
}

// Searches applciations directory under the data for .desktop files, and adds
// entry objects for each of them.
function getEntriesFromApplications(dataDir) {
	var entries = [];
	var dir = path.join(dataDir, 'applications');
	if (fs.existsSync(dir)) {
		var desktopFiles = fs.readdirSync(dir);
		for (var j= 0, len = desktopFiles.length; j < len; j++) {
			entries.push(fileToEntry(path.join(dir, desktopFiles[j])));
		}
	}
	return entries;
}

// Filters out the first 5 entries that match the query.
function getQueryResults(entries, query) {
	if (query === "") {""
		return [];
	}
	var lowerQuery = query.toLowerCase();

	function addScore(entry) {
		var lowerTitle = entry.title.toLowerCase();
		entry.score = clj_fuzzy.metrics.jaccard(lowerTitle, lowerQuery);
		return entry;
	}

	function entryMatches(entry) {
		if (!entry.exists) {
			return false;
		}
		var lowerTitle = entry.title.toLowerCase();
		var contains = lowerQuery.indexOf(lowerTitle) != -1;
		var wildcardRegex = new RegExp(lowerQuery.split("").join(".*"), "i");
		var wildcardMatch = wildcardRegex.test(lowerTitle);
		return contains || wildcardMatch;
	}

	return entries.filter(entryMatches)
	              .map(addScore)
	              .sort(function (a, b) { return a.score - b.score; })
	              .slice(0, 5);
}

// Converts an entry number into a display string for the  appropriate shortcut.
// Currently hardcoded as "Return" for the first entry, and Alt+n for the nth
// entry. Should be configurable in the future.
function getShortcut(entryNumber) {
	if (entryNumber == 0) {
		return "\u23CE";  // return symbol
	} else {
		return "Alt+" + (entryNumber + 1);
	}
}

// Converts an entry object to HTML for display purposes
function entryToHTML(queryResult, entryNumber) {
	var elem = document.createElement("li");
	elem.className = "menu-item";

	var icon = document.createElement("img");
	icon.className = "icon";
	icon.src = queryResult.icon;

	var text = document.createElement("div");
	text.className = "text";

	var title = document.createElement("span");
	title.className = "title";
	title.appendChild(document.createTextNode(queryResult.title));
	text.appendChild(title);

	var path = document.createElement("span");
	path.className = "path";
	path.appendChild(document.createTextNode(queryResult.path));
	text.appendChild(path);

	var shortcut = document.createElement("span");
	shortcut.className = "shortcut";
	shortcut.appendChild(document.createTextNode(getShortcut(entryNumber)));

	elem.appendChild(icon);
	elem.appendChild(text);
	elem.appendChild(shortcut);

	elem.addEventListener('click', function (e) {
		executeCommand(queryResult.path);
	}, true);
	return elem;

}

// Updates the DOM with the entry objects
function updateResults(queryResults) {
	// Change elements
	while (results.hasChildNodes()) {
		results.removeChild(results.lastChild);
	}
	for (var i = 0, len = queryResults.length; i < len; i++) {
		var queryResult = queryResults[i];
		results.appendChild(entryToHTML(queryResult, i));
	}

	// Don't display footer if 1 or fewer elements.
	var footer = document.getElementById("footer");
	if (queryResults.length > 1) {
		footer.style.display = "block";
	} else {
		footer.style.display = "none";
	}
}

// Gets the selected application to run. If the user hit enter and something was
// highlighted via arrow keys, use that one. Otherwise, use the firs tone.
// If the user hit Alt+n, return n.
function getNumSelected(highlighted, e) {
	var selected = CLEAR_SELECT;
	// Enter
	if (e.keyCode == 13) {
		selected = highlighted == CLEAR_SELECT ? 1 : highlighted + 1;
	}
	// Alt + number
	var numPressed = parseInt(String.fromCharCode(e.keyCode), 10);
	if (e.altKey && !isNaN(numPressed)) {
		selected = numPressed;
	}
	return selected;
}

// Updates the DOM to reflect the current highlighted entry.
function updateHighlighted(highlighted) {
	var numEntries = results.childNodes.length;
	for (var i = 0; i < numEntries; i++) {
		results.childNodes[i].className = 'menu-item';
		if (i == highlighted) {
			results.childNodes[i].className += ' selected';
		}
	}
}

function listenForEscapeToClose() {
	document.addEventListener('keyup', function (e) {
		if (e.keyCode == 27) {  // escape
			var win = gui.Window.get();
			win.close();
		}
	}, true);
}

// Handles Enter or Alt+n keyboard shortcuts
function handleShortcuts(highlighted, queryResults, e) {
	var numSelected = getNumSelected(highlighted, e);  // 1-based
	if (numSelected != -1 && queryResults.length >= numSelected) {
		var selectedEntry = queryResults[numSelected - 1];
		var path = selectedEntry.path;
		executeCommand(path);
	}
}

function getHighlightChangedFromKeyPress(highlighted, keyCode) {
	if (keyCode == 40) {  // down arrow; increase the index value
		return Math.min(highlighted + 1, results.childNodes.length - 1);
	} else if (keyCode == 38) {  // up arrow; decrease the index value
		return Math.max(highlighted - 1, 0);
	} else if (keyCode != 13) {  // anything but Enter clears the selected
		return CLEAR_SELECT;
	}
}

function main() {
	listenForEscapeToClose();

	var highlighted = -1;  // none
	var entries = [];
	xdg.forEachDataDir(function (dataDir) {
		entries = entries.concat(getEntriesFromApplications(dataDir));
	});

	var searchTextbox = document.getElementById("search");
	searchTextbox.addEventListener('keyup', function (e) {
		var query = e.target.value;
		var queryResults = getQueryResults(entries, query);
		updateResults(queryResults);
		highlighted = getHighlightChangedFromKeyPress(highlighted, e.keyCode)

		updateHighlighted(highlighted);
		handleShortcuts(highlighted, queryResults, e);
	}, true);

	win.on('blur', function () {
		win.close();
	}, true);
}

main();

})();<|endoftext|>


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

function renderMainPage(req, res) {
    req.db.get('trails').find( {access: 'public'}, {fields: { 'trailname':1, 'location':1 }},
        function(err, doc) {
	if (err || doc == null) { throw err; }
	    res.render('main', { title: 'Just Another Trail Map', authenticated: false, trails: doc });
	});
}

function checkuser(req, res, callback) {
    var user = req.cookies.username;
    var pass = req.cookies.password;

    if (user == undefined) {
	console.log("ERROR: Username didn't find from cookies");
	callback(req, res, "ERROR Username didn't find from cookies");
	return;
    }
    if (pass == undefined) {
	console.log("ERROR: Password didn't find from cookies");
	callback(req, res, "ERROR: Password didn't find from cookies");
	return;
    }
    req.db.get('users').find( { username: user }, { fields: {password: 1, _id: 1 } }, function(err, doc) {
	if (err || doc == null) {
	    throw err;
	}
	if (doc.length == 0) {
	    console.log("username wasn't found from database");
	    callback(req, res, "Username " + user + " wasn't found from database");
	    return;
	}
	if (doc[0].password != pass) {
	    console.log("wrong password");
	    callback(req, res, "Wrong password");
	    return;
	}
	callback(req, res, null, doc[0]._id);
    });
}

router.get('/groups', function(req, res) {
    checkuser(req, res, function(req, res, err, userid) {
	if (err == null) {
	    req.db.get('groups').find( {'ownerid': {$eq : userid}}, {fields: { 'name':1}}, function(err, doc) {
		if (err || doc == null) {
		    throw err;
		}
		res.render('groups', { title: 'Manage Groups', groups: doc });
	    });
	}
	else {
	    console.log("username and password don't match");
	    renderMainPage(req, res);
	}
    });
});

router.get('/newgroup', function(req, res) {
    checkuser(req, res, function(req, res, err, userid) {
	if (err == null) {
	    req.db.get('users').find( {'_id': {$ne : userid}}, {fields: { 'fullname':1}}, function(err, doc) {
		if (err || doc == null) {
		    throw err;
		}
		res.render('newgroup', { title: 'Add New Group', users: doc });
	    });
	}
	else {
	    renderMainPage(req, res);
	}
    });
});

router.post('/addgroup', function(req, res) {
    var name = req.body.groupname;
    var users = req.body.users;
    checkuser(req, res, function(req, res, err, userid) {
	if (err == null) {
	    req.db.get('groups').insert({'ownerid': userid, 'members': users, 'name': name}, function(err, doc) {
		if (err || doc == null) {
		    throw err;
		}
		res.json({"status": "ok"});
	    });
	}
	else {
	    res.json({"status": "notok", "msg": err});
	}
    });
});

router.get('/editgroup/*', function(req, res) {
    checkuser(req, res, function(req, res, err, userid) {
	if (err == null) {
	    var parts = req.url.split("/");
	    if (parts.length != 3) {
		return;
	    }
	    var groupid = parts[2];
	    req.db.get('groups').find( {'_id': groupid, 'ownerid': userid}, {fields: { 'members':1, 'name':1 } }, function(err, doc) {
		if (err || doc == null) {
		    throw err;
		}
		if (doc.length == 0) {
		    console.log("group wasn't found");
		    res.status(404);
		    res.send("The group wasn't found");
		    return;
		}
		var groupname = doc[0].name;
		var ids = [];
		for (var i=0; i<doc[0].members.length; i++) {
		    ids[i] = { '_id':doc[0].members[i] };
		}
		req.db.get('users').find( { '$or': ids }, {fields: {'fullname':1} }, function(err, doc) {
		    if (err || doc == null) {
			throw err;
		    }
		    var members = [];
		    if (doc) {
			members = doc
		    }

		    // do a query for getting all non member ids
		    var ids = [];
		    for (var i=0; i<members.length; i++) {
			ids[i] = { '_id':members[i]._id };
		    }
		    ids[i] = { '_id':userid };
		    req.db.get('users').find( { '$nor': ids }, {fields: {'fullname':1} }, function(err, doc) {
			if (err || doc == null) {
			    throw err;
			}
			var nonmembers = [];
			if (doc) {
			    nonmembers = doc
			}
			res.render('editgroup', { title: 'Add New Group', groupid:groupid, groupname: groupname, members: members, nonmembers: nonmembers });
		    });
		});
	    });
	}
    });
});

router.post('/updategroup', function(req, res) {
    checkuser(req, res, function(req, res, err, userid) {
	var groupname = req.body.groupname;
	var members = req.body.members;
	var groupid = req.body.groupid;
	if (err == null) {
	    req.db.get('groups').update( { '_id': groupid, 'ownerid':userid },
		{ "$set": { "name": groupname, "members": members } },
		function(err, result) {
		    if (err) { throw err; }
		    if (result.nModified == 1) {
			res.json({"status": "ok"});
		    }
		    else {
			res.json({"status": "notok", "msg": "The group wasn't updated."});
		    }
		});
	}
	else {
	    res.json({"status": "notok", "msg": err});
	}
    });
});

router.delete('/group/*', function(req, res) {
    checkuser(req, res, function(req, res, err, userid) {
	if (err == null) {
	    var parts = req.url.split("/");

	    if (parts.length == 3) {
		var id = parts[2];
		console.log('id', id);
		console.log('userid', userid);
		req.db.get('groups').remove( { "_id": id, 'ownerid': userid }, function(err, result) {
		    if (err) {
			throw err;
		    }
		    if (result.result.n == 1) {
			res.json({"status": "ok"});
		    }
		    else {
			res.json({"status": "notok", "msg": "The group " + id + " was not deleted"});
		    }
		});
	    }
	    else {
		res.json({"status": "notok", "msg": "parse error"});
	    }
	}
	else {
	    res.json({"status": "notok", "msg": err});
	}
    });
});

module.exports = router;
<commit_msg>Replaced clear username and password with session token.<commit_after>var express = require('express');
var router = express.Router();
var ObjectId = require('mongodb').ObjectID;

function renderMainPage(req, res) {
    req.db.get('trails').find( {access: 'public'}, {fields: { 'trailname':1, 'location':1 }},
        function(err, doc) {
	if (err || doc == null) { throw err; }
	    res.render('main', { title: 'Just Another Trail Map', authenticated: false, trails: doc });
	});
}

function authenticateUser(req, res, callback) {
    var token = req.cookies.token;

    req.db.get('sessions').find( { 'token': token }, { fields: {'userid': 1} }, function(err, doc) {
	if (err || doc == null) {
	    throw err;
	}
	if (doc.length == 1) {
	    callback(req, res, null, doc[0].userid);
	}
	else {
	    console.log("session token '" + token + "' not found from db");
	    callback(req, res, "Session is expired");
	}
    });
}

router.get('/groups', function(req, res) {
    authenticateUser(req, res, function(req, res, err, userid) {
	if (err == null) {
	    req.db.get('groups').find( {'ownerid': {$eq : userid}}, {fields: { 'name':1}}, function(err, doc) {
		if (err || doc == null) {
		    throw err;
		}
		res.render('groups', { title: 'Manage Groups', groups: doc });
	    });
	}
	else {
	    renderMainPage(req, res);
	}
    });
});

router.get('/newgroup', function(req, res) {
    authenticateUser(req, res, function(req, res, err, userid) {
	if (err == null) {
	    req.db.get('users').find( {'_id': {$ne : userid}}, {fields: { 'fullname':1, 'username':1}}, function(err, users) {
		if (err || users == null) {
		    throw err;
		}
		for (var i=0; i<users.length; i++) {
		    if (users[i].fullname == "") {
			users[i].fullname = users[i].username;
		    }
		}
		res.render('newgroup', { title: 'Add New Group', users: users });
	    });
	}
	else {
	    renderMainPage(req, res);
	}
    });
});

router.post('/addgroup', function(req, res) {
    authenticateUser(req, res, function(req, res, err, userid) {
	var name = req.body.groupname;
	var users = req.body.users;
	if (err == null) {
	    req.db.get('groups').insert({'ownerid': userid, 'members': users, 'name': name}, function(err, doc) {
		if (err || doc == null) {
		    throw err;
		}
		res.json({"status": "ok"});
	    });
	}
	else {
	    res.json({"status": "notok", "msg": err});
	}
    });
});

router.get('/editgroup/*', function(req, res) {
    authenticateUser(req, res, function(req, res, err, userid) {
	if (err == null) {
	    var parts = req.url.split("/");
	    if (parts.length != 3) {
		return;
	    }
	    var groupid = parts[2];
	    req.db.get('groups').find( {'_id': groupid, 'ownerid': userid}, {fields: { 'members':1, 'name':1 } }, function(err, doc) {
		if (err || doc == null) {
		    throw err;
		}
		if (doc.length == 0) {
		    console.log("group wasn't found");
		    res.status(404);
		    res.send("The group wasn't found");
		    return;
		}
		var groupname = doc[0].name;
		var ids = doc[0].members;

		// get all member ids
		req.db.get('users').find( { _id: {'$in': ids} }, {fields: {'fullname':1, 'username': 1} }, function(err, members) {
		    if (err || doc == null) {
			throw err;
		    }
		    // get all non member ids
		    ids.push(userid);
		    req.db.get('users').find( { '$nor': [ {_id: { '$in':ids } } ] }, {fields: {'fullname':1, 'username': 1} }, function(err, nonmembers) {
			if (err || doc == null) {
			    throw err;
			}
			// if full name is not available, use username
			for (var i=0; i<members.length; i++) {
			    if (members[i].fullname == "") {
				members[i].fullname = members[i].username;
			    }
			}
			for (var i=0; i<nonmembers.length; i++) {
			    if (nonmembers[i].fullname == "") {
				nonmembers[i].fullname = nonmembers[i].username;
			    }
			}
			res.render('editgroup', { title: 'Edit Group', groupid:groupid, groupname: groupname, members: members, nonmembers: nonmembers });
		    });
		});
	    });
	}
	else {
	    renderMainPage(req, res);
	}
    });
});

router.post('/updategroup', function(req, res) {
    authenticateUser(req, res, function(req, res, err, userid) {
	var groupname = req.body.groupname;
	var groupid = req.body.groupid;
	var members = [];

	if (req.body.members) {
	    for (var i=0; i<req.body.members.length; i++) {
		members[i] = ObjectId(req.body.members[i]);
	    }
	}
	if (err == null) {
	    req.db.get('groups').update( { '_id': groupid, 'ownerid':userid },
	     { "$set": { "name": groupname, "members": members } },
	      function(err, result) {
		if (err) { throw err; }
		if (result.nModified == 1) {
		    res.json({"status": "ok"});
		}
		else {
		    res.json({"status": "notok", "msg": "The group wasn't updated."});
		}
	      });
	}
	else {
	    res.json({"status": "notok", "msg": err});
	}
    });
});

router.delete('/group/*', function(req, res) {
    authenticateUser(req, res, function(req, res, err, userid) {
	if (err == null) {
	    var parts = req.url.split("/");

	    if (parts.length == 3) {
		var id = parts[2];
		req.db.get('groups').remove( { "_id": id, 'ownerid': userid }, function(err, result) {
		    if (err) {
			throw err;
		    }
		    if (result.result.n == 1) {
			res.json({"status": "ok"});
		    }
		    else {
			res.json({"status": "notok", "msg": "The group " + id + " was not deleted"});
		    }
		});
	    }
	    else {
		res.json({"status": "notok", "msg": "parse error"});
	    }
	}
	else {
	    res.json({"status": "notok", "msg": err});
	}
    });
});

module.exports = router;
<|endoftext|>