<commit_before>import { EventEmitter } from 'events';
import { Server as HttpServer } from 'http';
import get from 'lodash-es/get';
import ip from 'ip';
import { createTransport } from 'nodemailer';
import { markdown } from 'nodemailer-markdown';
import WebSocket, { Server as WsServer } from 'ws';

import {
  Cache,
  HttpConnector,
  Logger,
  PubSub,
  Router,
  WsConnection,
  WsConnector,
  handleError
} from '@scola/api';

import {
  Auth,
  load as loadAuth
} from '@scola/auth-server';

import { ScolaError } from '@scola/error';
import { I18n } from '@scola/i18n';

import Processor from './processor';
import Route from './route';

export default class Server extends EventEmitter {
  constructor() {
    super();

    this._auth = null;
    this._cache = null;
    this._config = {};
    this._database = null;
    this._http = null;
    this._httpServer = null;
    this._i18n = null;
    this._id = null;
    this._logger = null;
    this._processors = [];
    this._pubsub = null;
    this._router = null;
    this._smtp = null;
    this._ws = null;
    this._wsServer = null;

    this._handleError = (e) => this._error(e);
  }

  destroy(code, reason, callback = () => {}) {
    this._unbindHttp();
    this._unbindRouter();
    this._unbindWs();

    if (this._auth) {
      this._auth.destroy();
    }

    if (this._cache) {
      this._cache.destroy();
    }

    if (this._pubsub) {
      this._pubsub.destroy();
    }

    if (this._database) {
      this._closeDatabase();
    }

    this._closeWs(code, reason, () => {
      this._closeHttp(callback);
    });
  }

  auth(dao = null) {
    if (dao === null) {
      return this._auth;
    }

    this._auth = new Auth()
      .dao(dao);

    return this;
  }

  cache(client = null) {
    if (client === null) {
      return this._cache;
    }

    this._cache = new Cache()
      .client(client);

    return this;
  }

  config(value = null) {
    if (value === null) {
      return this._config;
    }

    if (typeof value === 'string') {
      return get(this._config, value);
    }

    this._config = value;
    return this;
  }

  database(value = null) {
    if (value === null) {
      return this._database;
    }

    this._database = value;
    return this;
  }

  error(message) {
    return new ScolaError(message);
  }

  http(options = null) {
    if (options === null) {
      return this._http;
    }

    this._http = new HttpConnector()
      .server(this._httpInstance(options))
      .router(this.router());

    this._bindHttp();
    return this;
  }

  i18n(options = null) {
    if (options === null) {
      return this._i18n;
    }

    this._i18n = new I18n()
      .locale(options.locale)
      .timezone(options.timezone);

    return this;
  }

  id() {
    return this._id;
  }

  logger(config = null) {
    if (config === null) {
      return this._logger;
    }

    this._logger = new Logger()
      .config(config)
      .server(this);

    return this;
  }

  processor(config = null) {
    if (config === null) {
      return this._proccesors;
    }

    const processor = new Processor()
      .config(config)
      .server(this);

    this._processors.push(processor);
    return this;
  }

  route() {
    return new Route()
      .server(this);
  }

  router() {
    if (this._router === null) {
      this._router = new Router();
      this._router.on('error', handleError());
      this._bindRouter();
    }

    return this._router;
  }

  pubsub(options = null) {
    if (this._pubsub === null) {
      this._pubsub = new PubSub();
    }

    if (options === null) {
      return this._pubsub;
    }

    options.factory = (u, p, o) => {
      return new WebSocket(u, p, o);
    };

    const connection = new WsConnection()
      .codec(options.codec)
      .reconnector(options);

    this._pubsub.connection(connection);
    return this;
  }

  smtp(options = null) {
    if (options === null) {
      return this._smtp;
    }

    this._smtp = createTransport(options);
    this._smtp.use('compile', markdown());

    return this;
  }

  ws(options = null) {
    if (options === null) {
      return this._ws;
    }

    options.server = this._httpInstance(options);

    delete options.port;
    delete options.host;

    this._wsServer = new WsServer(options);

    this._ws = new WsConnector()
      .server(this._wsServer)
      .router(this.router())
      .codec(options.codec)
      .ping(options.ping);

    this._bindWs();
    return this;
  }

  start() {
    this._id = ip.toLong(ip.address());

    if (this._auth) {
      loadAuth(this);
    }

    if (this._pubsub) {
      this._pubsub.open();
    }

    this._processors.forEach((processor) => {
      processor.start();
    });

    return this;
  }

  _bindHttp() {
    if (this._http) {
      this._http.setMaxListeners(this._http.getMaxListeners() + 1);
      this._http.on('error', this._handleError);
    }
  }

  _unbindHttp() {
    if (this._http) {
      this._http.setMaxListeners(this._http.getMaxListeners() - 1);
      this._http.removeListener('error', this._handleError);
    }
  }

  _bindRouter() {
    if (this._router) {
      this._router.setMaxListeners(this._router.getMaxListeners() + 1);
      this._router.on('error', this._handleError);
    }
  }

  _unbindRouter() {
    if (this._router) {
      this._router.setMaxListeners(this._router.getMaxListeners() - 1);
      this._router.removeListener('error', this._handleError);
    }
  }

  _bindWs() {
    if (this._ws) {
      this._ws.setMaxListeners(this._ws.getMaxListeners() + 1);
      this._ws.on('error', this._handleError);
    }
  }

  _unbindWs() {
    if (this._ws) {
      this._ws.setMaxListeners(this._ws.getMaxListeners() - 1);
      this._ws.removeListener('error', this._handleError);
    }
  }

  _error(error) {
    this.emit('error', error);
  }

  _httpInstance(options) {
    if (this._httpServer) {
      return this._httpServer;
    }

    this._httpServer = new HttpServer();
    this._httpServer.listen(options.port, options.host);

    return this._httpServer;
  }

  _closeDatabase() {
    this._database.destroy();
    this._database = null;
  }

  _closeHttp(callback = () => {}) {
    if (this._http) {
      this._http.close();
      this._http = null;
    }

    if (this._httpServer) {
      this._httpServer.close(callback);
      this._httpServer = null;
      return;
    }

    callback();
  }

  _closeWs(code, reason, callback = () => {}) {
    if (this._ws) {
      this._ws.close(code, reason);
      this._ws = null;
    }

    if (this._wsServer) {
      this._wsServer.close(callback);
      this._wsServer = null;
      return;
    }

    callback();
  }
}
<commit_msg>Set dictionary on websocket connector<commit_after>import { EventEmitter } from 'events';
import { Server as HttpServer } from 'http';
import get from 'lodash-es/get';
import ip from 'ip';
import { createTransport } from 'nodemailer';
import { markdown } from 'nodemailer-markdown';
import WebSocket, { Server as WsServer } from 'ws';

import {
  Cache,
  HttpConnector,
  Logger,
  PubSub,
  Router,
  WsConnection,
  WsConnector,
  handleError
} from '@scola/api';

import {
  Auth,
  load as loadAuth
} from '@scola/auth-server';

import { ScolaError } from '@scola/error';
import { I18n } from '@scola/i18n';

import Processor from './processor';
import Route from './route';

export default class Server extends EventEmitter {
  constructor() {
    super();

    this._auth = null;
    this._cache = null;
    this._config = {};
    this._database = null;
    this._http = null;
    this._httpServer = null;
    this._i18n = null;
    this._id = null;
    this._logger = null;
    this._processors = [];
    this._pubsub = null;
    this._router = null;
    this._smtp = null;
    this._ws = null;
    this._wsServer = null;

    this._handleError = (e) => this._error(e);
  }

  destroy(code, reason, callback = () => {}) {
    this._unbindHttp();
    this._unbindRouter();
    this._unbindWs();

    if (this._auth) {
      this._auth.destroy();
    }

    if (this._cache) {
      this._cache.destroy();
    }

    if (this._pubsub) {
      this._pubsub.destroy();
    }

    if (this._database) {
      this._closeDatabase();
    }

    this._closeWs(code, reason, () => {
      this._closeHttp(callback);
    });
  }

  auth(dao = null) {
    if (dao === null) {
      return this._auth;
    }

    this._auth = new Auth()
      .dao(dao);

    return this;
  }

  cache(client = null) {
    if (client === null) {
      return this._cache;
    }

    this._cache = new Cache()
      .client(client);

    return this;
  }

  config(value = null) {
    if (value === null) {
      return this._config;
    }

    if (typeof value === 'string') {
      return get(this._config, value);
    }

    this._config = value;
    return this;
  }

  database(value = null) {
    if (value === null) {
      return this._database;
    }

    this._database = value;
    return this;
  }

  error(message) {
    return new ScolaError(message);
  }

  http(options = null) {
    if (options === null) {
      return this._http;
    }

    this._http = new HttpConnector()
      .server(this._httpInstance(options))
      .router(this.router());

    this._bindHttp();
    return this;
  }

  i18n(options = null) {
    if (options === null) {
      return this._i18n;
    }

    this._i18n = new I18n()
      .locale(options.locale)
      .timezone(options.timezone);

    return this;
  }

  id() {
    return this._id;
  }

  logger(config = null) {
    if (config === null) {
      return this._logger;
    }

    this._logger = new Logger()
      .config(config)
      .server(this);

    return this;
  }

  processor(config = null) {
    if (config === null) {
      return this._proccesors;
    }

    const processor = new Processor()
      .config(config)
      .server(this);

    this._processors.push(processor);
    return this;
  }

  route() {
    return new Route()
      .server(this);
  }

  router() {
    if (this._router === null) {
      this._router = new Router();
      this._router.on('error', handleError());
      this._bindRouter();
    }

    return this._router;
  }

  pubsub(options = null) {
    if (this._pubsub === null) {
      this._pubsub = new PubSub();
    }

    if (options === null) {
      return this._pubsub;
    }

    options.factory = (u, p, o) => {
      return new WebSocket(u, p, o);
    };

    const connection = new WsConnection()
      .codec(options.codec)
      .reconnector(options);

    this._pubsub.connection(connection);
    return this;
  }

  smtp(options = null) {
    if (options === null) {
      return this._smtp;
    }

    this._smtp = createTransport(options);
    this._smtp.use('compile', markdown());

    return this;
  }

