<commit_before>// Copyright 2016, University of Colorado Boulder

/**
 * TObject is the root of the wrapper type hierarchy.  All wrapper types extend from TObject.
 * TObject also applies any "eager" customizations to instances immediately after they are
 * registered with PhET-iO.  The customizations are supplied via the phet-io.expressions query
 * parameter or set with TPhetIO.addExpressions.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var phetio = require( 'PHET_IO/phetio' );

  var phetioExpressionsString = phet.chipper.queryParameters[ 'phet-io.expressions' ];
  var phetioExpressionsJSON = JSON.parse( phetioExpressionsString );

  /**
   * Apply a customization expression to a wrapped object.
   * @param {Object} instance
   * @param {string} phetioID
   * @param {Object} wrapper
   * @param {function} type
   * @param {Object} phetioExpression
   */
  var applyExpression = function( instance, phetioID, wrapper, type, phetioExpression ) {
    if ( phetioID === phetioExpression[ 0 ] ) {
      var methodName = phetioExpression[ 1 ];
      var args = phetioExpression[ 2 ];

      // Map using fromStateObject from the type method signature
      var signature = type.getMethodDeclaration( methodName );
      assert && assert( !!signature, 'Method declaration not found for ' + type.typeName + '.' + methodName );

      // Convert from JSON to objects
      var parameterTypes = signature.parameterTypes;
      assert && assert( parameterTypes, 'parameterTypes not defined' );
      assert && assert( parameterTypes.length === args.length, 'wrong number of arguments' );
      var stateObjects = [];
      for ( var k = 0; k < args.length; k++ ) {
        stateObjects.push( parameterTypes[ k ].fromStateObject( args[ k ] ) );
      }

      // phetio.setState is scheduled for after the simulation launches
      if ( phetioID === 'phetio' && methodName === 'setState' ) {

        // IIFE to capture iteration vars
        (function( wrapper, methodName, stateObjects ) {
          phetio.simulationStartedEmitter.addListener( function() {
            wrapper[ methodName ].apply( wrapper, stateObjects );
          } );
        })( wrapper, methodName, stateObjects );
      }
      else {
        // invoke the method on the wrapper immediately after wrapper construction using the parsed/marshalled args
        wrapper[ methodName ].apply( wrapper, stateObjects );
      }
    }
  };

  /**
   * Apply all customization expressions to a newly registered simulation instance.
   *
   * @param {Object} instance
   * @param {string} phetioID
   * @param {Object} wrapper
   * @param {function} type
   */
  var applyExpressions = function( instance, phetioID, wrapper, type ) {

    // Apply query parameters first
    for ( var i = 0; i < phetioExpressionsJSON.length; i++ ) {
      applyExpression( instance, phetioID, wrapper, type, phetioExpressionsJSON[ i ] );
    }

    // Apply values set through addExpressions
    if ( window.phetioExpressions ) {
      for ( i = 0; i < window.phetioExpressions.length; i++ ) {

        // When https://github.com/phetsims/phet-io/issues/573 is addressed, there will be no need to package as array
        var expression = [
          window.phetioExpressions[ i ].phetioID,
          window.phetioExpressions[ i ].method,
          window.phetioExpressions[ i ].args
        ];
        applyExpression( instance, phetioID, wrapper, type, expression );
      }
    }
  };

  /**
   * Main constructor for TObject base wrapper type.
   * @param {Object} instance
   * @param {string} phetioID
   * @constructor
   */
  function TObject( instance, phetioID ) {
    assert && assert( instance, 'instance should be truthy' );
    assert && assert( phetioID, 'phetioID should be truthy' );

    // @public
    this.instance = instance;

    // @public
    this.phetioID = phetioID;

    // If any query parameter calls have been made, apply them now.
    // Pass the self sub-type because this is called before the type is registered with phetio
    applyExpressions( instance, phetioID, this, this.constructor );
  }

  // TObject inherits from window.Object because it starts with its prototype in phetioInherit.inheritBase
  // However, when serialized, the TObject supertype is reported as null (not sent in the JSON).
  phetioInherit( window.Object, 'TObject', TObject, {}, {
    documentation: 'The root of the wrapper object hierarchy',

    /**
     * Decodes the object from a state, used in phetio.setState.  This should be overriden
     * by subclasses.
     * @param o
     * @returns {*}
     */
    fromStateObject: function( o ) {
      return o;
    }
  } );

  phetioNamespace.register( 'TObject', TObject );

  return TObject;
} );<commit_msg>Renamed ?phet-io.value => ?phetioValue, see https://github.com/phetsims/phet-io/issues/859<commit_after>// Copyright 2016, University of Colorado Boulder

/**
 * TObject is the root of the wrapper type hierarchy.  All wrapper types extend from TObject.
 * TObject also applies any "eager" customizations to instances immediately after they are
 * registered with PhET-iO.  The customizations are supplied via the phetioExpressions query
 * parameter or set with TPhetIO.addExpressions.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var phetio = require( 'PHET_IO/phetio' );

  var phetioExpressionsString = phet.chipper.queryParameters.phetioExpressions;
  var phetioExpressionsJSON = JSON.parse( phetioExpressionsString );

  /**
   * Apply a customization expression to a wrapped object.
   * @param {Object} instance
   * @param {string} phetioID
   * @param {Object} wrapper
   * @param {function} type
   * @param {Object} phetioExpression
   */
  var applyExpression = function( instance, phetioID, wrapper, type, phetioExpression ) {
    if ( phetioID === phetioExpression[ 0 ] ) {
      var methodName = phetioExpression[ 1 ];
      var args = phetioExpression[ 2 ];

      // Map using fromStateObject from the type method signature
      var signature = type.getMethodDeclaration( methodName );
      assert && assert( !!signature, 'Method declaration not found for ' + type.typeName + '.' + methodName );

      // Convert from JSON to objects
      var parameterTypes = signature.parameterTypes;
      assert && assert( parameterTypes, 'parameterTypes not defined' );
      assert && assert( parameterTypes.length === args.length, 'wrong number of arguments' );
      var stateObjects = [];
      for ( var k = 0; k < args.length; k++ ) {
        stateObjects.push( parameterTypes[ k ].fromStateObject( args[ k ] ) );
      }

      // phetio.setState is scheduled for after the simulation launches
      if ( phetioID === 'phetio' && methodName === 'setState' ) {

        // IIFE to capture iteration vars
        (function( wrapper, methodName, stateObjects ) {
          phetio.simulationStartedEmitter.addListener( function() {
            wrapper[ methodName ].apply( wrapper, stateObjects );
          } );
        })( wrapper, methodName, stateObjects );
      }
      else {
        // invoke the method on the wrapper immediately after wrapper construction using the parsed/marshalled args
        wrapper[ methodName ].apply( wrapper, stateObjects );
      }
    }
  };

  /**
   * Apply all customization expressions to a newly registered simulation instance.
   *
   * @param {Object} instance
   * @param {string} phetioID
   * @param {Object} wrapper
   * @param {function} type
   */
  var applyExpressions = function( instance, phetioID, wrapper, type ) {

    // Apply query parameters first
    for ( var i = 0; i < phetioExpressionsJSON.length; i++ ) {
      applyExpression( instance, phetioID, wrapper, type, phetioExpressionsJSON[ i ] );
    }

    // Apply values set through addExpressions
    if ( window.phetioExpressions ) {
      for ( i = 0; i < window.phetioExpressions.length; i++ ) {

        // When https://github.com/phetsims/phet-io/issues/573 is addressed, there will be no need to package as array
        var expression = [
          window.phetioExpressions[ i ].phetioID,
          window.phetioExpressions[ i ].method,
          window.phetioExpressions[ i ].args
        ];
        applyExpression( instance, phetioID, wrapper, type, expression );
      }
    }
  };

  /**
   * Main constructor for TObject base wrapper type.
   * @param {Object} instance
   * @param {string} phetioID
   * @constructor
   */
  function TObject( instance, phetioID ) {
    assert && assert( instance, 'instance should be truthy' );
    assert && assert( phetioID, 'phetioID should be truthy' );

    // @public
    this.instance = instance;

    // @public
    this.phetioID = phetioID;

    // If any query parameter calls have been made, apply them now.
    // Pass the self sub-type because this is called before the type is registered with phetio
    applyExpressions( instance, phetioID, this, this.constructor );
  }

  // TObject inherits from window.Object because it starts with its prototype in phetioInherit.inheritBase
  // However, when serialized, the TObject supertype is reported as null (not sent in the JSON).
  phetioInherit( window.Object, 'TObject', TObject, {}, {
    documentation: 'The root of the wrapper object hierarchy',

    /**
     * Decodes the object from a state, used in phetio.setState.  This should be overriden
     * by subclasses.
     * @param o
     * @returns {*}
     */
    fromStateObject: function( o ) {
      return o;
    }
  } );

  phetioNamespace.register( 'TObject', TObject );

  return TObject;
} );<|endoftext|>


<commit_before>import electron from 'electron';
import multihashes from 'multihashes';
import { View } from 'backbone';
import loadTemplate from '../utils/loadTemplate';
import app from '../app';
import { getDoc } from '../utils/selectors';

const remote = electron.remote;

export default class PageNav extends View {
  constructor(options) {
    super({
      className: 'pageNav',
      events: {
        'click .js-navClose': 'navCloseClick',
        'click .js-navMin': 'navMinClick',
        'click .js-navMax': 'navMaxClick',
        'keyup .js-addressBar': 'onKeyupAddressBar',
        'click .js-navListBtn': 'navListBtnClick',
        'click .js-navSettings': 'navSettingsClick',
        'click document': 'onDocClick',
      },
      ...options,
    });

    getDoc().on('click', this.onDocClick.bind(this));

    this.listenTo(app.localSettings, 'change:mac_style_win_controls',
      this.onWinControlsStyleChange);
    this.setWinControlsStyle(app.localSettings.get('mac_style_win_controls') ? 'mac' : 'win');
  }

  setWinControlsStyle(style) {
    if (style !== 'mac' && style !== 'win') {
      throw new Error('Style must be \'mac\' or \'win\'.');
    }

    this.$el.removeClass('winStyleWindowControls macStyleWindowControls');
    this.$el.addClass(style === 'mac' ? 'macStyleWindowControls' : 'winStyleWindowControls');
  }

  onWinControlsStyleChange(model, useMacStyle) {
    this.setWinControlsStyle(useMacStyle ? 'mac' : 'win');
  }

  navCloseClick() {
    if (remote.process.platform !== 'darwin') {
      remote.getCurrentWindow().close();
    } else {
      remote.getCurrentWindow().hide();
    }
  }

