<commit_before>var util = require('util'),
  os = require('os'),
  PythonShell = require('python-shell'),
  exec = require('child_process').exec,
  bleno = require('bleno'),
  gpio = require("pi-gpio"),
  Descriptor = bleno.Descriptor,
  Characteristic = bleno.Characteristic,
  ShinySettings = require('./ShinySettings');

var BatteryLevelCharacteristic = function() {
  BatteryLevelCharacteristic.super_.call(this, {
      uuid: '2A19',
      properties: ['read', 'write', 'notify'],
      descriptors: [
        new Descriptor({
            uuid: '2901',
            value: 'Battery level between 0 and 100 percent'
        }),
        new Descriptor({
            uuid: '2904',
            value: new Buffer([0x04, 0x01, 0x27, 0xAD, 0x01, 0x00, 0x00 ]) // maybe 12 0xC unsigned 8 bit
        })
      ]
  });
};

util.inherits(BatteryLevelCharacteristic, Characteristic);

BatteryLevelCharacteristic.prototype.onReadRequest = function(offset, callback) {

  console.log("in read");
  if (os.platform() === 'darwin') {
    exec('pmset -g batt', function (error, stdout, stderr) {

      var data = stdout.toString();
      // data - 'Now drawing from \'Battery Power\'\n -InternalBattery-0\t95%; discharging; 4:11 remaining\n'
      var percent = data.split('\t')[1].split(';')[0];
      console.log(percent);
      percent = parseInt(percent, 10);
      callback(this.RESULT_SUCCESS, new Buffer([percent]));

    });
  } else {
    // return hardcoded value
    console.log("reading...")
    callback(this.RESULT_SUCCESS, new Buffer([98]));

  }
};

BatteryLevelCharacteristic.prototype.onWriteRequest = function(data, offset, withoutResponse, callback) {
  //console.log("in write");
  if (offset) {
    //console.log("in write - offset");
    callback(this.RESULT_ATTR_NOT_LONG);
  }
  //else if (data.length !== 1) {
   // console.log("data length !== 1");
    //console.log(JSON.stringify(data));
    //callback(this.RESULT_INVALID_ATTRIBUTE_LENGTH);
  //}
  else {
    // console.log(JSON.stringify(data));
    // console.log('processing write request');
    // var receivedData = data.readUInt8(0);
    // console.log(typeof data);
    // console.log(data.toString('ascii'));

    // console.log(receivedData);
    // console.log(typeof receivedData);
        var command = data.toString('ascii');
    //console.log('command');
    console.log(command);

    if(command === "0"){
      console.log("stop");
      // print "Now stop"
      // GPIO.output(Motor1E,GPIO.LOW)

          gpio.open(22, "output", function(err) {
          if(err){
            console.log(err);
          }       // Open pin 22 for output
          gpio.write(22, 0, function() {            // Set pin 22 low (0)
              console.log("set pin 22 low");
            //gpio.close(22);                        // Close pin 22
          });
        });

    }
    else if(command === "1"){
      console.log("command left");

            PythonShell.defaultOptions = {
              scriptPath: './gpiopython'
            };

            var pyshell = new PythonShell('pwmRelative.py', {
                mode: 'text'
            });

            var output = '';
            pyshell.stdout.on('data', function (data) {
                output += ''+data;
                console.log(output);
            });

            pyshell.send('left').end(function (err) {
                if (err) return console.log(err);
                console.log(output);

            });

            pyshell.send(ShinySettings.wheelAngle.toString()).end(function (err) {
                if (err) return console.log(err);
                ShinySettings.wheelAngle = output;
                console.log(output);

            });

            ShinySettings.wheelAngle = ShinySettings.wheelAngle + 1;

    }else if(command === "2"){
      console.log("command right");

            PythonShell.defaultOptions = {
              scriptPath: './gpiopython'
            };

            var pyshell = new PythonShell('pwm.py', {
                pythonOptions: '-u'
            });

            var output = '';
            pyshell.stdout.on('data', function (data) {
                output += ''+data;
                console.log(output);
            });

            pyshell.send('right').end(function (err) {
                if (err) return console.log(err);
                console.log(output);

            });
    }
    else if(command === "3"){
      console.log("forward");

          gpio.open(16, "output", function(err) {
            if(err){
              console.log(err);
            }       // Open pin 16 for output
            gpio.write(16, 0, function() {            // Set pin 16 high (1)
                console.log("set pin 16 low");
              //gpio.close(16);                        // Close pin 16
              //18
              gpio.open(18, "output", function(err) {
                if(err){
                  console.log(err);
                }       // Open pin 18 for output
                gpio.write(18, 1, function() {            // Set pin 18 low (0)
                    console.log("set pin 18 high");
                  //gpio.close(18);                        // Close pin 18
                    gpio.open(22, "output", function(err) {
                          if(err){
                            console.log(err);
                          }       // Open pin 22 for output
                          gpio.write(22, 1, function() {            // Set pin 22 high (1)
                              console.log("set pin 22 high");
                            //gpio.close(22);                        // Close pin 22
                          });
                        });
                });
              });
            });
          });

    }
    else if(command === "4"){
      console.log("back");
                gpio.open(16, "output", function(err) {
            if(err){
              console.log(err);
            }       // Open pin 16 for output
            gpio.write(16, 1, function() {            // Set pin 16 high (1)
                console.log("set pin 16 high");
              //gpio.close(16);                        // Close pin 16
              //18
              gpio.open(18, "output", function(err) {
                if(err){
                  console.log(err);
                }       // Open pin 18 for output
                gpio.write(18, 0, function() {            // Set pin 18 low (0)
                    console.log("set pin 18 low");
                  //gpio.close(18);                        // Close pin 18
                    gpio.open(22, "output", function(err) {
                          if(err){
                            console.log(err);
                          }       // Open pin 22 for output
                          gpio.write(22, 1, function() {            // Set pin 22 high (1)
                              console.log("set pin 22 high");
                            //gpio.close(22);                        // Close pin 22
                          });
                        });
                });
              });
            });
          });
    }

  }
  callback(this.RESULT_SUCCESS);
};

function setMotorDirection(direction) {
    console.log('Setting: ' + direction);

          var pin16 = 0;
          var pin18 = 0;
          var pin22 = 0;

          if(direction === 'forward'){
            pin16 = 1;
            pin18 = 0;
            pin22 = 1;
          }else if (direction == 'reverse'){
            pin16 = 1;
            pin18 = 0;
            pin22 = 1;
          }

          gpio.open(16, "output", function(err) {
            if(err){
              console.log(err);
            }       // Open pin 16 for output
            gpio.write(16, pin16, function() {            // Set pin 16 high (1)
                console.log("set pin 16 " + pin16);
              //gpio.close(16);                        // Close pin 16
              //18
              gpio.open(18, "output", function(err) {
                if(err){
                  console.log(err);
                }       // Open pin 18 for output
                gpio.write(18, pin18, function() {            // Set pin 18 low (0)
                    console.log("set pin 18 " + pin18);
                  //gpio.close(18);                        // Close pin 18
                    gpio.open(22, "output", function(err) {
                          if(err){
                            console.log(err);
                          }       // Open pin 22 for output
                          gpio.write(22, pin22, function() {            // Set pin 22 high (1)
                              console.log("set pin 22 " + pin22);
                            //gpio.close(22);                        // Close pin 22
                          });
                        });
                });
              });
            });
          });
}

BatteryLevelCharacteristic.prototype.onNotify = function() {
  console.log('NotifyOnlyCharacteristic on notify');
};

module.exports = BatteryLevelCharacteristic;
<commit_msg>troubleshoot python shell error<commit_after>var util = require('util'),
  os = require('os'),
  PythonShell = require('python-shell'),
  exec = require('child_process').exec,
  bleno = require('bleno'),
  gpio = require("pi-gpio"),
  Descriptor = bleno.Descriptor,
  Characteristic = bleno.Characteristic,
  ShinySettings = require('./shiny');

var BatteryLevelCharacteristic = function() {
  BatteryLevelCharacteristic.super_.call(this, {
      uuid: '2A19',
      properties: ['read', 'write', 'notify'],
      descriptors: [
        new Descriptor({
            uuid: '2901',
            value: 'Battery level between 0 and 100 percent'
        }),
        new Descriptor({
            uuid: '2904',
            value: new Buffer([0x04, 0x01, 0x27, 0xAD, 0x01, 0x00, 0x00 ]) // maybe 12 0xC unsigned 8 bit
        })
      ]
  });
};

util.inherits(BatteryLevelCharacteristic, Characteristic);

BatteryLevelCharacteristic.prototype.onReadRequest = function(offset, callback) {

  console.log("in read");
  if (os.platform() === 'darwin') {
    exec('pmset -g batt', function (error, stdout, stderr) {

      var data = stdout.toString();
      // data - 'Now drawing from \'Battery Power\'\n -InternalBattery-0\t95%; discharging; 4:11 remaining\n'
      var percent = data.split('\t')[1].split(';')[0];
      console.log(percent);
      percent = parseInt(percent, 10);
      callback(this.RESULT_SUCCESS, new Buffer([percent]));

    });
  } else {
    // return hardcoded value
    console.log("reading...")
    callback(this.RESULT_SUCCESS, new Buffer([98]));

  }
};