  ws(options = null) {
    if (options === null) {
      return this._ws;
    }

    options.server = this._httpInstance(options);

    delete options.port;
    delete options.host;

    this._wsServer = new WsServer(options);
    this._ws = new WsConnector();

    this._ws.server(this._wsServer);
    this._ws.router(this.router());
    this._ws.codec(options.codec);
    this._ws.ping(options.ping);
    this._ws.dictionary(options.dictionary);

    this._bindWs();
    return this;
  }

  start() {
    this._id = ip.toLong(ip.address());

    if (this._auth) {
      loadAuth(this);
    }

    if (this._pubsub) {
      this._pubsub.open();
    }

    this._processors.forEach((processor) => {
      processor.start();
    });

    return this;
  }

  _bindHttp() {
    if (this._http) {
      this._http.setMaxListeners(this._http.getMaxListeners() + 1);
      this._http.on('error', this._handleError);
    }
  }

  _unbindHttp() {
    if (this._http) {
      this._http.setMaxListeners(this._http.getMaxListeners() - 1);
      this._http.removeListener('error', this._handleError);
    }
  }

  _bindRouter() {
    if (this._router) {
      this._router.setMaxListeners(this._router.getMaxListeners() + 1);
      this._router.on('error', this._handleError);
    }
  }

  _unbindRouter() {
    if (this._router) {
      this._router.setMaxListeners(this._router.getMaxListeners() - 1);
      this._router.removeListener('error', this._handleError);
    }
  }

  _bindWs() {
    if (this._ws) {
      this._ws.setMaxListeners(this._ws.getMaxListeners() + 1);
      this._ws.on('error', this._handleError);
    }
  }

  _unbindWs() {
    if (this._ws) {
      this._ws.setMaxListeners(this._ws.getMaxListeners() - 1);
      this._ws.removeListener('error', this._handleError);
    }
  }

  _error(error) {
    this.emit('error', error);
  }

  _httpInstance(options) {
    if (this._httpServer) {
      return this._httpServer;
    }

    this._httpServer = new HttpServer();
    this._httpServer.listen(options.port, options.host);

    return this._httpServer;
  }

  _closeDatabase() {
    this._database.destroy();
    this._database = null;
  }

  _closeHttp(callback = () => {}) {
    if (this._http) {
      this._http.close();
      this._http = null;
    }

    if (this._httpServer) {
      this._httpServer.close(callback);
      this._httpServer = null;
      return;
    }

    callback();
  }

  _closeWs(code, reason, callback = () => {}) {
    if (this._ws) {
      this._ws.close(code, reason);
      this._ws = null;
    }

    if (this._wsServer) {
      this._wsServer.close(callback);
      this._wsServer = null;
      return;
    }

    callback();
  }
}
<|endoftext|>


<commit_before>/*jshint esnext: true */

// TESTING PURPOSES ONLY

class Scratch {

  constructor (msg1, msg2) {
    this.msg1 = msg1
    this.msg2 = msg2
  }

  helloWorld () {
    return this.msg1 + ' ' + this.msg2
  }

}

export default Scratch
<commit_msg>Removes the scratch file<commit_after><|endoftext|>


<commit_before>/* jshint esnext: true */
var data;

var margin = {top: 0, right: 60, bottom: 50, left: 100};
var width = 960 - margin.left - margin.right;
var height = 600 - margin.top - margin.bottom;

var dataMargin = {top: 10, right: 14, bottom: 5, left: 5};
var dataWidth = width - dataMargin.left - dataMargin.right;
var dataHeight = height - dataMargin.top - dataMargin.bottom;

var zoomedOut = false;
var current_x_min = 0;

var discrete_mode = false; // this is a kludge to fix centerOn bug
var pinned = false;

var x = d3.scaleLinear()
  .domain([current_x_min, current_x_min + 10])
  .range([dataMargin.left, dataWidth]);

var y = d3.scaleLinear()
  .domain([1, 30])
  .range([dataMargin.top, dataHeight]);

var line = d3.line()
  .curve(d3.curveMonotoneX)
  .x(d => x(d.week))
  .y(d => y(d.rank));

var voronoi = d3.voronoi()
  .x(d => d.x)
  .y(d => d.y)
  .size([x(24), height]);

var format = d3.format(".01f");

window.onload = function() {
  d3.json('api/rankings/2016', function(error, json) {
    if (error) {
      return console.warn(error);
    }
    data = json.results;
    $('#spinner-container').css('display', 'none');

    // find initial rankings for greensock
    var start_rankings = new Array(30);
    data.forEach(function(team) {
      let rank = team.rankings[0].rank;
      start_rankings[rank - 1] = '.' + team.slug;
    });
    start_rankings.reverse();

    /*
     * D3.js Code
     */
    var outer = d3.select(".chart").append("svg")
        .attr("style", "border: 1px solid black;")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom);

    var inner = outer
      .append("g")
        .attr("transform", `translate(${margin.left}, ${margin.top})`)
      .append("svg")
        .attr("width", dataWidth + dataMargin.left + dataMargin.right)
        .attr("height", dataHeight + dataMargin.top + dataMargin.bottom)
      .append('g')
        .attr("transform", `translate(${dataMargin.left}, ${dataMargin.top})`);

    var xAxis = d3.axisBottom(x);
    var yAxis = d3.axisRight(y)
                  .tickValues([1, 5, 10, 15, 20, 25, 30]);

    var gX = outer.append('g')
      .attr('transform', `translate(${margin.left + dataMargin.left},
                                    ${dataHeight + margin.top + dataMargin.top + dataMargin.bottom})`)
      .call(xAxis);

    gX.append('text')
        .text('Week')
        .attr('fill', 'black')
        .attr('font-size', 15)
        .attr('transform', `translate(${width / 2}, 40)`);

    var gY = outer.append('g')
      .attr('transform', `translate(${margin.left},
                                    ${margin.top + dataMargin.top})`);

    var rankAxis = outer.append('g')
      .attr('transform', `translate(${margin.left + dataMargin.left + width},
                                    ${margin.top + dataMargin.top})`)
      .call(yAxis)
      .append('text')
        .text('Rank')
        .attr('fill', 'black')
        .attr('font-size', 15)
        .attr('transform', `translate(40, ${height / 2}) rotate(-90)`);

    var labels = gY.selectAll('.team-label')
      .data(data)
      .enter().append('text')
        .attr('class', d => `${d.slug} team-label`)
        .attr('text-anchor', 'end')
        .attr('transform', d => `translate(0, ${y(d.rankings[current_x_min].rank) + 5})`)
        .text(d => d.name)
        .on('click', team => pin(team.slug))
        .on('mouseover', team => {
            if (team && !pinned) {
              highlightTeam(team.slug);
            }
          })
        .on('mouseout', () => {
            if (!pinned) {
              highlightAll();
            }
          });

    var team = inner.selectAll('.team')
      .data(data)
      .enter().append('g')
        .attr('class', d => `${d.slug} team`);

    team
      .append('path')
        .attr('d', d => line(d.rankings))
        .style('fill', 'none')
        .style('stroke-width', 1.5)
        .style('stroke', d => d.color)
        .attr('team', d => d.slug);

    team.selectAll('circle')
      .data(d => d.rankings)
      .enter().append('circle')
        .attr('cx', d => x(d.week))
        .attr('cy', d => y(d.rank))
        .attr('r', '5px')
        .style('opacity', 0)
        .style('fill', d => d.color);

    var playoffs = inner.append('g')
        .attr('class', 'playoffs-marker');
    var playoffsElements = playoffs.append('g')
        .attr('transform', `translate(${x(24) + 10}, ${dataHeight + dataMargin.top}) rotate(-90)`);
    playoffsElements.append('path')
      .attr('stroke-width', 2.4)
      .attr(`d`, `M15 0 H ${dataHeight - 7}`);
    playoffsElements.append('rect')
      .style('fill', 'white')
      .style('stroke', 'white')
      .attr('width', `100`)
      .attr('height', `20`)
      .attr(`transform`, `translate(${dataHeight/2 - 50}, -10)`);
    playoffsElements.append('text')
      .attr('text-anchor', 'middle')
      .attr(`transform`, `translate(${dataHeight/2}, 5)`)
      .text('Playoffs Begin');

    var zoom = d3.zoom()
      .on('zoom', zoomed)
      .on('end', centerOnNearestBase)
      .translateExtent([[0,0], [3200, height + margin.top + margin.bottom]])
      .scaleExtent([1,1]);

    var zoomHandle = inner.append('rect')
      .attr('width', width)
      .attr('height', height)
      .attr('class', 'zoom-handle')
      .call(zoom);

    generateVoronoi();

    function generateVoronoi() {
      var voronoiData = voronoi.polygons(generateVoronoiPoints($('.team path')));
      inner.selectAll('.voronoi').remove();
      inner.selectAll('.voronoi').data(voronoiData)
        .enter().append('g')
          .attr('class', d => 'voronoi')
        .append('path')
          .attr('d', d => d ? "M" + d.join("L") + "Z" : null)
          .on('click', team => pin(team.data.slug))
          .on('mouseover', team => {
              if (team && !pinned) {
                highlightTeam(team.data.slug);
              }
            })
          .on('mouseout', () => {
              if (!pinned) {
                highlightAll();
              }
            });
    }

    window.onclick = function () {
      highlightAll();
      pinned = false;
    };

    function zoomed() {
      team.attr('transform', d3.event.transform);
      playoffs.attr('transform', d3.event.transform);
      inner.selectAll('.voronoi').attr('transform', d3.event.transform);
      gX.call(xAxis.scale(d3.event.transform.rescaleX(x)));

      var x_min = format(x.invert(-d3.event.transform.x));
      var xFloor = Math.floor(x_min);
      var xCeil = Math.ceil(x_min);
      var percent = d3.easeCubic(x_min % 1);

      labels.attr('transform', function(d) {
        var floor = y(d.rankings[xFloor].rank);
        var ceil = y(d.rankings[xCeil].rank);
        var travel = ceil - floor;
        var newY = floor + ( travel * percent );
        return `translate(0, ${newY})`;
      });
    }

    /*
     * Panning Logic
     */
    function centerOnNearestBase() {
      if (discrete_mode) {
        // there's a bug here where if you hit the pan buttons too fast
        // we get into an infinite loop trying to center while another
        // zoom event is happening
        return;
      }
      var base = format(x.invert(-d3.event.transform.x)); // where the left hand of the axis lies
      var roundedBase = format(Math.round(base));
      if (Math.abs(x(roundedBase - base)) > 1)  {
        // if we're more than 1 pixel off
        centerOn(roundedBase);
      }
    }

    function centerOn(base) {
      var mX = x(base);
      var t = d3.zoomIdentity.translate(-mX, 0);
      zoomHandle
        .transition()
        .duration(200)
        .call(zoom.transform, t);
    }

    // Desktop Panning Controls
    var leftButton = d3.select('#left')
      .on('click', function() {
        d3.event.stopPropagation();
        discrete_mode = true;
        if (current_x_min > 0) {
          current_x_min--;
          centerOn(current_x_min);
        }
      });
    var rightButton = d3.select('#right')
      .on('click', function() {
        d3.event.stopPropagation();
        discrete_mode = true;
        if (current_x_min + 10 < 24) {
          current_x_min++;
          centerOn(current_x_min);
        }
      });

    var zoomButton = d3.select('#zoom')
      .on('click', function() {
        d3.event.stopPropagation();
        if (zoomedOut) {
          x.domain([current_x_min, current_x_min + 10]);
          settleZoom(500);
          zoomedOut = false;
        } else {
          x.domain([0, 24]);
          settleZoom(500);
          zoomedOut = true;
        }
      });

    function settleZoom(duration) {
      //var t = d3.zoomIdentity.scaleTo(-mX, 0);
      //zoomHandle
        //.transition()
        //.duration(200)
        //.call(zoom.transform, t);

      gX.transition()
        .duration(duration)
        .call(xAxis)
      // slight kludge, we just want to to do this once
        .on('end', generateVoronoi);

      team.selectAll('path')
        .transition()
        .duration(duration)
        .attr('d', d => line(d.rankings));

      team.selectAll('circle')
        .transition()
        .duration(duration)
        .attr('cx', d => x(d.week))
        .attr('cy', d => y(d.rank));
    }

    // Animate all this garbage in
    TweenMax.staggerFrom(start_rankings, 1, {opacity: 0}, 0.025);
  }); // End of window.onload

  function pin(slug) {
    d3.event.stopPropagation();
    highlightAll();
    highlightTeam(slug);
    pinned = true;
  }

  function highlightTeam(slug) {
    d3.selectAll('.team > path')
      .transition()
      .duration(15)
      .ease(d3.easeLinear)
      .style('stroke-width', d => (slug === d.slug) ? '3px' : '1px')
      .style('stroke', d => (slug === d.slug) ? d.color : 'gray');

    d3.selectAll('.team-label')
      .transition()
      .duration(15)
      .attr('fill', d => (slug === d.slug) ? 'black' : 'gray')
      .attr('font-weight', d => (slug === d.slug) ? 900 : 100);

    d3.selectAll(`.${slug} > circle`)
      .transition()
      .duration(200)
      .ease(d3.easeLinear)
      .style('opacity', 1);
  }

  function highlightAll() {
    d3.selectAll('.team path')
      .transition()
      .duration(15)
      .ease(d3.easeLinear)
      .style('stroke', d => d.color)
      .style('stroke-width', '1.5px');

    d3.selectAll('.team-label')
      .transition()
      .duration(15)
      .attr('font-weight', 100)
      .attr('fill', 'black');

    d3.selectAll('.team circle')
      .transition()
      .duration(15)
      .ease(d3.easeLinear)
      .style('opacity', 0);
  }

  /*
   * Voronoi Support Code
   */
  function samplePath(pathNode, precision) {
    var pathLength = pathNode.getTotalLength();
    var samples = [];
    for (let sample, sampleLength = 0; sampleLength <= pathLength; sampleLength += precision) {
      sample = pathNode.getPointAtLength(sampleLength);
      samples.push({
        x: sample.x,
        y: sample.y,
        slug: pathNode.__data__.slug // there is surely a better way to get this
      });
    }
    return samples;
  }

  function generateVoronoiPoints(paths) {
    var allPoints = [];
    for (var path of paths) {
      allPoints = allPoints.concat( samplePath(path, 15) );
    }
    return allPoints;
  }

};
<commit_msg>removing zoom out code for release<commit_after>/* jshint esnext: true */
var data;