  navMinClick() {
    remote.getCurrentWindow().minimize();
  }

  navMaxClick() {
    if (remote.getCurrentWindow().isMaximized()) {
      remote.getCurrentWindow().unmaximize();
      // this.$('.js-navMax').attr('data-tooltip', window.polyglot.t('Maximize'));
    } else {
      remote.getCurrentWindow().maximize();
      // this.$('.js-navMax').attr('data-tooltip', window.polyglot.t('Restore'));
    }
  }

  navListBtnClick() {
    const $popMenu = this.$navList;
    this.togglePopMenu($popMenu);
  }

  togglePopMenu($popMenu) {
    if ($popMenu) {
      this.$popMenus.not($popMenu).removeClass('open');
      $popMenu.toggleClass('open');
    } else {
      this.$popMenus.removeClass('open');
    }
  }

  onDocClick(e) {
    if (!this.$(e.target).closest('.js-navListBtn, .js-navNotifBtn, .js-navPopMenu').length) {
      this.togglePopMenu();
    }
  }

  onKeyupAddressBar(e) {
    if (e.which === 13) {
      let text = this.$addressBar.val();
      let isGuid = true;

      if (text.startsWith('ob://')) text = text.slice(5);

      const firstTerm = text.split(' ')[0];

      try {
        multihashes.validate(multihashes.fromB58String(firstTerm));
      } catch (exc) {
        isGuid = false;
      }

      // temporary way to check for GUIDs, since our dummy guids from
      // start.js aren't valid v2 guids, but are registered with the
      // one-name api.
      if (firstTerm.startsWith('Qm')) isGuid = true;
      // end - temporary guid check

      if (isGuid) {
        app.router.navigate(firstTerm, { trigger: true });
      } else if (firstTerm.charAt(0) === '@' && firstTerm.length > 1) {
        // a handle
        app.router.navigate(firstTerm, { trigger: true });
      } else {
        // tag(s)
        const tags = text.trim()
          .replace(',', ' ')
          .replace(/\s+/g, ' ') // collapse multiple spaces into single spaces
          .split(' ')
          .map((frag) => (frag.charAt(0) === '#' ? frag.slice(1) : frag));

        alert(`boom - Searching for tags: ${tags.join(', ')}`);
      }
    }
  }

  setAddressBar(text = '') {
    if (this.$addressBar) {
      this.$addressBar.val(text);
    }
  }

  navSettingsClick() {
    // activate settings modal here
  }

  render() {
    loadTemplate('pageNav.html', (t) => {
      this.$el.html(t());
    });

    this.$addressBar = this.$('.js-addressBar');
    this.$navList = this.$('.js-navList');
    this.$popMenus = this.$('.js-navPopMenu');

    return this;
  }

  remove() {
    getDoc().off('click', this.onDocClick);
  }
}
<commit_msg>Clean up on doc click function.<commit_after>import electron from 'electron';
import multihashes from 'multihashes';
import { View } from 'backbone';
import loadTemplate from '../utils/loadTemplate';
import app from '../app';
import { getDoc } from '../utils/selectors';

const remote = electron.remote;

export default class PageNav extends View {
  constructor(options) {
    super({
      className: 'pageNav',
      events: {
        'click .js-navClose': 'navCloseClick',
        'click .js-navMin': 'navMinClick',
        'click .js-navMax': 'navMaxClick',
        'keyup .js-addressBar': 'onKeyupAddressBar',
        'click .js-navListBtn': 'navListBtnClick',
        'click .js-navSettings': 'navSettingsClick',
      },
      ...options,
    });

    getDoc().on('click', this.onDocClick.bind(this));

    this.listenTo(app.localSettings, 'change:mac_style_win_controls',
      this.onWinControlsStyleChange);
    this.setWinControlsStyle(app.localSettings.get('mac_style_win_controls') ? 'mac' : 'win');
  }

  setWinControlsStyle(style) {
    if (style !== 'mac' && style !== 'win') {
      throw new Error('Style must be \'mac\' or \'win\'.');
    }

    this.$el.removeClass('winStyleWindowControls macStyleWindowControls');
    this.$el.addClass(style === 'mac' ? 'macStyleWindowControls' : 'winStyleWindowControls');
  }

  onWinControlsStyleChange(model, useMacStyle) {
    this.setWinControlsStyle(useMacStyle ? 'mac' : 'win');
  }

  navCloseClick() {
    if (remote.process.platform !== 'darwin') {
      remote.getCurrentWindow().close();
    } else {
      remote.getCurrentWindow().hide();
    }
  }

  navMinClick() {
    remote.getCurrentWindow().minimize();
  }

  navMaxClick() {
    if (remote.getCurrentWindow().isMaximized()) {
      remote.getCurrentWindow().unmaximize();
      // this.$('.js-navMax').attr('data-tooltip', window.polyglot.t('Maximize'));
    } else {
      remote.getCurrentWindow().maximize();
      // this.$('.js-navMax').attr('data-tooltip', window.polyglot.t('Restore'));
    }
  }

  navListBtnClick() {
    const $popMenu = this.$navList;
    this.togglePopMenu($popMenu);
  }

  togglePopMenu($popMenu) {
    if ($popMenu) {
      this.$popMenus.not($popMenu).removeClass('open');
      $popMenu.toggleClass('open');
    } else {
      this.$popMenus.removeClass('open');
    }
  }

  onDocClick(e) {
    if (!this.$(e.target).closest('.js-navListBtn, .js-navNotifBtn, .js-navPopMenu').length) {
      this.togglePopMenu();
    }
  }

  onKeyupAddressBar(e) {
    if (e.which === 13) {
      let text = this.$addressBar.val();
      let isGuid = true;

      if (text.startsWith('ob://')) text = text.slice(5);

      const firstTerm = text.split(' ')[0];

      try {
        multihashes.validate(multihashes.fromB58String(firstTerm));
      } catch (exc) {
        isGuid = false;
      }

      // temporary way to check for GUIDs, since our dummy guids from
      // start.js aren't valid v2 guids, but are registered with the
      // one-name api.
      if (firstTerm.startsWith('Qm')) isGuid = true;
      // end - temporary guid check

      if (isGuid) {
        app.router.navigate(firstTerm, { trigger: true });
      } else if (firstTerm.charAt(0) === '@' && firstTerm.length > 1) {
        // a handle
        app.router.navigate(firstTerm, { trigger: true });
      } else {
        // tag(s)
        const tags = text.trim()
          .replace(',', ' ')
          .replace(/\s+/g, ' ') // collapse multiple spaces into single spaces
          .split(' ')
          .map((frag) => (frag.charAt(0) === '#' ? frag.slice(1) : frag));

        alert(`boom - Searching for tags: ${tags.join(', ')}`);
      }
    }
  }

  setAddressBar(text = '') {
    if (this.$addressBar) {
      this.$addressBar.val(text);
    }
  }

  navSettingsClick() {
    // activate settings modal here
  }

  render() {
    loadTemplate('pageNav.html', (t) => {
      this.$el.html(t());
    });

    this.$addressBar = this.$('.js-addressBar');
    this.$navList = this.$('.js-navList');
    this.$popMenus = this.$('.js-navPopMenu');

    return this;
  }

  remove() {
    getDoc().off('click', this.onDocClick);
  }
}
<|endoftext|>


<commit_before>var width = $('#content').parent().width(),
    height = 700,
    centered;

var svg, projection, path, g;
var school_scale, school_data;

var identifiers = {
  'no_neighborhood_data' : {
    'domain' : [],
    'range' : []
  },
  'poverty' : {
    'domain' : [.01, .17, .27, .38],
    'range' : ["#e5ffc7", "#d9fcb9", "#bbef8e", "#9ad363", "#6eb43f"]
  },
  'no_hs_degree_25_plus' : {
    'domain' : [99, 270, 548, 898],
    'range' : ["#e5ffc7", "#d9fcb9", "#bbef8e", "#9ad363", "#6eb43f"]
  },
  'population_total' : {
    'domain' : [2566, 7928, 17362, 28207],
    'range' : ["#e5ffc7", "#d9fcb9", "#bbef8e", "#9ad363", "#6eb43f"]
  },
  'population_under_18' : {
    'domain' : [287, 1643, 2924, 4727],
    'range' : ["#e5ffc7", "#d9fcb9", "#bbef8e", "#9ad363", "#6eb43f"]
  },
  'population_under_18' : {
    'domain' : [287, 1643, 2924, 4727],
    'range' : ["#e5ffc7", "#d9fcb9", "#bbef8e", "#9ad363", "#6eb43f"]
  },
}

var all_data = {},
    choropleth_data;

$(document).ready(function() {
  init();
}); // end document ready function

function init(){
  drawChoropleth();
  drawSchools();

  // slide out menu
  $('.menu-toggle').on('click', function(){
    if ($(this).parent().hasClass('toggled')){
      $(this).parent().animate({ 'left' : 0 }, 350, function(){ $('#main-container').removeClass('toggled') });
    } else {
      $(this).parent().animate({ 'left' : $('#nav-panel').width() }, 350, function(){ $('#main-container').addClass('toggled') });
    }
  });

  // event listeners for changing d3
  // choropleth color change
  $('.neighborhood-menu > li').on('click', 'a', function(e){
    e.preventDefault();
    changeNeighborhoodData($(this).attr('id'));
    $(this).parent().addClass('selected').siblings().removeClass('selected');
  });
  // circle changes
  $('.school-menu > li').on('click', 'a', function(e){
    e.preventDefault();
    var value = $(this).attr('id') === 'no_school_data' ? 4 : $(this).attr('id');
    changeSchoolData(value);
    $(this).parent().addClass('selected').siblings().removeClass('selected');
  });
}

function drawChoropleth(){

  projection = d3.geo.mercator()
    .center([-77.01551, 38.90755]) // Dunbar High School
    .scale(150000)
    .translate([width/2, height/2]);

  path = d3.geo.path().projection(projection);

  svg = d3.select("#content")
    .append("svg:svg")
    .attr("width", width)
    .attr("height", height);

  svg.append("rect")
      .attr("class", "background")
      .attr("width", width)
      .attr("height", height)
      .on("click", clicked);

  g = svg.append("g");
  g.append("g").attr("id", "neighborhoods");
  g.append("g").attr("id", "schools");

  queue()
<<<<<<>>>>>> d47e32a6e69654520f04d5e6ac8f2130ba3cf30a
    .defer(d3.csv, "data/neighborhoods44.csv")
    .await(setUpChoropleth);

  function setUpChoropleth(error, dc, choropleth) {
    choropleth_data = choropleth;
    choropleth_data.forEach(function(d) {
      all_data[d.gis_id] = d;
      choropleth_data[d.gis_id] = +d.poverty;
    });

    g.select("#neighborhoods")
      .selectAll("path")
        .data(dc.features)
      .enter().append("path")
        .attr("d", path)
        .attr('class', 'nbhd')
        .on("click", clicked)
        .style("fill", "#AAA");

  } // setUpChoropleth function

}