BatteryLevelCharacteristic.prototype.onWriteRequest = function(data, offset, withoutResponse, callback) {
  //console.log("in write");
  if (offset) {
    //console.log("in write - offset");
    callback(this.RESULT_ATTR_NOT_LONG);
  }
  //else if (data.length !== 1) {
   // console.log("data length !== 1");
    //console.log(JSON.stringify(data));
    //callback(this.RESULT_INVALID_ATTRIBUTE_LENGTH);
  //}
  else {
    // console.log(JSON.stringify(data));
    // console.log('processing write request');
    // var receivedData = data.readUInt8(0);
    // console.log(typeof data);
    // console.log(data.toString('ascii'));

    // console.log(receivedData);
    // console.log(typeof receivedData);
        var command = data.toString('ascii');
    //console.log('command');
    console.log(command);

    if(command === "0"){
      console.log("stop");
      // print "Now stop"
      // GPIO.output(Motor1E,GPIO.LOW)

          gpio.open(22, "output", function(err) {
          if(err){
            console.log(err);
          }       // Open pin 22 for output
          gpio.write(22, 0, function() {            // Set pin 22 low (0)
              console.log("set pin 22 low");
            //gpio.close(22);                        // Close pin 22
          });
        });

    }
    else if(command === "1"){
      console.log("command left");

            PythonShell.defaultOptions = {
              scriptPath: './gpiopython'
            };

            var pyshell = new PythonShell('pwmRelative.py', {
                mode: 'text'
            });

            var output = '';
            pyshell.stdout.on('data', function (data) {
                output += ''+data;
                console.log(output);
            });

            pyshell.send('left').end(function (err) {
                if (err) return console.log(err);
                console.log(output);

            });

            pyshell.send(ShinySettings.wheelAngle.toString()).end(function (err) {
                if (err) return console.log(err);
                console.log(output);

            });

            ShinySettings.wheelAngle = ShinySettings.wheelAngle + 1;

    }else if(command === "2"){
      console.log("command right");

            PythonShell.defaultOptions = {
              scriptPath: './gpiopython'
            };

            var pyshell = new PythonShell('pwm.py', {
                pythonOptions: '-u'
            });

            var output = '';
            pyshell.stdout.on('data', function (data) {
                output += ''+data;
                console.log(output);
            });

            pyshell.send('right').end(function (err) {
                if (err) return console.log(err);
                console.log(output);

            });
    }
    else if(command === "3"){
      console.log("forward");

          gpio.open(16, "output", function(err) {
            if(err){
              console.log(err);
            }       // Open pin 16 for output
            gpio.write(16, 0, function() {            // Set pin 16 high (1)
                console.log("set pin 16 low");
              //gpio.close(16);                        // Close pin 16
              //18
              gpio.open(18, "output", function(err) {
                if(err){
                  console.log(err);
                }       // Open pin 18 for output
                gpio.write(18, 1, function() {            // Set pin 18 low (0)
                    console.log("set pin 18 high");
                  //gpio.close(18);                        // Close pin 18
                    gpio.open(22, "output", function(err) {
                          if(err){
                            console.log(err);
                          }       // Open pin 22 for output
                          gpio.write(22, 1, function() {            // Set pin 22 high (1)
                              console.log("set pin 22 high");
                            //gpio.close(22);                        // Close pin 22
                          });
                        });
                });
              });
            });
          });

    }
    else if(command === "4"){
      console.log("back");
                gpio.open(16, "output", function(err) {
            if(err){
              console.log(err);
            }       // Open pin 16 for output
            gpio.write(16, 1, function() {            // Set pin 16 high (1)
                console.log("set pin 16 high");
              //gpio.close(16);                        // Close pin 16
              //18
              gpio.open(18, "output", function(err) {
                if(err){
                  console.log(err);
                }       // Open pin 18 for output
                gpio.write(18, 0, function() {            // Set pin 18 low (0)
                    console.log("set pin 18 low");
                  //gpio.close(18);                        // Close pin 18
                    gpio.open(22, "output", function(err) {
                          if(err){
                            console.log(err);
                          }       // Open pin 22 for output
                          gpio.write(22, 1, function() {            // Set pin 22 high (1)
                              console.log("set pin 22 high");
                            //gpio.close(22);                        // Close pin 22
                          });
                        });
                });
              });
            });
          });
    }

  }
  callback(this.RESULT_SUCCESS);
};

function setMotorDirection(direction) {
    console.log('Setting: ' + direction);

          var pin16 = 0;
          var pin18 = 0;
          var pin22 = 0;

          if(direction === 'forward'){
            pin16 = 1;
            pin18 = 0;
            pin22 = 1;
          }else if (direction == 'reverse'){
            pin16 = 1;
            pin18 = 0;
            pin22 = 1;
          }

          gpio.open(16, "output", function(err) {
            if(err){
              console.log(err);
            }       // Open pin 16 for output
            gpio.write(16, pin16, function() {            // Set pin 16 high (1)
                console.log("set pin 16 " + pin16);
              //gpio.close(16);                        // Close pin 16
              //18
              gpio.open(18, "output", function(err) {
                if(err){
                  console.log(err);
                }       // Open pin 18 for output
                gpio.write(18, pin18, function() {            // Set pin 18 low (0)
                    console.log("set pin 18 " + pin18);
                  //gpio.close(18);                        // Close pin 18
                    gpio.open(22, "output", function(err) {
                          if(err){
                            console.log(err);
                          }       // Open pin 22 for output
                          gpio.write(22, pin22, function() {            // Set pin 22 high (1)
                              console.log("set pin 22 " + pin22);
                            //gpio.close(22);                        // Close pin 22
                          });
                        });
                });
              });
            });
          });
}

BatteryLevelCharacteristic.prototype.onNotify = function() {
  console.log('NotifyOnlyCharacteristic on notify');
};

module.exports = BatteryLevelCharacteristic;
<|endoftext|>


<commit_before>require("es6-shim");

var exec = require("child_process").exec;
var os = require("os");
var useMraa = (function() {
  var release = os.release();
  return release.includes("yocto") ||
    release.includes("edison");
})();

if (useMraa) {
  exec("npm install mraa@0.6.1-36-gbe4312e");
}
<commit_msg>Check for safe version of libmraa0 before installing own copy.<commit_after>require("es6-shim");

var exec = require("child_process").exec;
var os = require("os");
var useMraa = (function() {
  var release = os.release();
  return release.includes("yocto") ||
    release.includes("edison");
})();

var safeBuild = "0.6.1+git0+805d22f0b1-r0";
var safeVersion = "0.6.1-36-gbe4312e";

if (useMraa) {
  console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
  console.log("  Do not quit the program until npm completes the installation process.  ");
  console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");

  exec("opkg info libmraa0", function(error, stdout, stderr) {
    if (!stdout.includes(safeBuild)) {
      console.log("");
      console.log("  Galileo-IO needs to install a trusted version of libmraa0.");
      console.log("  This process takes approximately one minute.");
      console.log("  Thanks for your patience.");

      exec("npm install mraa@" + safeVersion, function() {
        console.log("  Completed!");
        console.log("");
      });
    }
  });
}
<|endoftext|>


<commit_before>var neo4j = require('neo4j');
var errors = require('./errors');
var db = require('./db');
require('./constraints');
var Tag = require('./tag');

//Event model
/** TABLE OF CONTENTS:
 * PRIVATE CONSTRUCTOR
 * var Event
 *
 * PUBLIC INSTANCE METHODS
 * Event.prototype.del - Delete an event from DB
 * Event.prototype.tag - Associate an event with a tag
 * Event.prototype.untag - Dissociate an event from a tag
 *
 * STATIC METHODS
 * Event.get - Query for returning a single event with a given eventname
 * Event.create - Create a new event in the db
 */

// PRIVATE CONSTRUCTOR
var Event = module.exports = function Event(_node) {
    this._node = _node;
    this.myTags = [];
};

// Public constants:

Event.VALIDATION_INFO = {
  'eventname': {
    required: true,
    minLength: 2,
    maxLength: 16,
    pattern: /^[A-Za-z0-9_]+$/,
    message: '2-16 characters; letters, numbers, and underscores only.'
  },
};

// Public instance properties:
Object.defineProperty(Event.prototype, 'eventname', {
    get: function () { return this._node.properties['eventname']; }
});

// Private helpers:

// Takes the given caller-provided properties, selects only known ones,
// validates them, and returns the known subset.
// By default, only validates properties that are present.
// (This allows `Event.prototype.patch` to not require any.)
// You can pass `true` for `required` to validate that all required properties
// are present too. (Useful for `Event.create`.)
function validate(props, required) {
    var safeProps = {};

    for (var prop in Event.VALIDATION_INFO) {
        var val = props[prop];
        validateProp(prop, val, required);
        safeProps[prop] = val;
    }

    return safeProps;
}

// Validates the given property based on the validation info above.
// By default, ignores null/undefined/empty values, but you can pass `true` for
// the `required` param to enforce that any required properties are present.
function validateProp(prop, val, required) {
  var info = Event.VALIDATION_INFO[prop];
  var message = info.message;

  if (!val) {
    if (info.required && required) {
      throw new errors.ValidationError(
        'Missing ' + prop + ' (required).');
    } else {
      return;
    }
  }

  if (info.minLength && val.length < info.minLength) {
    throw new errors.ValidationError(
      'Invalid ' + prop + ' (too short). Requirements: ' + message);
  }

  if (info.maxLength && val.length > info.maxLength) {
    throw new errors.ValidationError(
      'Invalid ' + prop + ' (too long). Requirements: ' + message);
  }

  if (info.pattern && !info.pattern.test(val)) {
    throw new errors.ValidationError(
      'Invalid ' + prop + ' (format). Requirements: ' + message);
  }
}

function isConstraintViolation(err) {
  return err instanceof neo4j.ClientError &&
    err.neo4j.code === 'Neo.ClientError.Schema.ConstraintViolation';
}

// Helper function to check that Event exists
Event.get = function (eventname, callback) {
    var query = [
        'MATCH (event:Event {eventname: {eventname}})',
        'RETURN event',
    ].join('\n')

    var params = {
        eventname: eventname
    };

    db.cypher({
        query: query,
        params: params,
    }, function (err, results) {
        if (err) return callback(err);
        if (!results.length) {
            err = new Error('No such event with eventname: ' + eventname);
            return callback(err);
        }
        var event = new Event(results[0]['event']);
        callback(null, event);
    });
};
//returns all events
Event.getAll = function (callback) {
  var query = [
    'MATCH (event:Event)',
    'RETURN event',
  ].join('\n');

  db.cypher({
    query: query,
  }, function (err, results) {
    if (err) return callback(err);
    var events = results.map(function (result) {
      return new Event(result['event']);
    });
    callback(null, events);
  });
};

Event.create = function (props, callback) {
    var query = [
        'CREATE (event:Event {props})',
        'RETURN event',
    ].join('\n');

    var params = {
        props: props
    }

    db.cypher({
        query: query,
        params: params,
    }, function (err, results) {
        if (err) return callback(err);

        var event = new Event(results[0]['event']);

        callback(null, event);
    });
}

Event.prototype.del = function (callback) {
    // Use a Cypher query to delete both this event and his/her following
    // relationships in one query and one network request:
    // (Note that this'll still fail if there are any relationships attached
    // of any other types, which is good because we don't expect any.)
    var query = [
        'MATCH (event:Event {eventname: {eventname}})',
        'OPTIONAL MATCH (event) -[rel:is]- (tag)',
        'DELETE event, rel',
    ].join('\n')

    var params = {
        eventname: this.eventname,
    };

    // console.log('Param to pass into query:');
    // console.log(params);

    // console.log('Constructed Query:');
    // console.log(query);

    db.cypher({
        query: query,
        params: params,
    }, function (err) {
        callback(err);
    });
};

Event.prototype.tag = function (tag, callback) {
    var query = [
        'MATCH (event:Event {eventname: {thisEventname}})',
        'MATCH (tag:Tag {tagname: {targetTagname}})',
        'MERGE (event) -[rel:is]-> (tag)',
    ].join('\n')
    var params = {
        thisEventname: this.eventname,
        targetTagname: tag.tagname,
    };

    db.cypher({
        query: query,
        params: params,
    }, function (err) {
        callback(err);
    });
};

Event.prototype.untag = function (tag, callback) {
    var query = [
        'MATCH (event:Event {eventname: {thisEventname}})',
        'MATCH (tag:Tag {tagname: {targetTagname}})',
        'MATCH (event) -[rel:is]-> (tag)',
        'DELETE rel',
    ].join('\n')

    var params = {
        thisEventname: this.eventname,
        targetTagname: tag.tagname,
    };

    db.cypher({
        query: query,
        params: params,
    }, function (err, results) {
        callback(err);
    });
};