var margin = {top: 0, right: 60, bottom: 50, left: 100};
var width = 960 - margin.left - margin.right;
var height = 600 - margin.top - margin.bottom;

var dataMargin = {top: 10, right: 14, bottom: 5, left: 5};
var dataWidth = width - dataMargin.left - dataMargin.right;
var dataHeight = height - dataMargin.top - dataMargin.bottom;

var zoomedOut = false;
var current_x_min = 0;
var panOffset = 0;

var discrete_mode = false; // this is a kludge to fix centerOn bug
var pinned = false;

var x = d3.scaleLinear()
  .domain([current_x_min, current_x_min + 10])
  .range([dataMargin.left, dataWidth]);

var y = d3.scaleLinear()
  .domain([1, 30])
  .range([dataMargin.top, dataHeight]);

var line = d3.line()
  .curve(d3.curveMonotoneX)
  .x(d => x(d.week))
  .y(d => y(d.rank));

var voronoi = d3.voronoi()
  .x(d => d.x)
  .y(d => d.y)
  .size([x(24), height]);

var format = d3.format(".01f");

window.onload = function() {
  d3.json('api/rankings/2016', function(error, json) {
    if (error) {
      return console.warn(error);
    }
    data = json.results;
    $('#spinner-container').css('display', 'none');

    // find initial rankings for greensock
    var start_rankings = new Array(30);
    data.forEach(function(team) {
      let rank = team.rankings[0].rank;
      start_rankings[rank - 1] = '.' + team.slug;
    });
    start_rankings.reverse();

    /*
     * D3.js Code
     */
    var outer = d3.select(".chart").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom);

    var inner = outer
      .append("g")
        .attr("transform", `translate(${margin.left}, ${margin.top})`)
      .append("svg")
        .attr("width", dataWidth + dataMargin.left + dataMargin.right)
        .attr("height", dataHeight + dataMargin.top + dataMargin.bottom)
      .append('g')
        .attr("transform", `translate(${dataMargin.left}, ${dataMargin.top})`);

    var xAxis = d3.axisBottom(x);
    var yAxis = d3.axisRight(y)
                  .tickValues([1, 5, 10, 15, 20, 25, 30]);

    var gX = outer.append('g')
      .attr('transform', `translate(${margin.left + dataMargin.left},
                                    ${dataHeight + margin.top + dataMargin.top + dataMargin.bottom})`)
      .call(xAxis);

    gX.append('text')
        .text('Week')
        .attr('fill', 'black')
        .attr('font-size', 15)
        .attr('transform', `translate(${width / 2}, 40)`);

    var gY = outer.append('g')
      .attr('transform', `translate(${margin.left},
                                    ${margin.top + dataMargin.top})`);

    var rankAxis = outer.append('g')
      .attr('transform', `translate(${margin.left + dataMargin.left + width},
                                    ${margin.top + dataMargin.top})`)
      .call(yAxis)
      .append('text')
        .text('Rank')
        .attr('fill', 'black')
        .attr('font-size', 15)
        .attr('transform', `translate(40, ${height / 2}) rotate(-90)`);

    var labels = gY.selectAll('.team-label')
      .data(data)
      .enter().append('text')
        .attr('class', d => `${d.slug} team-label`)
        .attr('text-anchor', 'end')
        .attr('transform', d => `translate(0, ${y(d.rankings[current_x_min].rank) + 5})`)
        .text(d => d.name)
        .on('click', team => pin(team.slug))
        .on('mouseover', team => {
            if (team && !pinned) {
              highlightTeam(team.slug);
            }
          })
        .on('mouseout', () => {
            if (!pinned) {
              highlightAll();
            }
          });

    var team = inner.selectAll('.team')
      .data(data)
      .enter().append('g')
        .attr('class', d => `${d.slug} team`);

    team
      .append('path')
        .attr('d', d => line(d.rankings))
        .style('fill', 'none')
        .style('stroke-width', 1.5)
        .style('stroke', d => d.color)
        .attr('team', d => d.slug);

    team.selectAll('circle')
      .data(d => d.rankings)
      .enter().append('circle')
        .attr('cx', d => x(d.week))
        .attr('cy', d => y(d.rank))
        .attr('r', '5px')
        .style('opacity', 0)
        .style('fill', d => d.color);

    var playoffs = inner.append('g')
        .attr('class', 'playoffs-marker');
    var playoffsElements = playoffs.append('g')
        .attr('transform', `translate(${x(24) + 10}, ${dataHeight + dataMargin.top}) rotate(-90)`);
    playoffsElements.append('path')
      .attr('stroke-width', 2.4)
      .attr(`d`, `M15 0 H ${dataHeight - 7}`);
    playoffsElements.append('rect')
      .style('fill', 'white')
      .style('stroke', 'white')
      .attr('width', `100`)
      .attr('height', `20`)
      .attr(`transform`, `translate(${dataHeight/2 - 50}, -10)`);
    playoffsElements.append('text')
      .attr('text-anchor', 'middle')
      .attr(`transform`, `translate(${dataHeight/2}, 5)`)
      .text('Playoffs Begin');

    var zoom = d3.zoom()
      .on('zoom', zoomed)
      .on('end', centerOnNearestBase)
      .translateExtent([[0,0], [3200, height + margin.top + margin.bottom]])
      .scaleExtent([1,1]);

    var zoomHandle = inner.append('rect')
      .attr('width', width)
      .attr('height', height)
      .attr('class', 'zoom-handle')
      .call(zoom);

    generateVoronoi();

    function generateVoronoi() {
      var voronoiData = voronoi.polygons(generateVoronoiPoints($('.team path')));
      inner.selectAll('.voronoi').remove();
      inner.selectAll('.voronoi').data(voronoiData)
        .enter().append('g')
          .attr('class', d => 'voronoi')
        .append('path')
          .attr('d', d => d ? "M" + d.join("L") + "Z" : null)
          .on('click', team => pin(team.data.slug))
          .on('mouseover', team => {
              if (team && !pinned) {
                highlightTeam(team.data.slug);
              }
            })
          .on('mouseout', () => {
              if (!pinned) {
                highlightAll();
              }
            });
    }

    window.onclick = function () {
      highlightAll();
      pinned = false;
    };

    function zoomed() {
      team.attr('transform', d3.event.transform);
      playoffs.attr('transform', d3.event.transform);
      inner.selectAll('.voronoi').attr('transform', d3.event.transform);
      gX.call(xAxis.scale(d3.event.transform.rescaleX(x)));

      var x_min = format(x.invert(-d3.event.transform.x));
      var xFloor = Math.floor(x_min);
      var xCeil = Math.ceil(x_min);
      var percent = d3.easeCubic(x_min % 1);

      labels.attr('transform', function(d) {
        var floor = y(d.rankings[xFloor].rank);
        var ceil = y(d.rankings[xCeil].rank);
        var travel = ceil - floor;
        var newY = floor + ( travel * percent );
        return `translate(0, ${newY})`;
      });
    }

    /*
     * Panning Logic
     */
    function centerOnNearestBase() {
      if (discrete_mode) {
        // there's a bug here where if you hit the pan buttons too fast
        // we get into an infinite loop trying to center while another
        // zoom event is happening
        return;
      }
      var base = format(x.invert(-d3.event.transform.x)); // where the left hand of the axis lies
      var roundedBase = format(Math.round(base));
      if (Math.abs(x(roundedBase - base)) > 1)  {
        // if we're more than 1 pixel off
        centerOn(roundedBase);
      }
    }

    function centerOn(base) {
      panOffset = x(base);
      var t = d3.zoomIdentity.translate(-panOffset, 0);
      zoomHandle
        .transition()
        .duration(200)
        .call(zoom.transform, t);
    }

    // Desktop Panning Controls
    var leftButton = d3.select('#left')
      .on('click', function() {
        d3.event.stopPropagation();
        discrete_mode = true;
        if (current_x_min > 0) {
          current_x_min--;
          centerOn(current_x_min);
        }
      });
    var rightButton = d3.select('#right')
      .on('click', function() {
        d3.event.stopPropagation();
        discrete_mode = true;
        if (current_x_min + 10 < 24) {
          current_x_min++;
          centerOn(current_x_min);
        }
      });

    /*
     *I'm having trouble reconciling using zoom to pan
     *and using scales to effect zooming in and out.
     *One solution might be to zoom the scale only on one
     *dimension, but I don't belive that's an option.
     *Leaving this code in here for future reference.
     */
    //var zoomButton = d3.select('#zoom')
      //.on('click', function() {
        //d3.event.stopPropagation();
        //if (zoomedOut) {
          //x.domain([current_x_min, current_x_min + 10]);
          //xAxis.scale(x);
          //x.range([dataMargin.left, dataWidth]);
          //settleZoom(500);
          //zoomedOut = false;
        //} else {
          //x.domain([0, 24]);
          //xAxis.scale(x);
          //x.range([dataMargin.left + panOffset, dataWidth + panOffset]);
          //settleZoom(500);
          //zoomedOut = true;
        //}
      //});

    //function settleZoom(duration) {
      //gX.transition()
        //.duration(duration)
        //.call(xAxis)
      //// slight kludge, we just want to to do this once
        //.on('end', generateVoronoi);

      //team.selectAll('path')
        //.transition()
        //.duration(duration)
        //.attr('d', d => line(d.rankings));

      //team.selectAll('circle')
        //.transition()
        //.duration(duration)
        //.attr('cx', d => x(d.week))
        //.attr('cy', d => y(d.rank));
    //}

    // Animate all this garbage in
    TweenMax.staggerFrom(start_rankings, 1, {opacity: 0}, 0.025);
  }); // End of window.onload

  function pin(slug) {
    d3.event.stopPropagation();
    highlightAll();
    highlightTeam(slug);
    pinned = true;
  }

  function highlightTeam(slug) {
    d3.selectAll('.team > path')
      .transition()
      .duration(15)
      .ease(d3.easeLinear)
      .style('stroke-width', d => (slug === d.slug) ? '3px' : '1px')
      .style('stroke', d => (slug === d.slug) ? d.color : 'gray');

    d3.selectAll('.team-label')
      .transition()
      .duration(15)
      .attr('fill', d => (slug === d.slug) ? 'black' : 'gray')
      .attr('font-weight', d => (slug === d.slug) ? 900 : 100);

    d3.selectAll(`.${slug} > circle`)
      .transition()
      .duration(200)
      .ease(d3.easeLinear)
      .style('opacity', 1);
  }

  function highlightAll() {
    d3.selectAll('.team path')
      .transition()
      .duration(15)
      .ease(d3.easeLinear)
      .style('stroke', d => d.color)
      .style('stroke-width', '1.5px');

    d3.selectAll('.team-label')
      .transition()
      .duration(15)
      .attr('font-weight', 100)
      .attr('fill', 'black');

    d3.selectAll('.team circle')
      .transition()
      .duration(15)
      .ease(d3.easeLinear)
      .style('opacity', 0);
  }

  /*
   * Voronoi Support Code
   */
  function samplePath(pathNode, precision) {
    var pathLength = pathNode.getTotalLength();
    var samples = [];
    for (let sample, sampleLength = 0; sampleLength <= pathLength; sampleLength += precision) {
      sample = pathNode.getPointAtLength(sampleLength);
      samples.push({
        x: sample.x,
        y: sample.y,
        slug: pathNode.__data__.slug // there is surely a better way to get this
      });
    }
    return samples;
  }

  function generateVoronoiPoints(paths) {
    var allPoints = [];
    for (var path of paths) {
      allPoints = allPoints.concat( samplePath(path, 15) );
    }
    return allPoints;
  }

};
<|endoftext|>