function changeNeighborhoodData(new_data_column) {
  var choro_color = d3.scale.threshold()
    .domain(identifiers[new_data_column]['domain'])
    .range(identifiers[new_data_column]['range']);

  choropleth_data.forEach(function(d) {
    choropleth_data[d.gis_id] = +d[new_data_column];
  });
  g.select("#neighborhoods").selectAll("path")
    .transition().duration(600)
    .style("fill", function(d) {
      return choro_color(all_data[d.properties.gis_id][new_data_column]);
    });
}

function drawSchools(){
  var packer = sm.packer();

  d3.csv('data/schools.csv', function(data){
    school_data = data;
    school_scale = d3.scale.sqrt().range([1,10]);
    g.select("#schools").selectAll("circle")
      .data(data).enter().append("circle")
        .attr('class', 'school')
        .attr("r", 4)
        .attr("transform", function(d) {
          return "translate(" +
            projection([d.long, d.lat]) +
            ")";})
        .on("click", displaySchoolData)
        .append("title").text(function(d){return d.name;});
    packMetros();
    function displaySchoolData(school) {
      $("#details").prepend("

"+school.name+"

enrollment: " +
                                school.enrollment + "

allocation: " +
                                school.alloc + "

");
    }
  });

  function packMetros() {
    var elements = d3.selectAll('#content circle')[0];
    packer.elements(elements).start();
  }
}

function changeSchoolData(new_data_column) {
  if (typeof new_data_column === 'string'){
    matchScaleToData(school_scale, function(d){return +d[new_data_column];})
  }
  g.select("#schools").selectAll("circle")
    .transition().duration(600)
    .attr("r", function(d) {
      return typeof new_data_column !== 'string' ? 4 : school_scale(d[new_data_column]);
    });
}

function matchScaleToData(scale, fieldFunction) {
  var minimum = d3.min(school_data, fieldFunction),
      maximum = d3.max(school_data, fieldFunction);
  scale.domain([minimum, maximum]);
}

function clicked(d) {
  var x, y, k;

  if (d && centered !== d) {
    var centroid = path.centroid(d);
    x = centroid[0];
    y = centroid[1];
    k = 4;
    centered = d;
  } else {
    x = width / 2;
    y = height / 2;
    k = 1;
    centered = null;
  }

  g.selectAll("path")
      .classed("active", centered && function(d) { return d === centered; });

  g.transition()
      .duration(750)
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
      .style("stroke-width", 1.5 / k + "px");
}  <commit_msg>fixing a conflict<commit_after>var width = $('#content').parent().width(),
    height = 700,
    centered;

var svg, projection, path, g;
var school_scale, school_data;

var identifiers = {
  'no_neighborhood_data' : {
    'domain' : [],
    'range' : []
  },
  'poverty' : {
    'domain' : [.01, .17, .27, .38],
    'range' : ["#e5ffc7", "#d9fcb9", "#bbef8e", "#9ad363", "#6eb43f"]
  },
  'no_hs_degree_25_plus' : {
    'domain' : [99, 270, 548, 898],
    'range' : ["#e5ffc7", "#d9fcb9", "#bbef8e", "#9ad363", "#6eb43f"]
  },
  'population_total' : {
    'domain' : [2566, 7928, 17362, 28207],
    'range' : ["#e5ffc7", "#d9fcb9", "#bbef8e", "#9ad363", "#6eb43f"]
  },
  'population_under_18' : {
    'domain' : [287, 1643, 2924, 4727],
    'range' : ["#e5ffc7", "#d9fcb9", "#bbef8e", "#9ad363", "#6eb43f"]
  },
  'population_under_18' : {
    'domain' : [287, 1643, 2924, 4727],
    'range' : ["#e5ffc7", "#d9fcb9", "#bbef8e", "#9ad363", "#6eb43f"]
  },
}

var all_data = {},
    choropleth_data;

$(document).ready(function() {
  init();
}); // end document ready function

function init(){
  drawChoropleth();
  drawSchools();

  // slide out menu
  $('.menu-toggle').on('click', function(){
    if ($(this).parent().hasClass('toggled')){
      $(this).parent().animate({ 'left' : 0 }, 350, function(){ $('#main-container').removeClass('toggled') });
    } else {
      $(this).parent().animate({ 'left' : $('#nav-panel').width() }, 350, function(){ $('#main-container').addClass('toggled') });
    }
  });

  // event listeners for changing d3
  // choropleth color change
  $('.neighborhood-menu > li').on('click', 'a', function(e){
    e.preventDefault();
    changeNeighborhoodData($(this).attr('id'));
    $(this).parent().addClass('selected').siblings().removeClass('selected');
  });
  // circle changes
  $('.school-menu > li').on('click', 'a', function(e){
    e.preventDefault();
    var value = $(this).attr('id') === 'no_school_data' ? 4 : $(this).attr('id');
    changeSchoolData(value);
    $(this).parent().addClass('selected').siblings().removeClass('selected');
  });
}

function drawChoropleth(){

  projection = d3.geo.mercator()
    .center([-77.01551, 38.90755]) // Dunbar High School
    .scale(150000)
    .translate([width/2, height/2]);

  path = d3.geo.path().projection(projection);

  svg = d3.select("#content")
    .append("svg:svg")
    .attr("width", width)
    .attr("height", height);

  svg.append("rect")
      .attr("class", "background")
      .attr("width", width)
      .attr("height", height)
      .on("click", clicked);

  g = svg.append("g");
  g.append("g").attr("id", "neighborhoods");
  g.append("g").attr("id", "schools");

  queue()
    // .defer(d3.json, "data/neighborhood_boundaries.json")
    // .defer(d3.csv, "data/neighborhoods.csv")
    .defer(d3.json, "data/neighborhoods44.json")
    .defer(d3.csv, "data/neighborhoods44.csv")
    .await(setUpChoropleth);

  function setUpChoropleth(error, dc, choropleth) {
    choropleth_data = choropleth;
    choropleth_data.forEach(function(d) {
      all_data[d.gis_id] = d;
      choropleth_data[d.gis_id] = +d.poverty;
    });

    g.select("#neighborhoods")
      .selectAll("path")
        .data(dc.features)
      .enter().append("path")
        .attr("d", path)
        .attr('class', 'nbhd')
        .on("click", clicked)
        .style("fill", "#AAA");

  } // setUpChoropleth function

}

function changeNeighborhoodData(new_data_column) {
  var choro_color = d3.scale.threshold()
    .domain(identifiers[new_data_column]['domain'])
    .range(identifiers[new_data_column]['range']);

  choropleth_data.forEach(function(d) {
    choropleth_data[d.gis_id] = +d[new_data_column];
  });
  g.select("#neighborhoods").selectAll("path")
    .transition().duration(600)
    .style("fill", function(d) {
      return choro_color(all_data[d.properties.gis_id][new_data_column]);
    });
}

function drawSchools(){
  var packer = sm.packer();

  d3.csv('data/schools.csv', function(data){
    school_data = data;
    school_scale = d3.scale.sqrt().range([1,10]);
    g.select("#schools").selectAll("circle")
      .data(data).enter().append("circle")
        .attr('class', 'school')
        .attr("r", 4)
        .attr("transform", function(d) {
          return "translate(" +
            projection([d.long, d.lat]) +
            ")";})
        .on("click", displaySchoolData)
        .append("title").text(function(d){return d.name;});
    packMetros();
    function displaySchoolData(school) {
      $("#details").prepend("

"+school.name+"

enrollment: " +
                                school.enrollment + "

allocation: " +
                                school.alloc + "

");
    }
  });

  function packMetros() {
    var elements = d3.selectAll('#content circle')[0];
    packer.elements(elements).start();
  }
}

function changeSchoolData(new_data_column) {
  if (typeof new_data_column === 'string'){
    matchScaleToData(school_scale, function(d){return +d[new_data_column];})
  }
  g.select("#schools").selectAll("circle")
    .transition().duration(600)
    .attr("r", function(d) {
      return typeof new_data_column !== 'string' ? 4 : school_scale(d[new_data_column]);
    });
}

function matchScaleToData(scale, fieldFunction) {
  var minimum = d3.min(school_data, fieldFunction),
      maximum = d3.max(school_data, fieldFunction);
  scale.domain([minimum, maximum]);
}

function clicked(d) {
  var x, y, k;

  if (d && centered !== d) {
    var centroid = path.centroid(d);
    x = centroid[0];
    y = centroid[1];
    k = 4;
    centered = d;
  } else {
    x = width / 2;
    y = height / 2;
    k = 1;
    centered = null;
  }

  g.selectAll("path")
      .classed("active", centered && function(d) { return d === centered; });

  g.transition()
      .duration(750)
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
      .style("stroke-width", 1.5 / k + "px");
}  <|endoftext|>


<commit_before>VBox.obligatory = ["children"]

function VBox(div, options, finishedCallback, utils) {
    this.name = "VBox";

    this.options = options;
    this.children = options.get("children");

    assert_is_arraylike(this.children, "The 'children' option of VBox must be an array");
    assert(this.children.length % 2 == 0, "The 'children' array for VBox must contain an even number of elements");

    this.childInstances = [];
    this.childUtils = [];
    for (var i = 0; i < this.children.length; i += 2) {
        var controllerClass = this.children[i];
        var childOptions = this.children[i + 1];
        var childOptionsHash = flat_alist_to_hash(
            "Error: options array containing an odd number of elements in VBox",
            childOptions
        );
        childOptionsHash.add(get_defaults_for(controllerClass));

        var d = document.createElement("p");
        d.style.clear = "both";
        div.appendChild(d);
        var t = this;
        var u = new Utils(utils.getValuesFromPreviousItem());
        this.childUtils.push(u);
        var lastIndex = this.childUtils.length - 1;
        this.childInstances.push(
            new controllerClass(
                d,
                childOptionsHash,
                function (r) { t.myFinishedCallback(lastIndex, r); },
                u
            )
        );
    }

    this.indicesAndResultsOfThingsThatHaveFinished = [];

    this.handleKey = function(code, time) {
        iter(this.childInstances, function (c) {
            if (c.handleKey)
                c.handleKey(code, time);
        });
    }

    this.myFinishedCallback = function(index, results) {
        this.childUtils[index].gc();
        this.indicesAndResultsOfThingsThatHaveFinished.push([index, results]);

        if (this.indicesAndResultsOfThingsThatHaveFinished.length == this.childInstances.length) {
            finishedCallback(concatResults(indicesAndResultsOfThingsThatHaveFinished));
        }
    }

    this.concatResults = function(iar) {
        iar.sort(function(x, y) { return x[0] < y[0]; });
        var res;
        iter(iar, function(r) {
            if (r) {
                res.push("*");
                iter(r, function() { res.append(r); })
            }
        });
    }
}
<commit_msg>VBox now working more-or-less properly except for format of results.<commit_after>VBox.obligatory = ["children"]

function VBox(div, options, finishedCallback, utils) {
    this.name = "VBox";

    this.options = options;
    this.children = options.get("children");

    assert_is_arraylike(this.children, "The 'children' option of VBox must be an array");
    assert(this.children.length % 2 == 0, "The 'children' array for VBox must contain an even number of elements");

    this.childInstances = [];
    this.childUtils = [];
    for (var i = 0; i < this.children.length; i += 2) {
        var controllerClass = this.children[i];
        var childOptions = this.children[i + 1];
        var childOptionsHash = flat_alist_to_hash(
            "Error: options array containing an odd number of elements in VBox",
            childOptions
        );
        childOptionsHash.add(get_defaults_for(controllerClass));

        var d = document.createElement("p");
        d.style.clear = "both";
        div.appendChild(d);
        var t = this;
        var u = new Utils(utils.getValuesFromPreviousItem());
        this.childUtils.push(u);
        var lastIndex = this.childUtils.length - 1;
        this.childInstances.push(
            new controllerClass(
                d,
                childOptionsHash,
                function (r) { t.myFinishedCallback(lastIndex, r); },
                u
            )
        );
    }

    this.indicesAndResultsOfThingsThatHaveFinished = [];

    this.handleKey = function(code, time) {
        iter(this.childInstances, function (c) {
            if (c.handleKey)
                c.handleKey(code, time);
        });
    }

    this.myFinishedCallback = function(index, results) {
        this.childUtils[index].gc();
        this.indicesAndResultsOfThingsThatHaveFinished.push([index, results]);

        if (this.indicesAndResultsOfThingsThatHaveFinished.length == this.childInstances.length) {
            finishedCallback(this.concatResults(this.indicesAndResultsOfThingsThatHaveFinished));
        }
    }

    this.concatResults = function(iar) {
        iar.sort(function(x, y) { return x[0] < y[0]; });
        var res = [];
        iter(iar, function(r) {
            var r = r[1];
            if (r) {
                res.push("*");
                iter(r, function(x) { res.push(x); })
            }
        });
        return res;
    }
}
<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
	value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _assert = require('assert');

var _assert2 = _interopRequireDefault(_assert);

var _amqplib = require('amqplib');

var _amqplib2 = _interopRequireDefault(_amqplib);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var debug = require('debug')('tibbar:worker');

var Worker = function () {
	function Worker(options) {
		_classCallCheck(this, Worker);

		// todo assign option values
		this._queues = {};
		this._options = {
			assertQueue: {
				exclusive: false,
				durable: false,
				autoDelete: false,
				arguments: null
			},
			prefetch: 1
		};
	}

	_createClass(Worker, [{
		key: 'use',
		value: function use(name, callback) {
			(0, _assert2.default)(!this._queues[name], '\'' + name + '\'\' already exists');

			debug('Adding queue \'' + name + '\'');

			this._queues[name] = [];
			this._queues[name].callback = callback;

			if (this._ch) {
				this._openQueue(name);
			}
		}
	}, {
		key: 'disconnect',
		value: function disconnect() {
			if (this._conn) {
				this._conn.close();
				delete this._conn;
			}
		}
	}, {
		key: 'connect',
		value: function connect(url) {
			var _this = this;

			debug('Connecting ' + url);

			return _amqplib2.default.connect(url).then(function (conn) {
				_this._conn = conn;
				return conn.createChannel();
			}).then(function (ch) {
				_this._ch = ch;

				var promises = [];

				for (var q in _this._queues) {
					promises.push(_this._openQueue(q));
				}

				return Promise.all(promises);
			});
		}
	}, {
		key: '_openQueue',
		value: function _openQueue(q) {
			var _this2 = this;

			debug('[' + q + '] Opening');

			var queue = this._queues[q];

			this._ch.assertQueue(q, this._options.assertQueue);
			this._ch.prefetch(this._options.prefetch);

			var cb = function cb(msg) {
				debug('[' + q + '] Received');
				debug('[' + q + '] fields: ' + JSON.stringify(msg.fields));
				debug('[' + q + '] properties: ' + JSON.stringify(msg.properties));
				debug('[' + q + '] content: ' + msg.content.toString());

				try {
					var res = queue.callback(JSON.parse(msg.content.toString()));

					if (!msg.properties.replyTo || !msg.properties.correlationId) {
						debug('[' + q + '] No response');
						_this2._ch.ack(msg);
					} else if ('function' === typeof res.then) {
						// if res is a Promise
						res.then(function (p) {
							debug('[' + q + '] Respond: ' + JSON.stringify(p));
							_this2._sendResponse(p, msg);
						}).catch(function (ex) {
							debug('[' + q + '] Exception: ' + JSON.stringify(ex));
							_this2._sendResponse(null, msg, ex);
						});
					} else {
						debug('[' + q + '] Respond: ' + JSON.stringify(res));
						_this2._sendResponse(res, msg);
					}
				} catch (ex) {
					debug('[' + q + '] Exception: ' + JSON.stringify(ex));
					_this2._sendResponse(null, msg, ex);
				}
			};

			return this._ch.consume(q, cb);
		}
	}, {
		key: '_closeQueue',
		value: function _closeQueue(q) {
			debug('[' + q + '] Closing');

			this._ch.deleteQueue(q);
			delete this._queues[q];
		}
	}, {
		key: '_sendResponse',
		value: function _sendResponse(payload, msg, exception) {
			if (!msg) {
				return;
			}

			var buffer = void 0;

			if (!exception) {
				buffer = new Buffer(JSON.stringify({
					type: 'response',
					body: payload
				}));
			} else {
				buffer = new Buffer(JSON.stringify({
					type: 'exception',
					name: exception.constructor.name,
					body: exception
				}));
			}

			this._ch.sendToQueue(
			/* queue   */msg.properties.replyTo,
			/* payload */buffer,
			/* options */{ correlationId: msg.properties.correlationId });

			this._ch.ack(msg);
		}
	}]);

	return Worker;
}();

exports.default = Worker;<commit_msg>npm library update<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
	value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _assert = require('assert');

var _assert2 = _interopRequireDefault(_assert);

var _amqplib = require('amqplib');

var _amqplib2 = _interopRequireDefault(_amqplib);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var debug = require('debug')('tibbar:worker');

var Worker = function () {
	function Worker(options) {
		_classCallCheck(this, Worker);

		// todo assign option values
		this._queues = {};
		this._options = {
			assertQueue: {
				exclusive: false,
				durable: false,
				autoDelete: false,
				arguments: null
			},
			prefetch: 1
		};
	}

	_createClass(Worker, [{
		key: 'use',
		value: function use(name, callback) {
			(0, _assert2.default)(!this._queues[name], '\'' + name + '\'\' already exists');

			debug('Adding queue \'' + name + '\'');

			this._queues[name] = {};
			this._queues[name].callback = callback;

			if (this._ch) {
				this._openQueue(name);
			}
		}
	}, {
		key: 'disconnect',
		value: function disconnect() {
			if (this._conn) {
				this._conn.close();
				delete this._conn;
			}
		}
	}, {
		key: 'connect',
		value: function connect(url) {
			var _this = this;

			debug('Connecting ' + url);

			return _amqplib2.default.connect(url).then(function (conn) {
				_this._conn = conn;
				return conn.createChannel();
			}).then(function (ch) {
				_this._ch = ch;

				var promises = [];

				for (var q in _this._queues) {
					promises.push(_this._openQueue(q));
				}

				return Promise.all(promises);
			});
		}
	}, {
		key: '_openQueue',
		value: function _openQueue(q) {
			var _this2 = this;

			debug('[' + q + '] Opening');

			var queue = this._queues[q];

			this._ch.assertQueue(q, this._options.assertQueue);
			this._ch.prefetch(this._options.prefetch);

			var cb = function cb(msg) {
				if (!msg) {
					return;
				}

				debug('[' + q + '] Received');
				debug('[' + q + '] fields: ' + JSON.stringify(msg.fields));
				debug('[' + q + '] properties: ' + JSON.stringify(msg.properties));
				debug('[' + q + '] content: ' + msg.content.toString());

				try {
					var res = queue.callback(JSON.parse(msg.content.toString()), msg.properties, msg.fields);

					if (!res || !msg.properties.replyTo || !msg.properties.correlationId) {
						debug('[' + q + '] No response');
						_this2._ch.ack(msg);
					} else if ('function' === typeof res.then) {
						// if res is a Promise
						res.then(function (p) {
							debug('[' + q + '] Respond: ' + JSON.stringify(p));
							_this2._sendResponse(p, msg);
						}).catch(function (ex) {
							debug('[' + q + '] Exception: ' + JSON.stringify(ex));
							_this2._sendResponse(null, msg, ex);
						});
					} else {
						debug('[' + q + '] Respond: ' + JSON.stringify(res));
						_this2._sendResponse(res, msg);
					}
				} catch (ex) {
					debug('[' + q + '] Exception: ' + JSON.stringify(ex));
					_this2._sendResponse(null, msg, ex);
				}
			};

			return this._ch.consume(q, cb);
		}
	}, {
		key: '_closeQueue',
		value: function _closeQueue(q) {
			debug('[' + q + '] Closing');

			this._ch.deleteQueue(q);
			delete this._queues[q];
		}
	}, {
		key: '_sendResponse',
		value: function _sendResponse(payload, msg, exception) {
			if (!msg) {
				return;
			}

			var buffer = void 0;

			if (!exception) {
				buffer = new Buffer(JSON.stringify({
					type: 'response',
					body: payload
				}));
			} else {
				buffer = new Buffer(JSON.stringify({
					type: 'exception',
					name: exception.constructor.name,
					body: exception
				}));
			}

			this._ch.sendToQueue(
			/* queue   */msg.properties.replyTo,
			/* payload */buffer,
			/* options */{ correlationId: msg.properties.correlationId });

			this._ch.ack(msg);
		}
	}]);

	return Worker;
}();

exports.default = Worker;<|endoftext|>


<commit_before>var _                 = require('underscore')
  , Promise           = require('bluebird')
  , config            = require('config')
  , url               = require('url')
  ;

function Worker() { }

function promise_time(p$, msg) {
  var s_hrtime = process.hrtime();
  return p$.tap(function(){
    var diff = process.hrtime(s_hrtime)
      , span = ((diff[0] * 1e9 + diff[1]) / 1e6).toFixed(2) + 'ms'
      ;

    console.log(msg, span);
  });
}

Worker.prototype.listen = function(options, cb) {
  options = options || {};

  options.port = options.port || config.port || 80;

  var tunnel_url  = url.format({
      protocol : config.get('tunnel.protocol')
    , hostname : config.get('tunnel.host')
    , port     : config.get('tunnel.port')
  });

  var tunnel_opts = {
      host      : tunnel_url
    , subdomain : config.get('req.id')
  };

  var p$tunnel  = Promise.method(() => {
                    var localtunnel = require('localtunnel');

                    return Promise.promisify(localtunnel)(options.port, tunnel_opts);
                  })
    , p$http    = Promise.method(() => {
                    var express       = require('express')
                      , responseTime  = require('response-time')
                      , onFinished    = require('on-finished')
                      , http          = express()
                      , me            = this
                      ;

                    http.use(responseTime({ header : 'x-tm-response-time-worker' }));
                    http.use(function(req, res, next){
                      clearTimeout(me.timeout_for_req_start_token);

                      onFinished(res, function (err, res) {
                        me.exit(err, res);
                      });

                      me.run(config.get('req'), req, res, _.once((err) => {
                        res.status(500).send(me.errorify(err));
                      }));
                    });

                    return Promise.promisify(http.listen, http)(options.port);
                  })
    ;

  // p$tunnel = promise_time(p$tunnel(), 'tunnel-connection-time');
  // p$http = promise_time(p$http(), 'express-server-listen-time');

  Promise
    .all([ p$tunnel, p$http ])
    .then(() => {
      this.timeout_for_req_start_token = setTimeout(() => {
        this.exit(new Error('no requests received after connection to relay'));
      }, 10 * 1000);
    })
    .nodeify(cb)
    ;
};

Worker.prototype.exit = function(err) {
  if (err) {
    var msg = _.isError(err)? err.message : err.toString();
    console.error(msg);
  }

  // todo [akamel] using timeout otherwise relay crashes with socket error
  setTimeout(() => {
    process.exit();
  }, 4 * 1000);
};

Worker.prototype.run = function(data, req, res, next) {
  // todo [akamel] maybe move this to after listen? no need to wait for req to come in
  var Code = require(config.get('code-module'));

  var code = new Code(data);

  // todo [akamel] should this be on req.manual or req.app.manual
  req.details   = data;
  req.manual    = data.manual;
  req.metadata  = data.metadata;

  var request   = require('./request');

  var mw        = request.middleware(req, data.manual)
    , err_next  = (err) => {
        err.source = code.source;
        next(err);
      }
    ;

  var App = require('./app');

  mw(req, res, function(){
    try {
      req.app = new App(req, res);

      code.run(req, res, next);
    } catch(err) {
      err_next(err);
    }
  });
};

Worker.prototype.errorify = function(err) {
  var ret = {
      type    : 'notification'
    , target  : 'taskmill-core-worker'
  };

  if (_.isError(err)) {
    ret.type      = err.name;
    ret.error     = err.message;
    ret.message   = err.toString();
    ret.stack     = err.stack;
  };

  if (_.has(err, 'help_url')) {
    ret.details = err.help_url;
  }

  return ret;
};

module.exports = Worker;<commit_msg>fix no load<commit_after>var _                 = require('underscore')
  , Promise           = require('bluebird')
  , config            = require('config')
  , url               = require('url')
  ;

function Worker() { }

function promise_time(p$, msg) {
  var s_hrtime = process.hrtime();
  return p$.tap(function(){
    var diff = process.hrtime(s_hrtime)
      , span = ((diff[0] * 1e9 + diff[1]) / 1e6).toFixed(2) + 'ms'
      ;

    console.log(msg, span);
  });
}

Worker.prototype.listen = function(options, cb) {
  options = options || {};

  options.port = options.port || config.port || 80;

  var tunnel_url  = url.format({
      protocol : config.get('tunnel.protocol')
    , hostname : config.get('tunnel.host')
    , port     : config.get('tunnel.port')
  });

  var tunnel_opts = {
      host      : tunnel_url
    , subdomain : config.get('req.id')
  };

  var p$tunnel  = Promise.method(() => {
                    var localtunnel = require('localtunnel');

                    return Promise.promisify(localtunnel)(options.port, tunnel_opts);
                  })
    , p$http    = Promise.method(() => {
                    var express       = require('express')
                      , responseTime  = require('response-time')
                      , onFinished    = require('on-finished')
                      , http          = express()
                      , me            = this
                      ;

                    http.use(responseTime({ header : 'x-tm-response-time-worker' }));
                    http.use(function(req, res, next){
                      clearTimeout(me.timeout_for_req_start_token);

                      onFinished(res, function (err, res) {
                        me.exit(err, res);
                      });

                      me.run(config.get('req'), req, res, _.once((err) => {
                        res.status(500).send(me.errorify(err));
                      }));
                    });

                    return Promise.promisify(http.listen, http)(options.port);
                  })
    ;

  // p$tunnel = promise_time(p$tunnel(), 'tunnel-connection-time');
  // p$http = promise_time(p$http(), 'express-server-listen-time');

  Promise
    .all([ p$tunnel(), p$http() ])
    .then(() => {
      this.timeout_for_req_start_token = setTimeout(() => {
        this.exit(new Error('no requests received after connection to relay'));
      }, 10 * 1000);
    })
    .nodeify(cb)
    ;
};

Worker.prototype.exit = function(err) {
  if (err) {
    var msg = _.isError(err)? err.message : err.toString();
    console.error(msg);
  }

  // todo [akamel] using timeout otherwise relay crashes with socket error
  setTimeout(() => {
    process.exit();
  }, 4 * 1000);
};

Worker.prototype.run = function(data, req, res, next) {
  // todo [akamel] maybe move this to after listen? no need to wait for req to come in
  var Code = require(config.get('code-module'));

  var code = new Code(data);

  // todo [akamel] should this be on req.manual or req.app.manual
  req.details   = data;
  req.manual    = data.manual;
  req.metadata  = data.metadata;

  var request   = require('./request');

  var mw        = request.middleware(req, data.manual)
    , err_next  = (err) => {
        err.source = code.source;
        next(err);
      }
    ;

  var App = require('./app');

  mw(req, res, function(){
    try {
      req.app = new App(req, res);

      code.run(req, res, next);
    } catch(err) {
      err_next(err);
    }
  });
};

Worker.prototype.errorify = function(err) {
  var ret = {
      type    : 'notification'
    , target  : 'taskmill-core-worker'
  };

  if (_.isError(err)) {
    ret.type      = err.name;
    ret.error     = err.message;
    ret.message   = err.toString();
    ret.stack     = err.stack;
  };

  if (_.has(err, 'help_url')) {
    ret.details = err.help_url;
  }

  return ret;
};

module.exports = Worker;<|endoftext|>


<commit_before>let JWT   = require('jsonwebtoken');  // used to sign our content
let aguid = require('aguid');
let _ = require('lodash');

let { getUser, createUser } = require('./db/users.js');
let { addSession, getSession } = require('./db/sessions.js');

const SECRET = process.env.GOOGLE_SECRET;
const GOOGLE_CLIENT_ID = "750179824923-go79gjlsik6vupafrp65q4s3cuu2dcpk.apps.googleusercontent.com";

module.exports = {
	handleAuth: function(request, reply) {
		if (!request.auth.isAuthenticated) {
			console.log(request.auth.error.message);
			return reply.redirect('/authenticate/google');
			//return reply('Authentication failed due to: ' + request.auth.error.message);
		}

		let email = request.auth.credentials.profile.emails[0].value;
		//console.log(request.auth.credentials.profile);
		let id = aguid(email);

		function createSession() {
			let payload = { id }
			const token = JWT.sign(payload, SECRET);
			addSession({
				token: token,
				user_id: id
			}).then(() => {
				reply(
					`
					<input type="hidden" id='GST_AUTH_TOKEN' value='${token}'/>
					`
				)
					.header("Authorization", token);
			}).catch(console.error);
		}

		getUser(email)
			.then(function(resp) {
				if (!resp.length) {
					let avatar = _.property('auth.credentials.profile.raw.image.url')(request);

					createUser({
						id: id,
						name: request.auth.credentials.profile.displayName.trim(),
						email: email.trim(),
						avatar: avatar ? avatar.trim() : null,
						created: 'now'
					}).then(createSession).catch(console.error);
				} else {
					createSession()
				}
			})
			.catch(console.error);

	},

	validate: function(decoded, request, callback) {

		getSession(decoded.id)
			.then((result) => {
				if (result.length) {
					return callback(null, true);
				} else {
					return callback(null, false);
				}
			})
			.catch((err) => {
				console.error(err);
				callback(null, false);
			});
	},

	SECRET: SECRET,
	GOOGLE_CLIENT_ID: GOOGLE_CLIENT_ID
};
<commit_msg>Add redirect to marketing site on successful login<commit_after>let JWT   = require('jsonwebtoken');  // used to sign our content
let aguid = require('aguid');
let _ = require('lodash');

let { getUser, createUser } = require('./db/users.js');
let { addSession, getSession } = require('./db/sessions.js');

const SECRET = process.env.GOOGLE_SECRET;
const GOOGLE_CLIENT_ID = "750179824923-go79gjlsik6vupafrp65q4s3cuu2dcpk.apps.googleusercontent.com";

module.exports = {
	handleAuth: function(request, reply) {
		if (!request.auth.isAuthenticated) {
			console.log(request.auth.error.message);
			return reply.redirect('/authenticate/google');
			//return reply('Authentication failed due to: ' + request.auth.error.message);
		}

		let email = request.auth.credentials.profile.emails[0].value;
		//console.log(request.auth.credentials.profile);
		let id = aguid(email);

		function createSession() {
			let payload = { id }
			const token = JWT.sign(payload, SECRET);
			addSession({
				token: token,
				user_id: id
			}).then(() => {
				reply(
					`
					<input type="hidden" id='GST_AUTH_TOKEN' value='${token}'/>
					<script>setTimeout(function() {
						window.location = "http://gst.dev";
					}, 100)</script>
					`
				)
					.header("Authorization", token);
			}).catch(console.error);
		}

		getUser(email)
			.then(function(resp) {
				if (!resp.length) {
					let avatar = _.property('auth.credentials.profile.raw.image.url')(request);

					createUser({
						id: id,
						name: request.auth.credentials.profile.displayName.trim(),
						email: email.trim(),
						avatar: avatar ? avatar.trim() : null,
						created: 'now'
					}).then(createSession).catch(console.error);
				} else {
					createSession()
				}
			})
			.catch(console.error);

	},

	validate: function(decoded, request, callback) {

		getSession(decoded.id)
			.then((result) => {
				if (result.length) {
					return callback(null, true);
				} else {
					return callback(null, false);
				}
			})
			.catch((err) => {
				console.error(err);
				callback(null, false);
			});
	},

	SECRET: SECRET,
	GOOGLE_CLIENT_ID: GOOGLE_CLIENT_ID
};
<|endoftext|>


<commit_before>// Set up a collection to contain player information. On the server,
// it is backed by a MongoDB collection named "players".

Players = new Meteor.Collection("players");
Cards = new Meteor.Collection("cards");
Messages = new Meteor.Collection("messages");
CurrRoom = 1;

CardNames = ['0', '1/2', '1', '2', '3', '5', '8', '13', '20', '40', '100', '?'];
CardValues = [0, 1/2, 1, 2, 3, 5, 8, 13, 20, 40, 100, -1];
NullCard = {name: "Empty", value: -1000};

function getAllPlayers() {
    return Players.find({}, {sort: {name: 1}});
};

if (Meteor.isClient) {

  Session.set("current_player", null);

  Template.stage.players = getAllPlayers();

  Template.stage.events({
    'click input.clear-votes': function() {
        Players.update({}, {$set: {vote: NullCard, voted: false}}, {multi: true});
        Messages.update({room: CurrRoom}, {$set: {content: Session.get("current_player") + " cleared all votes."}});
    }
  });

  Template.stage.everyone_voted = function() {
    if (Players.find({voted: false}).count() != 0 || Players.find().count() === 0) {
        return false;
    }
    return true;
  };

  Template.message.message = function() {
    return Messages.findOne({room: CurrRoom});
  };

  Template.join_game.events({
    'click input.join': function(evt, tmpl) {
        var clientName = tmpl.find("#player-name-input").value;
        if (Players.find({name: clientName}).count() > 0) {
            alert("Player with the same name already exist!");
            return;
        }
        if (!clientName) {
          alert("Please enter your name!");
          return;
        }
        Players.insert({name: clientName, vote: NullCard, voted: false});
        Messages.update({room: CurrRoom}, {$set: {content: clientName + " joined the game."}});
        Session.set("current_player", clientName);
    }
  });

  Template.join_game.curr_joined = function() {
    return Session.get("current_player") != null ? false : true;
  };

  Template.card_board.cards = function () {
    return Cards.find();
  };

  Template.card_board.events({
    'click input.vote': function (evt, tmpl) {
      var currentPlayerName = Session.get("current_player");
      Players.update({name: currentPlayerName}, {$set: {vote: this, voted: true}});
    }
  });

  Template.card.selected = function() {
    var player = Players.findOne({name: Session.get("current_player")});
    if (player) {
      return player.vote.name == this.name ? 'selected' : '';
    }
    return '';
  };

  Template.current_players.players = getAllPlayers();

  Template.player.selected = function () {
    return Session.equals("current_player", this.name) ? "selected" : '';
  };

  Template.player.events({
    'click input.remove-player': function () {
        Players.remove(this);
        Messages.update({room: CurrRoom}, {$set: {content: this.name + " left the game."}});
        if (Session.get("current_player") == this.name) {
          Session.set("current_player", null);
        }
    }
  });
}

// On server startup
if (Meteor.isServer) {
  Meteor.startup(function () {
    if (Cards.find().count() === 0) {
        for (var i = 0; i < CardValues.length; i++) {
            Cards.insert({name: CardNames[i], value: CardValues[i]});
        }
    }
    if (Messages.find().count() === 0) {
      Messages.insert({content: "Welcome to Planning Poker!", room: CurrRoom});
    }
  });
}
<commit_msg>add comments<commit_after>// Set up a collection to contain player information. On the server,
// it is backed by a MongoDB collection named "players".

// All players
Players = new Meteor.Collection("players");
// A static collection of cards
// I'd like to use datastore instead of static array because we might need to update them in the future.
Cards = new Meteor.Collection("cards");
// Store messages for each room
Messages = new Meteor.Collection("messages");
// At the moment, room functionality is not in place. So we use the only room globally.
CurrRoom = 1;

// Used to initialize cards
CardNames = ['0', '1/2', '1', '2', '3', '5', '8', '13', '20', '40', '100', '?'];
CardValues = [0, 1/2, 1, 2, 3, 5, 8, 13, 20, 40, 100, -1];
NullCard = {name: "Empty", value: -1000};

function getAllPlayers() {
    return Players.find({}, {sort: {name: 1}});
};

// Refactor needed
// We should separate client and server, and put functions in common module
if (Meteor.isClient) {

  // Each player's own session, reset at loading page
  Session.set("current_player", null);

  Template.stage.players = getAllPlayers();

  Template.stage.events({
    'click input.clear-votes': function() {
        Players.update({}, {$set: {vote: NullCard, voted: false}}, {multi: true});
        Messages.update({room: CurrRoom}, {$set: {content: Session.get("current_player") + " cleared all votes."}});
    }
  });

  Template.stage.everyone_voted = function() {
    if (Players.find({voted: false}).count() != 0 || Players.find().count() === 0) {
        return false;
    }
    return true;
  };

  Template.message.message = function() {
    return Messages.findOne({room: CurrRoom});
  };

  Template.join_game.events({
    'click input.join': function(evt, tmpl) {
        var clientName = tmpl.find("#player-name-input").value;
        if (Players.find({name: clientName}).count() > 0) {
            alert("Player with the same name already exist!");
            return;
        }
        if (!clientName) {
          alert("Please enter your name!");
          return;
        }
        Players.insert({name: clientName, vote: NullCard, voted: false});
        Messages.update({room: CurrRoom}, {$set: {content: clientName + " joined the game."}});
        Session.set("current_player", clientName);
    }
  });

  Template.join_game.curr_joined = function() {
    return Session.get("current_player") != null ? false : true;
  };

  Template.card_board.cards = function () {
    return Cards.find();
  };

  Template.card_board.events({
    'click input.vote': function (evt, tmpl) {
      var currentPlayerName = Session.get("current_player");
      Players.update({name: currentPlayerName}, {$set: {vote: this, voted: true}});
    }
  });

  Template.card.selected = function() {
    var player = Players.findOne({name: Session.get("current_player")});
    if (player) {
      return player.vote.name == this.name ? 'selected' : '';
    }
    return '';
  };

  Template.current_players.players = getAllPlayers();

  Template.player.selected = function () {
    return Session.equals("current_player", this.name) ? "selected" : '';
  };

  Template.player.events({
    'click input.remove-player': function () {
        Players.remove(this);
        Messages.update({room: CurrRoom}, {$set: {content: this.name + " left the game."}});
        if (Session.get("current_player") == this.name) {
          Session.set("current_player", null);
        }
    }
  });
}

// On server startup
if (Meteor.isServer) {
  Meteor.startup(function () {
    if (Cards.find().count() === 0) {
        for (var i = 0; i < CardValues.length; i++) {
            Cards.insert({name: CardNames[i], value: CardValues[i]});
        }
    }
    if (Messages.find().count() === 0) {
      // Insert the first message for a given room
      Messages.insert({content: "Welcome to Planning Poker!", room: CurrRoom});
    }
  });
}
<|endoftext|>


<commit_before>// Copyright 2013 Danny Yates

//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at

//        http://www.apache.org/licenses/LICENSE-2.0

//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

var Transform = require('stream').Transform,
    lzf = require('lzf'),
    util = require('util'),
    Int64 = require('int64-native'),
    Crc64 = require('../build/Release/Crc64.node').Crc64;

exports = module.exports = Writer;

util.inherits(Writer, Transform);

function Writer(options) {
    if (!(this instanceof Writer)) {
        return new Writer(options);
    }

    Transform.call(this, {objectMode: true});

    options = options || {};

    var self = this;
    var currentDatabase = undefined;
    var encoding = options.encoding || 'utf8';
    var compressionThreshold = options.compressionThreshold || 4;  // 4 is what Redis uses.
    var crc = new Crc64();
    var outputBuffers = [];
    var expectedNext = ['header'];
    var handlers = {};

    self._transform = function(obj, encoding, cb) {
        try {
            handleObject(obj, cb);
        } catch(e) {
            self.emit('error', e);
        }
    }

    function handleObject(obj, cb) {
        if (!obj || !obj.type) throw new Error('Unexpected object received');
        if (expectedNext.indexOf(obj.type) == -1) throw new Error('Unexpected object received: ' + obj.type + '; was expecting one of: ' + expectedNext);

        handlers[obj.type](obj, function() {
            if (outputBuffers.length) {
                var output = Buffer.concat(outputBuffers);
                crc.push(output);
                self.push(output);
                outputBuffers = [];
            }
            expectedNext = Array.prototype.slice.call(arguments, 0);
            cb();
        });
    }

    handlers.header = function(obj, next) {
        var header = 'REDIS' + ('000' + obj.version).slice(-4);
        output(new Buffer(header, 'ascii'));
        next('database', 'end');
    }

    handlers.database = function(obj, next) {
        // don't do anything explicit with database objects; switch databases based on the key objects
        next('database', 'key', 'end');
    }

    handlers.key = function(obj, next) {
        if (obj.database != currentDatabase) {
            switchDatabase(obj.database);
        }

        if (typeof(obj.expiry) != 'undefined') {
            outputExpiry(obj.expiry);
        }

        handlers[obj.rtype + 'Key'](obj);

        next('database', 'key', 'end');
    }

    handlers.end = function(obj, next) {
        output(new Buffer([0xFF]));
        next('crc');
    }

    handlers.crc = function(obj, next) {
        // ignore the CRC object itself, and use this as a signal to write a CRC
        output(crc.value());
        next();
    }

    handlers.stringKey = function(obj) {
        output(new Buffer([0]));
        outputString(obj.key);
        outputString(obj.value);
    }

    handlers.listKey = function(obj) {
        output(new Buffer([1]));
        outputString(obj.key);
        outputLengthEncoding(obj.value.length, false);
        for (var i = 0, n = obj.value.length; i < n; i++) {
            outputString(obj.value[i]);
        }
    }

    handlers.setKey = function(obj) {
        output(new Buffer([2]));
        outputString(obj.key);
        outputLengthEncoding(obj.value.length, false);
        for (var i = 0, n = obj.value.length; i < n; i++) {
            outputString(obj.value[i]);
        }
    }

    handlers.zsetKey = function(obj) {
        output(new Buffer([3]));
        outputString(obj.key);
        outputLengthEncoding(Object.keys(obj.value).length, false);
        for (key in obj.value) {
            outputString(key);
            outputString(obj.value[key]);
        }
    }

    handlers.hashKey = function(obj) {
        output(new Buffer([4]));
        outputString(obj.key);
        outputLengthEncoding(Object.keys(obj.value).length, false);
        for (key in obj.value) {
            outputString(key);
            outputString(obj.value[key]);
        }
    }

    function outputExpiry(expiry) {
        if (expiry % 1000 == 0) {
            throw new Error('Second granularity expiries not supported yet');
        } else {
            var buffer = new Buffer(9);
            var int64 = new Int64(expiry);

            buffer.writeUInt8(0xFC, 0);
            buffer.writeUInt32LE(int64.low32(), 1);
            buffer.writeUInt32LE(int64.high32(), 5);
        }

        output(buffer);
    }

    function switchDatabase(n) {
        output(new Buffer([0xFE]));
        outputLengthEncoding(n, false);
        currentDatabase = n;
    }

    function outputLengthEncoding(n, special) {
        if (n < 0) throw new Error('Cannot write negative length encoding: ' + n);

        if (!special) {
            if (n <= 0x3F) {
                return output(new Buffer([n]));
            } else if (n <= 0x3FFF) {
                return output(new Buffer([0x40 | (n >> 8), n & 0xFF]));
            } else if (n <= 0xFFFFFFFF) {
                var buffer = new Buffer(5);
                buffer.writeUInt8(0x80, 0);
                buffer.writeUInt32BE(n, 1);
                return output(buffer);
            }

            throw new Error('Failed to write length encoding: ' + n);
        } else {
            if (n > 0x3F) {
                throw new Error('Cannot encode ' + n + ' using special length encoding');
            }
            return output(new Buffer([0xC0 | n]));
        }
    }

    function outputString(s) {
        var buffer;

        // Does it look like a number?
        if (s.match(/^-?\d+$/)) {
            var n = parseInt(s);
            if (n >= -128 && n <= 127) {
                buffer = new Buffer(1);
                buffer.writeInt8(n, 0);
                outputLengthEncoding(0, true);
                output(buffer);
                return;
            } else if (n >= -32768 && n <= 32767) {
                buffer = new Buffer(2);
                buffer.writeInt16LE(n, 0);
                outputLengthEncoding(1, true);
                output(buffer);
                return;
            } else if (n >= -2147483648 && n <= 2147483647) {
                buffer = new Buffer(4);
                buffer.writeInt32LE(n, 0);
                outputLengthEncoding(2, true);
                output(buffer);
                return;
            }
        }

        // It doesn't look like a number, or it's too big
        buffer = new Buffer(s, encoding);
        if (buffer.length > compressionThreshold) {
            var compressed = lzf.compress(buffer);
            if (compressed.length < buffer.length) {
                // It saved some space
                outputLengthEncoding(3, true);
                outputLengthEncoding(compressed.length, false);
                outputLengthEncoding(buffer.length, false);
                output(compressed);
                return;
            }
        }

        outputLengthEncoding(buffer.length, false);
        output(buffer);
    }

    function output(data) {
        if (data instanceof Buffer) return outputBuffers.push(data);
        throw new Error('Unknown output data type');
    }
}
<commit_msg>WRITER: Second granularity expiries<commit_after>// Copyright 2013 Danny Yates

//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at

//        http://www.apache.org/licenses/LICENSE-2.0

//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

var Transform = require('stream').Transform,
    lzf = require('lzf'),
    util = require('util'),
    Int64 = require('int64-native'),
    Crc64 = require('../build/Release/Crc64.node').Crc64;

exports = module.exports = Writer;

util.inherits(Writer, Transform);

function Writer(options) {
    if (!(this instanceof Writer)) {
        return new Writer(options);
    }

    Transform.call(this, {objectMode: true});

    options = options || {};

    var self = this;
    var currentDatabase = undefined;
    var encoding = options.encoding || 'utf8';
    var compressionThreshold = options.compressionThreshold || 4;  // 4 is what Redis uses.
    var crc = new Crc64();
    var outputBuffers = [];
    var expectedNext = ['header'];
    var handlers = {};

    self._transform = function(obj, encoding, cb) {
        try {
            handleObject(obj, cb);
        } catch(e) {
            self.emit('error', e);
        }
    }

    function handleObject(obj, cb) {
        if (!obj || !obj.type) throw new Error('Unexpected object received');
        if (expectedNext.indexOf(obj.type) == -1) throw new Error('Unexpected object received: ' + obj.type + '; was expecting one of: ' + expectedNext);

        handlers[obj.type](obj, function() {
            if (outputBuffers.length) {
                var output = Buffer.concat(outputBuffers);
                crc.push(output);
                self.push(output);
                outputBuffers = [];
            }
            expectedNext = Array.prototype.slice.call(arguments, 0);
            cb();
        });
    }

    handlers.header = function(obj, next) {
        var header = 'REDIS' + ('000' + obj.version).slice(-4);
        output(new Buffer(header, 'ascii'));
        next('database', 'end');
    }

    handlers.database = function(obj, next) {
        // don't do anything explicit with database objects; switch databases based on the key objects
        next('database', 'key', 'end');
    }

    handlers.key = function(obj, next) {
        if (obj.database != currentDatabase) {
            switchDatabase(obj.database);
        }

        if (typeof(obj.expiry) != 'undefined') {
            outputExpiry(obj.expiry);
        }

        handlers[obj.rtype + 'Key'](obj);

        next('database', 'key', 'end');
    }

    handlers.end = function(obj, next) {
        output(new Buffer([0xFF]));
        next('crc');
    }

    handlers.crc = function(obj, next) {
        // ignore the CRC object itself, and use this as a signal to write a CRC
        output(crc.value());
        next();
    }

    handlers.stringKey = function(obj) {
        output(new Buffer([0]));
        outputString(obj.key);
        outputString(obj.value);
    }

    handlers.listKey = function(obj) {
        output(new Buffer([1]));
        outputString(obj.key);
        outputLengthEncoding(obj.value.length, false);
        for (var i = 0, n = obj.value.length; i < n; i++) {
            outputString(obj.value[i]);
        }
    }

    handlers.setKey = function(obj) {
        output(new Buffer([2]));
        outputString(obj.key);
        outputLengthEncoding(obj.value.length, false);
        for (var i = 0, n = obj.value.length; i < n; i++) {
            outputString(obj.value[i]);
        }
    }

    handlers.zsetKey = function(obj) {
        output(new Buffer([3]));
        outputString(obj.key);
        outputLengthEncoding(Object.keys(obj.value).length, false);
        for (key in obj.value) {
            outputString(key);
            outputString(obj.value[key]);
        }
    }

    handlers.hashKey = function(obj) {
        output(new Buffer([4]));
        outputString(obj.key);
        outputLengthEncoding(Object.keys(obj.value).length, false);
        for (key in obj.value) {
            outputString(key);
            outputString(obj.value[key]);
        }
    }

    function outputExpiry(expiry) {
        if (expiry % 1000 == 0) {
            var buffer = new Buffer(5);

            buffer.writeUInt8(0xFD, 0);
            buffer.writeInt32LE(expiry / 1000, 1);
        } else {
            var buffer = new Buffer(9);
            var int64 = new Int64(expiry);

            buffer.writeUInt8(0xFC, 0);
            buffer.writeUInt32LE(int64.low32(), 1);
            buffer.writeUInt32LE(int64.high32(), 5);
        }

        output(buffer);
    }

    function switchDatabase(n) {
        output(new Buffer([0xFE]));
        outputLengthEncoding(n, false);
        currentDatabase = n;
    }

    function outputLengthEncoding(n, special) {
        if (n < 0) throw new Error('Cannot write negative length encoding: ' + n);

        if (!special) {
            if (n <= 0x3F) {
                return output(new Buffer([n]));
            } else if (n <= 0x3FFF) {
                return output(new Buffer([0x40 | (n >> 8), n & 0xFF]));
            } else if (n <= 0xFFFFFFFF) {
                var buffer = new Buffer(5);
                buffer.writeUInt8(0x80, 0);
                buffer.writeUInt32BE(n, 1);
                return output(buffer);
            }

            throw new Error('Failed to write length encoding: ' + n);
        } else {
            if (n > 0x3F) {
                throw new Error('Cannot encode ' + n + ' using special length encoding');
            }
            return output(new Buffer([0xC0 | n]));
        }
    }

    function outputString(s) {
        var buffer;

        // Does it look like a number?
        if (s.match(/^-?\d+$/)) {
            var n = parseInt(s);
            if (n >= -128 && n <= 127) {
                buffer = new Buffer(1);
                buffer.writeInt8(n, 0);
                outputLengthEncoding(0, true);
                output(buffer);
                return;
            } else if (n >= -32768 && n <= 32767) {
                buffer = new Buffer(2);
                buffer.writeInt16LE(n, 0);
                outputLengthEncoding(1, true);
                output(buffer);
                return;
            } else if (n >= -2147483648 && n <= 2147483647) {
                buffer = new Buffer(4);
                buffer.writeInt32LE(n, 0);
                outputLengthEncoding(2, true);
                output(buffer);
                return;
            }
        }

        // It doesn't look like a number, or it's too big
        buffer = new Buffer(s, encoding);
        if (buffer.length > compressionThreshold) {
            var compressed = lzf.compress(buffer);
            if (compressed.length < buffer.length) {
                // It saved some space
                outputLengthEncoding(3, true);
                outputLengthEncoding(compressed.length, false);
                outputLengthEncoding(buffer.length, false);
                output(compressed);
                return;
            }
        }

        outputLengthEncoding(buffer.length, false);
        output(buffer);
    }

    function output(data) {
        if (data instanceof Buffer) return outputBuffers.push(data);
        throw new Error('Unknown output data type');
    }
}
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var assert = require('assert');
var inherits = require('util').inherits;
var debug = require('debug')('wave:writer');
var Parser = require('../parser');

/**
 * Module exports.
 */

module.exports = Writer;

/**
 * RIFF Chunk IDs in Buffers.
 */

var RIFF = new Buffer('RIFF');
var WAVE = new Buffer('WAVE');
var fmt  = new Buffer('fmt ');
var data = new Buffer('data');

/**
 * The max size of the "data" chunk of a WAVE file. This is the max unsigned
 * 32-bit int value, minus 100 bytes (overkill, 44 would be safe) for the header.
 */

var MAX_WAV = 4294967295 - 100;

/**
 * The `Writer` class.
 */

function Writer (opts) {
  if (!(this instanceof Writer)) {
    return new Writer(opts);
  }
  Parser.call(this, opts);

  this.endianness = 'LE';

  this.format = 1; // raw PCM
  this.channels = 2;
  this.sampleRate = 44100;
  this.bitDepth = 16;

  if (opts) {
    if (null != opts.format) this.format = opts.format;
    if (null != opts.channels) this.channels = opts.channels;
    if (null != opts.sampleRate) this.sampleRate = opts.sampleRate;
    if (null != opts.bitDepth) this.bitDepth = opts.bitDepth;
  }

  // the first time _transform() is called, _writeHeader() will be run
  //this.immediate(this._writeHeader);
  this.buffer(0, this._writeHeader);
}
inherits(Writer, Parser);

/**
 * Writes the WAVE header.
 */

Writer.prototype._writeHeader = function (chunk, write) {
  var headerLength = 44; // TODO: 44 is only for format 1 (PCM), any other
                         // format will have a variable size...
  var dataLength = this.dataLength;
  if (null == dataLength) dataLength = MAX_WAV;
  var fileSize = dataLength + headerLength;
  var header = new Buffer(headerLength);
  var offset = 0;

  // write the "RIFF" identifier
  RIFF.copy(header, offset);
  offset += RIFF.length;

  // write the file size minus the identifier and this 32-bit int
  header['writeUInt32' + this.endianness](fileSize - 8, offset);
  offset += 4;

  // write the "WAVE" identifier
  WAVE.copy(header, offset);
  offset += WAVE.length;

  // write the "fmt " sub-chunk identifier
  fmt.copy(header, offset);
  offset += fmt.length;

  // write the size of the "fmt " chunk
  // XXX: value of 16 is hard-coded for raw PCM format. other formats have
  // different size.
  header['writeUInt32' + this.endianness](16, offset);
  offset += 4;

  // write the audio format code
  header['writeUInt16' + this.endianness](this.format, offset);
  offset += 2;

  // write the number of channels
  header['writeUInt16' + this.endianness](this.channels, offset);
  offset += 2;

  // write the sample rate
  header['writeUInt32' + this.endianness](this.sampleRate, offset);
  offset += 4;

  // write the byte rate
  var byteRate = this.byteRate;
  if (null == byteRate) {
    byteRate = this.sampleRate * this.channels * this.bitDepth / 8;
  }
  header['writeUInt32' + this.endianness](byteRate, offset);
  offset += 4;

  // write the block align
  var blockAlign = this.blockAlign;
  if (null == blockAlign) {
    blockAlign = this.channels * this.bitDepth / 8;
  }
  header['writeUInt16' + this.endianness](blockAlign, offset);
  offset += 2;

  // write the bits per sample
  header['writeUInt16' + this.endianness](this.bitDepth, offset);
  offset += 2;

  // write the "data" sub-chunk ID
  data.copy(header, offset);
  offset += data.length;

  // write the remaining length of the rest of the data
  header['writeUInt32' + this.endianness](dataLength, offset);
  offset += 4;

  // save the "header" Buffer for the end, we emit the "header" event at the end
  // with the "size" values properly filled out. if this stream is being piped to
  // a file (or anything else seekable), then this correct header should be placed
  // at the very beginning of the file.
  this._header = header;
  this.headerLength = headerLength;

  // flush the header and after that pass-through "dataLength" bytes
  write(header);
  this.passthrough(dataLength);
};

/**
 * Emits a "header" event after the readable side of the stream has finished.
 */

Writer.prototype._flush = function (write, done) {
  done();
  this.dataLength = this.bytesProcessed;
  process.nextTick(this._emitHeader.bind(this));
};

/**
 * Emits the "header" event. This can safely be ignored, or if you are writing
 * this WAVE file to somewhere that is seekable (i.e. the filesystem), then you
 * should write this "header" buffer at the beginning of the file to get the
 * correct file size values in the file. This isn't too important since most audio
 * players look at the file size rather than those byte values in the header, but
 * it's good to when when possible.
 */

Writer.prototype._emitHeader = function () {
  var dataLength = this.dataLength;
  var headerLength = this.headerLength;
  var header = this._header;

  // write the file length at the beginning of the header
  header['writeUInt32' + this.endianness](dataLength + headerLength - 8, 4);

  // write the data length at the end of the header
  header['writeUInt32' + this.endianness](dataLength, headerLength - 4);

  this.emit('header', header);
};
<commit_msg>writer: add some debug() calls<commit_after>
/**
 * Module dependencies.
 */

var assert = require('assert');
var inherits = require('util').inherits;
var debug = require('debug')('wave:writer');
var Parser = require('../parser');

/**
 * Module exports.
 */

module.exports = Writer;

/**
 * RIFF Chunk IDs in Buffers.
 */

var RIFF = new Buffer('RIFF');
var WAVE = new Buffer('WAVE');
var fmt  = new Buffer('fmt ');
var data = new Buffer('data');

/**
 * The max size of the "data" chunk of a WAVE file. This is the max unsigned
 * 32-bit int value, minus 100 bytes (overkill, 44 would be safe) for the header.
 */

var MAX_WAV = 4294967295 - 100;

/**
 * The `Writer` class.
 */

function Writer (opts) {
  if (!(this instanceof Writer)) {
    return new Writer(opts);
  }
  Parser.call(this, opts);

  this.endianness = 'LE';

  this.format = 1; // raw PCM
  this.channels = 2;
  this.sampleRate = 44100;
  this.bitDepth = 16;

  if (opts) {
    if (null != opts.format) this.format = opts.format;
    if (null != opts.channels) this.channels = opts.channels;
    if (null != opts.sampleRate) this.sampleRate = opts.sampleRate;
    if (null != opts.bitDepth) this.bitDepth = opts.bitDepth;
  }

  // the first time _transform() is called, _writeHeader() will be run
  //this.immediate(this._writeHeader);
  this.buffer(0, this._writeHeader);
}
inherits(Writer, Parser);

/**
 * Writes the WAVE header.
 */

Writer.prototype._writeHeader = function (chunk, write) {
  debug('_writeHeader()');
  var headerLength = 44; // TODO: 44 is only for format 1 (PCM), any other
                         // format will have a variable size...
  var dataLength = this.dataLength;
  if (null == dataLength) dataLength = MAX_WAV;
  var fileSize = dataLength + headerLength;
  var header = new Buffer(headerLength);
  var offset = 0;

  // write the "RIFF" identifier
  RIFF.copy(header, offset);
  offset += RIFF.length;

  // write the file size minus the identifier and this 32-bit int
  header['writeUInt32' + this.endianness](fileSize - 8, offset);
  offset += 4;

  // write the "WAVE" identifier
  WAVE.copy(header, offset);
  offset += WAVE.length;

  // write the "fmt " sub-chunk identifier
  fmt.copy(header, offset);
  offset += fmt.length;

  // write the size of the "fmt " chunk
  // XXX: value of 16 is hard-coded for raw PCM format. other formats have
  // different size.
  header['writeUInt32' + this.endianness](16, offset);
  offset += 4;

  // write the audio format code
  header['writeUInt16' + this.endianness](this.format, offset);
  offset += 2;

  // write the number of channels
  header['writeUInt16' + this.endianness](this.channels, offset);
  offset += 2;

  // write the sample rate
  header['writeUInt32' + this.endianness](this.sampleRate, offset);
  offset += 4;

  // write the byte rate
  var byteRate = this.byteRate;
  if (null == byteRate) {
    byteRate = this.sampleRate * this.channels * this.bitDepth / 8;
  }
  header['writeUInt32' + this.endianness](byteRate, offset);
  offset += 4;

  // write the block align
  var blockAlign = this.blockAlign;
  if (null == blockAlign) {
    blockAlign = this.channels * this.bitDepth / 8;
  }
  header['writeUInt16' + this.endianness](blockAlign, offset);
  offset += 2;

  // write the bits per sample
  header['writeUInt16' + this.endianness](this.bitDepth, offset);
  offset += 2;

  // write the "data" sub-chunk ID
  data.copy(header, offset);
  offset += data.length;

  // write the remaining length of the rest of the data
  header['writeUInt32' + this.endianness](dataLength, offset);
  offset += 4;

  // save the "header" Buffer for the end, we emit the "header" event at the end
  // with the "size" values properly filled out. if this stream is being piped to
  // a file (or anything else seekable), then this correct header should be placed
  // at the very beginning of the file.
  this._header = header;
  this.headerLength = headerLength;

  // flush the header and after that pass-through "dataLength" bytes
  write(header);
  this.passthrough(dataLength, this._onEnd);
};

Writer.prototype._onEnd = function (write) {
  debug('_onEnd()');
};

/**
 * Emits a "header" event after the readable side of the stream has finished.
 */

Writer.prototype._flush = function (write, done) {
  debug('_flush()');
  done();
  this.dataLength = this.bytesProcessed;
  process.nextTick(this._emitHeader.bind(this));
};

/**
 * Emits the "header" event. This can safely be ignored, or if you are writing
 * this WAVE file to somewhere that is seekable (i.e. the filesystem), then you
 * should write this "header" buffer at the beginning of the file to get the
 * correct file size values in the file. This isn't too important since most audio
 * players look at the file size rather than those byte values in the header, but
 * it's good to when when possible.
 */

Writer.prototype._emitHeader = function () {
  debug('_emitHeader()');
  var dataLength = this.dataLength;
  var headerLength = this.headerLength;
  var header = this._header;

  // write the file length at the beginning of the header
  header['writeUInt32' + this.endianness](dataLength + headerLength - 8, 4);

  // write the data length at the end of the header
  header['writeUInt32' + this.endianness](dataLength, headerLength - 4);

  this.emit('header', header);
};
<|endoftext|>