Event.prototype.patch = function (props, callback) {
  var safeProps = validate(props);

  var query = [
    'MATCH (event:Event {eventname: {eventname}})',
    'SET event += {props}',
    'RETURN event',
  ].join('\n');

  var params = {
    eventname: this.eventname,
    props: safeProps,
  };

  var self = this;

  db.cypher({
    query: query,
    params: params,
  }, function (err, results) {
    if (isConstraintViolation(err)) {
      // TODO: This assumes eventname is the only relevant constraint.
      // We could parse the constraint property out of the error message,
      // but it'd be nicer if Neo4j returned this data semantically.
      // Alternately, we could tweak our query to explicitly check first
      // whether the eventname is taken or not.
      err = new errors.ValidationError(
        'The eventname ‘' + props.eventname + '’ is taken.');
    }
    if (err) return callback(err);

    if (!results.length) {
      err = new Error('Event has been deleted! Eventname: ' + self.eventname);
      return callback(err);
    }

    // Update our node with this updated+latest data from the server:
    self._node = results[0]['event'];

    callback(null);
  });
};

// Returns all tags as event has associated with it
Event.prototype.getAllTags = function (callback) {
  var query = [
    'MATCH (event:Event {eventname: {thisEventname}})-[:is]->(tag:Tag)',
    'RETURN DISTINCT tag'
  ].join('\n');
  var setTags = function(tags){this.myTags = tags;}.bind(this);
  var params = {
    thisEventname: this.eventname
  };
  var tags = [];
  db.cypher({
    query: query,
    params: params
  }, function (err, results) {
    if (err) return callback(err);
    tags = results.map(function (result) {
      return new Tag(result['tag']);
    });
    setTags(tags);
    callback(null, tags);
  });
};

// Given a profile, find matching events with that profile {'tag1': 1, 'tag2': 0, 'tag3': 1...}
Event.getMatchingEvents = function(profile, callback) {
  var eventsPromise = new Promise(function(resolve, reject){
    var query = ['MATCH'];
    var where = 'WHERE ';
    var count = 0;
    for (var tag in profile) {
      if (profile[tag] === 1) {
        count++;
        where += "tag" + count + ".tagname =~ \"" + tag + "\" AND ";
        query.push('(event:Event)-[:is]->(tag' + count + ':Tag),');
      }
    }
    var lastEventRelation = query[query.length - 1];
    //remove unecessary comma from last match statement
    query[query.length - 1] = lastEventRelation.substring(0, lastEventRelation.length - 1)
      //remove unecessary AND statement and space
    where = where.substring(0, where.length - 4);
    query.push(where);
    query.push('RETURN event as event;');
    query = query.join('\n');
    db.cypher({
      query: query,
    }, function(err, results) {
      if (err) return reject(err);
      var events = results.map(function(result) {
        return new Event(result['event']);
      });
      resolve(events);
    });
  });
  return eventsPromise;
}

<commit_msg>(fix) added bluebird require statement for heroku<commit_after>var neo4j = require('neo4j');
var errors = require('./errors');
var db = require('./db');
require('./constraints');
var Tag = require('./tag');
var Promise = require('bluebird');

//Event model
/** TABLE OF CONTENTS:
 * PRIVATE CONSTRUCTOR
 * var Event
 *
 * PUBLIC INSTANCE METHODS
 * Event.prototype.del - Delete an event from DB
 * Event.prototype.tag - Associate an event with a tag
 * Event.prototype.untag - Dissociate an event from a tag
 *
 * STATIC METHODS
 * Event.get - Query for returning a single event with a given eventname
 * Event.create - Create a new event in the db
 */

// PRIVATE CONSTRUCTOR
var Event = module.exports = function Event(_node) {
    this._node = _node;
    this.myTags = [];
};

// Public constants:

Event.VALIDATION_INFO = {
  'eventname': {
    required: true,
    minLength: 2,
    maxLength: 16,
    pattern: /^[A-Za-z0-9_]+$/,
    message: '2-16 characters; letters, numbers, and underscores only.'
  },
};

// Public instance properties:
Object.defineProperty(Event.prototype, 'eventname', {
    get: function () { return this._node.properties['eventname']; }
});

// Private helpers:

// Takes the given caller-provided properties, selects only known ones,
// validates them, and returns the known subset.
// By default, only validates properties that are present.
// (This allows `Event.prototype.patch` to not require any.)
// You can pass `true` for `required` to validate that all required properties
// are present too. (Useful for `Event.create`.)
function validate(props, required) {
    var safeProps = {};

    for (var prop in Event.VALIDATION_INFO) {
        var val = props[prop];
        validateProp(prop, val, required);
        safeProps[prop] = val;
    }

    return safeProps;
}

// Validates the given property based on the validation info above.
// By default, ignores null/undefined/empty values, but you can pass `true` for
// the `required` param to enforce that any required properties are present.
function validateProp(prop, val, required) {
  var info = Event.VALIDATION_INFO[prop];
  var message = info.message;

  if (!val) {
    if (info.required && required) {
      throw new errors.ValidationError(
        'Missing ' + prop + ' (required).');
    } else {
      return;
    }
  }

  if (info.minLength && val.length < info.minLength) {
    throw new errors.ValidationError(
      'Invalid ' + prop + ' (too short). Requirements: ' + message);
  }

  if (info.maxLength && val.length > info.maxLength) {
    throw new errors.ValidationError(
      'Invalid ' + prop + ' (too long). Requirements: ' + message);
  }

  if (info.pattern && !info.pattern.test(val)) {
    throw new errors.ValidationError(
      'Invalid ' + prop + ' (format). Requirements: ' + message);
  }
}

function isConstraintViolation(err) {
  return err instanceof neo4j.ClientError &&
    err.neo4j.code === 'Neo.ClientError.Schema.ConstraintViolation';
}

// Helper function to check that Event exists
Event.get = function (eventname, callback) {
    var query = [
        'MATCH (event:Event {eventname: {eventname}})',
        'RETURN event',
    ].join('\n')

    var params = {
        eventname: eventname
    };

    db.cypher({
        query: query,
        params: params,
    }, function (err, results) {
        if (err) return callback(err);
        if (!results.length) {
            err = new Error('No such event with eventname: ' + eventname);
            return callback(err);
        }
        var event = new Event(results[0]['event']);
        callback(null, event);
    });
};
//returns all events
Event.getAll = function (callback) {
  var query = [
    'MATCH (event:Event)',
    'RETURN event',
  ].join('\n');

  db.cypher({
    query: query,
  }, function (err, results) {
    if (err) return callback(err);
    var events = results.map(function (result) {
      return new Event(result['event']);
    });
    callback(null, events);
  });
};

Event.create = function (props, callback) {
    var query = [
        'CREATE (event:Event {props})',
        'RETURN event',
    ].join('\n');

    var params = {
        props: props
    }

    db.cypher({
        query: query,
        params: params,
    }, function (err, results) {
        if (err) return callback(err);

        var event = new Event(results[0]['event']);

        callback(null, event);
    });
}

Event.prototype.del = function (callback) {
    // Use a Cypher query to delete both this event and his/her following
    // relationships in one query and one network request:
    // (Note that this'll still fail if there are any relationships attached
    // of any other types, which is good because we don't expect any.)
    var query = [
        'MATCH (event:Event {eventname: {eventname}})',
        'OPTIONAL MATCH (event) -[rel:is]- (tag)',
        'DELETE event, rel',
    ].join('\n')

    var params = {
        eventname: this.eventname,
    };

    // console.log('Param to pass into query:');
    // console.log(params);

    // console.log('Constructed Query:');
    // console.log(query);

    db.cypher({
        query: query,
        params: params,
    }, function (err) {
        callback(err);
    });
};

Event.prototype.tag = function (tag, callback) {
    var query = [
        'MATCH (event:Event {eventname: {thisEventname}})',
        'MATCH (tag:Tag {tagname: {targetTagname}})',
        'MERGE (event) -[rel:is]-> (tag)',
    ].join('\n')
    var params = {
        thisEventname: this.eventname,
        targetTagname: tag.tagname,
    };

    db.cypher({
        query: query,
        params: params,
    }, function (err) {
        callback(err);
    });
};

Event.prototype.untag = function (tag, callback) {
    var query = [
        'MATCH (event:Event {eventname: {thisEventname}})',
        'MATCH (tag:Tag {tagname: {targetTagname}})',
        'MATCH (event) -[rel:is]-> (tag)',
        'DELETE rel',
    ].join('\n')

    var params = {
        thisEventname: this.eventname,
        targetTagname: tag.tagname,
    };

    db.cypher({
        query: query,
        params: params,
    }, function (err, results) {
        callback(err);
    });
};

Event.prototype.patch = function (props, callback) {
  var safeProps = validate(props);

  var query = [
    'MATCH (event:Event {eventname: {eventname}})',
    'SET event += {props}',
    'RETURN event',
  ].join('\n');

  var params = {
    eventname: this.eventname,
    props: safeProps,
  };

  var self = this;

  db.cypher({
    query: query,
    params: params,
  }, function (err, results) {
    if (isConstraintViolation(err)) {
      // TODO: This assumes eventname is the only relevant constraint.
      // We could parse the constraint property out of the error message,
      // but it'd be nicer if Neo4j returned this data semantically.
      // Alternately, we could tweak our query to explicitly check first
      // whether the eventname is taken or not.
      err = new errors.ValidationError(
        'The eventname ‘' + props.eventname + '’ is taken.');
    }
    if (err) return callback(err);

    if (!results.length) {
      err = new Error('Event has been deleted! Eventname: ' + self.eventname);
      return callback(err);
    }

    // Update our node with this updated+latest data from the server:
    self._node = results[0]['event'];

    callback(null);
  });
};

// Returns all tags as event has associated with it
Event.prototype.getAllTags = function (callback) {
  var query = [
    'MATCH (event:Event {eventname: {thisEventname}})-[:is]->(tag:Tag)',
    'RETURN DISTINCT tag'
  ].join('\n');
  var setTags = function(tags){this.myTags = tags;}.bind(this);
  var params = {
    thisEventname: this.eventname
  };
  var tags = [];
  db.cypher({
    query: query,
    params: params
  }, function (err, results) {
    if (err) return callback(err);
    tags = results.map(function (result) {
      return new Tag(result['tag']);
    });
    setTags(tags);
    callback(null, tags);
  });
};