<commit_before>/* @flow */

import path from 'path';
import morgan from 'morgan';
import express from 'express';
import compression from 'compression';
import helmet from 'helmet';
import hpp from 'hpp';
import favicon from 'serve-favicon';
import React from 'react';
import { renderToString, renderToStaticMarkup } from 'react-dom/server';
import { StaticRouter, matchPath } from 'react-router-dom';
import { Provider } from 'react-redux';
import chalk from 'chalk';

import createHistory from 'history/createMemoryHistory';
import configureStore from './redux/store';
import Html from './utils/Html';
import App from './containers/App';
import routes from './routes';
import { port, host } from './config';

const app = express();

// Using helmet to secure Express with various HTTP headers
app.use(helmet());
// Prevent HTTP parameter pollution.
app.use(hpp());
// Compress all requests
app.use(compression());

// Use morgan for http request debug (only show error)
app.use(morgan('dev', { skip: (req, res) => res.statusCode < 400 }));
app.use(favicon(path.join(process.cwd(), './public/favicon.ico')));
app.use(express.static(path.join(process.cwd(), './public')));

// Run express as webpack dev server
if (__DEV__) {
  const webpack = require('webpack');
  const webpackConfig = require('../tools/webpack/config.babel');

  const compiler = webpack(webpackConfig);

  app.use(require('webpack-dev-middleware')(compiler, {
    publicPath: webpackConfig.output.publicPath,
    hot: true,
    noInfo: true,
    stats: 'errors-only',
    serverSideRender: true,
  }));

  app.use(require('webpack-hot-middleware')(compiler));
}

// Register server-side rendering middleware
app.get('*', (req, res) => {
  if (__DEV__) webpackIsomorphicTools.refresh();

  const history = createHistory();
  const store = configureStore(history);
  const renderHtml = (store, htmlContent) => { // eslint-disable-line no-shadow
    const html = renderToStaticMarkup(<Html store={store} htmlContent={htmlContent} />);

    return `<!doctype html>${html}`;
  };

  // If __DISABLE_SSR__ = true, disable server side rendering
  if (__DISABLE_SSR__) {
    res.send(renderHtml(store));
    return;
  }

  // Load data on server-side
  const loadBranchData = () => {
    const promises = [];

    routes.some((route) => {
      const match = matchPath(req.path, route);

      // $FlowFixMe: the params of pre-load actions are dynamic
      if (match && route.loadData) promises.push(route.loadData(store.dispatch, match.params));

      return match;
    });

    return Promise.all(promises);
  };

  // Send response after all the action(s) are dispathed
  loadBranchData()
    .then(() => {
      // Setup React-Router server-side rendering
      const routerContext = {};
      const htmlContent = renderToString(
        <Provider store={store}>
          <StaticRouter location={req.url} context={routerContext}>
            <App />
          </StaticRouter>
        </Provider>,
      );

      // Check if the render result contains a redirect, if so we need to set
      // the specific status and redirect header and end the response
      if (routerContext.url) {
        res.status(301).setHeader('Location', routerContext.url);
        res.end();

        return;
      }

      // Checking is page is 404
      const status = routerContext.status === '404' ? 404 : 200;

      // Pass the route and initial state into html template
      res.status(status).send(renderHtml(store, htmlContent));
    })
    .catch((err) => {
      res.status(404).send('Not Found :(');

      console.error(`==> 😭  Rendering routes error: ${err}`);
    });
});

if (port) {
  app.listen(port, host, (err) => {
    const url = `http://${host}:${port}`;

    if (err) console.error(`==> 😭  OMG!!! ${err}`);

    console.info(chalk.green(`==> 🌎  Listening at ${url}`));

    // Open Chrome
    require('../tools/openBrowser')(url);
  });
} else {
  console.error(chalk.red('==> 😭  OMG!!! No PORT environment variable has been specified'));
}
<commit_msg>Correct the configuration of wepack-dev-middleware<commit_after>/* @flow */

import path from 'path';
import morgan from 'morgan';
import express from 'express';
import compression from 'compression';
import helmet from 'helmet';
import hpp from 'hpp';
import favicon from 'serve-favicon';
import React from 'react';
import { renderToString, renderToStaticMarkup } from 'react-dom/server';
import { StaticRouter, matchPath } from 'react-router-dom';
import { Provider } from 'react-redux';
import chalk from 'chalk';

import createHistory from 'history/createMemoryHistory';
import configureStore from './redux/store';
import Html from './utils/Html';
import App from './containers/App';
import routes from './routes';
import { port, host } from './config';

const app = express();

// Using helmet to secure Express with various HTTP headers
app.use(helmet());
// Prevent HTTP parameter pollution.
app.use(hpp());
// Compress all requests
app.use(compression());

// Use morgan for http request debug (only show error)
app.use(morgan('dev', { skip: (req, res) => res.statusCode < 400 }));
app.use(favicon(path.join(process.cwd(), './public/favicon.ico')));
app.use(express.static(path.join(process.cwd(), './public')));

