<commit_before>/*  crypto.js @GlassToeStudio - GlassToeStudio@gmail.com

    16 September, 2017
    https://github.com/GlassToeStudio
    http://glasstoestudio.weebly.com/
    https://twitter.com/GlassToeStudio

    ------------------------------------------------------------------------
    Return current price of a given crypto-currency in $US

    The following command is uisng a free API from https://www.cryptocompare.com/ (CC BY-NC 3.0)
    The API request can be found here: https://www.cryptocompare.com/api#-api-data-price-

    Usage:
      !price <COIN> (COIN)...

    Example:
      !price BTC ETH

      ------ Current exchange rates for 1 BTC ------
                ETH.......... 14.47

    ------------------------------------------------------------------------

*/
const Confax = require('../bot.js')
const request = require('request')
const Discord = require('discord.js')
const currencySymbolMap = require('../map.js')

GlassBot.registerCommand('crypto', 'default', (message, bot) => {
  //  Init variables
  let symbols = (message.content.split(' ')).map(function (x) { return x.toUpperCase() })
  let fromSymbol = (symbols.shift()).replace(/`/ig, '')
  if (symbols.length === 0) symbols.push('USD')
  CrytpoComparePrice(fromSymbol, symbols, message)
}, ['crypt', 'price'], 'Get latest crypto exchange price in USD, or in other cryptos.', '<crypto-currency ticker>')

/**
 * Return the exchange rate for one crypto currency in terms of other currencies.
 * @param  {string} fsym
 * @param  {string[]} tsyms
 * @param  {string} messge
 */
function CrytpoComparePrice (fsym, tsyms, message) {
  //  The API call string.
  let cryptoComparePrice = 'https://min-api.cryptocompare.com/data/price?fsym=' + fsym + '&tsyms=' + tsyms

  request(cryptoComparePrice, function (error, response, body) {
    if (error) message.channel.send('Not a valid crypto currency, try BTC or ETH.')
    let embed = new Discord.RichEmbed().setTitle('cryptocompare.com')
      .setDescription('```MarkDown\n#_Exchange rates for 1 ' + fsym + '```')
      .setURL('https://www.cryptocompare.com/api/')
      .setColor(586901)
      .setTimestamp()
    try {
      let responseBody = JSON.parse(body)
      for (let sym = 0; sym < tsyms.length; sym++) {
        let price = responseBody[tsyms[sym]]
        if (price === undefined) price = '¯\\_(ツ)_/¯' // Not valid crypto currency ¯\_(ツ)_/¯
        else if (getSymbolFromCurrency(tsyms[sym]) !== undefined) price = ' ' + getSymbolFromCurrency(tsyms[sym]) + ' ' + parseFloat(price).toLocaleString('en-IN', { maximumSignificantDigits: 10, minimumFractionDigits: 2 })
        else price = parseFloat(price).toLocaleString('en-IN', { maximumSignificantDigits: 10, minimumFractionDigits: 2 })
        embed.addField('*  ' + tsyms[sym], '```js\n' + price + '```', true)
      }
      message.channel.send('**' + fsym + '**', {embed})
    } catch (error) {
      message.channel.send('<:doggo:328259712963313665>' + ' Not a valid crypto-currency, try BTC or ETH.')
    }
  })
}

function getSymbolFromCurrency (currencyCode) {
  if (typeof currencyCode !== 'string') return undefined
  var code = currencyCode.toUpperCase()
  if (!currencySymbolMap.hasOwnProperty(code)) return undefined
  return currencySymbolMap[code]
}
<commit_msg>Fix crypto command<commit_after>/*  crypto.js @GlassToeStudio - GlassToeStudio@gmail.com

    16 September, 2017
    https://github.com/GlassToeStudio
    http://glasstoestudio.weebly.com/
    https://twitter.com/GlassToeStudio

    ------------------------------------------------------------------------
    Return current price of a given crypto-currency in $US

    The following command is uisng a free API from https://www.cryptocompare.com/ (CC BY-NC 3.0)
    The API request can be found here: https://www.cryptocompare.com/api#-api-data-price-

    Usage:
      !price <COIN> (COIN)...

    Example:
      !price BTC ETH

      ------ Current exchange rates for 1 BTC ------
                ETH.......... 14.47

    ------------------------------------------------------------------------

*/
const Confax = require('../bot.js')
const request = require('request')
const Discord = require('discord.js')
const currencySymbolMap = require('../map.js')

Confax.registerCommand('crypto', 'default', (message, bot) => {
  //  Init variables
  let symbols = (message.content.split(' ')).map(function (x) { return x.toUpperCase() })
  let fromSymbol = (symbols.shift()).replace(/`/ig, '')
  if (symbols.length === 0) symbols.push('USD')
  CryptoComparePrice(fromSymbol, symbols, message)
}, ['crypt', 'price'], 'Get latest crypto exchange price in USD, or in other cryptos.', '<crypto-currency ticker>')

/**
 * Return the exchange rate for one crypto currency in terms of other currencies.
 * @param  {string} fsym
 * @param  {string[]} tsyms
 * @param  {string} messge
 */
function CryptoComparePrice (fsym, tsyms, message) {
  //  The API call string.
  let cryptoComparePrice = 'https://min-api.cryptocompare.com/data/price?fsym=' + fsym + '&tsyms=' + tsyms

  request(cryptoComparePrice, function (error, response, body) {
    if (error) message.channel.send('Not a valid crypto currency, try BTC or ETH.')
    let embed = new Discord.RichEmbed().setTitle('cryptocompare.com')
      .setDescription('```MarkDown\n#_Exchange rates for 1 ' + fsym + '```')
      .setURL('https://www.cryptocompare.com/api/')
      .setColor(586901)
      .setTimestamp()
    try {
      let responseBody = JSON.parse(body)
      for (let sym = 0; sym < tsyms.length; sym++) {
        let price = responseBody[tsyms[sym]]
        if (price === undefined) price = '¯\\_(ツ)_/¯' // Not valid crypto currency ¯\_(ツ)_/¯
        else if (getSymbolFromCurrency(tsyms[sym]) !== undefined) price = ' ' + getSymbolFromCurrency(tsyms[sym]) + ' ' + parseFloat(price).toLocaleString('en-IN', { maximumSignificantDigits: 10, minimumFractionDigits: 2 })
        else price = parseFloat(price).toLocaleString('en-IN', { maximumSignificantDigits: 10, minimumFractionDigits: 2 })
        embed.addField('*  ' + tsyms[sym], '```js\n' + price + '```', true)
      }
      message.channel.send('**' + fsym + '**', {embed})
    } catch (error) {
      message.channel.send('<:doggo:328259712963313665>' + ' Not a valid crypto-currency, try BTC or ETH.')
    }
  })
}

function getSymbolFromCurrency (currencyCode) {
  if (typeof currencyCode !== 'string') return undefined
  var code = currencyCode.toUpperCase()
  if (!currencySymbolMap.hasOwnProperty(code)) return undefined
  return currencySymbolMap[code]
}
<|endoftext|>


<commit_before>'use strict';