// Given a profile, find matching events with that profile {'tag1': 1, 'tag2': 0, 'tag3': 1...}
Event.getMatchingEvents = function(profile, callback) {
  var eventsPromise = new Promise(function(resolve, reject){
    var query = ['MATCH'];
    var where = 'WHERE ';
    var count = 0;
    for (var tag in profile) {
      if (profile[tag] === 1) {
        count++;
        where += "tag" + count + ".tagname =~ \"" + tag + "\" AND ";
        query.push('(event:Event)-[:is]->(tag' + count + ':Tag),');
      }
    }
    var lastEventRelation = query[query.length - 1];
    //remove unecessary comma from last match statement
    query[query.length - 1] = lastEventRelation.substring(0, lastEventRelation.length - 1)
      //remove unecessary AND statement and space
    where = where.substring(0, where.length - 4);
    query.push(where);
    query.push('RETURN event as event;');
    query = query.join('\n');
    db.cypher({
      query: query,
    }, function(err, results) {
      if (err) return reject(err);
      var events = results.map(function(result) {
        return new Event(result['event']);
      });
      resolve(events);
    });
  });
  return eventsPromise;
}

<|endoftext|>


<commit_before>/** DO NOT MODIFY **/
import React, { Component } from "react";
import { render } from "react-dom";

import { Root, getHttpClient } from "gluestick-shared";
import originalMatch from "react-router/lib/match";
import browserHistory from "react-router/lib/browserHistory";
import { StyleRoot } from "radium";
import config from "./application";

const httpClient = getHttpClient(config.httpClient);

export default class Entry extends Component {
  render () {
    const {
      routerContext,
      getRoutes,
      radiumConfig,
      store
    } = this.props;

    return (
      <StyleRoot radiumConfig={radiumConfig}>
        <Root routerContext={routerContext} routes={getRoutes(store)} store={store} />
      </StyleRoot>
    );
  }
}

Entry.start = function (getRoutes, getStore, match=originalMatch, history=browserHistory) {
  const newStore = getStore(httpClient);
  match({ history, routes: getRoutes(newStore)}, (error, redirectLocation, renderProps) => {
    const entry = (
      <Entry
        radiumConfig={{userAgent: window.navigator.userAgent}}
        store={newStore}
        getRoutes={getRoutes}
        {...renderProps}
      />
    );
    render(entry, document.getElementById("main"));
  });
};

<commit_msg>add support for `src/config/init.browser.js`<commit_after>/** DO NOT MODIFY **/
import React, { Component } from "react";
import { render } from "react-dom";

import { Root, getHttpClient } from "gluestick-shared";
import originalMatch from "react-router/lib/match";
import browserHistory from "react-router/lib/browserHistory";
import { StyleRoot } from "radium";
import config from "./application";

const httpClient = getHttpClient(config.httpClient);

export default class Entry extends Component {
  render () {
    const {
      routerContext,
      getRoutes,
      radiumConfig,
      store
    } = this.props;

    return (
      <StyleRoot radiumConfig={radiumConfig}>
        <Root routerContext={routerContext} routes={getRoutes(store)} store={store} />
      </StyleRoot>
    );
  }
}

Entry.start = function (getRoutes, getStore, match=originalMatch, history=browserHistory) {
  // Allow developers to include code that will be executed before the app is
  // set up in the browser. If the file doesn't exist then nothing will happen
  require("./init.browser");

  const newStore = getStore(httpClient);
  match({ history, routes: getRoutes(newStore)}, (error, redirectLocation, renderProps) => {
    const entry = (
      <Entry
        radiumConfig={{userAgent: window.navigator.userAgent}}
        store={newStore}
        getRoutes={getRoutes}
        {...renderProps}
      />
    );
    render(entry, document.getElementById("main"));
  });
};

<|endoftext|>


<commit_before>'use strict';

angular.module('core')
.controller('HomeController', ['$scope', 'Authentication',
  function ($scope, Authentication) {
    // This provides Authentication context.
    $scope.authentication = Authentication;

  }
])

.controller('HomeController', ['$scope', function($scope) {
  $scope.format = 'MM/dd/yyyy h:mm:ss a';
}])
.directive('myCurrentTime', ['$interval', 'dateFilter', function($interval, dateFilter) {

  function link(scope, element, attrs) {
    var format,
        timeoutId;

    function updateTime() {
      element.text(dateFilter(new Date(), format));
    }

    scope.$watch(attrs.myCurrentTime, function(value) {
      format = value;
      updateTime();
    });

    element.on('$destroy', function() {
      $interval.cancel(timeoutId);
    });

    // start the UI update process; save the timeoutId for canceling
    timeoutId = $interval(function() {
      updateTime(); // update DOM
    }, 1000);
  }

  return {
    link: link
  };
}]);

//stars background
window.onload = function() {
    setTimeout(start, 200);
};
function start() {
    //Helpers
    function lineToAngle(x1, y1, length, radians) {
        var x2 = x1 + length * Math.cos(radians),
            y2 = y1 + length * Math.sin(radians);
        return { x: x2, y: y2 };
    }

    function randomRange(min, max) {
        return min + Math.random() * (max - min);
    }

    function degreesToRads(degrees) {
        return degrees / 180 * Math.PI;
    }

    //Particle
    var particle = {
        x: 0,
        y: 0,
        vx: 0,
        vy: 0,
        radius: 0,

        create: function(x, y, speed, direction) {
            var obj = Object.create(this);
            obj.x = x;
            obj.y = y;
            obj.vx = Math.cos(direction) * speed;
            obj.vy = Math.sin(direction) * speed;
            return obj;
        },

        getSpeed: function() {
            return Math.sqrt(this.vx * this.vx + this.vy * this.vy);
        },

        setSpeed: function(speed) {
            var heading = this.getHeading();
            this.vx = Math.cos(heading) * speed;
            this.vy = Math.sin(heading) * speed;
        },

        getHeading: function() {
            return Math.atan2(this.vy, this.vx);
        },

        setHeading: function(heading) {
            var speed = this.getSpeed();
            this.vx = Math.cos(heading) * speed;
            this.vy = Math.sin(heading) * speed;
        },

        update: function() {
            this.x += this.vx;
            this.y += this.vy;
        }
    };

    //Canvas and settings
    var canvas = document.getElementById("canvas"),
        context = canvas.getContext("2d"),
        width = canvas.width = window.innerWidth,
        height = canvas.height = window.innerHeight,
        stars = [],
        shootingStars = [],
        layers = [
            { speed: 0.015, scale: 0.2, count: 320 },
            { speed: 0.03, scale: 0.5, count: 50 },
            { speed: 0.05, scale: 0.75, count: 30 }
        ],
        starsAngle = 145,
        shootingStarSpeed = {
            min: 10,
            max: 20
        },
        shootingStarOpacityDelta = 0.01,
        trailLengthDelta = 0.01,
        shootingStarEmittingInterval = 2000,
        shootingStarLifeTime = 500,
        maxTrailLength = 300,
        starBaseRadius = 2,
        shootingStarRadius = 3,
        paused = false;

    //Create all stars
    for (var j = 0; j < layers.length; j += 1) {
        var layer = layers[j];
        for (var i = 0; i < layer.count; i += 1) {
            var star = particle.create(randomRange(0, width), randomRange(0, height), 0, 0);
            star.radius = starBaseRadius * layer.scale;
            star.setSpeed(layer.speed);
            star.setHeading(degreesToRads(starsAngle));
            stars.push(star);
        }
    }

    function createShootingStar() {
        var shootingStar = particle.create(randomRange(width / 2, width), randomRange(0, height / 2), 0, 0);
        shootingStar.setSpeed(randomRange(shootingStarSpeed.min, shootingStarSpeed.max));
        shootingStar.setHeading(degreesToRads(starsAngle));
        shootingStar.radius = shootingStarRadius;
        shootingStar.opacity = 0;
        shootingStar.trailLengthDelta = 0;
        shootingStar.isSpawning = true;
        shootingStar.isDying = false;
        shootingStars.push(shootingStar);
    }

    function killShootingStar(shootingStar) {
        setTimeout(function() {
            shootingStar.isDying = true;
        }, shootingStarLifeTime);
    }

    function update() {
        if (!paused) {
            context.clearRect(0, 0, width, height);
            context.fillStyle = "#20212d";
            context.fillRect(0, 0, width, height);
            context.fill();

            for (var i = 0; i < stars.length; i += 1) {
                var star = stars[i];
                star.update();
                drawStar(star);
                if (star.x > width) {
                    star.x = 0;
                }
                if (star.x < 0) {
                    star.x = width;
                }
                if (star.y > height) {
                    star.y = 0;
                }
                if (star.y < 0) {
                    star.y = height;
                }
            }

            for (i = 0; i < shootingStars.length; i += 1) {
                var shootingStar = shootingStars[i];
                if (shootingStar.isSpawning) {
                    shootingStar.opacity += shootingStarOpacityDelta;
                    if (shootingStar.opacity >= 1.0) {
                        shootingStar.isSpawning = false;
                        killShootingStar(shootingStar);
                    }
                }
                if (shootingStar.isDying) {
                    shootingStar.opacity -= shootingStarOpacityDelta;
                    if (shootingStar.opacity <= 0.0) {
                        shootingStar.isDying = false;
                        shootingStar.isDead = true;
                    }
                }
                shootingStar.trailLengthDelta += trailLengthDelta;

                shootingStar.update();
                if (shootingStar.opacity > 0.0) {
                    drawShootingStar(shootingStar);
                }
            }

            //Delete dead shooting shootingStars
            for (i = shootingStars.length -1; i >= 0 ; i--){
                if (shootingStars[i].isDead){
                    shootingStars.splice(i, 1);
                }
            }
        }
        requestAnimationFrame(update);
    }

    function drawStar(star) {
        context.fillStyle = "rgb(255, 221, 157)";
        context.beginPath();
        context.arc(star.x, star.y, star.radius, 0, Math.PI * 2, false);
        context.fill();
    }

    function drawShootingStar(p) {
        var x = p.x,
            y = p.y,
            currentTrailLength = (maxTrailLength * p.trailLengthDelta),
            pos = lineToAngle(x, y, -currentTrailLength, p.getHeading());

        context.fillStyle = "rgba(255, 255, 255, " + p.opacity + ")";
        // context.beginPath();
        // context.arc(x, y, p.radius, 0, Math.PI * 2, false);
        // context.fill();
        var starLength = 5;
        context.beginPath();
        context.moveTo(x - 1, y + 1);

        context.lineTo(x, y + starLength);
        context.lineTo(x + 1, y + 1);

        context.lineTo(x + starLength, y);
        context.lineTo(x + 1, y - 1);

        context.lineTo(x, y + 1);
        context.lineTo(x, y - starLength);

        context.lineTo(x - 1, y - 1);
        context.lineTo(x - starLength, y);

        context.lineTo(x - 1, y + 1);
        context.lineTo(x - starLength, y);

        context.closePath();
        context.fill();

        //trail
        context.fillStyle = "rgba(255, 221, 157, " + p.opacity + ")";
        context.beginPath();
        context.moveTo(x - 1, y - 1);
        context.lineTo(pos.x, pos.y);
        context.lineTo(x + 1, y + 1);
        context.closePath();
        context.fill();
    }

    //Run
    update();

    //Shooting stars
    setInterval(function() {
        if (paused) return;
        createShootingStar();
    }, shootingStarEmittingInterval);

    window.onfocus = function () {
      paused = false;
    };

    window.onblur = function () {
      paused = true;
    };

}
//stars background <commit_msg>backgound 03<commit_after>'use strict';