// Run express as webpack dev server
if (__DEV__) {
  const webpack = require('webpack');
  const webpackConfig = require('../tools/webpack/config.babel');

  const compiler = webpack(webpackConfig);

  app.use(require('webpack-dev-middleware')(compiler, {
    publicPath: webpackConfig.output.publicPath,
    hot: true,
    noInfo: true,
    stats: { colors: true },
    serverSideRender: true,
  }));

  app.use(require('webpack-hot-middleware')(compiler));
}

// Register server-side rendering middleware
app.get('*', (req, res) => {
  if (__DEV__) webpackIsomorphicTools.refresh();

  const history = createHistory();
  const store = configureStore(history);
  const renderHtml = (store, htmlContent) => { // eslint-disable-line no-shadow
    const html = renderToStaticMarkup(<Html store={store} htmlContent={htmlContent} />);

    return `<!doctype html>${html}`;
  };

  // If __DISABLE_SSR__ = true, disable server side rendering
  if (__DISABLE_SSR__) {
    res.send(renderHtml(store));
    return;
  }

  // Load data on server-side
  const loadBranchData = () => {
    const promises = [];

    routes.some((route) => {
      const match = matchPath(req.path, route);

      // $FlowFixMe: the params of pre-load actions are dynamic
      if (match && route.loadData) promises.push(route.loadData(store.dispatch, match.params));

      return match;
    });

    return Promise.all(promises);
  };

  // Send response after all the action(s) are dispathed
  loadBranchData()
    .then(() => {
      // Setup React-Router server-side rendering
      const routerContext = {};
      const htmlContent = renderToString(
        <Provider store={store}>
          <StaticRouter location={req.url} context={routerContext}>
            <App />
          </StaticRouter>
        </Provider>,
      );

      // Check if the render result contains a redirect, if so we need to set
      // the specific status and redirect header and end the response
      if (routerContext.url) {
        res.status(301).setHeader('Location', routerContext.url);
        res.end();

        return;
      }

      // Checking is page is 404
      const status = routerContext.status === '404' ? 404 : 200;

      // Pass the route and initial state into html template
      res.status(status).send(renderHtml(store, htmlContent));
    })
    .catch((err) => {
      res.status(404).send('Not Found :(');

      console.error(`==> 😭  Rendering routes error: ${err}`);
    });
});