exports.start = function () {

if (process.env.NEW_RELIC_ENABLED === "true") require('newrelic');

var env = process.env.NODE_ENV || 'development';

var _ = require('lodash');
var Hapi = require('hapi');
var Blankie = require('blankie');
var Scooter = require('scooter');
var Chairo = require('chairo');
var path = require('path');
var options = require('./options.' + env + '.js');
var locale = require('locale');
var languages = require('./config/languages.js');
var cacheTimes = require('./config/cache-times');

require('./lib/dust-i18n.js');

var availableLocales = new locale.Locales(_.pluck(languages, 'code'));
var server = new Hapi.Server(options.hapi)
var port = process.env.PORT || 8000
var host = process.env.HOSTNAME || 'localhost';
var protocol = process.env.PROTOCOL || 'http';
var hostWithPort = protocol + '://' + host + ':' + port;

function checkHapiPluginError (name) {
  return function (error) {
    if (error) {
      console.error('Failed loading a Hapi plugin: "' + name + '".');
      throw error;
    }
  };
}

// Set up HAPI

server.connection({
  port: port,
  // According to the HTTP spec and Chrome audit tool, Cache-Control headers should match what
  // would be sent for 200 when a 304 (Not Modified) is sent.
  routes: {
    cache: { statuses: [200,304] },
    cors: { origin: [ hostWithPort, 'https://changex.org' ] }
  }
});

server.views({
  engines: { dust: require('hapi-dust') },
  path: path.join(__dirname, './public/templates'),
  partialsPath: path.join(__dirname, './public/templates')
});

server.ext('onPreAuth', function (request, reply) {
  var localesFormReq = (request.state && request.state.NG_TRANSLATE_LANG_KEY && request.state.NG_TRANSLATE_LANG_KEY.replace(/\"/g, ''))
    || request.headers['accept-language'];

  var requestLocales = new locale.Locales(localesFormReq);

  request.locals = {
    context: {
      locality: requestLocales.best(availableLocales).code
    }
  };

  return reply.continue();
});

// Handler for 404/401
server.ext('onPreResponse', function (request, reply) {
  var status = request.response.statusCode;

  if (status !== 404 && status !== 401) {
    return reply.continue();
  }

  return reply.view('errors/404', request.locals);
});

// Handler for 500
server.ext('onPreResponse', function (request, reply) {
  var headerStatus = _.get(request, 'response.statusCode', 500);
  var bodyStatus = _.get(request, 'response.output.payload.statusCode', undefined);

  if (headerStatus !== 500 && bodyStatus !== 500) {
    return reply.continue();
  }

  // Display full error message if not in production environment.
  if (env !== 'production') {
    return reply.continue();
  }

  // Otherwise, give a generic error reply to hide errors in production.
  return reply.view('errors/500', request.locals);
});

// TODO Using stream here causes responses from seneca-web to be buffered, which may impact performance.
//      However, most of them aren't large sized responses, so the benefit of Etag outweighs that penalty.
//      Implementing better streaming support in hapi-etags may be fairly straightforward using Etag in the
//      Trailer rather than Header... - wprl
server.register({ register: require('hapi-etags'), options: { varieties: ['plain', 'buffer', 'stream'] } }, checkHapiPluginError('hapi-etags'));

server.register(Scooter, function (err) {
  checkHapiPluginError('scooter')(err);

  server.register({ register: Blankie, options: {
    childSrc: "'none'",
    connectSrc: "'self'",
    defaultSrc: "'none'",
    fontSrc: "'self' http://fonts.gstatic.com https://fonts.gstatic.com",
    frameSrc: "https://www.google.com",
    frameAncestors: "'none'",
    imgSrc: "'self' 'unsafe-eval' 'unsafe-inline' data: *",
    manifestSrc: "'none'",
    mediaSrc: "'none'",
    objectSrc: "'none'",
    reflectedXss: 'block',
    scriptSrc: "'self' 'unsafe-inline' 'unsafe-eval' https://*.googleapis.com https://www.google-analytics.com https://maps.gstatic.com https://www.gstatic.com https://widget.intercom.io https://js.intercomcdn.com https://www.google.com https://apis.google.com",
    styleSrc: "'self' 'unsafe-inline' http://fonts.googleapis.com https://fonts.googleapis.com"
  }}, checkHapiPluginError('blankie'));
});

server.register({ register: require('./controllers') }, checkHapiPluginError('CoderDojo controllers'));

// Serve CSS files.
server.register({
  register: require('hapi-less'),
  options: {
    home: path.join(__dirname, './public/css'),
    route: '/css/{filename*}',
    config: { cache: { privacy: 'public', expiresIn: cacheTimes.short } },
    less: { compress: true }
  }
}, checkHapiPluginError('hapi-less'));

// Set up Chairo and seneca, then start the server.
server.register({ register: Chairo, options: options }, function (err) {
  checkHapiPluginError('Chairo')(err);

  server.register({ register: require('chairo-cache'), options: { cacheName: 'cd-cache' } }, function (err) {
    checkHapiPluginError('chairo-cache')(err);

    var seneca = server.seneca;

    seneca
      .use('ng-web')
      .use(require('../lib/users/user.js'))
      .use('auth')
      .use('user-roles')
      .use('web-access')
      .use(require('../lib/charter/cd-charter.js'))
      .use(require('../lib/dojos/cd-dojos.js'))
      .use(require('../lib/users/cd-users.js'))
      .use(require('../lib/agreements/cd-agreements.js'))
      .use(require('../lib/badges/cd-badges.js'))
      .use(require('../lib/profiles/cd-profiles.js'))
      .use(require('../lib/events/cd-events.js'))
      .use(require('../lib/oauth2/cd-oauth2.js'))
      .use(require('../lib/config/cd-config.js'), options.webclient)
      .use(require('../lib/sys/cd-sys.js'));

    _.each(options.client, function(opts) {
      seneca.client(opts);
    });

    // // Potentially useful extra logging.

    // seneca.logroute( {level:'all' });

    // // capture seneca messages - leaving this here as we *may* do something with it
    // // if the debug level json is not good enough logging.
    // seneca.sub({}, captureAllMessages);
    // function captureAllMessages(args) {
    //   console.log('*** captured = ', JSON.stringify(args));
    // }

    // Use seneca-web middleware with Hapi.
    server.register({
      register: require('hapi-seneca'),
      options: {
        cors: true,
        session: {
          /*store: sessionStore, */ // TODO remote session store
          secret: options.session.secret,
          name: 'CD.ZENPLATFORM',
          saveUninitialized: true,
          resave: true
        }
      }
    }, function (err) {
      checkHapiPluginError('hapi-seneca')(err);
      server.start(function() {
        console.log('[%s] Listening on http://localhost:%d', env, port);
      });
    });
  });
});

};
<commit_msg>added both https and http urls for google analytics when checking for hapi errors<commit_after>'use strict';

exports.start = function () {

if (process.env.NEW_RELIC_ENABLED === "true") require('newrelic');

var env = process.env.NODE_ENV || 'development';

var _ = require('lodash');
var Hapi = require('hapi');
var Blankie = require('blankie');
var Scooter = require('scooter');
var Chairo = require('chairo');
var path = require('path');
var options = require('./options.' + env + '.js');
var locale = require('locale');
var languages = require('./config/languages.js');
var cacheTimes = require('./config/cache-times');

require('./lib/dust-i18n.js');

var availableLocales = new locale.Locales(_.pluck(languages, 'code'));
var server = new Hapi.Server(options.hapi)
var port = process.env.PORT || 8000
var host = process.env.HOSTNAME || 'localhost';
var protocol = process.env.PROTOCOL || 'http';
var hostWithPort = protocol + '://' + host + ':' + port;

function checkHapiPluginError (name) {
  return function (error) {
    if (error) {
      console.error('Failed loading a Hapi plugin: "' + name + '".');
      throw error;
    }
  };
}

// Set up HAPI

server.connection({
  port: port,
  // According to the HTTP spec and Chrome audit tool, Cache-Control headers should match what
  // would be sent for 200 when a 304 (Not Modified) is sent.
  routes: {
    cache: { statuses: [200,304] },
    cors: { origin: [ hostWithPort, 'https://changex.org' ] }
  }
});

server.views({
  engines: { dust: require('hapi-dust') },
  path: path.join(__dirname, './public/templates'),
  partialsPath: path.join(__dirname, './public/templates')
});

server.ext('onPreAuth', function (request, reply) {
  var localesFormReq = (request.state && request.state.NG_TRANSLATE_LANG_KEY && request.state.NG_TRANSLATE_LANG_KEY.replace(/\"/g, ''))
    || request.headers['accept-language'];

  var requestLocales = new locale.Locales(localesFormReq);

  request.locals = {
    context: {
      locality: requestLocales.best(availableLocales).code
    }
  };

  return reply.continue();
});

// Handler for 404/401
server.ext('onPreResponse', function (request, reply) {
  var status = request.response.statusCode;

  if (status !== 404 && status !== 401) {
    return reply.continue();
  }

  return reply.view('errors/404', request.locals);
});

// Handler for 500
server.ext('onPreResponse', function (request, reply) {
  var headerStatus = _.get(request, 'response.statusCode', 500);
  var bodyStatus = _.get(request, 'response.output.payload.statusCode', undefined);

  if (headerStatus !== 500 && bodyStatus !== 500) {
    return reply.continue();
  }

  // Display full error message if not in production environment.
  if (env !== 'production') {
    return reply.continue();
  }

  // Otherwise, give a generic error reply to hide errors in production.
  return reply.view('errors/500', request.locals);
});

// TODO Using stream here causes responses from seneca-web to be buffered, which may impact performance.
//      However, most of them aren't large sized responses, so the benefit of Etag outweighs that penalty.
//      Implementing better streaming support in hapi-etags may be fairly straightforward using Etag in the
//      Trailer rather than Header... - wprl
server.register({ register: require('hapi-etags'), options: { varieties: ['plain', 'buffer', 'stream'] } }, checkHapiPluginError('hapi-etags'));

server.register(Scooter, function (err) {
  checkHapiPluginError('scooter')(err);

  server.register({ register: Blankie, options: {
    childSrc: "'none'",
    connectSrc: "'self'",
    defaultSrc: "'none'",
    fontSrc: "'self' http://fonts.gstatic.com https://fonts.gstatic.com",
    frameSrc: "https://www.google.com",
    frameAncestors: "'none'",
    imgSrc: "'self' 'unsafe-eval' 'unsafe-inline' data: *",
    manifestSrc: "'none'",
    mediaSrc: "'none'",
    objectSrc: "'none'",
    reflectedXss: 'block',
    scriptSrc: "'self' 'unsafe-inline' 'unsafe-eval' https://*.googleapis.com http://www.google-analytics.com https://www.google-analytics.com https://maps.gstatic.com https://www.gstatic.com https://widget.intercom.io https://js.intercomcdn.com https://www.google.com https://apis.google.com",
    styleSrc: "'self' 'unsafe-inline' http://fonts.googleapis.com https://fonts.googleapis.com"
  }}, checkHapiPluginError('blankie'));
});

server.register({ register: require('./controllers') }, checkHapiPluginError('CoderDojo controllers'));

// Serve CSS files.
server.register({
  register: require('hapi-less'),
  options: {
    home: path.join(__dirname, './public/css'),
    route: '/css/{filename*}',
    config: { cache: { privacy: 'public', expiresIn: cacheTimes.short } },
    less: { compress: true }
  }
}, checkHapiPluginError('hapi-less'));

// Set up Chairo and seneca, then start the server.
server.register({ register: Chairo, options: options }, function (err) {
  checkHapiPluginError('Chairo')(err);

  server.register({ register: require('chairo-cache'), options: { cacheName: 'cd-cache' } }, function (err) {
    checkHapiPluginError('chairo-cache')(err);

    var seneca = server.seneca;

    seneca
      .use('ng-web')
      .use(require('../lib/users/user.js'))
      .use('auth')
      .use('user-roles')
      .use('web-access')
      .use(require('../lib/charter/cd-charter.js'))
      .use(require('../lib/dojos/cd-dojos.js'))
      .use(require('../lib/users/cd-users.js'))
      .use(require('../lib/agreements/cd-agreements.js'))
      .use(require('../lib/badges/cd-badges.js'))
      .use(require('../lib/profiles/cd-profiles.js'))
      .use(require('../lib/events/cd-events.js'))
      .use(require('../lib/oauth2/cd-oauth2.js'))
      .use(require('../lib/config/cd-config.js'), options.webclient)
      .use(require('../lib/sys/cd-sys.js'));

    _.each(options.client, function(opts) {
      seneca.client(opts);
    });

    // // Potentially useful extra logging.

    // seneca.logroute( {level:'all' });

    // // capture seneca messages - leaving this here as we *may* do something with it
    // // if the debug level json is not good enough logging.
    // seneca.sub({}, captureAllMessages);
    // function captureAllMessages(args) {
    //   console.log('*** captured = ', JSON.stringify(args));
    // }

    // Use seneca-web middleware with Hapi.
    server.register({
      register: require('hapi-seneca'),
      options: {
        cors: true,
        session: {
          /*store: sessionStore, */ // TODO remote session store
          secret: options.session.secret,
          name: 'CD.ZENPLATFORM',
          saveUninitialized: true,
          resave: true
        }
      }
    }, function (err) {
      checkHapiPluginError('hapi-seneca')(err);
      server.start(function() {
        console.log('[%s] Listening on http://localhost:%d', env, port);
      });
    });
  });
});

};
<|endoftext|>


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

// This is a script to load the lively total_time per server data and
// present it in a dynamic column graph with a red horizontal
// threshold line

// Strict mode - error undeclared variables
"use strict";

// Load the google charts and draw the chart when loaded
google.load('visualization', '1.0', {'packages':['corechart']});
google.setOnLoadCallback(drawVisualization);

// Set up static variables
var chart = null; // Initially this is null. We set it once

// Options for the chart. Title, width, height and y-axis must always start at 0
var options = {
    'title' : 'Response Time (msec)',
    'width' : 400,
    'height' : 300,
    'vAxis' : { 'viewWindow': {'min' : 0, 'max' : 450 },
              },
    'legend' : { 'position' : 'none' },
    'chartArea' : { 'width' : '75%' }
};

// The lively date comes back keyed by server URL. Map these to friendly labels
var label_map = [
    { url: "http://tokyo.gee-project.net",
      name: "U. Tokyo, Japan",
      color: "blue" },
    { url: "http://nicta.gee-project.net",
      name: "NICTA, Australia",
      color: "blue" },
    { url: "http://uvic.gee-project.net",
      name: "UVic, Canada",
      color: "blue" },
    { url: "http://stanford.gee-project.net",
      name: "Stanford, US",
      color: "blue" },
    { url: "http://tamu.gee-project.net",
      name: "Texas A&M, US",
      color: "blue" },
    { url: "http://maxgigapop.gee-project.net",
      name: "MAX, US",
      color: "green" },
    { url: "http://iminds.gee-project.net",
      name: "iMinds, Belgium",
      color: "blue" },
    { url: "http://141.89.225.14",
      name: "HPI, Germany",
      color: "blue" },
];

// The value at which to place the threshold red horizontal line
var threshold_level = 150;

// Add a red threshold line
// This is added once to the chart, doesn't need to be re-added with new data
function addLine() {
    var newLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
    newLine.setAttribute('id', 'lineId');
    newLine.setAttribute('style', 'stroke:rgb(0,0,0); stroke-width:3;');
    newLine.setAttribute('x1',
                         chart.getChartLayoutInterface().getChartAreaBoundingBox().left);
    newLine.setAttribute('y1',
                         chart.getChartLayoutInterface().getYLocation(threshold_level));
    newLine.setAttribute('x2',
                         chart.getChartLayoutInterface().getChartAreaBoundingBox().left +
                         chart.getChartLayoutInterface().getChartAreaBoundingBox().width);
    newLine.setAttribute('y2',
                         chart.getChartLayoutInterface().getYLocation(threshold_level));
    newLine.setAttribute('style', 'stroke:red;stroke-width:2');
    $("svg").append(newLine);
}

// Top-level method, called on initialization and then every 5 seconds
function drawVisualization() {
    // Create the table first time through
    if(chart == null)  {
        var div_elt = document.getElementById('chart_div');
        chart = new google.visualization.ColumnChart(div_elt);
        $(div_elt).draggable();
    }

    // URL for grabbing lively data
    var grab_lively_url = "grab_lively_data.php"
    $.getJSON(grab_lively_url, function(json_data) {
        // In the JSON callback, we have the JSON data from server
        // Create an array data, start with headder line
        // role:style allows per-bar color changes
        var rows = [['Server', 'Total Time', { role: 'style' }]];
        $.each(label_map, function(i, site) {
            var json_idx = '"' + site.url + '"';
            var site_data = json_data[json_idx];
            if (! site_data) return;

            var total_time = site_data['total_time'];

            // These two lines are just to test animation
            //                 var noise = Math.floor(Math.random() * 200) - 100; // Between -100..100
            //                 total_time = Math.max(0, total_time + noise);

            // Create a row per server
            var row = [site.name, total_time, site.color];
            rows.push(row);
        });
        var data = google.visualization.arrayToDataTable(rows);
        // Redraw the same chart with new data
        chart.draw(data, options);
        setTimeout(drawVisualization, 5000);

    });

    // Create a one-time listener when the chart is ready, add the line and
    // then turn off the listener (we only need to add the line once.
    var runOnce = google.visualization.events.addListener(chart,
                                                          'ready', function() {
                                                              addLine();
                                                              google.visualization.events.removeListener(runOnce);
                                                          });

};

<commit_msg>Make the bar chart refresh every 20 seconds per Rick's request, ignore NICTA and TAMU entries in file, per Rick's request<commit_after>//----------------------------------------------------------------------
// Copyright (c) 2012-2015 Raytheon BBN Technologies
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and/or hardware specification (the "Work") to
// deal in the Work without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Work, and to permit persons to whom the Work
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Work.
//
// THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS
// IN THE WORK.
//----------------------------------------------------------------------

// This is a script to load the lively total_time per server data and
// present it in a dynamic column graph with a red horizontal
// threshold line

// Strict mode - error undeclared variables
"use strict";

// Load the google charts and draw the chart when loaded
google.load('visualization', '1.0', {'packages':['corechart']});
google.setOnLoadCallback(drawVisualization);

// Set up static variables
var chart = null; // Initially this is null. We set it once

// Options for the chart. Title, width, height and y-axis must always start at 0
var options = {
    'title' : 'Response Time (msec)',
    'width' : 400,
    'height' : 300,
    'vAxis' : { 'viewWindow': {'min' : 0, 'max' : 450 },
              },
    'legend' : { 'position' : 'none' },
    'chartArea' : { 'width' : '75%' }
};

// The lively date comes back keyed by server URL. Map these to friendly labels
var label_map = [
    { url: "http://tokyo.gee-project.net",
      name: "U. Tokyo, Japan",
      color: "blue" },
    //    { url: "http://nicta.gee-project.net",
    //      name: "NICTA, Australia",
    //      color: "blue" },
    { url: "http://uvic.gee-project.net",
      name: "UVic, Canada",
      color: "blue" },
    { url: "http://stanford.gee-project.net",
      name: "Stanford, US",
      color: "blue" },
    //    { url: "http://tamu.gee-project.net",
    //      name: "Texas A&M, US",
    //      color: "blue" },
    { url: "http://maxgigapop.gee-project.net",
      name: "MAX, US",
      color: "green" },
    { url: "http://iminds.gee-project.net",
      name: "iMinds, Belgium",
      color: "blue" },
    { url: "http://141.89.225.14",
      name: "HPI, Germany",
      color: "blue" },
];

// The value at which to place the threshold red horizontal line
var threshold_level = 150;

// Add a red threshold line
// This is added once to the chart, doesn't need to be re-added with new data
function addLine() {
    var newLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
    newLine.setAttribute('id', 'lineId');
    newLine.setAttribute('style', 'stroke:rgb(0,0,0); stroke-width:3;');
    newLine.setAttribute('x1',
                         chart.getChartLayoutInterface().getChartAreaBoundingBox().left);
    newLine.setAttribute('y1',
                         chart.getChartLayoutInterface().getYLocation(threshold_level));
    newLine.setAttribute('x2',
                         chart.getChartLayoutInterface().getChartAreaBoundingBox().left +
                         chart.getChartLayoutInterface().getChartAreaBoundingBox().width);
    newLine.setAttribute('y2',
                         chart.getChartLayoutInterface().getYLocation(threshold_level));
    newLine.setAttribute('style', 'stroke:red;stroke-width:2');
    $("svg").append(newLine);
}

// Top-level method, called on initialization and then every 5 seconds
function drawVisualization() {
    // Create the table first time through
    if(chart == null)  {
        var div_elt = document.getElementById('chart_div');
        chart = new google.visualization.ColumnChart(div_elt);
        $(div_elt).draggable();
    }

    // URL for grabbing lively data
    var grab_lively_url = "grab_lively_data.php"
    $.getJSON(grab_lively_url, function(json_data) {
        // In the JSON callback, we have the JSON data from server
        // Create an array data, start with headder line
        // role:style allows per-bar color changes
        var rows = [['Server', 'Total Time', { role: 'style' }]];
        $.each(label_map, function(i, site) {
            var json_idx = '"' + site.url + '"';
            var site_data = json_data[json_idx];
            if (! site_data) return;

            var total_time = site_data['total_time'];

            // These two lines are just to test animation
            //                 var noise = Math.floor(Math.random() * 200) - 100; // Between -100..100
            //                 total_time = Math.max(0, total_time + noise);

            // Create a row per server
            var row = [site.name, total_time, site.color];
            rows.push(row);
        });
        var data = google.visualization.arrayToDataTable(rows);
        // Redraw the same chart with new data
        chart.draw(data, options);
        setTimeout(drawVisualization, 20000);

    });

    // Create a one-time listener when the chart is ready, add the line and
    // then turn off the listener (we only need to add the line once.
    var runOnce = google.visualization.events.addListener(chart,
                                                          'ready', function() {
                                                              addLine();
                                                              google.visualization.events.removeListener(runOnce);
                                                          });

};

<|endoftext|>


<commit_before><commit_msg>create new bundle<commit_after><|endoftext|>


<commit_before>describe('ceb-feature-template', function () {
    'use strict';

    var sandbox = document.createElement('div'),
        counter = 0,
        tagName, ce, clonedCe,
        tpl,
        div,
        timeout = 10;

    beforeEach(function (done) {
        div = document.body.appendChild(sandbox).appendChild(document.createElement('div'));
        tagName = 'tag-ceb-feature-template-' + (counter++);
        tpl = [
            '<button class="child" ceb-ref="button"></button>',
            '

',
            ''
        ].join('');
        setTimeout(done, timeout);
    });

    describe('A created custom element having a simple template', function () {
        beforeEach(function (done) {
            ceb().name(tagName).feature(cebFeatureTemplate, {
                template: tpl
            }).register();
            div.innerHTML = '<' + tagName + '></' + tagName + '>';
            ce = div.querySelector(tagName);
            setTimeout(done, timeout);
        });
        it('should contains the templated nodes', function () {
            expect(ce.querySelector('button.child')).to.exist();
            expect(ce.querySelector('div.child.content')).to.exist();
            expect(ce.querySelector('footer.child')).to.exist();
        });
        it('should contains the initial light DOM', function () {
            expect(ce.querySelector('div.child.content > span.lightDOM')).to.exist();
        });
        it('should have the linked nodes', function () {
            expect(cebFeatureTemplate(ce).button).to.exist();
            expect(cebFeatureTemplate(ce).footer).to.exist();
        });
        describe('when the custom element is deeply cloned', function () {
            beforeEach(function (done) {
                clonedCe = ce.cloneNode(true);
                div.appendChild(clonedCe);
                setTimeout(done, timeout);
            });
            it('should contains the templated nodes', function () {
                expect(clonedCe.querySelector('button.child')).to.exist();
                expect(clonedCe.querySelector('div.child.content')).to.exist();
                expect(clonedCe.querySelector('footer.child')).to.exist();
            });
            it('should contains the initial light DOM', function () {
                expect(clonedCe.querySelector('div.child.content > span.lightDOM')).to.exist();
                expect(clonedCe.querySelector('div.child.content > span.lightDOM').children.length).to.be.eq(0);
            });
        });
    });

    describe('A created custom element having a complex template', function () {
        beforeEach(function (done) {
            ceb().name(tagName).feature(cebFeatureTemplate, {
                template: tpl
            }).register();
            div.innerHTML = '<' + tagName + '><' + tagName + ' class="lightDOM"></' + tagName + '></' + tagName + '>';
            ce = div.querySelector(tagName);
            setTimeout(done, timeout);
        });
        it('should contains the templated nodes', function () {
            expect(ce.querySelector('button.child')).to.exist();
            expect(ce.querySelector('div.child.content')).to.exist();
            expect(ce.querySelector('footer.child')).to.exist();
        });
        it('should contains the initial light DOM', function () {
            expect(ce.querySelector('div.child.content ' + tagName + '.lightDOM div.child.content span.lightDOM'), 'ce').to.exist();
        });
        it('should have the linked nodes', function () {
            expect(cebFeatureTemplate(ce).button).to.exist();
            expect(cebFeatureTemplate(ce).footer).to.exist();
        });
        describe('when the custom element is deeply cloned', function () {
            beforeEach(function (done) {
                clonedCe = ce.cloneNode(true);
                div.appendChild(clonedCe);
                setTimeout(function () {
                    setTimeout(done, timeout);
                }, timeout);
            });
            it('should contains the templated nodes', function () {
                expect(clonedCe.querySelector('button.child')).to.exist();
                expect(clonedCe.querySelector('div.child.content')).to.exist();
                expect(clonedCe.querySelector('footer.child')).to.exist();
            });
            it('should contains the initial light DOM', function () {
                expect(clonedCe.querySelector('div.child.content ' + tagName + '.lightDOM div.child.content span.lightDOM'), 'clonedCe').to.exist();
            });
        });
    });

    describe('A created custom element having an empty template', function () {
        beforeEach(function (done) {
            ceb().name(tagName).feature(cebFeatureTemplate).register();
            div.innerHTML = '<' + tagName + '></' + tagName + '>';
            ce = div.querySelector(tagName);
            setTimeout(done, timeout);
        });
        it('should contains light DOM', function () {
            expect(ce.querySelector('span.lightDOM')).to.not.exist();
        });
    });

});<commit_msg>increse timeout for ie10<commit_after>describe('ceb-feature-template', function () {
    'use strict';

    var sandbox = document.createElement('div'),
        counter = 0,
        tagName, ce, clonedCe,
        tpl,
        div,
        timeout = 50;

    beforeEach(function (done) {
        div = document.body.appendChild(sandbox).appendChild(document.createElement('div'));
        tagName = 'tag-ceb-feature-template-' + (counter++);
        tpl = [
            '<button class="child" ceb-ref="button"></button>',
            '

',
            ''
        ].join('');
        setTimeout(done, timeout);
    });

    describe('A created custom element having a simple template', function () {
        beforeEach(function (done) {
            ceb().name(tagName).feature(cebFeatureTemplate, {
                template: tpl
            }).register();
            div.innerHTML = '<' + tagName + '></' + tagName + '>';
            ce = div.querySelector(tagName);
            setTimeout(done, timeout);
        });
        it('should contains the templated nodes', function () {
            expect(ce.querySelector('button.child')).to.exist();
            expect(ce.querySelector('div.child.content')).to.exist();
            expect(ce.querySelector('footer.child')).to.exist();
        });
        it('should contains the initial light DOM', function () {
            expect(ce.querySelector('div.child.content > span.lightDOM')).to.exist();
        });
        it('should have the linked nodes', function () {
            expect(cebFeatureTemplate(ce).button).to.exist();
            expect(cebFeatureTemplate(ce).footer).to.exist();
        });
        describe('when the custom element is deeply cloned', function () {
            beforeEach(function (done) {
                clonedCe = ce.cloneNode(true);
                div.appendChild(clonedCe);
                setTimeout(done, timeout);
            });
            it('should contains the templated nodes', function () {
                expect(clonedCe.querySelector('button.child')).to.exist();
                expect(clonedCe.querySelector('div.child.content')).to.exist();
                expect(clonedCe.querySelector('footer.child')).to.exist();
            });
            it('should contains the initial light DOM', function () {
                expect(clonedCe.querySelector('div.child.content > span.lightDOM')).to.exist();
                expect(clonedCe.querySelector('div.child.content > span.lightDOM').children.length).to.be.eq(0);
            });
        });
    });

    describe('A created custom element having a complex template', function () {
        beforeEach(function (done) {
            ceb().name(tagName).feature(cebFeatureTemplate, {
                template: tpl
            }).register();
            div.innerHTML = '<' + tagName + '><' + tagName + ' class="lightDOM"></' + tagName + '></' + tagName + '>';
            ce = div.querySelector(tagName);
            setTimeout(done, timeout);
        });
        it('should contains the templated nodes', function () {
            expect(ce.querySelector('button.child')).to.exist();
            expect(ce.querySelector('div.child.content')).to.exist();
            expect(ce.querySelector('footer.child')).to.exist();
        });
        it('should contains the initial light DOM', function () {
            expect(ce.querySelector('div.child.content ' + tagName + '.lightDOM div.child.content span.lightDOM'), 'ce').to.exist();
        });
        it('should have the linked nodes', function () {
            expect(cebFeatureTemplate(ce).button).to.exist();
            expect(cebFeatureTemplate(ce).footer).to.exist();
        });
        describe('when the custom element is deeply cloned', function () {
            beforeEach(function (done) {
                clonedCe = ce.cloneNode(true);
                div.appendChild(clonedCe);
                setTimeout(function () {
                    setTimeout(done, timeout);
                }, timeout);
            });
            it('should contains the templated nodes', function () {
                expect(clonedCe.querySelector('button.child')).to.exist();
                expect(clonedCe.querySelector('div.child.content')).to.exist();
                expect(clonedCe.querySelector('footer.child')).to.exist();
            });
            it('should contains the initial light DOM', function () {
                expect(clonedCe.querySelector('div.child.content ' + tagName + '.lightDOM div.child.content span.lightDOM'), 'clonedCe').to.exist();
            });
        });
    });

    describe('A created custom element having an empty template', function () {
        beforeEach(function (done) {
            ceb().name(tagName).feature(cebFeatureTemplate).register();
            div.innerHTML = '<' + tagName + '></' + tagName + '>';
            ce = div.querySelector(tagName);
            setTimeout(done, timeout);
        });
        it('should contains light DOM', function () {
            expect(ce.querySelector('span.lightDOM')).to.not.exist();
        });
    });

});
<|endoftext|>


<commit_before>const Logger = require('../functions/logger');

module.exports = {
	commands: [
		'lmgtfy',
    'lmg'
	],
	usage: 'lmgtfy <content>',
	description: 'Learning to use google',
	category: 'Fun',
	execute: (bot, msg, args) => {
		Logger.cmd("Lmgtfy");
    if (!args[0]) {
        return message.edit('You must provide something to search for!')
    } else {
    message.edit(`Heres how you google this! http://www.lmgtfy.com/?q=${args.join('+')}`);
    }
	}
};
<commit_msg>idiotic move<commit_after>const Logger = require('../functions/logger');

module.exports = {
	commands: [
		'lmgtfy',
    'lmg'
	],
	usage: 'lmgtfy <content>',
	description: 'Learning to use google',
	category: 'Fun',
	execute: (bot, msg, args) => {
		Logger.cmd("Lmgtfy");
    if (!args[0]) {
        return msg.edit('You must provide something to search for!')
    } else {
    msg.edit(`Heres how you google this! http://www.lmgtfy.com/?q=${args.join('+')}`);
    }
	}
};
<|endoftext|>


<commit_before>require([
	'goo/renderer/Material',
	'goo/renderer/Camera',
	'goo/shapes/Box',
	'goo/shapes/Sphere',
	'goo/shapes/Quad',
	'goo/renderer/TextureCreator',
	'goo/renderer/shaders/ShaderLib',
	'goo/entities/World',
	'goo/scripts/OrbitCamControlScript',
	'goo/math/Vector3',
	'goo/addons/ammo/AmmoSystem',
	'goo/addons/ammo/AmmoComponent',
	'goo/renderer/light/PointLight',
	'VehicleHelper',
	'../../lib/V'
], function (
	Material,
	Camera,
	Box,
	Sphere,
	Quad,
	TextureCreator,
	ShaderLib,
	World,
	OrbitCamControlScript,
	Vector3,
	AmmoSystem,
	AmmoComponent,
	PointLight,
	VehicleHelper,
	V
) {
	'use strict';

	var ammoSystem;
	function init() {
		ammoSystem = new AmmoSystem();
		goo.world.setSystem(ammoSystem);

		function addPrimitives() {
			for (var i=0;i<20;i++) {
				var x = V.rng.nextFloat() * 16 - 8, y = V.rng.nextFloat() * 16 + 8, z = V.rng.nextFloat() * 16 - 8;
				if (V.rng.nextFloat() < 0.5) {
					createEntity(goo, new Box(1+V.rng.nextFloat()*2, 1+V.rng.nextFloat()*2, 1+V.rng.nextFloat()*2), {mass:1}, [x,y,z]);
				} else {
					createEntity(goo, new Sphere(10, 10, 1+V.rng.nextFloat()), {mass:1}, [x,y,z]);
				}
			}
		}
		addPrimitives();

		// some walls
		createEntity(goo, new Box(20, 10, 1), {mass: 0}, [0,-10,20]).transformComponent.transform.setRotationXYZ(-Math.PI/3, 0, 0);
		createEntity(goo, new Box(20, 10, 1), {mass: 0}, [0,-5,-10]);

		// the floor
		var planeEntity = createEntity(goo, new Quad(1000, 1000, 100, 100), {mass: 0}, [0,-10,0]);
		planeEntity.transformComponent.transform.setRotationXYZ(-Math.PI/2, 0, 0);

		var keys = new Array(127).join('0').split('').map(parseFloat); // prefill with 0s
		function keyHandler(e) {
			keys[e.keyCode] = e.type === "keydown" ? 1 : 0;
			if( keys[32]) {
				addPrimitives();
			}
			if( keys[82]) { // r
				vehicleHelper.resetAtPos(0, 4, 0);
			}
		}
		document.body.addEventListener('keyup', keyHandler, false);
		document.body.addEventListener('keydown', keyHandler, false);

		goo.world.createEntity(new PointLight(), [0, 100, -10]).addToWorld();

		var camScript = new OrbitCamControlScript({
			domElement: goo.renderer.domElement,
			spherical: new Vector3(40, 0, Math.PI/4)
		});
		goo.world.createEntity(new Camera(45, 1, 0.1, 1000), camScript).addToWorld();

		/* shift center of gravity, felt kinda useless to me
			var box = createEntity(goo, new Box(2, 2, 4), undefined, [0, 0.6, 0]);
			var compound = goo.world.createEntity([0,7,0]);
			compound.transformComponent.attachChild(box.transformComponent);
			compound.setComponent(new AmmoComponent({mass:150}));
			compound.addToWorld();
			goo.world.process();
			var chassis = compound;
		*/

		var chassis = createEntity(goo, new Box(2, 1, 4), {mass: 150, showBounds:true, useWorldBounds:true}, [13, 2, 10]);
		var vehicleHelper = new VehicleHelper( goo, ammoSystem, chassis, 0.5, 0.3, true);
		vehicleHelper.setWheelAxle( -1, 0, 0);
		vehicleHelper.addFrontWheel( [ -1, 0.0,  1.0] );
		vehicleHelper.addFrontWheel( [  1, 0.0,  1.0]);
		vehicleHelper.addRearWheel(  [ -1, 0.0, -1.0]);
		vehicleHelper.addRearWheel(  [  1, 0.0, -1.0]);

		goo.callbacksPreProcess.push(function() {
			vehicleHelper.setSteeringValue( keys[37] * 0.3 + keys[39] * -0.3);
			vehicleHelper.applyEngineForce( keys[38] * 1500 + keys[40] * -500, true);
			vehicleHelper.updateWheelTransform();

			camScript.lookAtPoint.set( chassis.transformComponent.transform.translation);
			camScript.dirty = true;
		});
	}

	var texture = new TextureCreator().loadTexture2D('../../resources/goo.png');
	var material = new Material(ShaderLib.texturedLit);
	material.setTexture('DIFFUSE_MAP', texture);
	function createEntity(goo, meshData, ammoSettings, pos) {
		var entity = goo.world.createEntity(meshData, material, pos);
		if (ammoSettings !== undefined) {
			entity.setComponent(new AmmoComponent(ammoSettings));
		}
		entity.addToWorld();
		return entity;
	}

	var goo = V.initGoo();
	var world = goo.world;

	init();
});
<commit_msg>Added better camera script<commit_after>require([
	'goo/renderer/Material',
	'goo/renderer/Camera',
	'goo/shapes/Box',
	'goo/shapes/Sphere',
	'goo/shapes/Quad',
	'goo/renderer/TextureCreator',
	'goo/renderer/shaders/ShaderLib',
	'goo/entities/World',
	'goo/scripts/OrbitCamControlScript',
	'goo/math/Vector3',
	'goo/addons/ammo/AmmoSystem',
	'goo/addons/ammo/AmmoComponent',
	'goo/renderer/light/PointLight',
	'VehicleHelper',
	'../../lib/V'
], function (
	Material,
	Camera,
	Box,
	Sphere,
	Quad,
	TextureCreator,
	ShaderLib,
	World,
	OrbitCamControlScript,
	Vector3,
	AmmoSystem,
	AmmoComponent,
	PointLight,
	VehicleHelper,
	V
) {
	'use strict';

	var ammoSystem;
	function init() {
		ammoSystem = new AmmoSystem();
		goo.world.setSystem(ammoSystem);

		function addPrimitives() {
			for (var i=0;i<20;i++) {
				var x = V.rng.nextFloat() * 16 - 8, y = V.rng.nextFloat() * 16 + 8, z = V.rng.nextFloat() * 16 - 8;
				if (V.rng.nextFloat() < 0.5) {
					createEntity(goo, new Box(1+V.rng.nextFloat()*2, 1+V.rng.nextFloat()*2, 1+V.rng.nextFloat()*2), {mass:1}, [x,y,z]);
				} else {
					createEntity(goo, new Sphere(10, 10, 1+V.rng.nextFloat()), {mass:1}, [x,y,z]);
				}
			}
		}
		addPrimitives();

		// some walls
		createEntity(goo, new Box(20, 10, 1), {mass: 0}, [0,-10,20]).transformComponent.transform.setRotationXYZ(-Math.PI/3, 0, 0);
		createEntity(goo, new Box(20, 10, 1), {mass: 0}, [0,-5,-10]);

		// the floor
		var planeEntity = createEntity(goo, new Quad(1000, 1000, 100, 100), {mass: 0}, [0,-10,0]);
		planeEntity.transformComponent.transform.setRotationXYZ(-Math.PI/2, 0, 0);

		var keys = new Array(127).join('0').split('').map(parseFloat); // prefill with 0s
		function keyHandler(e) {
			keys[e.keyCode] = e.type === "keydown" ? 1 : 0;
			if( keys[32]) {
				addPrimitives();
			}
			if( keys[82]) { // r
				vehicleHelper.resetAtPos(0, 4, 0);
			}
		}
		document.body.addEventListener('keyup', keyHandler, false);
		document.body.addEventListener('keydown', keyHandler, false);

		goo.world.createEntity(new PointLight(), [0, 100, -10]).addToWorld();

		/* shift center of gravity, felt kinda useless to me
			var box = createEntity(goo, new Box(2, 2, 4), undefined, [0, 0.6, 0]);
			var compound = goo.world.createEntity([0,7,0]);
			compound.transformComponent.attachChild(box.transformComponent);
			compound.setComponent(new AmmoComponent({mass:150}));
			compound.addToWorld();
			goo.world.process();
			var chassis = compound;
		*/

		var chassis = createEntity(goo, new Box(2, 1, 4), {mass: 150, showBounds:true, useWorldBounds:true}, [13, 2, 10]);
		var vehicleHelper = new VehicleHelper( goo, ammoSystem, chassis, 0.5, 0.3, true);
		vehicleHelper.setWheelAxle( -1, 0, 0);
		vehicleHelper.addFrontWheel( [ -1, 0.0,  1.0] );
		vehicleHelper.addFrontWheel( [  1, 0.0,  1.0]);
		vehicleHelper.addRearWheel(  [ -1, 0.0, -1.0]);
		vehicleHelper.addRearWheel(  [  1, 0.0, -1.0]);

		goo.callbacksPreProcess.push(function() {
			vehicleHelper.setSteeringValue( keys[37] * 0.3 + keys[39] * -0.3);
			vehicleHelper.applyEngineForce( keys[38] * 1500 + keys[40] * -500, true);
			vehicleHelper.updateWheelTransform();
		});

		var aboveCar = new Vector3();
		var behindCar = new Vector3();
		var camScriptObject = {};
		camScriptObject.run = function(entity) {
			var transform = chassis.transformComponent.transform;
			var pos = transform.translation;
			behindCar.setd(0,0,-16);
			transform.rotation.applyPost(behindCar);
			behindCar.addv(pos).add_d(0,15,0);
			entity.transformComponent.transform.translation.lerp(behindCar,0.05);
			entity.lookAt(aboveCar.setv(pos).add_d(0,1,0),Vector3.UNIT_Y);
		};

		goo.world.createEntity(new Camera(45, 1, 0.1, 1000), camScriptObject).addToWorld();
	}

	var texture = new TextureCreator().loadTexture2D('../../resources/goo.png');
	var material = new Material(ShaderLib.texturedLit);
	material.setTexture('DIFFUSE_MAP', texture);
	function createEntity(goo, meshData, ammoSettings, pos) {
		var entity = goo.world.createEntity(meshData, material, pos);
		if (ammoSettings !== undefined) {
			entity.setComponent(new AmmoComponent(ammoSettings));
		}
		entity.addToWorld();
		return entity;
	}

	var goo = V.initGoo();

	init();
});
<|endoftext|>


<commit_before>'use strict';
/* jshint node:true */
/* global module, process, console, require */

var Command     = require('ronin').Command,
    spinner     = require('simple-spinner'),
    argv        = require('minimist')(process.argv.slice(2)),
    inspect     = require('util').inspect,
    stream      = require('stream'),
    JSONStream  = require('JSONStream'),
    eventstream = require('event-stream'),
    stringify   = require('../lib/helpers').safeJsonStringify,
    out         = require('../lib/helpers').out,
    conf        = require('../lib/config'),
    api         = require('../lib/logsene-api');

//var $this = this;
spinner.change_sequence(["◓", "◑", "◒", "◐"]);

var Search = Command.extend({ use: ['auth'],
  desc: 'Search Logsene logs',

  run: function () {
    inspect(argv); // TODO clean

    // Object.keys(argv).length < 2
    if (argv._.length < 2) {
      console.warn(out.warn('Too few parameters!\n\n'));
      console.log(this.help());
      process.exit(1); // bail out
    } else if (argv._.length === 2) {
      // if no -q use first command after search as q
      // so we can do 'logsene search <query>'
      argv.q = argv._[1];
    }

    //spinner.start();  // TODO replace with isaacs spinner, which doesn't leave anything behind
    api.search({
      q:      argv.q,
      appKey: conf.getSync('appKey'),
      apiKey: conf.getSync('apiKey'),
      size:   argv.size || 200,
      offset: argv.offset || 0
    }, function(err, esReadable) {
      //spinner.stop();
      if(err) {
        console.error(out.error('Search error: ' + err.message));
        process.exit(1); // bail out
      }

      // TODO return final counter
      //console.log(out.info(hits.hits.length + ' results:'));

      // TODO pass back readable stream and handle the rest from here
      /*esReadable
          .pipe(JSONStream.parse('_source.*'))
          .pipe(eventstream.mapSync(function(data) {
            //out.info(data);
            return data._source || data;
          })).pipe(process.stdout);*/

      //console.log(stringify(hits));
      //esReadable.on('close', function() {process.exit(0);})
    });

  },

  help: function () {
    return 'Usage: logsene ' + this.name + ' query [OPTIONS]\n' +
    '  where OPTIONS may be:\n' +
    '    --q <search-query>       (Optional, but then query must come immediately after keyword ' + this.name + ')\n' +
    '    --size <return-size>     (Number of matches to return. Defaults to 20)\n' +
    '    --offset <return-offset> (Number of matches to skip. Defaults to 0)\n' +
    '\n' +
    '  Examples:\n' +
    '  logsene search --q ERROR --s 50\n' +
    '  returns at most 50 matches of term ERROR\n' +
    '\n' +
    '  logsene search ERROR --s 50\n' +
    '  equivalent to first example\n' +
    '\n' +
    '  logsene search ERROR --s 50 --offset 20\n' +
    '  returns hits from 21th to 71th (useful for paging)\n' +
    '  \n' +
    '--------\n';
  }
});

module.exports = Search;
<commit_msg>Transform stream to return only the _source subkey (like Logsene web app)<commit_after>'use strict';
/* jshint node:true */
/* global module, process, console, require */

// not ideal place, but circular dependency otherwise
require('../lib/bootstrap');  // throw away, just bootstrap

var Command         = require('ronin').Command,
    //spinner         = require('simple-spinner'),
    inspect         = require('util').inspect,
    JSONStream      = require('JSONStream'),
    Transform       = require('stream').Transform,
    eos             = require('end-of-stream'),
    argv            = require('../lib/helpers').argv,
    out             = require('../lib/helpers').out,
    isDef           = require('../lib/helpers').isDef,
    isStrOrBoolTrue = require('../lib/helpers').isStrOrBoolTrue,
    conf            = require('../lib/config'),
    api             = require('../lib/logsene-api');

//var $this = this;
//spinner.change_sequence(["◓", "◑", "◒", "◐"]);

var Search = Command.extend({ use: ['auth'],
  desc: 'Search Logsene logs',

  run: function _run() {
    inspect(argv); // TODO clean

    if (argv._.length < 2) {
      out.warn('Too few parameters!\n\n');
      out.info(this.help());
      process.exit(1); // bail out
    } else if (argv._.length === 2) {
      // if no -q use first command after search as q
      // so 'logsene search <query>' works as expected
      argv.q = argv._[1];
    }

    //spinner.start();
    api.search({
      q:        argv.q,
      apiKey:   conf.getSync('apiKey'),
      appKey:   conf.getSync('appKey'),
      size:     argv.size || conf.getSync('defaultSize') || conf.maxHits,
      offset:   argv.offset || 0,
      logLevel: argv.trace || isStrOrBoolTrue(conf.getSync('trace')) ? 'trace' : 'error'
  }, function(err, esReadableHits) {
      //spinner.stop();
      if(err) {
        out.error('Search error: ' + err.message);
        process.exit(1); // bail out
      }

      var extractor = new Transform({objectMode: true}),
          hitCnt = 0;

      extractor._transform = function _extractorTransform(data, encoding, next) {
        this.push(isDef(data['_source']) ? data['_source'] : data);
        hitCnt++;
        next();
      };

      eos(esReadableHits, function(err) {
        if (err) {
          out.error('ES stream had an error or closed early.');
          process.exit(1);
        }
        out.info('\nReturned hits: ' + hitCnt + (hitCnt === 200 ? ' (max)' : ''));
        process.exit(0);
      });

      // pipe em up
      esReadableHits
          .pipe(extractor)
          .pipe(JSONStream.stringify(false))
          .pipe(process.stdout);

    });
  },

  help: function _help() {
    return 'Usage: logsene ' + this.name + ' query [OPTIONS]\n' +
    '  where OPTIONS may be:\n' +
    '    --q <search-query>    (Query string)\n' +
    '    --s <return-size>     (Number of matches to return. Defaults to 200)\n' +
    '    --o <return-offset>   (Number of matches to skip. Defaults to 0)\n' +
    '\n' +
    '  Examples:\n' +
    '  logsene search --q ERROR --s 50\n' +
    '      returns at most 50 matches of term ERROR\n' +
    '\n' +
    '  logsene search ERROR --s 50\n' +
    '      equivalent to the previous example\n' +
    '\n' +
    '  logsene search ERROR --s 50 --o 20\n' +
    '      returns hits from 21th to 71th\n' +
    '  \n' +
    '--------\n';
  }
});

module.exports = Search;
<|endoftext|>


<commit_before>var app=angular.module('login',[]);
app.controller('auth',function($scope){

});
var app=angular.module('registration',[]);
app.controller('create',function($scope){
    $scope.validateForm=function(){
        var fullname=$.trim(document.accountform.user_name.value);
        if(fullname!=""){
            var email=$.trim(document.accountform.user_email.value);
            if(email!=""){
                var pass1=document.accountform.user_password.value;
                if(pass1.length>=8){
                    var pass2=document.accountform.user_password2.value;
                    if(pass2===pass1){
                        $(".btn-primary").addClass("disabled");
                        document.accountform.submit();
                    }
                    else{
                        messageBox("Password Mismatch","Please ensure that the password you repeat matches the first password.");
                    }
                }
                else{
                    messageBox("Invalid Password","Please enter a valid password with at least 8 characters.");
                }
            }
            else{
                messageBox("Invalid Email","Please enter a valid email ID.");
            }
        }
        else{
            messageBox("Invalid Name","Please enter a valid full name.");
        }
    };
});
var app=angular.module('applications',[]);
app.controller('apps',function($scope,$http,$compile){
    $scope.applicationArray=[];
    $scope.application_id=null;
    $scope.appCount=0;
    $scope.getApplications=function(){
        $http({
            method: 'GET',
            url: 'getApplications'
        }).then(function success(response){
            response=response.data;
            if(response=="INVALID_USER_ID"){
                window.location='logout';
            }
            else if(response=="NO_APPLICATIONS_FOUND"){
                var p=document.createElement("p");
                $(p).html("No applications found.");
                $("#appHolder").html(p);
            }
            else{
                response=JSON.parse(response);
                $scope.applicationArray=response.slice();
                $scope.displayApplications();
            }
        }, function error(response){
            messageBox("Problem","Something went wrong while loading your list of applications. Please try again later. This is the error we see: "+response);
        });
    };
    $scope.displayApplications=function(){
        var applications=$scope.applicationArray.slice();

    };
    $scope.createApplicationForm=function(){
        var form=document.createElement("form");
        $(form).attr("method","post");
        $(form).attr("action","createApplication");
        $(form).attr("autocomplete","off");
        $(form).attr("name","createapp");
            var appTitleGroup=document.createElement("div");
            $(appTitleGroup).addClass("form-group");
                var appTitleLabel=document.createElement("label");
                $(appTitleLabel).attr("for","apptitle");
                $(appTitleLabel).html("Application title");
                $(appTitleGroup).append(appTitleLabel);
                var appTitle=document.createElement("input");
                $(appTitle).attr("type","text");
                $(appTitle).addClass("form-control");
                $(appTitle).attr("id","apptitle");
                $(appTitle).attr("name","apptitle");
                $(appTitle).attr("placeholder","Enter a valid application name");
                $(appTitle).attr("required","true");
                $(appTitleGroup).append(appTitle);
            $(form).append(appTitleGroup);
            var appDescGroup=document.createElement("div");
            $(appDescGroup).addClass("form-group");
                var appDescLabel=document.createElement("label");
                $(appDescLabel).attr("for","appdesc");
                $(appDescLabel).html("Application description");
                $(appDescGroup).append(appDescLabel);
                var appDescTA=document.createElement("textarea");
                $(appDescTA).addClass("form-control");
                $(appDescTA).attr("rows","5");
                $(appDescTA).attr("id","appdesc");
                $(appDescTA).attr("name","appdesc");
                $(appDescTA).attr("placeholder","Enter some description of this application.");
                $(appDescGroup).append(appDescTA);
            $(form).append(appDescGroup);
        messageBox("Create Application",form);
        $compile("#myModal")($scope);
    };
});<commit_msg>Application creation<commit_after>var app=angular.module('login',[]);
app.controller('auth',function($scope){

});
var app=angular.module('registration',[]);
app.controller('create',function($scope){
    $scope.validateForm=function(){
        var fullname=$.trim(document.accountform.user_name.value);
        if(fullname!=""){
            var email=$.trim(document.accountform.user_email.value);
            if(email!=""){
                var pass1=document.accountform.user_password.value;
                if(pass1.length>=8){
                    var pass2=document.accountform.user_password2.value;
                    if(pass2===pass1){
                        $(".btn-primary").addClass("disabled");
                        document.accountform.submit();
                    }
                    else{
                        messageBox("Password Mismatch","Please ensure that the password you repeat matches the first password.");
                    }
                }
                else{
                    messageBox("Invalid Password","Please enter a valid password with at least 8 characters.");
                }
            }
            else{
                messageBox("Invalid Email","Please enter a valid email ID.");
            }
        }
        else{
            messageBox("Invalid Name","Please enter a valid full name.");
        }
    };
});
var app=angular.module('applications',[]);
app.controller('apps',function($scope,$http,$compile){
    $scope.applicationArray=[];
    $scope.application_id=null;
    $scope.appCount=0;
    $scope.getApplications=function(){
        $http({
            method: 'GET',
            url: 'getApplications'
        }).then(function success(response){
            response=response.data;
            if(response=="INVALID_USER_ID"){
                window.location='logout';
            }
            else if(response=="NO_APPLICATIONS_FOUND"){
                var p=document.createElement("p");
                $(p).html("No applications found.");
                $("#appHolder").html(p);
            }
            else{
                console.log(response);
                response=JSON.parse(response);
                $scope.applicationArray=response.slice();
                $scope.displayApplications();
            }
        }, function error(response){
            messageBox("Problem","Something went wrong while loading your list of applications. Please try again later. This is the error we see: "+response);
        });
    };
    $scope.displayApplications=function(){
        var applications=$scope.applicationArray.slice();

    };
    $scope.createApplicationForm=function(){
        var form=document.createElement("form");
        $(form).attr("method","post");
        $(form).attr("action","createApplication");
        $(form).attr("autocomplete","off");
        $(form).attr("name","createapp");
            var appTitleGroup=document.createElement("div");
            $(appTitleGroup).addClass("form-group");
                var appTitleLabel=document.createElement("label");
                $(appTitleLabel).attr("for","apptitle");
                $(appTitleLabel).html("Application title");
                $(appTitleGroup).append(appTitleLabel);
                var appTitle=document.createElement("input");
                $(appTitle).attr("type","text");
                $(appTitle).addClass("form-control");
                $(appTitle).attr("id","apptitle");
                $(appTitle).attr("name","apptitle");
                $(appTitle).attr("placeholder","Enter a valid application name");
                $(appTitle).attr("required","true");
                $(appTitleGroup).append(appTitle);
            $(form).append(appTitleGroup);
            var appDescGroup=document.createElement("div");
            $(appDescGroup).addClass("form-group");
                var appDescLabel=document.createElement("label");
                $(appDescLabel).attr("for","appdesc");
                $(appDescLabel).html("Application description");
                $(appDescGroup).append(appDescLabel);
                var appDescTA=document.createElement("textarea");
                $(appDescTA).addClass("form-control");
                $(appDescTA).attr("rows","5");
                $(appDescTA).attr("id","appdesc");
                $(appDescTA).attr("name","appdesc");
                $(appDescTA).attr("placeholder","Enter some description of this application.");
                $(appDescGroup).append(appDescTA);
            $(form).append(appDescGroup);
        messageBox("Create Application",form);
        $compile("#myModal")($scope);
    };
});<|endoftext|>


<commit_before>var getRandomInt = function(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
};

var getStepSize = function() {
    return (90*ponies.length*50)/(raceLength*1000);
};

var runPonies = function() {
    if (running) {
        // Figure out which (if any) ponies haven't finished
        var notFinished = [];
        for (var i = 0; i < ponies.length; i++) {
            if (ponies[i].progress < 90) {
                notFinished.push(i);
            }
        }

        // See if any of the ponies still need to finish
        if (notFinished.length > 0) {
            // Move a random (still running) pony forward and record if they
            // made it to the end
            var tmp = getRandomInt(0,notFinished.length-1);
            ponies[notFinished[tmp]].progress += getStepSize();
            if (ponies[notFinished[tmp]].progress >= 90)
            {
                ponies[notFinished[tmp]].finishPos = nextPlace++;
            }

            // Actually move the pony
            d3.selectAll('.pony').data(ponies)
                .transition().ease('linear').duration(50)
                .attr('transform',function(d,i) { return 'translate('+x(d.progress)+',0)';})
            setTimeout(runPonies,50);
        } else {
            d3.select('#winner-list').selectAll('.rank-entry')
               .data(ponies,function(d) { return d.finishPos; })
              .enter()
                .append('p')
                .classed('rank-entry',true)
                .text(function(d,i) { return d.finishPos + ': ' + d.jockey;}) ;

           d3.selectAll('.rank-entry').sort(function(a,b) { return a.finishPos < b.finishPos ? -1 : 1; }).order();

           d3.select('#winner-list').style('display','block');

            d3.selectAll('#controls button').filter(function(d,i) { return i == 0;}).text('Done');
            done = true;
            running = false;
        }
    }
};

var clearWinners = function() {
    d3.selectAll('.rank-entry').remove();
    d3.select('#winner-list').style('display','none');
};

var addEntrant = function() {
    var name = $('#name').val(),
        num = $('#num').val(),
        col = $('#color1').val();

    if (name.length > 0 && !isNaN(+num)) {
        // Check to see if a jockey name exists, if so, don't allow it
        // to be reused
        var previouslyUsed = false;
        for (var i=0; i < jockeys.length; i++) {
            previouslyUsed = name == jockeys[i].name ? true : false;
        }
        if (previouslyUsed) {
            window.alert('Sorry, you can not reuse a Jockey')
        } else {

            // Add the individual ponies and the jockey to the list
            for (var i = 0; i < +num; i++) {
                ponies.push({progress:0,
                        jockey:name,
                        col:col,
                        finishPos:0});
            }

            // Add the jockey to the jockies list
            jockeys.push({name:name,num:num,col:col});

            updateJockeyLineup();
            updatePonyLineup();
        }
    } else {
        window.alert('Please enter a unique jockey name and # of ponies for that jockey!')
    }
};

var removeEntrant = function(i) {
    // Figure out which indexes we need to remove
    var toRemove = [];
    for (var j = 0; j < ponies.length; j++) {
        if (ponies[j].jockey == jockeys[i].name) {
            toRemove.push(j);
        }
    }

    // Remove them in reverse order so we don't have
    // to do anything fancy with indexes
    for (var j = toRemove.length-1; j > -1; j--) {
        ponies.splice(toRemove[j],1);
    }

    // Remove jockey's rects and move remaining ponies/fix y-scale
    updatePonyLineup();

    // Remove jockeys name from displayed list list
    jockeys.splice(i,1);
    updateJockeyLineup();
};

var resetPonies = function() {
    // Send the ponies back to the beginning
    for (var i = 0; i < ponies.length; i++) {
        ponies[i].progress = 0;
    }

    done = false;
    running = false;
    nextPlace = 1;

    d3.selectAll('.pony').data(ponies)
        .transition().ease('linear').duration(250)
        .attr('transform',function(d,i) { return 'translate('+x(d.progress)+',0)';})

    d3.selectAll('#controls button').filter(function(d,i) { return i ==
            0;}).text('Go!');

    d3.selectAll('.rank-entry').remove();
};

var updateJockeyLineup = function() {
    var jockeyList = d3.select('#jockey-list').selectAll('.jockey')
            .data(jockeys)
        .text(function(d) { return d.name + ' (' + d.num + ')'; })
        .style('color',function(d) { return d.col; })

    jockeyList.enter()
            .append('p')
            .text(function(d) { return d.name + ' (' + d.num + ')'; })
            .classed('jockey',true)
            .style('color',function(d) { return d.col; })
        .on('click',function(d,i) { removeEntrant(i); });

    jockeyList.exit().remove();
};

var updatePonyLineup = function() {
    // Make sure y domain is correct
    y.domain([0,ponies.length]);

    var ponyGroup = d3.select('#data-region').selectAll('.pony-group')
            .data(ponies);

    // Update position for old ponies
    ponyGroup.transition().duration(100)
            .attr('transform',function(d,i) { return 'translate(0,'+y(i)+')';});

    // Add new group for new ponies
    var newPonyGroup = ponyGroup.enter()
        .append('svg:g')
        .attr('transform',function(d,i) { return 'translate(0,'+y(i)+')';})
        .classed('pony-group',true);

    // Update positions for existing lanes
    ponyGroup.select('.pony-lane')
        .transition().duration(100)
            .attr('y',y(.5-.025))
            .style('fill',function(d) { return d.col;})
            .attr('height',y(.050)-y(0));

    // Add new lanes
    newPonyGroup.append('svg:rect')
            .attr('height',y(.05)-y(0))
            .attr('x',x(10))
            .attr('width',x(90)-x(0))
            .attr('y',y(.5-.025))
            .style('stroke','none')
            .classed('pony-lane',true)
            .style('fill',function(d) { return d.col;});

    // Update positions for existing ponies
    ponyGroup.select('.pony').select('.race-pony')
        .transition().duration(100)
            .style('fill',function(d) { return d.col;})
            .attr('y',y(.25))
            .attr('height',y(.50)-y(0));

    // Add new pony groups
    var racePonies = newPonyGroup.append('svg:g')
            .classed('pony',true);

    racePonies.append('svg:rect')
            .attr('y',y(.25))
            .style('stroke','none')
            .attr('height',y(.5)-y(0))
            .attr('width',x(10)-x(0))
            .style('stroke','none')
            .classed('race-pony',true)
            .style('fill',function(d) { return d.col;});

    //racePonies.append('svg:text')
    //    .text(function(d) { console.log(d); return d.jockey[0]; })
    //    .attr('x',0)
    //    .attr('y',0);

    ponyGroup.exit().remove();
};

<commit_msg>Delay opening of winner popup<commit_after>var getRandomInt = function(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
};

var getStepSize = function() {
    return (90*ponies.length*50)/(raceLength*1000);
};

var runPonies = function() {
    if (running) {
        // Figure out which (if any) ponies haven't finished
        var notFinished = [];
        for (var i = 0; i < ponies.length; i++) {
            if (ponies[i].progress < 90) {
                notFinished.push(i);
            }
        }

        // See if any of the ponies still need to finish
        if (notFinished.length > 0) {
            // Move a random (still running) pony forward and record if they
            // made it to the end
            var tmp = getRandomInt(0,notFinished.length-1);
            ponies[notFinished[tmp]].progress += getStepSize();
            if (ponies[notFinished[tmp]].progress >= 90)
            {
                ponies[notFinished[tmp]].finishPos = nextPlace++;
            }

            // Actually move the pony
            d3.selectAll('.pony').data(ponies)
                .transition().ease('linear').duration(50)
                .attr('transform',function(d,i) { return 'translate('+x(d.progress)+',0)';})
            setTimeout(runPonies,50);
        } else {
            d3.select('#winner-list').selectAll('.rank-entry')
               .data(ponies,function(d) { return d.finishPos; })
              .enter()
                .append('p')
                .classed('rank-entry',true)
                .text(function(d,i) { return d.finishPos + ': ' + d.jockey;}) ;

           d3.selectAll('.rank-entry').sort(function(a,b) { return a.finishPos < b.finishPos ? -1 : 1; }).order();

           setTimeout(function() { d3.select('#winner-list').style('display','block'); }, 350);

            d3.selectAll('#controls button').filter(function(d,i) { return i == 0;}).text('Done');
            done = true;
            running = false;
        }
    }
};

var clearWinners = function() {
    d3.selectAll('.rank-entry').remove();
    d3.select('#winner-list').style('display','none');
};

var addEntrant = function() {
    var name = $('#name').val(),
        num = $('#num').val(),
        col = $('#color1').val();

    if (name.length > 0 && !isNaN(+num)) {
        // Check to see if a jockey name exists, if so, don't allow it
        // to be reused
        var previouslyUsed = false;
        for (var i=0; i < jockeys.length; i++) {
            previouslyUsed = name == jockeys[i].name ? true : false;
        }
        if (previouslyUsed) {
            window.alert('Sorry, you can not reuse a Jockey')
        } else {

            // Add the individual ponies and the jockey to the list
            for (var i = 0; i < +num; i++) {
                ponies.push({progress:0,
                        jockey:name,
                        col:col,
                        finishPos:0});
            }

            // Add the jockey to the jockies list
            jockeys.push({name:name,num:num,col:col});

            updateJockeyLineup();
            updatePonyLineup();
        }
    } else {
        window.alert('Please enter a unique jockey name and # of ponies for that jockey!')
    }
};

var removeEntrant = function(i) {
    // Figure out which indexes we need to remove
    var toRemove = [];
    for (var j = 0; j < ponies.length; j++) {
        if (ponies[j].jockey == jockeys[i].name) {
            toRemove.push(j);
        }
    }

    // Remove them in reverse order so we don't have
    // to do anything fancy with indexes
    for (var j = toRemove.length-1; j > -1; j--) {
        ponies.splice(toRemove[j],1);
    }

    // Remove jockey's rects and move remaining ponies/fix y-scale
    updatePonyLineup();

    // Remove jockeys name from displayed list list
    jockeys.splice(i,1);
    updateJockeyLineup();
};

var resetPonies = function() {
    // Send the ponies back to the beginning
    for (var i = 0; i < ponies.length; i++) {
        ponies[i].progress = 0;
    }

    done = false;
    running = false;
    nextPlace = 1;

    d3.selectAll('.pony').data(ponies)
        .transition().ease('linear').duration(250)
        .attr('transform',function(d,i) { return 'translate('+x(d.progress)+',0)';})

    d3.selectAll('#controls button').filter(function(d,i) { return i ==
            0;}).text('Go!');

    d3.selectAll('.rank-entry').remove();
};

var updateJockeyLineup = function() {
    var jockeyList = d3.select('#jockey-list').selectAll('.jockey')
            .data(jockeys)
        .text(function(d) { return d.name + ' (' + d.num + ')'; })
        .style('color',function(d) { return d.col; })

    jockeyList.enter()
            .append('p')
            .text(function(d) { return d.name + ' (' + d.num + ')'; })
            .classed('jockey',true)
            .style('color',function(d) { return d.col; })
        .on('click',function(d,i) { removeEntrant(i); });

    jockeyList.exit().remove();
};

var updatePonyLineup = function() {
    // Make sure y domain is correct
    y.domain([0,ponies.length]);

    var ponyGroup = d3.select('#data-region').selectAll('.pony-group')
            .data(ponies);

    // Update position for old ponies
    ponyGroup.transition().duration(100)
            .attr('transform',function(d,i) { return 'translate(0,'+y(i)+')';});

    // Add new group for new ponies
    var newPonyGroup = ponyGroup.enter()
        .append('svg:g')
        .attr('transform',function(d,i) { return 'translate(0,'+y(i)+')';})
        .classed('pony-group',true);

    // Update positions for existing lanes
    ponyGroup.select('.pony-lane')
        .transition().duration(100)
            .attr('y',y(.5-.025))
            .style('fill',function(d) { return d.col;})
            .attr('height',y(.050)-y(0));

    // Add new lanes
    newPonyGroup.append('svg:rect')
            .attr('height',y(.05)-y(0))
            .attr('x',x(10))
            .attr('width',x(90)-x(0))
            .attr('y',y(.5-.025))
            .style('stroke','none')
            .classed('pony-lane',true)
            .style('fill',function(d) { return d.col;});

    // Update positions for existing ponies
    ponyGroup.select('.pony').select('.race-pony')
        .transition().duration(100)
            .style('fill',function(d) { return d.col;})
            .attr('y',y(.25))
            .attr('height',y(.50)-y(0));

    // Add new pony groups
    var racePonies = newPonyGroup.append('svg:g')
            .classed('pony',true);

    racePonies.append('svg:rect')
            .attr('y',y(.25))
            .style('stroke','none')
            .attr('height',y(.5)-y(0))
            .attr('width',x(10)-x(0))
            .style('stroke','none')
            .classed('race-pony',true)
            .style('fill',function(d) { return d.col;});

    //racePonies.append('svg:text')
    //    .text(function(d) { console.log(d); return d.jockey[0]; })
    //    .attr('x',0)
    //    .attr('y',0);

    ponyGroup.exit().remove();
};

<|endoftext|>


<commit_before>const fetch = require('node-fetch');
const Parkingspace = require('./Parkingspace.js');

const baseURL = 'http://opendata.dbbahnpark.info/api/beta';

class ParkingspaceLoader {
  constructor(APIToken) {
    this.APIToken = APIToken;
  }

  get fetchConfiguration() {
    const headers = {};
    const configuration = {
      method: 'GET',
      headers,
    };

    return configuration;
  }

  spaceById(spaceId) {
    const url = `${baseURL}/sites`;
    const configuration = this.fetchConfiguration;

    const promise = fetch(url, configuration)
      .then(res => res.json())
      .then((result) => {
        if (result.count > 0) {
          const filteredResult = result.results.filter(elem => elem.parkraumId == spaceId);

          if (filteredResult.length > 0) {
            return filteredResult[0];
          }
          return null;
        }
      });

    return promise;
  }

  occupancyForId(spaceId) {
    const url = `${baseURL}/occupancy/${spaceId}`;
    const configuration = this.fetchConfiguration;

    const promise = fetch(url, configuration)
      .then(res => res.json())
      .then((result) => {
        const occupancyData = result;

        if (occupancyData.code == 5101) {
          return null;
        }

        return occupancyData.allocation;
      });

    return promise;
  }

  spacesForStationNumber(stationNumber) {
    const url = `${baseURL}/sites`;
    const configuration = this.fetchConfiguration;

    const promise = fetch(url, configuration)
      .then(res => res.json())
      .then((result) => {
        if (result.count > 0) {
          const filteredResult = result.results.filter(elem => elem.parkraumBahnhofNummer == stationNumber);

          if (filteredResult.length > 0) {
            return filteredResult;
          }
          return null;
        }
      });

    return promise;
  }

  nearbyParkingspaces(latitude, longitude, radius) {
    const url = `${baseURL}/sites`;
    const configuration = this.fetchConfiguration;

    const promise = fetch(url, configuration)
      .then(res => res.json())
      .then((result) => {
        if (result.count > 0) {
          // Sort by distance
          // geolib.orderByDistance(object latlng, mixed coords)
          const mapped = result.results.map((elem) => {
            elem.distance = calculateDistance(latitude, longitude, parseFloat(elem.parkraumGeoLatitude), parseFloat(elem.parkraumGeoLongitude));
            return elem;
          });

          // sort by distance
          mapped.sort((elem1, elem2) => elem1.distance - elem2.distance);
          return mapped.filter(elem => elem.distance <= radius/1000);
        }
      });

    return promise;
  }
}

function calculateDistance(lat1, lon1, lat2, lon2) {
  const radlat1 = Math.PI * lat1 / 180;
  const radlat2 = Math.PI * lat2 / 180;
  const radlon1 = Math.PI * lon1 / 180;
  const radlon2 = Math.PI * lon2 / 180;
  const theta = lon1 - lon2;
  const radtheta = Math.PI * theta / 180;
  let dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
  dist = Math.acos(dist);
  dist = dist * 180 / Math.PI;
  dist = dist * 60 * 1.1515;

  // Miles to Kilometers
  dist *= 1.609344;

  return dist;
}

module.exports = ParkingspaceLoader;
<commit_msg>Returns empty Array (not null) if no parkingspaces were found<commit_after>const fetch = require('node-fetch');
const Parkingspace = require('./Parkingspace.js');

const baseURL = 'http://opendata.dbbahnpark.info/api/beta';

class ParkingspaceLoader {
  constructor(APIToken) {
    this.APIToken = APIToken;
  }

  get fetchConfiguration() {
    const headers = {};
    const configuration = {
      method: 'GET',
      headers,
    };

    return configuration;
  }

  spaceById(spaceId) {
    const url = `${baseURL}/sites`;
    const configuration = this.fetchConfiguration;

    const promise = fetch(url, configuration)
      .then(res => res.json())
      .then((result) => {
        if (result.count > 0) {
          const filteredResult = result.results.filter(elem => elem.parkraumId == spaceId);

          if (filteredResult.length > 0) {
            return filteredResult[0];
          }
          return null;
        }
      });

    return promise;
  }

  occupancyForId(spaceId) {
    const url = `${baseURL}/occupancy/${spaceId}`;
    const configuration = this.fetchConfiguration;

    const promise = fetch(url, configuration)
      .then(res => res.json())
      .then((result) => {
        const occupancyData = result;

        if (occupancyData.code == 5101) {
          return null;
        }

        return occupancyData.allocation;
      });

    return promise;
  }

  spacesForStationNumber(stationNumber) {
    const url = `${baseURL}/sites`;
    const configuration = this.fetchConfiguration;

    const promise = fetch(url, configuration)
      .then(res => res.json())
      .then((result) => {
        if (result.count > 0) {
          const filteredResult = result.results.filter(elem => elem.parkraumBahnhofNummer == stationNumber);

          if (filteredResult.length > 0) {
            return filteredResult;
          }
        }
        return [];
      });

    return promise;
  }

  nearbyParkingspaces(latitude, longitude, radius) {
    const url = `${baseURL}/sites`;
    const configuration = this.fetchConfiguration;

    const promise = fetch(url, configuration)
      .then(res => res.json())
      .then((result) => {
        if (result.count > 0) {
          // Sort by distance
          // geolib.orderByDistance(object latlng, mixed coords)
          const mapped = result.results.map((elem) => {
            elem.distance = calculateDistance(latitude, longitude, parseFloat(elem.parkraumGeoLatitude), parseFloat(elem.parkraumGeoLongitude));
            return elem;
          });

          // sort by distance
          mapped.sort((elem1, elem2) => elem1.distance - elem2.distance);
          const filteredResult = mapped.filter(elem => elem.distance <= radius/1000);

          if (filteredResult.length > 0) {
            return filteredResult;
          }
        }
        return [];
      });

    return promise;
  }
}

function calculateDistance(lat1, lon1, lat2, lon2) {
  const radlat1 = Math.PI * lat1 / 180;
  const radlat2 = Math.PI * lat2 / 180;
  const radlon1 = Math.PI * lon1 / 180;
  const radlon2 = Math.PI * lon2 / 180;
  const theta = lon1 - lon2;
  const radtheta = Math.PI * theta / 180;
  let dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
  dist = Math.acos(dist);
  dist = dist * 180 / Math.PI;
  dist = dist * 60 * 1.1515;

  // Miles to Kilometers
  dist *= 1.609344;

  return dist;
}

module.exports = ParkingspaceLoader;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Board from './Board';

// Pixels of a square
const SIZE = 10;

function cell({color, x, y, onClick}) {
  let h;
  if (color === Board.BLACK) {
    h = "#000000";
  } else if (color === Board.WHITE) {
    h = "#FFFFFF";
  } else {
    h = "#777777";
  }
  return
 onClick(x, y)}
              key={'' + x + '-' + y}
              style={{
    left: x * SIZE,
    top: y * SIZE,
    backgroundColor: h,
  }}/>;
}

class BoardView extends Component {
  constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this);
  }

  onClick(x, y) {
    console.log('click on ' + x + ', ' + y);
    this.props.board.makeMove(x, y);

    // Should be a better way to do this
    this.setState({});
  }

  render() {
    let grid = this.props.board.grid;
    let cells = [];
    for (let y = 0; y < grid.length; y++) {
      for (let x = 0; x < grid[y].length; x++) {
        let color = grid[y][x];
        cells.push(cell({color, x, y, onClick: this.onClick}));
      }
    }
    return
{cells}
;
  }
}

export default BoardView;
<commit_msg>fix bug<commit_after>import React, { Component } from 'react';
import Board from './Board';

// Pixels of a square
const SIZE = 10;

function cell({color, x, y, onClick}) {
  let h;
  if (color === Board.BLACK) {
    h = "#000000";
  } else if (color === Board.WHITE) {
    h = "#FFFFFF";
  } else {
    h = "#777777";
  }
  return
 onClick(x, y)}
              key={'' + x + '-' + y}
              style={{
    left: x * SIZE,
    top: y * SIZE,
    backgroundColor: h,
  }}/>;
}

class BoardView extends Component {
  constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this);
  }

  onClick(x, y) {
    console.log('click on ' + x + ', ' + y);
    this.props.board.makeMove(x, y);

    // Should be a better way to do this
    this.setState({});
  }

  render() {
    let grid = this.props.board.board;
    let cells = [];
    for (let y = 0; y < grid.length; y++) {
      for (let x = 0; x < grid[y].length; x++) {
        let color = grid[y][x];
        cells.push(cell({color, x, y, onClick: this.onClick}));
      }
    }
    return
{cells}
;
  }
}

export default BoardView;
<|endoftext|>