angular.module('core')
.controller('HomeController', ['$scope', 'Authentication',
  function ($scope, Authentication) {
    // This provides Authentication context.
    $scope.authentication = Authentication;

  }
])

.controller('HomeController', ['$scope', function($scope) {
  $scope.format = 'MM/dd/yyyy h:mm:ss a';
}])
.directive('myCurrentTime', ['$interval', 'dateFilter', function($interval, dateFilter) {

  function link(scope, element, attrs) {
    var format,
        timeoutId;

    function updateTime() {
      element.text(dateFilter(new Date(), format));
    }

    scope.$watch(attrs.myCurrentTime, function(value) {
      format = value;
      updateTime();
    });

    element.on('$destroy', function() {
      $interval.cancel(timeoutId);
    });

    // start the UI update process; save the timeoutId for canceling
    timeoutId = $interval(function() {
      updateTime(); // update DOM
    }, 1000);
  }

  return {
    link: link
  };
}]);

//stars background
window.onload = function() {
    setTimeout(start, 200);
};
function start() {
    //Helpers
    function lineToAngle(x1, y1, length, radians) {
        var x2 = x1 + length * Math.cos(radians),
            y2 = y1 + length * Math.sin(radians);
        return { x: x2, y: y2 };
    }

    function randomRange(min, max) {
        return min + Math.random() * (max - min);
    }

    function degreesToRads(degrees) {
        return degrees / 180 * Math.PI;
    }

    //Particle
    var particle = {
        x: 0,
        y: 0,
        vx: 0,
        vy: 0,
        radius: 0,

        create: function(x, y, speed, direction) {
            var obj = Object.create(this);
            obj.x = x;
            obj.y = y;
            obj.vx = Math.cos(direction) * speed;
            obj.vy = Math.sin(direction) * speed;
            return obj;
        },

        getSpeed: function() {
            return Math.sqrt(this.vx * this.vx + this.vy * this.vy);
        },

        setSpeed: function(speed) {
            var heading = this.getHeading();
            this.vx = Math.cos(heading) * speed;
            this.vy = Math.sin(heading) * speed;
        },

        getHeading: function() {
            return Math.atan2(this.vy, this.vx);
        },

        setHeading: function(heading) {
            var speed = this.getSpeed();
            this.vx = Math.cos(heading) * speed;
            this.vy = Math.sin(heading) * speed;
        },

        update: function() {
            this.x += this.vx;
            this.y += this.vy;
        }
    };

    //Canvas and settings
    var canvas = document.getElementById("canvas"),
        context = canvas.getContext("2d"),
        width = canvas.width = window.innerWidth,
        height = canvas.height = window.innerHeight,
        stars = [],
        shootingStars = [],
        layers = [
            { speed: 0.015, scale: 0.2, count: 320 },
            { speed: 0.03, scale: 0.5, count: 50 },
            { speed: 0.05, scale: 0.75, count: 30 }
        ],
        starsAngle = 145,
        shootingStarSpeed = {
            min: 10,
            max: 20
        },
        shootingStarOpacityDelta = 0.01,
        trailLengthDelta = 0.01,
        shootingStarEmittingInterval = 2000,
        shootingStarLifeTime = 500,
        maxTrailLength = 300,
        starBaseRadius = 2,
        shootingStarRadius = 3,
        paused = false;

    //Create all stars
    for (var j = 0; j < layers.length; j += 1) {
        var layer = layers[j];
        for (var i = 0; i < layer.count; i += 1) {
            var star = particle.create(randomRange(0, width), randomRange(0, height), 0, 0);
            star.radius = starBaseRadius * layer.scale;
            star.setSpeed(layer.speed);
            star.setHeading(degreesToRads(starsAngle));
            stars.push(star);
        }
    }

    function createShootingStar() {
        var shootingStar = particle.create(randomRange(width / 2, width), randomRange(0, height / 2), 0, 0);
        shootingStar.setSpeed(randomRange(shootingStarSpeed.min, shootingStarSpeed.max));
        shootingStar.setHeading(degreesToRads(starsAngle));
        shootingStar.radius = shootingStarRadius;
        shootingStar.opacity = 0;
        shootingStar.trailLengthDelta = 0;
        shootingStar.isSpawning = true;
        shootingStar.isDying = false;
        shootingStars.push(shootingStar);
    }

    function killShootingStar(shootingStar) {
        setTimeout(function() {
            shootingStar.isDying = true;
        }, shootingStarLifeTime);
    }

    function update() {
        if (!paused) {
            context.clearRect(0, 0, width, height);
            context.fillStyle = "#0b0b0f";
            context.fillRect(0, 0, width, height);
            context.fill();

            for (var i = 0; i < stars.length; i += 1) {
                var star = stars[i];
                star.update();
                drawStar(star);
                if (star.x > width) {
                    star.x = 0;
                }
                if (star.x < 0) {
                    star.x = width;
                }
                if (star.y > height) {
                    star.y = 0;
                }
                if (star.y < 0) {
                    star.y = height;
                }
            }

            for (i = 0; i < shootingStars.length; i += 1) {
                var shootingStar = shootingStars[i];
                if (shootingStar.isSpawning) {
                    shootingStar.opacity += shootingStarOpacityDelta;
                    if (shootingStar.opacity >= 1.0) {
                        shootingStar.isSpawning = false;
                        killShootingStar(shootingStar);
                    }
                }
                if (shootingStar.isDying) {
                    shootingStar.opacity -= shootingStarOpacityDelta;
                    if (shootingStar.opacity <= 0.0) {
                        shootingStar.isDying = false;
                        shootingStar.isDead = true;
                    }
                }
                shootingStar.trailLengthDelta += trailLengthDelta;

                shootingStar.update();
                if (shootingStar.opacity > 0.0) {
                    drawShootingStar(shootingStar);
                }
            }

            //Delete dead shooting shootingStars
            for (i = shootingStars.length -1; i >= 0 ; i--){
                if (shootingStars[i].isDead){
                    shootingStars.splice(i, 1);
                }
            }
        }
        requestAnimationFrame(update);
    }

    function drawStar(star) {
        context.fillStyle = "rgb(255, 221, 157)";
        context.beginPath();
        context.arc(star.x, star.y, star.radius, 0, Math.PI * 2, false);
        context.fill();
    }

    function drawShootingStar(p) {
        var x = p.x,
            y = p.y,
            currentTrailLength = (maxTrailLength * p.trailLengthDelta),
            pos = lineToAngle(x, y, -currentTrailLength, p.getHeading());

        context.fillStyle = "rgba(255, 255, 255, " + p.opacity + ")";
        // context.beginPath();
        // context.arc(x, y, p.radius, 0, Math.PI * 2, false);
        // context.fill();
        var starLength = 5;
        context.beginPath();
        context.moveTo(x - 1, y + 1);

        context.lineTo(x, y + starLength);
        context.lineTo(x + 1, y + 1);

        context.lineTo(x + starLength, y);
        context.lineTo(x + 1, y - 1);

        context.lineTo(x, y + 1);
        context.lineTo(x, y - starLength);

        context.lineTo(x - 1, y - 1);
        context.lineTo(x - starLength, y);

        context.lineTo(x - 1, y + 1);
        context.lineTo(x - starLength, y);

        context.closePath();
        context.fill();

        //trail
        context.fillStyle = "rgba(255, 221, 157, " + p.opacity + ")";
        context.beginPath();
        context.moveTo(x - 1, y - 1);
        context.lineTo(pos.x, pos.y);
        context.lineTo(x + 1, y + 1);
        context.closePath();
        context.fill();
    }

    //Run
    update();

    //Shooting stars
    setInterval(function() {
        if (paused) return;
        createShootingStar();
    }, shootingStarEmittingInterval);

    window.onfocus = function () {
      paused = false;
    };

    window.onblur = function () {
      paused = true;
    };

}
//stars background <|endoftext|>


<commit_before>/* eslint-disable no-console */
'use strict';

const gw2          = require(__dirname + '/src/initialize.js');
const offsets      = require(__dirname + '/src/offsets.js');

/**
 * Start by trying to find the correct GW2 process
 * Terminates with an error if no process is found
 */