if (port) {
  app.listen(port, host, (err) => {
    const url = `http://${host}:${port}`;

    if (err) console.error(`==> 😭  OMG!!! ${err}`);

    console.info(chalk.green(`==> 🌎  Listening at ${url}`));

    // Open Chrome
    require('../tools/openBrowser')(url);
  });
} else {
  console.error(chalk.red('==> 😭  OMG!!! No PORT environment variable has been specified'));
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

WebInspector.Panel = function()
{
    WebInspector.View.call(this);

    this.element.addStyleClass("panel");
}

WebInspector.Panel.prototype = {
    get toolbarItem()
    {
        if (this._toolbarItem)
            return this._toolbarItem;

        // Sample toolbar item as markup:
        // <button class="toolbar-item resources toggleable">
        //

        //
Resources

        // </button>

        this._toolbarItem = document.createElement("button");
        this._toolbarItem.className = "toolbar-item toggleable";
        this._toolbarItem.panel = this;

        if ("toolbarItemClass" in this)
            this._toolbarItem.addStyleClass(this.toolbarItemClass);

        var iconElement = document.createElement("div");
        iconElement.className = "toolbar-icon";
        this._toolbarItem.appendChild(iconElement);

        if ("toolbarItemLabel" in this) {
            var labelElement = document.createElement("div");
            labelElement.className = "toolbar-label";
            labelElement.textContent = this.toolbarItemLabel;
            this._toolbarItem.appendChild(labelElement);
        }

        return this._toolbarItem;
    },

    show: function()
    {
        WebInspector.View.prototype.show.call(this);

        var statusBarItems = this.statusBarItems;
        if (statusBarItems) {
            this._statusBarItemContainer = document.createElement("div");
            for (var i = 0; i < statusBarItems.length; ++i)
                this._statusBarItemContainer.appendChild(statusBarItems[i]);
            document.getElementById("main-status-bar").appendChild(this._statusBarItemContainer);
        }

        if ("_toolbarItem" in this)
            this._toolbarItem.addStyleClass("toggled-on");

        WebInspector.currentFocusElement = document.getElementById("main-panels");
    },

    hide: function()
    {
        WebInspector.View.prototype.hide.call(this);

        if (this._statusBarItemContainer && this._statusBarItemContainer.parentNode)
            this._statusBarItemContainer.parentNode.removeChild(this._statusBarItemContainer);
        delete this._statusBarItemContainer;
        if ("_toolbarItem" in this)
            this._toolbarItem.removeStyleClass("toggled-on");
    },

    attach: function()
    {
        if (!this.element.parentNode)
            document.getElementById("main-panels").appendChild(this.element);
    },

    searchCanceled: function(startingNewSearch)
    {
        if (this._searchResults) {
            for (var i = 0; i < this._searchResults.length; ++i) {
                var view = this._searchResults[i];
                if (view.searchCanceled)
                    view.searchCanceled();
                delete view.currentQuery;
            }
        }

        WebInspector.updateSearchMatchesCount(0, this);

        if (this._currentSearchChrunkIntervalIdentifier) {
            clearInterval(this._currentSearchChrunkIntervalIdentifier);
            delete this._currentSearchChrunkIntervalIdentifier;
        }

        this._totalSearchMatches = 0;
        this._currentSearchResultIndex = 0;
        this._searchResults = [];
    },

    performSearch: function(query)
    {
        // Call searchCanceled since it will reset everything we need before doing a new search.
        this.searchCanceled(true);

        var searchableViews = this.searchableViews;
        if (!searchableViews || !searchableViews.length)
            return;

        var parentElement = this.viewsContainerElement;
        var visibleView = this.visibleView;
        var sortFuction = this.searchResultsSortFunction;

        var matchesCountUpdateTimeout = null;

        function updateMatchesCount()
        {
            WebInspector.updateSearchMatchesCount(this._totalSearchMatches, this);
            matchesCountUpdateTimeout = null;
        }

        function updateMatchesCountSoon()
        {
            if (matchesCountUpdateTimeout)
                return;
            // Update the matches count every half-second so it doesn't feel twitchy.
            matchesCountUpdateTimeout = setTimeout(updateMatchesCount.bind(this), 500);
        }

        function finishedCallback(view, searchMatches)
        {
            if (!searchMatches)
                return;

            this._totalSearchMatches += searchMatches;
            this._searchResults.push(view);

            if (sortFuction)
                this._searchResults.sort(sortFuction);

            if (this.searchMatchFound)
                this.searchMatchFound(view, searchMatches);

            updateMatchesCountSoon.call(this);

            if (view === visibleView)
                view.jumpToFirstSearchResult();
        }

        var i = 0;
        var panel = this;
        var boundFinishedCallback = finishedCallback.bind(this);
        var chunkIntervalIdentifier = null;

        // Split up the work into chunks so we don't block the
        // UI thread while processing.

        function processChunk()
        {
            var view = searchableViews[i];

            if (++i >= searchableViews.length) {
                if (panel._currentSearchChrunkIntervalIdentifier === chunkIntervalIdentifier)
                    delete panel._currentSearchChrunkIntervalIdentifier;
                clearInterval(chunkIntervalIdentifier);
            }

            if (!view)
                return;

            if (view.element.parentNode !== parentElement && view.element.parentNode && parentElement)
                view.detach();

            view.currentQuery = query;
            view.performSearch(query, boundFinishedCallback);
        }

        processChunk();

        chunkIntervalIdentifier = setInterval(processChunk, 25);
        this._currentSearchChrunkIntervalIdentifier = chunkIntervalIdentifier;
    },

    jumpToNextSearchResult: function()
    {
        if (!this.showView || !this._searchResults || !this._searchResults.length)
            return;

        var showFirstResult = false;

        this._currentSearchResultIndex = this._searchResults.indexOf(this.visibleView);
        if (this._currentSearchResultIndex === -1) {
            this._currentSearchResultIndex = 0;
            showFirstResult = true;
        }

        var currentView = this._searchResults[this._currentSearchResultIndex];

        if (currentView.showingLastSearchResult()) {
            if (++this._currentSearchResultIndex >= this._searchResults.length)
                this._currentSearchResultIndex = 0;
            currentView = this._searchResults[this._currentSearchResultIndex];
            showFirstResult = true;
        }

        if (currentView !== this.visibleView)
            this.showView(currentView);

        if (showFirstResult)
            currentView.jumpToFirstSearchResult();
        else
            currentView.jumpToNextSearchResult();
    },

    jumpToPreviousSearchResult: function()
    {
        if (!this.showView || !this._searchResults || !this._searchResults.length)
            return;

        var showLastResult = false;

        this._currentSearchResultIndex = this._searchResults.indexOf(this.visibleView);
        if (this._currentSearchResultIndex === -1) {
            this._currentSearchResultIndex = 0;
            showLastResult = true;
        }

        var currentView = this._searchResults[this._currentSearchResultIndex];

        if (currentView.showingFirstSearchResult()) {
            if (--this._currentSearchResultIndex < 0)
                this._currentSearchResultIndex = (this._searchResults.length - 1);
            currentView = this._searchResults[this._currentSearchResultIndex];
            showLastResult = true;
        }

        if (currentView !== this.visibleView)
            this.showView(currentView);

        if (showLastResult)
            currentView.jumpToLastSearchResult();
        else
            currentView.jumpToPreviousSearchResult();
    }
}

WebInspector.Panel.prototype.__proto__ = WebInspector.View.prototype;
<commit_msg>Fix a typo.<commit_after>/*
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

WebInspector.Panel = function()
{
    WebInspector.View.call(this);

    this.element.addStyleClass("panel");
}

WebInspector.Panel.prototype = {
    get toolbarItem()
    {
        if (this._toolbarItem)
            return this._toolbarItem;

        // Sample toolbar item as markup:
        // <button class="toolbar-item resources toggleable">
        //

        //
Resources

        // </button>

        this._toolbarItem = document.createElement("button");
        this._toolbarItem.className = "toolbar-item toggleable";
        this._toolbarItem.panel = this;

        if ("toolbarItemClass" in this)
            this._toolbarItem.addStyleClass(this.toolbarItemClass);

        var iconElement = document.createElement("div");
        iconElement.className = "toolbar-icon";
        this._toolbarItem.appendChild(iconElement);

        if ("toolbarItemLabel" in this) {
            var labelElement = document.createElement("div");
            labelElement.className = "toolbar-label";
            labelElement.textContent = this.toolbarItemLabel;
            this._toolbarItem.appendChild(labelElement);
        }

        return this._toolbarItem;
    },

    show: function()
    {
        WebInspector.View.prototype.show.call(this);

        var statusBarItems = this.statusBarItems;
        if (statusBarItems) {
            this._statusBarItemContainer = document.createElement("div");
            for (var i = 0; i < statusBarItems.length; ++i)
                this._statusBarItemContainer.appendChild(statusBarItems[i]);
            document.getElementById("main-status-bar").appendChild(this._statusBarItemContainer);
        }

        if ("_toolbarItem" in this)
            this._toolbarItem.addStyleClass("toggled-on");

        WebInspector.currentFocusElement = document.getElementById("main-panels");
    },

    hide: function()
    {
        WebInspector.View.prototype.hide.call(this);

        if (this._statusBarItemContainer && this._statusBarItemContainer.parentNode)
            this._statusBarItemContainer.parentNode.removeChild(this._statusBarItemContainer);
        delete this._statusBarItemContainer;
        if ("_toolbarItem" in this)
            this._toolbarItem.removeStyleClass("toggled-on");
    },

    attach: function()
    {
        if (!this.element.parentNode)
            document.getElementById("main-panels").appendChild(this.element);
    },

    searchCanceled: function(startingNewSearch)
    {
        if (this._searchResults) {
            for (var i = 0; i < this._searchResults.length; ++i) {
                var view = this._searchResults[i];
                if (view.searchCanceled)
                    view.searchCanceled();
                delete view.currentQuery;
            }
        }

        WebInspector.updateSearchMatchesCount(0, this);

        if (this._currentSearchChunkIntervalIdentifier) {
            clearInterval(this._currentSearchChunkIntervalIdentifier);
            delete this._currentSearchChunkIntervalIdentifier;
        }

        this._totalSearchMatches = 0;
        this._currentSearchResultIndex = 0;
        this._searchResults = [];
    },

    performSearch: function(query)
    {
        // Call searchCanceled since it will reset everything we need before doing a new search.
        this.searchCanceled(true);

        var searchableViews = this.searchableViews;
        if (!searchableViews || !searchableViews.length)
            return;

        var parentElement = this.viewsContainerElement;
        var visibleView = this.visibleView;
        var sortFuction = this.searchResultsSortFunction;

        var matchesCountUpdateTimeout = null;

        function updateMatchesCount()
        {
            WebInspector.updateSearchMatchesCount(this._totalSearchMatches, this);
            matchesCountUpdateTimeout = null;
        }

        function updateMatchesCountSoon()
        {
            if (matchesCountUpdateTimeout)
                return;
            // Update the matches count every half-second so it doesn't feel twitchy.
            matchesCountUpdateTimeout = setTimeout(updateMatchesCount.bind(this), 500);
        }

        function finishedCallback(view, searchMatches)
        {
            if (!searchMatches)
                return;

            this._totalSearchMatches += searchMatches;
            this._searchResults.push(view);

            if (sortFuction)
                this._searchResults.sort(sortFuction);

            if (this.searchMatchFound)
                this.searchMatchFound(view, searchMatches);

            updateMatchesCountSoon.call(this);

            if (view === visibleView)
                view.jumpToFirstSearchResult();
        }

        var i = 0;
        var panel = this;
        var boundFinishedCallback = finishedCallback.bind(this);
        var chunkIntervalIdentifier = null;

        // Split up the work into chunks so we don't block the
        // UI thread while processing.

        function processChunk()
        {
            var view = searchableViews[i];

            if (++i >= searchableViews.length) {
                if (panel._currentSearchChunkIntervalIdentifier === chunkIntervalIdentifier)
                    delete panel._currentSearchChunkIntervalIdentifier;
                clearInterval(chunkIntervalIdentifier);
            }

            if (!view)
                return;

            if (view.element.parentNode !== parentElement && view.element.parentNode && parentElement)
                view.detach();

            view.currentQuery = query;
            view.performSearch(query, boundFinishedCallback);
        }

        processChunk();

        chunkIntervalIdentifier = setInterval(processChunk, 25);
        this._currentSearchChunkIntervalIdentifier = chunkIntervalIdentifier;
    },

    jumpToNextSearchResult: function()
    {
        if (!this.showView || !this._searchResults || !this._searchResults.length)
            return;

        var showFirstResult = false;

        this._currentSearchResultIndex = this._searchResults.indexOf(this.visibleView);
        if (this._currentSearchResultIndex === -1) {
            this._currentSearchResultIndex = 0;
            showFirstResult = true;
        }

        var currentView = this._searchResults[this._currentSearchResultIndex];

        if (currentView.showingLastSearchResult()) {
            if (++this._currentSearchResultIndex >= this._searchResults.length)
                this._currentSearchResultIndex = 0;
            currentView = this._searchResults[this._currentSearchResultIndex];
            showFirstResult = true;
        }

        if (currentView !== this.visibleView)
            this.showView(currentView);

        if (showFirstResult)
            currentView.jumpToFirstSearchResult();
        else
            currentView.jumpToNextSearchResult();
    },

    jumpToPreviousSearchResult: function()
    {
        if (!this.showView || !this._searchResults || !this._searchResults.length)
            return;

        var showLastResult = false;

        this._currentSearchResultIndex = this._searchResults.indexOf(this.visibleView);
        if (this._currentSearchResultIndex === -1) {
            this._currentSearchResultIndex = 0;
            showLastResult = true;
        }

        var currentView = this._searchResults[this._currentSearchResultIndex];

        if (currentView.showingFirstSearchResult()) {
            if (--this._currentSearchResultIndex < 0)
                this._currentSearchResultIndex = (this._searchResults.length - 1);
            currentView = this._searchResults[this._currentSearchResultIndex];
            showLastResult = true;
        }

        if (currentView !== this.visibleView)
            this.showView(currentView);

        if (showLastResult)
            currentView.jumpToLastSearchResult();
        else
            currentView.jumpToPreviousSearchResult();
    }
}

WebInspector.Panel.prototype.__proto__ = WebInspector.View.prototype;
<|endoftext|>


<commit_before>//typpo.js
//by noah levenson

function Typpo(options) {

    this.self = this;

	this.speed = 0;

	this.badness = 0;

	this.correctionSpeed = 30;

	this.showCursor = false;

	this.cursor = "|";

	this.destination = document.getElementById(options.element);

	if (options.speed) {

		if (options.speed > 100) {

			this.speed = 100;

		}

		else if (options.speed < 0) {

			this.speed = 0;

		}

		else {

			this.speed = options.speed;

		}

	}

	this.slowness = 1000 - (this.speed * 10);

	if (options.badness) {

		if (options.badness > 100) {

			this.badness = 100;

		}

		else if (options.badness < 0) {

			this.badness = 0;

		}

		else {

			this.badness = options.badness;

		}

	}

	this.probability = this.badness / 100;

	if (options.correctionSpeed) {

		if (options.correctionSpeed > 100) {

			this.correctionSpeed = 100;

		}

		else if (options.correctionSpeed < 0) {

			this.correctionSpeed = 0;

		}

		else {

			this.correctionSpeed = options.correctionSpeed;

		}

	}

	this.backspaceSlowness = 1000 - (this.correctionSpeed * 10);

	this.pressKey = function(c) {

        window.requestAnimationFrame(function() {

            this.self.destination.innerHTML = this.self.destination.innerHTML + this.c;

        }.bind({self: this.self, c: c}));

	}

    this.write = function(s, callback, pos) {

        if (!pos) {

            var pos = 0;

        }

        if (!callback) {

            var callback = null;
        }

        setTimeout(function() {

            var c = this.s.substr(this.pos, 1);

            if (this.self.errorTable.hasOwnProperty(c) && this.self.probability > Math.random()) {

                this.self.pressKey(this.self.errorTable[c][Math.floor(Math.random() * this.self.errorTable[c].length)]);

                setTimeout(function() {

                    var html = this.self.destination.innerHTML;

                    window.requestAnimationFrame(function() {

                        this.self.destination.innerHTML = html.substr(0, html.length - 1);

                        this.self.write(this.s, this.callback, this.pos);

                    }.bind({self: this.self, s: this.s, callback: this.callback, pos: this.pos}));

                }.bind({self: this.self, s: this.s, callback: this.callback, pos: this.pos}), Math.random() * this.self.backspaceSlowness);

            }

            else {

                this.self.pressKey(c);

                this.pos += 1;

                if (this.pos <= this.s.length) {

                    this.self.write(this.s, this.callback, this.pos);

                }

                else {

                    if (callback) {

                        callback();

                    }

                }

            }

        }.bind({self: this.self, s: s, callback: callback, pos: pos}), Math.random() * this.self.slowness);

    }

    this.enter = function(n) {

        if (n && n > 1) {

            for (var i = 0; i < n; i += 1) {

                this.destination.innerHTML = this.destination.innerHTML + "
";

            }

        }

        else {

            this.destination.innerHTML = this.destination.innerHTML + "
";

        }

    }

	this.errorTable = {

		a: ["s", "z", "q"],
		b: ["v", "g", "n"],
		c: ["x", "d", "v"],
		d: ["s", "f", "c", "e"],
		e: ["w", "r", "d"],
		f: ["d", "g", "v", "r"],
		g: ["f", "h", "t", "b"],
		h: ["g", "j", "y", "n"],
		i: ["o", "u", "k"],
		j: ["h", "k", "u", "m"],
		k: ["l", "j", "i", ","],
		l: ["k", ";", "o", "."],
		m: ["n", ",", "j"],
		n: ["b", "m", "h"],
		o: ["i", "p", "l"],
		p: ["o", "[", ";"],
		q: ["w", "a"],
		r: ["e", "t", "f"],
		s: ["a", "d", "w", "x"],
		t: ["r", "y", "g"],
		u: ["y", "i", "j"],
		v: ["c", "b", "f"],
		w: ["q", "e", "s"],
		x: ["z", "c", "s"],
		y: ["t", "u", "h"],
		z: ["x", "a"],
		A: ["s", "z", "q", "a"],
		B: ["v", "n", "g", "b"],
		C: ["x", "v", "d", "c"],
		D: ["s", "f", "c", "e", "d"],
		E: ["w", "r", "d", "e"],
		F: ["d", "g", "r", "v", "f"],
		G: ["f", "h", "t", "b", "g"],
		H: ["g", "j", "y", "n", "h"],
		I: ["u", "o", "k", "i"],
		J: ["h", "k", "u", "m", "j"],
		K: ["j", "l", "i", ",", "k"],
		L: ["k", ";", "o", ".", "l"],
		M: ["m", ",", "j", "m"],
		N: ["b", "m", "h", "n"],
		O: ["i", "p", "l", "o"],
		P: ["o", "[", ";", "p"],
		Q: ["a", "s", "w", "q"],
		R: ["e", "t", "f", "r"],
		S: ["a", "d", "w", "x", "s"],
		T: ["r", "y", "g", "t"],
		U: ["y", "i", "j", "u"],
		V: ["c", "b", "f", "v"],
		W: ["e", "q", "s", "w"],
		X: ["z", "c", "s", "x"],
		Y: ["t", "u", "h", "y"],
		Z: ["x", "s", "a", "z"],
        "!": ["1", "@", "~"],
        "@": ["2", "!", "#"],
        "#": ["3", "@", "$"],
        "$": ["4", "#", "%"],
        "%": ["5", "$", "^"],
        "^": ["6", "%", "&"],
        "&": ["7", "^", "*"],
        "*": ["8,", "&", "("],
        "(": ["9", "*", ")"],
        ")": ["0", "(", "_"],
        "_": ["-", ")", "+"],
        "+": ["=", "_"]

	};

}

<commit_msg>Added header comment<commit_after>/*
*
*	typpo.js
*	A JavaScript library for procedurally animating imperfect typing
*	by Noah Levenson
*
*	https://github.com/noahlevenson/typpo.js
*
*/

function Typpo(options) {

    this.self = this;

	this.speed = 0;

	this.badness = 0;

	this.correctionSpeed = 30;

	this.showCursor = false;

	this.cursor = "|";

	this.destination = document.getElementById(options.element);

	if (options.speed) {

		if (options.speed > 100) {

			this.speed = 100;

		}

		else if (options.speed < 0) {

			this.speed = 0;

		}

		else {

			this.speed = options.speed;

		}

	}

	this.slowness = 1000 - (this.speed * 10);

	if (options.badness) {

		if (options.badness > 100) {

			this.badness = 100;

		}

		else if (options.badness < 0) {

			this.badness = 0;

		}

		else {

			this.badness = options.badness;

		}

	}

	this.probability = this.badness / 100;

	if (options.correctionSpeed) {

		if (options.correctionSpeed > 100) {

			this.correctionSpeed = 100;

		}

		else if (options.correctionSpeed < 0) {

			this.correctionSpeed = 0;

		}

		else {

			this.correctionSpeed = options.correctionSpeed;

		}

	}

	this.backspaceSlowness = 1000 - (this.correctionSpeed * 10);

	this.pressKey = function(c) {

        window.requestAnimationFrame(function() {

            this.self.destination.innerHTML = this.self.destination.innerHTML + this.c;

        }.bind({self: this.self, c: c}));

	}

    this.write = function(s, callback, pos) {

        if (!pos) {

            var pos = 0;

        }

        if (!callback) {

            var callback = null;
        }

        setTimeout(function() {

            var c = this.s.substr(this.pos, 1);

            if (this.self.errorTable.hasOwnProperty(c) && this.self.probability > Math.random()) {

                this.self.pressKey(this.self.errorTable[c][Math.floor(Math.random() * this.self.errorTable[c].length)]);

                setTimeout(function() {

                    var html = this.self.destination.innerHTML;

                    window.requestAnimationFrame(function() {

                        this.self.destination.innerHTML = html.substr(0, html.length - 1);

                        this.self.write(this.s, this.callback, this.pos);

                    }.bind({self: this.self, s: this.s, callback: this.callback, pos: this.pos}));

                }.bind({self: this.self, s: this.s, callback: this.callback, pos: this.pos}), Math.random() * this.self.backspaceSlowness);

            }

            else {

                this.self.pressKey(c);

                this.pos += 1;

                if (this.pos <= this.s.length) {

                    this.self.write(this.s, this.callback, this.pos);

                }

                else {

                    if (callback) {

                        callback();

                    }

                }

            }

        }.bind({self: this.self, s: s, callback: callback, pos: pos}), Math.random() * this.self.slowness);

    }

    this.enter = function(n) {

        if (n && n > 1) {

            for (var i = 0; i < n; i += 1) {

                this.destination.innerHTML = this.destination.innerHTML + "
";

            }

        }

        else {

            this.destination.innerHTML = this.destination.innerHTML + "
";

        }

    }

	this.errorTable = {

		a: ["s", "z", "q"],
		b: ["v", "g", "n"],
		c: ["x", "d", "v"],
		d: ["s", "f", "c", "e"],
		e: ["w", "r", "d"],
		f: ["d", "g", "v", "r"],
		g: ["f", "h", "t", "b"],
		h: ["g", "j", "y", "n"],
		i: ["o", "u", "k"],
		j: ["h", "k", "u", "m"],
		k: ["l", "j", "i", ","],
		l: ["k", ";", "o", "."],
		m: ["n", ",", "j"],
		n: ["b", "m", "h"],
		o: ["i", "p", "l"],
		p: ["o", "[", ";"],
		q: ["w", "a"],
		r: ["e", "t", "f"],
		s: ["a", "d", "w", "x"],
		t: ["r", "y", "g"],
		u: ["y", "i", "j"],
		v: ["c", "b", "f"],
		w: ["q", "e", "s"],
		x: ["z", "c", "s"],
		y: ["t", "u", "h"],
		z: ["x", "a"],
		A: ["s", "z", "q", "a"],
		B: ["v", "n", "g", "b"],
		C: ["x", "v", "d", "c"],
		D: ["s", "f", "c", "e", "d"],
		E: ["w", "r", "d", "e"],
		F: ["d", "g", "r", "v", "f"],
		G: ["f", "h", "t", "b", "g"],
		H: ["g", "j", "y", "n", "h"],
		I: ["u", "o", "k", "i"],
		J: ["h", "k", "u", "m", "j"],
		K: ["j", "l", "i", ",", "k"],
		L: ["k", ";", "o", ".", "l"],
		M: ["m", ",", "j", "m"],
		N: ["b", "m", "h", "n"],
		O: ["i", "p", "l", "o"],
		P: ["o", "[", ";", "p"],
		Q: ["a", "s", "w", "q"],
		R: ["e", "t", "f", "r"],
		S: ["a", "d", "w", "x", "s"],
		T: ["r", "y", "g", "t"],
		U: ["y", "i", "j", "u"],
		V: ["c", "b", "f", "v"],
		W: ["e", "q", "s", "w"],
		X: ["z", "c", "s", "x"],
		Y: ["t", "u", "h", "y"],
		Z: ["x", "s", "a", "z"],
        "!": ["1", "@", "~"],
        "@": ["2", "!", "#"],
        "#": ["3", "@", "$"],
        "$": ["4", "#", "%"],
        "%": ["5", "$", "^"],
        "^": ["6", "%", "&"],
        "&": ["7", "^", "*"],
        "*": ["8,", "&", "("],
        "(": ["9", "*", ")"],
        ")": ["0", "(", "_"],
        "_": ["-", ")", "+"],
        "+": ["=", "_"]

	};

}

<|endoftext|>


<commit_before>// ==UserScript==
// @name Memer
// @description Translates memes to hover overs and links
// @version 0.2
// @match http://chat.stackexchange.com/rooms/*
// @match http://chat.stackocerflow.com/rooms/*
// @authors
//		-- Ismael Miguel
//		-- Malachi26
//		-- The-Quill
// @run-at document-end
// @grant none
// ==/UserScript==
if (location.hostname == 'chat.stackexchange.com' || location.hostname == 'chat.stackoverflow.com')
{
	;(function (window, undefined){
		'use strict';
		//Just in case of jQuery.noConflict();
		(function($) {

			var REPO = 'https://github.com/ismael-miguel/memer/';
			var ROOT = 'https://raw.githubusercontent.com/ismael-miguel/memer/master/memes/';
			//Please, StackExchange, give us something decent!
			//This fixed a bug where another chat plugin would break the matching
			var SITE = $('head link[rel="shortcut icon"]')[0].href.match(/static.net\/([^\/]+)\//)[1];

			//avoids creating a global function
			var translate = function() {
				$('#chat .message:not([data-checked="1"])')
					.attr('data-checked', 1)
					.find('>.content')
					.filter(':not(:has(.onebox))')
					.contents()
					.filter(function() {

						return this.nodeType === window.Node.TEXT_NODE;

					}).each(function() {

						var tmp_html = $('
');
						tmp_html.text(this.nodeValue);

						for(var type in meme_database)
						{
							memerize(tmp_html, meme_database[type].memes,meme_database[type].meta);
						}

						$(this).replaceWith(tmp_html.html());
					});

				setTimeout(translate, 5000);
			};

			var memerize = function(tmp_html, memes, meta) {
				for (var meme_name in memes)
				{
					var meme = memes[meme_name];
					var find = meme.find
						? new RegExp(meme.find[0], meme.find[1])
						: new RegExp('(' + (meme_name.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')) + ')', 'g');
					var replace = [
							'$1'
						].join('');

					$(tmp_html).contents().each(function() {
						//It's stupid, but it must be done
						if (this.nodeType === window.Node.TEXT_NODE)
						{
							$(this).replaceWith(this.nodeValue.replace(find, replace));
						}
					});
				}
			};

			//this will be where all data is saved
			var meme_database = {
				'common': '_common',
				'memes': SITE
			};

			var sources = ['common', 'memes'];

			var popup = function(html) {
				//yup, standard way to create the popup
				popUp(0, 0)
					.css({
						'width': 'auto',
						'maxWidth': 300,
						'minWidth': 300,
						'top': 0,
						'left': (window.innerWidth - 300) / 2
					})
					.addClass('user-popup')
					.append(html);
			};

			var loader = function(){
				var source = sources.shift();
				$.get(
					ROOT + meme_database[source] + '.json',
					function(data) {
					if(data && (data = $.parseJSON(data)))
					{
						meme_database[source] = data;
					}
				})
				.fail(function(){
					//yeah, google chrome has an assy API. detects when running as extention
					//read http://stackoverflow.com/questions/7507277/detecting-if-code-is-being-run-as-a-chrome-extension
					if(window.chrome && chrome.runtime && chrome.runtime.id)
					{
						alert([
							'Memer error:',
							'Failed to load ' + meme_database[source] + '.json',
							'Visit ' + REPO + ' and check if it is available or provide your own'
						].join('\n'));
					}
					else
					{
						popup([ //what an ugly piece of code!
							'
Memer error:
',
							'
Failed to load ' + meme_database[source] + '.json
',
							'
If you are sure your connection is working, head to',
								' Memer\'s github ',
							'and provide your meme list.
'
						].join(''));
					}
					meme_database[source] = {};
				}).always(function(){
					if(sources.length)
					{
						setTimeout(loader, 0);
					}
					else
					{
						//only show when not running as an extention
						if(!window.chrome && !window.chrome.runtime && !window.chrome.runtime.id)
						{
							popup('
Memer:

All the files loaded successfully
');
						}
						setTimeout(translate, 5000);
					}
				});
			};

			loader();

		})(window.jQuery);
	})(Function('return this')());
}<commit_msg>Fixed a spelling error<commit_after>// ==UserScript==
// @name Memer
// @description Translates memes to hover overs and links
// @version 0.2
// @match http://chat.stackexchange.com/rooms/*
// @match http://chat.stackoverflow.com/rooms/*
// @authors
//		-- Ismael Miguel
//		-- Malachi26
//		-- The-Quill
// @run-at document-end
// @grant none
// ==/UserScript==
if (location.hostname == 'chat.stackexchange.com' || location.hostname == 'chat.stackoverflow.com')
{
	;(function (window, undefined){
		'use strict';
		//Just in case of jQuery.noConflict();
		(function($) {

			var REPO = 'https://github.com/ismael-miguel/memer/';
			var ROOT = 'https://raw.githubusercontent.com/ismael-miguel/memer/master/memes/';
			//Please, StackExchange, give us something decent!
			//This fixed a bug where another chat plugin would break the matching
			var SITE = $('head link[rel="shortcut icon"]')[0].href.match(/static.net\/([^\/]+)\//)[1];

			//avoids creating a global function
			var translate = function() {
				$('#chat .message:not([data-checked="1"])')
					.attr('data-checked', 1)
					.find('>.content')
					.filter(':not(:has(.onebox))')
					.contents()
					.filter(function() {

						return this.nodeType === window.Node.TEXT_NODE;

					}).each(function() {

						var tmp_html = $('
');
						tmp_html.text(this.nodeValue);

						for(var type in meme_database)
						{
							memerize(tmp_html, meme_database[type].memes,meme_database[type].meta);
						}

						$(this).replaceWith(tmp_html.html());
					});

				setTimeout(translate, 5000);
			};

			var memerize = function(tmp_html, memes, meta) {
				for (var meme_name in memes)
				{
					var meme = memes[meme_name];
					var find = meme.find
						? new RegExp(meme.find[0], meme.find[1])
						: new RegExp('(' + (meme_name.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')) + ')', 'g');
					var replace = [
							'$1'
						].join('');

					$(tmp_html).contents().each(function() {
						//It's stupid, but it must be done
						if (this.nodeType === window.Node.TEXT_NODE)
						{
							$(this).replaceWith(this.nodeValue.replace(find, replace));
						}
					});
				}
			};

			//this will be where all data is saved
			var meme_database = {
				'common': '_common',
				'memes': SITE
			};

			var sources = ['common', 'memes'];

			var popup = function(html) {
				//yup, standard way to create the popup
				popUp(0, 0)
					.css({
						'width': 'auto',
						'maxWidth': 300,
						'minWidth': 300,
						'top': 0,
						'left': (window.innerWidth - 300) / 2
					})
					.addClass('user-popup')
					.append(html);
			};

			var loader = function(){
				var source = sources.shift();
				$.get(
					ROOT + meme_database[source] + '.json',
					function(data) {
					if(data && (data = $.parseJSON(data)))
					{
						meme_database[source] = data;
					}
				})
				.fail(function(){
					//yeah, google chrome has an assy API. detects when running as extention
					//read http://stackoverflow.com/questions/7507277/detecting-if-code-is-being-run-as-a-chrome-extension
					if(window.chrome && chrome.runtime && chrome.runtime.id)
					{
						alert([
							'Memer error:',
							'Failed to load ' + meme_database[source] + '.json',
							'Visit ' + REPO + ' and check if it is available or provide your own'
						].join('\n'));
					}
					else
					{
						popup([ //what an ugly piece of code!
							'
Memer error:
',
							'
Failed to load ' + meme_database[source] + '.json
',
							'
If you are sure your connection is working, head to',
								' Memer\'s github ',
							'and provide your meme list.
'
						].join(''));
					}
					meme_database[source] = {};
				}).always(function(){
					if(sources.length)
					{
						setTimeout(loader, 0);
					}
					else
					{
						//only show when not running as an extention
						if(!window.chrome && !window.chrome.runtime && !window.chrome.runtime.id)
						{
							popup('
Memer:

All the files loaded successfully
');
						}
						setTimeout(translate, 5000);
					}
				});
			};

			loader();

		})(window.jQuery);
	})(Function('return this')());
}
<|endoftext|>


<commit_before>(function () {
    'use strict';

    /**
     * @param Base
     * @param {Waves} waves
     * @param {User} user
     * @param createPoll
     * @param {NotificationManager} notificationManager
     * @return {DexMyOrders}
     */
    const controller = function (Base, waves, user, createPoll, notificationManager) {

        class DexMyOrders extends Base {

            constructor() {
                super();

                /**
                 * @type {string}
                 * @private
                 */
                this._amountAssetId = null;
                /**
                 * @type {string}
                 * @private
                 */
                this._priceAssetId = null;

                this.syncSettings({
                    _amountAssetId: 'dex.amountAssetId',
                    _priceAssetId: 'dex.priceAssetId'
                });

                const poll = createPoll(this, this._getOrders, 'orders', 5000);
                this.observe(['_amountAssetId', '_priceAssetId'], () => poll.restart());
            }

            dropOrder(order) {
                user.getSeed().then((seed) => {
                    waves.matcher.cancelOrder(order.amount.asset.id, order.price.asset.id, order.id, seed.keyPair)
                        .then(() => {
                            const canceledOrder = tsUtils.find(this.orders, { id: order.id });
                            canceledOrder.state = 'Canceled';
                            notificationManager.info({
                                ns: 'app.dex',
                                title: { literal: 'directives.myOrders.notifications.isCanceled' }
                            });
                        })
                        .catch(() => {
                            notificationManager.error({
                                ns: 'app.dex',
                                title: { literal: 'directives.myOrders.notifications.somethingWentWrong' }
                            });
                        });
                });
            }

            /**
             * @returns {Promise}
             * @private
             */
            _getOrders() {
                return user.getSeed()
                    .then((seed) => waves.matcher.getOrders(seed.keyPair))
                    .then((orders) => {
                        const active = orders.filter(({ status }) => status === 'Accepted');
                        const filled = orders.filter(({ status }) => status === 'Filled');
                        const others = orders.filter(({ status }) => status !== 'Accepted' && status !== 'Filled');
                        return active.concat(filled).concat(others);
                    });
            }

        }

        return new DexMyOrders();
    };

    controller.$inject = ['Base', 'waves', 'user', 'createPoll', 'notificationManager'];

    angular.module('app.dex').component('wDexMyOrders', {
        bindings: {},
        templateUrl: 'modules/dex/directives/dexMyOrders/myOrders.html',
        controller
    });
})();
<commit_msg>CLIENT-292: fix myOrders<commit_after>(function () {
    'use strict';

    /**
     * @param Base
     * @param {Waves} waves
     * @param {User} user
     * @param createPoll
     * @param {NotificationManager} notificationManager
     * @param {app.utils} utils
     * @return {DexMyOrders}
     */
    const controller = function (Base, waves, user, createPoll, notificationManager, utils) {

        class DexMyOrders extends Base {

            constructor() {
                super();

                /**
                 * @type {string}
                 * @private
                 */
                this._amountAssetId = null;
                /**
                 * @type {string}
                 * @private
                 */
                this._priceAssetId = null;

                this.syncSettings({
                    _amountAssetId: 'dex.amountAssetId',
                    _priceAssetId: 'dex.priceAssetId'
                });

                const poll = createPoll(this, this._getOrders, 'orders', 5000);
                this.observe(['_amountAssetId', '_priceAssetId'], () => poll.restart());
            }

            dropOrder(order) {
                user.getSeed().then((seed) => {
                    waves.matcher.cancelOrder(order.amount.asset.id, order.price.asset.id, order.id, seed.keyPair)
                        .then(() => {
                            const canceledOrder = tsUtils.find(this.orders, { id: order.id });
                            canceledOrder.state = 'Canceled';
                            notificationManager.info({
                                ns: 'app.dex',
                                title: { literal: 'directives.myOrders.notifications.isCanceled' }
                            });
                        })
                        .catch(() => {
                            notificationManager.error({
                                ns: 'app.dex',
                                title: { literal: 'directives.myOrders.notifications.somethingWentWrong' }
                            });
                        });
                });
            }

            /**
             * @returns {Promise}
             * @private
             */
            _getOrders() {
                return user.getSeed()
                    .then((seed) => waves.matcher.getOrders(seed.keyPair))
                    .then((orders) => {
                        const active = [];
                        const filled = [];
                        const others = [];
                        orders.forEach((order) => {
                            switch (order.status) {
                                case 'Accepted':
                                    active.push(order);
                                    break;
                                case 'Filled':
                                    filled.push(order);
                                    break;
                                default:
                                    others.push(order);
                            }
                        });

                        active.sort(utils.comparators.process(({ timestamp }) => timestamp).desc);
                        filled.sort(utils.comparators.process(({ timestamp }) => timestamp).desc);
                        others.sort(utils.comparators.process(({ timestamp }) => timestamp).desc);

                        return active.concat(filled).concat(others);
                    });
            }

        }

        return new DexMyOrders();
    };

    controller.$inject = ['Base', 'waves', 'user', 'createPoll', 'notificationManager', 'utils'];

    angular.module('app.dex').component('wDexMyOrders', {
        bindings: {},
        templateUrl: 'modules/dex/directives/dexMyOrders/myOrders.html',
        controller
    });
})();
<|endoftext|>