gw2(function(err, process, module, memory) {
  if (err) {
    throw new Error(err);
  }

  /* eslint-disable no-extend-native */
  String.prototype.lpad = function(padString, length) {
    var str = this;
    while (str.length < length) {
      str = padString + str;
    }
    return str;
  };

  var interpretAsPTRBuffer = new Buffer(0x4);
  const pointerFound = (descriptor, ptr, substract, add, interpretAsPTR, offsetAdjustement) => {
    if (ptr) {
      var base = ptr[0] - module;
      if (substract) {
        base = base - substract;
      }
      if (add) {
        base = base + add;
      }
			if (interpretAsPTR) {
				memory.readData(module + base, interpretAsPTRBuffer, 0x4);
				base = interpretAsPTRBuffer.readInt32LE() - module;
			}
			if (offsetAdjustement) {
				base += offsetAdjustement;
			}
      console.log(descriptor, '0x' + (base).toString(16).toUpperCase().lpad('0', 8));
    } else {
      console.log(descriptor, 'ptr base not found');
    }
  };

  const findPattern = (pattern) => {
      return memory.find(pattern, 0, -1, 1, "-x");
  }

  const findStringRef = (str) => {
      var searchPattern = Buffer.from(str).toString('hex');
      var results = memory.find(searchPattern, 0, -1, 1, '--');

      if (results.length > 0)
      {
          results = memory.find(results[0].toString(16).lpad('0', 8).match(/[a-fA-F0-9]{2}/g).reverse().join(''), 0, -1, 1, '-x');
      }

      return results;
  };

  let pattern;

	/**
  * Debug related pointers
  * @type {String}
  */
  pattern = offsets.debug.original;
  pointerFound('offsets.debug.original', findPattern(pattern), 0, 22, true, module - 1104);

  /**
  * Animation related pointers
  * @type {String}
  */
  pattern = offsets.advancedView.animation.original.toString('hex');
  pointerFound('offsets.advancedView.animation.original', findPattern(pattern), 5, -0x450);

  /**
  * Agent related pointers
  * @type {String}
  */
  pattern = offsets.agent.highlight_effect.original.toString('hex');
  pointerFound('offsets.agent.highlight_effect.original', findPattern(pattern));

  /**
  * Camera related pointers
  * @type {String}
  */

  pattern = offsets.camera.original.toString('hex');
  pointerFound('offsets.camera.original', findPattern(pattern), 0, 0x45, true);

  pattern = offsets.camera.instructions.patch_1.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_1.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_2.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_2.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_3.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_3.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_4.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_4.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_5.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_5.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_6.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_6.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_7.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_7.original', findPattern(pattern));

  /**
  * Player related offsets
  * @type {String}
  */
  pattern = offsets.player.original.toString('hex');
  pointerFound('offsets.player.original', findPattern(pattern));

  /**
  * Environment related offsets
  * @type {String}
  */
  pointerFound('offsets.environment.fog.original', findStringRef("s_dxContext"), 0, 10, true);

  /**
  * Movement related offsets
  * @type {String}
  */
  pattern = offsets.player.movement.original.toString('hex');
  pointerFound('offsets.player.movement.original',  findPattern(pattern), 10);

  /**
  * Time of day related offsets
  * @type {String}
  */
  pattern = offsets.environment.timeOfDayOriginal.toString('hex');
  pointerFound('offsets.environment.timeOfDayOriginal', findPattern(pattern), 5);

  /**
  * Map rendering functions offsets
  * @type {String}
  */
  pattern = offsets.environment.rendering.audio.original.toString('hex');
  pointerFound('offsets.environment.rendering.audio', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.blocks.original.toString('hex');
  pointerFound('offsets.environment.rendering.blocks', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.decal.original.toString('hex');
  pointerFound('offsets.environment.rendering.decal', findPattern(pattern), 0x2A);
  pattern = offsets.environment.rendering.environment.original.toString('hex');
  pointerFound('offsets.environment.rendering.environment', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.river.original.toString('hex');
  pointerFound('offsets.environment.rendering.river', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.under_water.original.toString('hex');
  pointerFound('offsets.environment.rendering.under_water', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.zone.original.toString('hex');
  pointerFound('offsets.environment.rendering.zone', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.lights.original.toString('hex');
  pointerFound('offsets.environment.rendering.lights', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.shadows.original.toString('hex');
  pointerFound('offsets.environment.rendering.shadows', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.terrain.original.toString('hex');
  pointerFound('offsets.environment.rendering.terrain', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.cube_map.original.toString('hex');
  pointerFound('offsets.environment.rendering.cube_map', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.props.original.toString('hex');
  pointerFound('offsets.environment.rendering.props', findPattern(pattern), 5);
});
<commit_msg>fix tab spacing<commit_after>/* eslint-disable no-console */
'use strict';

const gw2          = require(__dirname + '/src/initialize.js');
const offsets      = require(__dirname + '/src/offsets.js');

/**
 * Start by trying to find the correct GW2 process
 * Terminates with an error if no process is found
 */
gw2(function(err, process, module, memory) {
  if (err) {
    throw new Error(err);
  }

  /* eslint-disable no-extend-native */
  String.prototype.lpad = function(padString, length) {
    var str = this;
    while (str.length < length) {
      str = padString + str;
    }
    return str;
  };

  var interpretAsPTRBuffer = new Buffer(0x4);
  const pointerFound = (descriptor, ptr, substract, add, interpretAsPTR, offsetAdjustement) => {
    if (ptr) {
      var base = ptr[0] - module;
      if (substract) {
        base = base - substract;
      }
      if (add) {
        base = base + add;
      }
      if (interpretAsPTR) {
        memory.readData(module + base, interpretAsPTRBuffer, 0x4);
        base = interpretAsPTRBuffer.readInt32LE() - module;
      }
      if (offsetAdjustement) {
        base += offsetAdjustement;
      }
      console.log(descriptor, '0x' + (base).toString(16).toUpperCase().lpad('0', 8));
    } else {
      console.log(descriptor, 'ptr base not found');
    }
  };

  const findPattern = (pattern) => {
      return memory.find(pattern, 0, -1, 1, "-x");
  }

  const findStringRef = (str) => {
      var searchPattern = Buffer.from(str).toString('hex');
      var results = memory.find(searchPattern, 0, -1, 1, '--');

      if (results.length > 0)
      {
          results = memory.find(results[0].toString(16).lpad('0', 8).match(/[a-fA-F0-9]{2}/g).reverse().join(''), 0, -1, 1, '-x');
      }

      return results;
  };

  let pattern;

	/**
  * Debug related pointers
  * @type {String}
  */
  pattern = offsets.debug.original;
  pointerFound('offsets.debug.original', findPattern(pattern), 0, 22, true, module - 1104);

  /**
  * Animation related pointers
  * @type {String}
  */
  pattern = offsets.advancedView.animation.original.toString('hex');
  pointerFound('offsets.advancedView.animation.original', findPattern(pattern), 5, -0x450);

  /**
  * Agent related pointers
  * @type {String}
  */
  pattern = offsets.agent.highlight_effect.original.toString('hex');
  pointerFound('offsets.agent.highlight_effect.original', findPattern(pattern));

  /**
  * Camera related pointers
  * @type {String}
  */

  pattern = offsets.camera.original.toString('hex');
  pointerFound('offsets.camera.original', findPattern(pattern), 0, 0x45, true);

  pattern = offsets.camera.instructions.patch_1.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_1.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_2.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_2.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_3.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_3.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_4.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_4.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_5.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_5.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_6.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_6.original', findPattern(pattern));
  pattern = offsets.camera.instructions.patch_7.original.toString('hex');
  pointerFound('offsets.camera.instructions.patch_7.original', findPattern(pattern));

  /**
  * Player related offsets
  * @type {String}
  */
  pattern = offsets.player.original.toString('hex');
  pointerFound('offsets.player.original', findPattern(pattern));

  /**
  * Environment related offsets
  * @type {String}
  */
  pointerFound('offsets.environment.fog.original', findStringRef("s_dxContext"), 0, 10, true);

  /**
  * Movement related offsets
  * @type {String}
  */
  pattern = offsets.player.movement.original.toString('hex');
  pointerFound('offsets.player.movement.original',  findPattern(pattern), 10);

  /**
  * Time of day related offsets
  * @type {String}
  */
  pattern = offsets.environment.timeOfDayOriginal.toString('hex');
  pointerFound('offsets.environment.timeOfDayOriginal', findPattern(pattern), 5);

  /**
  * Map rendering functions offsets
  * @type {String}
  */
  pattern = offsets.environment.rendering.audio.original.toString('hex');
  pointerFound('offsets.environment.rendering.audio', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.blocks.original.toString('hex');
  pointerFound('offsets.environment.rendering.blocks', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.decal.original.toString('hex');
  pointerFound('offsets.environment.rendering.decal', findPattern(pattern), 0x2A);
  pattern = offsets.environment.rendering.environment.original.toString('hex');
  pointerFound('offsets.environment.rendering.environment', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.river.original.toString('hex');
  pointerFound('offsets.environment.rendering.river', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.under_water.original.toString('hex');
  pointerFound('offsets.environment.rendering.under_water', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.zone.original.toString('hex');
  pointerFound('offsets.environment.rendering.zone', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.lights.original.toString('hex');
  pointerFound('offsets.environment.rendering.lights', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.shadows.original.toString('hex');
  pointerFound('offsets.environment.rendering.shadows', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.terrain.original.toString('hex');
  pointerFound('offsets.environment.rendering.terrain', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.cube_map.original.toString('hex');
  pointerFound('offsets.environment.rendering.cube_map', findPattern(pattern), 5);
  pattern = offsets.environment.rendering.props.original.toString('hex');
  pointerFound('offsets.environment.rendering.props', findPattern(pattern), 5);
});
<|endoftext|>


<commit_before>var repl = require("repl");
var expect = require("@truffle/expect");
var async = require("async");
var EventEmitter = require("events");
var inherits = require("util").inherits;

inherits(ReplManager, EventEmitter);

function ReplManager(options) {
  EventEmitter.call(this);

  expect.options(options, [
    "working_directory",
    "contracts_directory",
    "contracts_build_directory",
    "migrations_directory",
    "network",
    "network_id",
    "provider",
    "resolver",
    "build_directory"
  ]);

  this.options = options;
  this.repl = options.repl;

  this.contexts = [];
}

ReplManager.prototype.start = function(options) {
  var self = this;

  this.contexts.push({
    prompt: options.prompt,
    interpreter: options.interpreter,
    ignoreUndefined: options.ignoreUndefined || false,
    done: options.done
  });

  var currentContext = this.contexts[this.contexts.length - 1];

  if (!this.repl) {
    this.repl = repl.start({
      prompt: currentContext.prompt,
      eval: this.interpret.bind(this)
    });

    this.repl.on("exit", function() {
      // If we exit for some reason, call done functions for good measure
      // then ensure the process is completely killed. Once the repl exits,
      // the process is in a bad state and can't be recovered (e.g., stdin is closed).
      const doneFunctions = self.contexts.reduce((fns, ctx) => {
        if (ctx.done) fns.push(ctx.done);
        return fns;
      }, []);
      async.series(doneFunctions, function() {
        process.exit();
      });
    });
  }

  // Bubble the internal repl's exit event
  this.repl.on("exit", function() {
    self.emit("exit");
  });

  // Bubble the internal repl's reset event
  this.repl.on("reset", function() {
    process.stdout.write("\u001B[2J\u001B[0;0f");
    self.emit("reset");
  });

  this.repl.setPrompt(options.prompt);
  this.setContextVars(options.context || {});
  this.activate(options);
};

ReplManager.prototype.setContextVars = function(obj) {
  var self = this;
  if (this.repl) {
    Object.keys(obj || {}).forEach(function(key) {
      self.repl.context[key] = obj[key];
    });
  }
};

ReplManager.prototype.activate = function(session) {
  const { prompt, context, ignoreUndefined } = session;
  this.repl.setPrompt(prompt);
  this.repl.ignoreUndefined = ignoreUndefined;
  this.setContextVars(context);
};

ReplManager.prototype.stop = function(callback) {
  var oldContext = this.contexts.pop();

  if (oldContext.done) {
    oldContext.done();
  }

  var currentContext = this.contexts[this.contexts.length - 1];

  if (currentContext) {
    this.activate(currentContext);
  } else {
    // If there's no new context, stop the process altogether.
    // Though this might seem like an out of place process.exit(),
    // once the Node repl closes, the state of the process is not
    // recoverable; e.g., stdin is closed and can't be reopened.
    // Since we can't recover to a state before the repl was opened,
    // we should just exit. He're, we'll exit after we've popped
    // off the stack of all repl contexts.
    process.exit();
  }

  if (callback) {
    callback();
  }
};

ReplManager.prototype.interpret = function(
  replInput,
  context,
  filename,
  callback
) {
  const currentContext = this.contexts[this.contexts.length - 1];
  currentContext.interpreter(replInput, context, filename, callback);
};

module.exports = ReplManager;
<commit_msg>Improve readability, remove unnecessary callback<commit_after>var repl = require("repl");
var expect = require("@truffle/expect");
var async = require("async");
var EventEmitter = require("events");
var inherits = require("util").inherits;

inherits(ReplManager, EventEmitter);

function ReplManager(options) {
  EventEmitter.call(this);

  expect.options(options, [
    "working_directory",
    "contracts_directory",
    "contracts_build_directory",
    "migrations_directory",
    "network",
    "network_id",
    "provider",
    "resolver",
    "build_directory"
  ]);

  this.options = options;
  this.repl = options.repl;

  this.contexts = [];
}

ReplManager.prototype.start = function(options) {
  var self = this;

  this.contexts.push({
    prompt: options.prompt,
    interpreter: options.interpreter,
    ignoreUndefined: options.ignoreUndefined || false,
    done: options.done
  });

  var currentContext = this.contexts[this.contexts.length - 1];

  if (!this.repl) {
    this.repl = repl.start({
      prompt: currentContext.prompt,
      eval: this.interpret.bind(this)
    });

    this.repl.on("exit", function() {
      // If we exit for some reason, call done functions for good measure
      // then ensure the process is completely killed. Once the repl exits,
      // the process is in a bad state and can't be recovered (e.g., stdin is closed).
      const doneFunctions = self.contexts.reduce((fns, ctx) => {
        if (ctx.done) fns.push(ctx.done);
        return fns;
      }, []);
      async.series(doneFunctions, process.exit);
    });
  }

  // Bubble the internal repl's exit event
  this.repl.on("exit", function() {
    self.emit("exit");
  });

  // Bubble the internal repl's reset event
  this.repl.on("reset", function() {
    process.stdout.write("\u001B[2J\u001B[0;0f");
    self.emit("reset");
  });

  this.repl.setPrompt(options.prompt);
  this.setContextVars(options.context || {});
  this.activate(options);
};

ReplManager.prototype.setContextVars = function(obj) {
  var self = this;
  if (this.repl) {
    Object.keys(obj || {}).forEach(function(key) {
      self.repl.context[key] = obj[key];
    });
  }
};

ReplManager.prototype.activate = function(session) {
  const { prompt, context, ignoreUndefined } = session;
  this.repl.setPrompt(prompt);
  this.repl.ignoreUndefined = ignoreUndefined;
  this.setContextVars(context);
};

ReplManager.prototype.stop = function(callback) {
  var oldContext = this.contexts.pop();

  if (oldContext.done) {
    oldContext.done();
  }

  var currentContext = this.contexts[this.contexts.length - 1];

  if (currentContext) {
    this.activate(currentContext);
  } else {
    // If there's no new context, stop the process altogether.
    // Though this might seem like an out of place process.exit(),
    // once the Node repl closes, the state of the process is not
    // recoverable; e.g., stdin is closed and can't be reopened.
    // Since we can't recover to a state before the repl was opened,
    // we should just exit. He're, we'll exit after we've popped
    // off the stack of all repl contexts.
    process.exit();
  }

  if (callback) {
    callback();
  }
};

ReplManager.prototype.interpret = function(
  replInput,
  context,
  filename,
  callback
) {
  const currentContext = this.contexts[this.contexts.length - 1];
  currentContext.interpreter(replInput, context, filename, callback);
};

module.exports = ReplManager;
<|endoftext|>


<commit_before>import React from 'react';
import { addStoryInGroup, LOW_LEVEL_BLOCKS } from '../../../.storybook/utils';
import { boolean, select } from '@storybook/addon-knobs/react';
import { IconBuildingSmallOutline } from '@teamleader/ui-icons';
import { colorsWithout, Badge, TextDisplay } from '../../index';

const colors = colorsWithout(['teal']);
const iconPositions = ['left', 'right'];

export default {
  title: addStoryInGroup(LOW_LEVEL_BLOCKS, 'Badge'),

  parameters: {
    info: {
      propTablesExclude: [TextDisplay],
    },
  },
};

export const inline = () => (
  <TextDisplay>
    I'm display text with a
    <Badge
      color={select('Color', colors, 'neutral')}
      disabled={boolean('Disabled', false)}
      inherit={boolean('Inherit', true)}
      inverse={boolean('Inverse', false)}
    >
      badge
    </Badge>
    inside.
  </TextDisplay>
);

export const standalone = () => (
  <Badge
    color={select('Color', colors, 'neutral')}
    disabled={boolean('Disabled', false)}
    inherit={boolean('Inherit', false)}
    inverse={boolean('Inverse', false)}
  >
    I'm a badge
  </Badge>
);

export const withIcon = () => (
  <Badge
    color={select('Color', colors, 'neutral')}
    disabled={boolean('Disabled', false)}
    icon={<IconBuildingSmallOutline />}
    iconPlacement={select('Icon placement', iconPositions, 'left')}
    inherit={boolean('Inherit', false)}
    inverse={boolean('Inverse', false)}
  >
    I'm a badge
  </Badge>
);

withIcon.story = {
  name: 'With icon',
};

export const withCustomElement = () => (
  <Badge
    color={select('Color', colors, 'neutral')}
    disabled={boolean('Disabled', false)}
    element="a"
    href="https://teamleader.eu"
    inherit={boolean('Inherit', false)}
    inverse={boolean('Inverse', false)}
  >
    I'm a badge
  </Badge>
);

withCustomElement.story = {
  name: 'With custom element',
};
<commit_msg>If needed, we can optionally pass the marginHorizontal prop<commit_after>import React from 'react';
import { addStoryInGroup, LOW_LEVEL_BLOCKS } from '../../../.storybook/utils';
import { boolean, select } from '@storybook/addon-knobs/react';
import { IconBuildingSmallOutline } from '@teamleader/ui-icons';
import { colorsWithout, Badge, TextDisplay } from '../../index';

const colors = colorsWithout(['teal']);
const iconPositions = ['left', 'right'];

export default {
  title: addStoryInGroup(LOW_LEVEL_BLOCKS, 'Badge'),

  parameters: {
    info: {
      propTablesExclude: [TextDisplay],
    },
  },
};

export const inline = () => (
  <TextDisplay>
    I'm display text with a
    <Badge
      color={select('Color', colors, 'neutral')}
      disabled={boolean('Disabled', false)}
      inherit={boolean('Inherit', true)}
      inverse={boolean('Inverse', false)}
      marginHorizontal={1}
    >
      badge
    </Badge>
    inside.
  </TextDisplay>
);

export const standalone = () => (
  <Badge
    color={select('Color', colors, 'neutral')}
    disabled={boolean('Disabled', false)}
    inherit={boolean('Inherit', false)}
    inverse={boolean('Inverse', false)}
  >
    I'm a badge
  </Badge>
);

export const withIcon = () => (
  <Badge
    color={select('Color', colors, 'neutral')}
    disabled={boolean('Disabled', false)}
    icon={<IconBuildingSmallOutline />}
    iconPlacement={select('Icon placement', iconPositions, 'left')}
    inherit={boolean('Inherit', false)}
    inverse={boolean('Inverse', false)}
  >
    I'm a badge
  </Badge>
);

withIcon.story = {
  name: 'With icon',
};

export const withCustomElement = () => (
  <Badge
    color={select('Color', colors, 'neutral')}
    disabled={boolean('Disabled', false)}
    element="a"
    href="https://teamleader.eu"
    inherit={boolean('Inherit', false)}
    inverse={boolean('Inverse', false)}
  >
    I'm a badge
  </Badge>
);

withCustomElement.story = {
  name: 'With custom element',
};
<|endoftext|>


<commit_before>"use strict";

/**
 * Great Circle calculation
 * @author  Kevin Ulrich
 * @class  greatCircle
 */
class greatCircle {

	/**
	 * Constructor
	 * @param  {object} opts Option-Object. Accepts properties 'sort' ('asc' || 'desc' || false) and limit (positive integer || false)
	 */
	constructor(opts) {
		if(typeof opts != 'object') opts = {};

		this.sort = greatCircle._getValidSort(opts.sort);
		this.limit = greatCircle._getValidLimit(opts.limit);
	}

	/**
	 * Calculate a list of points. Can override default 'sort' and 'limit' by property.
	 * @param  {object} opts Option-Object. Accepts properties from (valid point), to (array of or single valid point), sort (see constructor), limit (see constructor)
	 * @return {array}      The resulting distance list with given points and distances
	 */
	calc(opts) {
		if(typeof opts.from != 'object' || typeof opts.from.lat == 'undefined' || typeof opts.from.lon == 'undefined') throw "greatCircle: From needs to be an object with at least lat and lon";
		if(typeof opts.to != 'object') throw "greatCircle: To needs to be an object with at least lat and lon";

		var tempSort = typeof opts.sort != 'undefined' ? greatCircle._getValidSort(opts.sort) : this.sort;
		var tempLimit = typeof opts.limit != 'undefined' ? greatCircle._getValidLimit(opts.limit) : this.limit;

		var from = greatCircle._getValidPoint(opts.from);
		var to = greatCircle._getValidPointList(opts.to);

		var distances = greatCircle._getDistanceList(from, to);

		if(tempSort !== false) distances = greatCircle._sortDistanceList(distances, tempSort);
		if(tempLimit !== false) distances = greatCircle._limitDistanceList(distances, tempLimit);

		return distances;
	}

	/**
	 * The raw calculation according to the haversine formula.
	 * Big thanks to http://www.movable-type.co.uk/scripts/latlong.html for the brilliant explanation of
	 * different methods of determining great circle distance!
	 * @param  {object} from A valid point
	 * @param  {object} to   A valid point
	 * @return {number}      Distance in meters
	 * @static
	 */
	static getDistanceBetween(from, to) {
		from = greatCircle._getValidPoint(from);
		to = greatCircle._getValidPoint(to);

		var radLatFrom = greatCircle.floatToRadians(from.lat);
		var radLatTo = greatCircle.floatToRadians(to.lat);

		var radDeltaLat = greatCircle.floatToRadians(to.lat - from.lat);
		var radDeltaLon = greatCircle.floatToRadians(to.lon - from.lon);

		var a = Math.sin(radDeltaLat / 2) * Math.sin(radDeltaLat / 2) +
		        Math.cos(radLatFrom) * Math.cos(radLatTo) *
		        Math.sin(radDeltaLon / 2) * Math.sin(radDeltaLon / 2);

		var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

		// Precision less than a meter is not really accurate here

		return parseInt(greatCircle.earthRadius * c);
	}

	/**
	 * Limit a list to a number of items
	 * @param  {object} list  The Array/Object to limit
	 * @param  {number} limit Number of allowed items as integer
	 * @return {object}       Truncated Array/Object
	 * @static
	 */
	static _limitDistanceList(list, limit) {
		limit = greatCircle._getValidLimit(limit);

		if(limit === false) return [];

		var limitedArray = [];

		for(var item in list) {
			if(item == limit) break;
			limitedArray.push(list[item]);
		}

		return limitedArray;
	}

	/**
	 * Sort a list of distances (as determined by the distance property of items)
	 * @param  {object} list      List of distances, as returned by _getDistanceList()
	 * @param  {mixed} direction A valid direction ('asc' || 'desc' || false)
	 * @return {object}           The sorted List
	 * @static
	 */
	static _sortDistanceList(list, direction) {
		direction = greatCircle._getValidSort(direction);

		if(direction != 'asc' && direction != 'desc') return list;

		// Use selection sort for now

		var sortedList = [];

		while(list.length > 0) {
			let maxIdx = 0;

			for(var item in list) {
				let thisItem = list[item];

				if(typeof thisItem.distance == 'undefined') continue;

				if(thisItem.distance >= list[maxIdx].distance) {
					maxIdx = item;
				}
			}

			sortedList.push(list.splice(maxIdx, 1)[0]);
		}

		if(direction == 'asc') sortedList.reverse();

		return sortedList;
	}

	/**
	 * Get a list of distances for from to each to point
	 * @param  {object} from A valid point
	 * @param  {object} to   An array of or a single valid point
	 * @return {object}      An Array containing the distances for from to each to point.
	 * @static
	 */
	static _getDistanceList(from, to) {
		from = greatCircle._getValidPoint(from);
		to = greatCircle._getValidPointList(to);

		var distanceList = [];

		for(var item in to) {
			try {
				let distance = greatCircle.getDistanceBetween(from, to[item]);
				distanceList.push({from: from, to: to[item], distance: distance});
			} catch(e) {
				continue;
			}
		}

		return distanceList;
	}

	/**
	 * Check/Clean/Format a given list for validity.
	 * @param  {object} list The list to check
	 * @return {object}      An Array containing valid points
	 * @static
	 */
	static _getValidPointList(list) {
		try {
			if(!(list instanceof Array)) return [greatCircle._getValidPoint(list)];
		} catch(e) {
			return [];
		}

		var cleanList = [];

		for(var item in list) {
			try {
				cleanList.push(greatCircle._getValidPoint(list[item]));
			} catch(e) {
				continue;
			}
		}

		return cleanList;
	}

	/**
	 * Check/Clean/Format a given point for validity
	 * @param  {object} point The point to check
	 * @return {object}       A valid point
	 * @static
	 */
	static _getValidPoint(point) {
		if(typeof point == 'undefined') throw "greatCircle: No coordinates given";
		if(isNaN(point.lat) || isNaN(point.lon)) throw "greatCircle: Invalid coordinates";
		if(parseFloat(point.lat) < -180 || parseFloat(point.lat) > 180) throw "greatCircle: Invalid coordinates";
		if(parseFloat(point.lon) < -180 || parseFloat(point.lon) > 180) throw "greatCircle: Invalid coordinates";

		var cleanPoint = {lat: parseFloat(point.lat), lon: parseFloat(point.lon)};

		if(typeof point.payload != 'undefined') cleanPoint.payload = point.payload;

		return cleanPoint;
	}

	/**
	 * Get a valid sorting parameter. Either 'asc', 'desc', or false for no sorting.
	 * @param  {mixed} input Input to check
	 * @return {mixed}       Valid sorting parameter for use with further functions
	 * @static
	 */
	static _getValidSort(input) {
		return (input && input == 'asc') ? 'asc' : (input && input == 'desc') ? 'desc' : false;
	}

	/**
	 * Get a valid limit parameter. Can either be false or a positive integer
	 * @param  {mixed} input Input to check
	 * @return {mixed}       Valid limit parameter
	 * @static
	 */
	static _getValidLimit(input) {
		return (typeof input == 'boolean') ? false : (input === null) ? false : isNaN(input) ? false : (parseInt(input) > 0) ? parseInt(input) : false;
	}

	/**
	 * The earths radius as required by the haversine formula
	 * @type {Number}
	 * @static
	 */
	static earthRadius = 6371000;

	/**
	 * Convert a degree as floating point number to degree radians
	 * @param  {number} number The input degree
	 * @return {number}        Degree Radians
	 * @static
	 */
	static floatToRadians(number) {
		return number * Math.PI / 180;
	}
}<commit_msg>Turn the class static into a property of the prototype<commit_after>"use strict";

/**
 * Great Circle calculation
 * @author  Kevin Ulrich
 * @class  greatCircle
 */
class greatCircle {

	/**
	 * Constructor
	 * @param  {object} opts Option-Object. Accepts properties 'sort' ('asc' || 'desc' || false) and limit (positive integer || false)
	 */
	constructor(opts) {
		if(typeof opts != 'object') opts = {};

		this.sort = greatCircle._getValidSort(opts.sort);
		this.limit = greatCircle._getValidLimit(opts.limit);
	}

	/**
	 * Calculate a list of points. Can override default 'sort' and 'limit' by property.
	 * @param  {object} opts Option-Object. Accepts properties from (valid point), to (array of or single valid point), sort (see constructor), limit (see constructor)
	 * @return {array}      The resulting distance list with given points and distances
	 */
	calc(opts) {
		if(typeof opts.from != 'object' || typeof opts.from.lat == 'undefined' || typeof opts.from.lon == 'undefined') throw "greatCircle: From needs to be an object with at least lat and lon";
		if(typeof opts.to != 'object') throw "greatCircle: To needs to be an object with at least lat and lon";

		var tempSort = typeof opts.sort != 'undefined' ? greatCircle._getValidSort(opts.sort) : this.sort;
		var tempLimit = typeof opts.limit != 'undefined' ? greatCircle._getValidLimit(opts.limit) : this.limit;

		var from = greatCircle._getValidPoint(opts.from);
		var to = greatCircle._getValidPointList(opts.to);

		var distances = greatCircle._getDistanceList(from, to);

		if(tempSort !== false) distances = greatCircle._sortDistanceList(distances, tempSort);
		if(tempLimit !== false) distances = greatCircle._limitDistanceList(distances, tempLimit);

		return distances;
	}

	/**
	 * The raw calculation according to the haversine formula.
	 * Big thanks to http://www.movable-type.co.uk/scripts/latlong.html for the brilliant explanation of
	 * different methods of determining great circle distance!
	 * @param  {object} from A valid point
	 * @param  {object} to   A valid point
	 * @return {number}      Distance in meters
	 * @static
	 */
	static getDistanceBetween(from, to) {
		from = greatCircle._getValidPoint(from);
		to = greatCircle._getValidPoint(to);

		var radLatFrom = greatCircle.floatToRadians(from.lat);
		var radLatTo = greatCircle.floatToRadians(to.lat);

		var radDeltaLat = greatCircle.floatToRadians(to.lat - from.lat);
		var radDeltaLon = greatCircle.floatToRadians(to.lon - from.lon);

		var a = Math.sin(radDeltaLat / 2) * Math.sin(radDeltaLat / 2) +
		        Math.cos(radLatFrom) * Math.cos(radLatTo) *
		        Math.sin(radDeltaLon / 2) * Math.sin(radDeltaLon / 2);

		var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

		// Precision less than a meter is not really accurate here

		return parseInt(greatCircle.earthRadius * c);
	}

	/**
	 * Limit a list to a number of items
	 * @param  {object} list  The Array/Object to limit
	 * @param  {number} limit Number of allowed items as integer
	 * @return {object}       Truncated Array/Object
	 * @static
	 */
	static _limitDistanceList(list, limit) {
		limit = greatCircle._getValidLimit(limit);

		if(limit === false) return [];

		var limitedArray = [];

		for(var item in list) {
			if(item == limit) break;
			limitedArray.push(list[item]);
		}

		return limitedArray;
	}

	/**
	 * Sort a list of distances (as determined by the distance property of items)
	 * @param  {object} list      List of distances, as returned by _getDistanceList()
	 * @param  {mixed} direction A valid direction ('asc' || 'desc' || false)
	 * @return {object}           The sorted List
	 * @static
	 */
	static _sortDistanceList(list, direction) {
		direction = greatCircle._getValidSort(direction);

		if(direction != 'asc' && direction != 'desc') return list;

		// Use selection sort for now

		var sortedList = [];

		while(list.length > 0) {
			let maxIdx = 0;

			for(var item in list) {
				let thisItem = list[item];

				if(typeof thisItem.distance == 'undefined') continue;

				if(thisItem.distance >= list[maxIdx].distance) {
					maxIdx = item;
				}
			}

			sortedList.push(list.splice(maxIdx, 1)[0]);
		}

		if(direction == 'asc') sortedList.reverse();

		return sortedList;
	}

	/**
	 * Get a list of distances for from to each to point
	 * @param  {object} from A valid point
	 * @param  {object} to   An array of or a single valid point
	 * @return {object}      An Array containing the distances for from to each to point.
	 * @static
	 */
	static _getDistanceList(from, to) {
		from = greatCircle._getValidPoint(from);
		to = greatCircle._getValidPointList(to);

		var distanceList = [];

		for(var item in to) {
			try {
				let distance = greatCircle.getDistanceBetween(from, to[item]);
				distanceList.push({from: from, to: to[item], distance: distance});
			} catch(e) {
				continue;
			}
		}

		return distanceList;
	}

	/**
	 * Check/Clean/Format a given list for validity.
	 * @param  {object} list The list to check
	 * @return {object}      An Array containing valid points
	 * @static
	 */
	static _getValidPointList(list) {
		try {
			if(!(list instanceof Array)) return [greatCircle._getValidPoint(list)];
		} catch(e) {
			return [];
		}

		var cleanList = [];

		for(var item in list) {
			try {
				cleanList.push(greatCircle._getValidPoint(list[item]));
			} catch(e) {
				continue;
			}
		}

		return cleanList;
	}

	/**
	 * Check/Clean/Format a given point for validity
	 * @param  {object} point The point to check
	 * @return {object}       A valid point
	 * @static
	 */
	static _getValidPoint(point) {
		if(typeof point == 'undefined') throw "greatCircle: No coordinates given";
		if(isNaN(point.lat) || isNaN(point.lon)) throw "greatCircle: Invalid coordinates";
		if(parseFloat(point.lat) < -180 || parseFloat(point.lat) > 180) throw "greatCircle: Invalid coordinates";
		if(parseFloat(point.lon) < -180 || parseFloat(point.lon) > 180) throw "greatCircle: Invalid coordinates";

		var cleanPoint = {lat: parseFloat(point.lat), lon: parseFloat(point.lon)};

		if(typeof point.payload != 'undefined') cleanPoint.payload = point.payload;

		return cleanPoint;
	}

	/**
	 * Get a valid sorting parameter. Either 'asc', 'desc', or false for no sorting.
	 * @param  {mixed} input Input to check
	 * @return {mixed}       Valid sorting parameter for use with further functions
	 * @static
	 */
	static _getValidSort(input) {
		return (input && input == 'asc') ? 'asc' : (input && input == 'desc') ? 'desc' : false;
	}

	/**
	 * Get a valid limit parameter. Can either be false or a positive integer
	 * @param  {mixed} input Input to check
	 * @return {mixed}       Valid limit parameter
	 * @static
	 */
	static _getValidLimit(input) {
		return (typeof input == 'boolean') ? false : (input === null) ? false : isNaN(input) ? false : (parseInt(input) > 0) ? parseInt(input) : false;
	}

	/**
	 * Convert a degree as floating point number to degree radians
	 * @param  {number} number The input degree
	 * @return {number}        Degree Radians
	 * @static
	 */
	static floatToRadians(number) {
		return number * Math.PI / 180;
	}
}

/**
 * The earths radius as required by the haversine formula
 * @type {Number}
 * @static
 */
greatCircle.earthRadius = 6371000;

module.exports = greatCircle;<|endoftext|>