<commit_before>/* Consistent asynchronous page loading */

var current_url = window.location.pathname;

/* This is a work around for the back button being broken in Opera
 * http://www.opera.com/support/kb/view/827/
 */
history.navigationMode = 'compatible';

function to_absolute(url) {
    if (url.match(/https?\:\/\//)) {
        return url;
    } else if (url.substr(0, 1) == "/") {
        return window.location.protocol + '//' + window.location.host + url;
    } else if (url.indexOf('?') != -1) {
        if (current_url.lastIndexOf('?') != -1) {
            return current_url.substring(0, current_url.lastIndexOf('?')) + url;
        }
        return current_url + url;
    } else {
        return current_url + url;
    }
}

function display_loading_screen(){
    $('body').append('

')
    $('#loading').height($('html').height())
    display_spinner()
}

/* reposition the spinner when the page is scrolled - on iPhone only */
function display_spinner(){
    offset = window.innerHeight / 2
    if (navigator.userAgent.match(/iPhone/i) ||
        navigator.userAgent.match(/iPod/i) ||
        navigator.userAgent.match(/iPad/i)) {
        offset += window.pageYOffset
    }
    $('#loading').css('background-position', '50% ' + offset + 'px')
}

$(window).scroll(display_spinner)

function clear_loading_screen(){
    $('#loading').remove();
}

// Callback method that swaps in the asynchronously loaded bits to the page, and fades it in
function async_load_callback(data, textStatus, xhr) {
    $('body').html(data.body);
    $('title').html(data.title);
    $(document).trigger('molly-page-change', [current_url])
    capture_outbound();
}

function ajax_failure() {
    $('#loading')
        .html('
Error loading page - please try again.
')
        .css({'font-size': '20px', 'font-weight': 'bold'})
        .fadeTo('fast', 0.9, function() {
            setTimeout(function() {
                clear_loading_screen();
            }, 1200);
        });
}

function async_load(url, query, meth) {

    /* Don't attempt AJAX for offsite links */
    if (to_absolute(url).substr(0, base.length) != base) {
        return true;
    }

    display_loading_screen()

    query['format'] = 'fragment';
    $.ajax({
            'url': to_absolute(url),
            'data': query,
            'type': meth,
            'dataType': 'json',
            'success': function(data, textStatus, xhr) {
                if (data.redirect) {
                    window.location = data.redirect;
                    return true;
                }
                current_url = data.uri;
                // Detect if history API is available - http://diveintohtml5.org/detect.html#history
                if (!!(window.history && history.pushState)) {
                    history.pushState(null, null, to_absolute(current_url))
                } else {
                    already_doing_hash_reload = false;
                    window.location.hash = current_url;
                }
                return async_load_callback(data, textStatus, xhr);
            },
            'error': ajax_failure
        });
    return false;
}

function capture_outbound()  {
    // Intercept all forms
    $('form:not(.has-ajax-handler)').unbind('submit')
    $('form:not(.has-ajax-handler)').submit(function(evt) {
            var serial = $(this).serializeArray();
            var datamap = {}
            var i = 0;
            for (i = 0; i < serial.length; i++) {
                datamap[serial[i].name] = serial[i].value;
            }
            return async_load($(this).attr('action'), datamap, $(this).attr('method'));
        });
    $('form:not(.has-ajax-handler) button[type="submit"]').click(function(e){
        var form = $(this).parents('form');
        $(form).find('input[type="hidden"][name="' + $(this).attr('name') + '"]').remove()
        $(form).append('<input type="hidden" name="' + $(this).attr('name') + '" value="' + $(this).attr('value') + '" />')
        return true;
    })

    // Intercept all links with an href
    $('a[href]:not(.has-ajax-handler)').unbind('click')
    $('a[href]:not(.has-ajax-handler)').click(function(evt) {
            return async_load($(this).attr('href'), {}, 'GET');
        });
}

$(window).load(function() {
    already_doing_hash_reload = false;
    function check_hash_change(){
        // Can't use window.location.hash directly because of
        // https://bugzilla.mozilla.org/show_bug.cgi?id=483304
        var pathpart = window.location.href.split('#');
        if (pathpart.length == 1) {
            pathpart = '';
        } else {
            pathpart = pathpart[1]
        }
        if (!already_doing_hash_reload && (window.location.hash && pathpart != current_url)) {
            already_doing_hash_reload = true;
            async_load(window.location.hash.substr(1), {}, "GET");
        }
        if (!already_doing_hash_reload && (!window.location.hash && current_url != window.location.pathname + window.location.search)) {
            already_doing_hash_reload = true;
            async_load(window.location.pathname + window.location.search, {}, "GET");
        }
        if (!!!(window.history && history.pushState)) {
            setTimeout(check_hash_change, 100);
        }
    }
    check_hash_change();
    $(document).trigger('molly-page-change', [current_url])
    capture_outbound();

    if (!!(window.history && history.pushState)) {
      window.addEventListener('popstate', function(e, state){
        if (current_url != window.location.pathname) {
          async_load(window.location.href, {}, 'GET');
        }
      }, false)
    }
});

<commit_msg>Fix for pages reloading multiple times when they don't need to<commit_after>/* Consistent asynchronous page loading */

var current_url = window.location.pathname + window.location.search;

/* This is a work around for the back button being broken in Opera
 * http://www.opera.com/support/kb/view/827/
 */
history.navigationMode = 'compatible';

function to_absolute(url) {
    if (url.match(/https?\:\/\//)) {
        return url;
    } else if (url.substr(0, 1) == "/") {
        return window.location.protocol + '//' + window.location.host + url;
    } else if (url.indexOf('?') != -1) {
        if (current_url.lastIndexOf('?') != -1) {
            return current_url.substring(0, current_url.lastIndexOf('?')) + url;
        }
        return current_url + url;
    } else {
        return current_url + url;
    }
}

function display_loading_screen(){
    $('body').append('

')
    $('#loading').height($('html').height())
    display_spinner()
}

/* reposition the spinner when the page is scrolled - on iPhone only */
function display_spinner(){
    offset = window.innerHeight / 2
    if (navigator.userAgent.match(/iPhone/i) ||
        navigator.userAgent.match(/iPod/i) ||
        navigator.userAgent.match(/iPad/i)) {
        offset += window.pageYOffset
    }
    $('#loading').css('background-position', '50% ' + offset + 'px')
}

$(window).scroll(display_spinner)

function clear_loading_screen(){
    $('#loading').remove();
}

// Callback method that swaps in the asynchronously loaded bits to the page, and fades it in
function async_load_callback(data, textStatus, xhr) {
    $('body').html(data.body);
    $('title').html(data.title);
    $(document).trigger('molly-page-change', [current_url])
    capture_outbound();
}

function ajax_failure() {
    $('#loading')
        .html('
Error loading page - please try again.
')
        .css({'font-size': '20px', 'font-weight': 'bold'})
        .fadeTo('fast', 0.9, function() {
            setTimeout(function() {
                clear_loading_screen();
            }, 1200);
        });
}

function async_load(url, query, meth) {

    /* Don't attempt AJAX for offsite links */
    if (to_absolute(url).substr(0, base.length) != base) {
        return true;
    }

    display_loading_screen()

    query['format'] = 'fragment';
    $.ajax({
            'url': to_absolute(url),
            'data': query,
            'type': meth,
            'dataType': 'json',
            'success': function(data, textStatus, xhr) {
                if (data.redirect) {
                    window.location = data.redirect;
                    return true;
                }
                current_url = data.uri;
                // Detect if history API is available - http://diveintohtml5.org/detect.html#history
                if (!!(window.history && history.pushState)) {
                    history.pushState(null, null, to_absolute(current_url))
                } else {
                    already_doing_hash_reload = false;
                    window.location.hash = current_url;
                }
                return async_load_callback(data, textStatus, xhr);
            },
            'error': ajax_failure
        });
    return false;
}

function capture_outbound()  {
    // Intercept all forms
    $('form:not(.has-ajax-handler)').unbind('submit')
    $('form:not(.has-ajax-handler)').submit(function(evt) {
            var serial = $(this).serializeArray();
            var datamap = {}
            var i = 0;
            for (i = 0; i < serial.length; i++) {
                datamap[serial[i].name] = serial[i].value;
            }
            return async_load($(this).attr('action'), datamap, $(this).attr('method'));
        });
    $('form:not(.has-ajax-handler) button[type="submit"]').click(function(e){
        var form = $(this).parents('form');
        $(form).find('input[type="hidden"][name="' + $(this).attr('name') + '"]').remove()
        $(form).append('<input type="hidden" name="' + $(this).attr('name') + '" value="' + $(this).attr('value') + '" />')
        return true;
    })

    // Intercept all links with an href
    $('a[href]:not(.has-ajax-handler)').unbind('click')
    $('a[href]:not(.has-ajax-handler)').click(function(evt) {
            return async_load($(this).attr('href'), {}, 'GET');
        });
}

$(window).load(function() {
    already_doing_hash_reload = false;
    function check_hash_change(){
        // Can't use window.location.hash directly because of
        // https://bugzilla.mozilla.org/show_bug.cgi?id=483304
        var pathpart = window.location.href.split('#');
        if (pathpart.length == 1) {
            pathpart = '';
        } else {
            pathpart = pathpart[1]
        }
        if (!already_doing_hash_reload && (window.location.hash && pathpart != current_url)) {
            already_doing_hash_reload = true;
            async_load(window.location.hash.substr(1), {}, "GET");
        }
        if (!already_doing_hash_reload && (!window.location.hash && current_url != window.location.pathname + window.location.search)) {
            already_doing_hash_reload = true;
            async_load(window.location.pathname + window.location.search, {}, "GET");
        }
        if (!!!(window.history && history.pushState)) {
            setTimeout(check_hash_change, 100);
        }
    }
    check_hash_change();
    $(document).trigger('molly-page-change', [current_url])
    capture_outbound();

    if (!!(window.history && history.pushState)) {
      window.addEventListener('popstate', function(e, state){
        if (current_url != window.location.pathname) {
          async_load(window.location.href, {}, 'GET');
        }
      }, false)
    }
});

<|endoftext|>


<commit_before>var util = require('util'),
    events = require('events'),
    redis = require('redis'),
    _ = require('underscore'),
    fs = require('fs'),
    ejs = require('ejs'),
    nodemailer = require('nodemailer'),
    contentParser = require('../content-parser'),
    init = false,
    templatePath = __dirname + '/../../tpl/{tplname}.html';

function extractEmails(message, exclude) {
  var emails = [];

  emails.push(message.from[0].address);

  [message.to, message.cc].forEach(function(group) {
    if (group && group.length > 0) {
      group.forEach(function(email) {
        if (email.address !== exclude) {
          emails.push(email.address);
        }
      })
    }
  });

  // Remove duplicates
  emails = _.uniq(emails);

  // Only the first 2 emails
  emails = emails.slice(0, 2);

  return emails;
}

function gameBody(game, activePlayer, assetsUrl, template, cb) {
  template.render('game', {
    layout: '_layout',
    mode: 'email',
    player1: game.player1,
    player2: game.player2,
    player: activePlayer,
    otherPlayer: game.getOtherPlayer(activePlayer),
    turn: game.turn,
    terrain: game.terrain.map,
    assetsUrl: assetsUrl
  },
  function(body) {
    return cb(body);
  });
}
function messageBody(message, assetsUrl, template, cb) {
  template.render('message', {
    layout: '_layout',
    mode: 'email',
    messageSubject: 'A message from Cursendus',
    messageBody: message,
    assetsUrl: assetsUrl
  },
  function(body) {
    return cb(body);
  });
}

var SmtpView = function() {
  events.EventEmitter.call(this);
};
util.inherits(SmtpView, events.EventEmitter);

SmtpView.prototype.start = function(gamesManager, template, pubsub, errorMessages, conf) {
  var self = this,
      transport;

  if (init) return;
  init = true;

  function handleMessage(message) {
    var addresses = extractEmails(message, conf.emailParams.email),
        gameId = contentParser.gameId(message.subject),
        fromAddress;

    console.log('[incoming message] %d email addresse(s)', addresses.length);

    if (addresses.length === 0 || !message.from[0] || !message.from[0].address) {
      // Error
      console.log('Error: missing the `from` address.');
      return;
    }

    fromAddress = message.from[0].address;

    // Game command
    if (gameId) {
      gamesManager.getGame(gameId, function(game) {
        var player = game.getPlayerById(fromAddress);
        if (player !== false) {
          var commands = contentParser.commands(message.text),
              oneValidCommand,
              lastCommandStatus;
          if (commands.length > 0) {
            for (var i=0; i < commands.length; i++) {
              lastCommandStatus = game.command(player, commands[i][0] + ' ' + commands[i][1]);
              if (!oneValidCommand && lastCommandStatus) {
                oneValidCommand = true;
              }
            }
            if (oneValidCommand) { // At least one valid command
              if (game.commandsEnd(player)) { // New turn?
                gameBody(game, game.player1, conf.assetsUrl, template, function(body) {
                  sendMessage(game.player1.email, game.id, true, body);
                });
                gameBody(game, game.player2, conf.assetsUrl, template, function(body) {
                  sendMessage(game.player2.email, game.id, true, body);
                });
              };
            } else {
              console.log('Invalid commands in the message.');
              messageBody(errorMessages['command'], conf.assetsUrl, template, function(body) {
                sendMessage(fromAddress, game.id, true, body);
              });
              return;
            }

          } else {
            console.log('Missing commands in the message.');
            messageBody(errorMessages['command'], conf.assetsUrl, template, function(body) {
              sendMessage(fromAddress, game, true, body);
            });
            return;
          }
        } else {
          console.log('Error: the user is not a player of this game');
        }
      });

    // The game does not exists, try to create a new game.
    } else if (addresses.length === 2) {
      gamesManager.addGame(addresses[0], addresses[1], function(game) {
        gameBody(game, game.player1, conf.assetsUrl, template, function(body) {
          sendMessage(addresses[0], game, false, body);
        });
        gameBody(game, game.player2, conf.assetsUrl, template, function(body) {
          sendMessage(addresses[1], game, false, body);
        });
      });

    // Not enough emails to create a game
    } else {
      console.log('Error: 2 mails are needed to create a game.');
      return;
    }

  }

  function sendMessage(playerEmail, gameId, reply, htmlBody, cb) {
    var subject = 'Cursendus ~ [battle id: ' + gameId + ']';
    if (reply) {
      subject = 'Re: ' + subject;
    }
    transport.sendMail({
        from: 'Cursendus <'+ conf.emailParams.email +'>',
        to: playerEmail,
        subject: subject,
        text: 'TODO',
        html: htmlBody
    }, cb);
  }

  transport = nodemailer.createTransport('SMTP', {
    service: 'Gmail',
    auth: {
      XOAuthToken: nodemailer.createXOAuthGenerator({
          user: conf.emailParams.email,
          token: conf.emailParams.oauthToken,
          tokenSecret: conf.emailParams.oauthTokenSecret
      })
    }
  });

  pubsub.on('message', function(channel, messageStr) {
    var message = JSON.parse(messageStr);
    console.log('subject', message.subject)
    console.log('text', message.text)
    console.log('from', message.from)
    console.log('to', message.to)
    console.log('cc', message.cc)
    return handleMessage(message);
  });

  pubsub.subscribe('game:emails');
};

module.exports = new SmtpView;
<commit_msg>Mail view: pass the game ID<commit_after>var util = require('util'),
    events = require('events'),
    redis = require('redis'),
    _ = require('underscore'),
    fs = require('fs'),
    ejs = require('ejs'),
    nodemailer = require('nodemailer'),
    contentParser = require('../content-parser'),
    init = false,
    templatePath = __dirname + '/../../tpl/{tplname}.html';

function extractEmails(message, exclude) {
  var emails = [];

  emails.push(message.from[0].address);

  [message.to, message.cc].forEach(function(group) {
    if (group && group.length > 0) {
      group.forEach(function(email) {
        if (email.address !== exclude) {
          emails.push(email.address);
        }
      })
    }
  });

  // Remove duplicates
  emails = _.uniq(emails);

  // Only the first 2 emails
  emails = emails.slice(0, 2);

  return emails;
}

function gameBody(game, activePlayer, assetsUrl, template, cb) {
  template.render('game', {
    layout: '_layout',
    mode: 'email',
    player1: game.player1,
    player2: game.player2,
    player: activePlayer,
    otherPlayer: game.getOtherPlayer(activePlayer),
    turn: game.turn,
    terrain: game.terrain.map,
    assetsUrl: assetsUrl
  },
  function(body) {
    return cb(body);
  });
}
function messageBody(message, assetsUrl, template, cb) {
  template.render('message', {
    layout: '_layout',
    mode: 'email',
    messageSubject: 'A message from Cursendus',
    messageBody: message,
    assetsUrl: assetsUrl
  },
  function(body) {
    return cb(body);
  });
}

var SmtpView = function() {
  events.EventEmitter.call(this);
};
util.inherits(SmtpView, events.EventEmitter);

SmtpView.prototype.start = function(gamesManager, template, pubsub, errorMessages, conf) {
  var self = this,
      transport;

  if (init) return;
  init = true;

  function handleMessage(message) {
    var addresses = extractEmails(message, conf.emailParams.email),
        gameId = contentParser.gameId(message.subject),
        fromAddress;

    console.log('[incoming message] %d email addresse(s)', addresses.length);

    if (addresses.length === 0 || !message.from[0] || !message.from[0].address) {
      // Error
      console.log('Error: missing the `from` address.');
      return;
    }

    fromAddress = message.from[0].address;

    // Game command
    if (gameId) {
      gamesManager.getGame(gameId, function(game) {
        var player = game.getPlayerById(fromAddress);
        if (player !== false) {
          var commands = contentParser.commands(message.text),
              oneValidCommand,
              lastCommandStatus;
          if (commands.length > 0) {
            for (var i=0; i < commands.length; i++) {
              lastCommandStatus = game.command(player, commands[i][0] + ' ' + commands[i][1]);
              if (!oneValidCommand && lastCommandStatus) {
                oneValidCommand = true;
              }
            }
            if (oneValidCommand) { // At least one valid command
              if (game.commandsEnd(player)) { // New turn?
                gameBody(game, game.player1, conf.assetsUrl, template, function(body) {
                  sendMessage(game.player1.email, game.id, true, body);
                });
                gameBody(game, game.player2, conf.assetsUrl, template, function(body) {
                  sendMessage(game.player2.email, game.id, true, body);
                });
              };
            } else {
              console.log('Invalid commands in the message.');
              messageBody(errorMessages['command'], conf.assetsUrl, template, function(body) {
                sendMessage(fromAddress, game.id, true, body);
              });
              return;
            }

          } else {
            console.log('Missing commands in the message.');
            messageBody(errorMessages['command'], conf.assetsUrl, template, function(body) {
              sendMessage(fromAddress, game.id, true, body);
            });
            return;
          }
        } else {
          console.log('Error: the user is not a player of this game');
        }
      });

    // The game does not exists, try to create a new game.
    } else if (addresses.length === 2) {
      gamesManager.addGame(addresses[0], addresses[1], function(game) {
        gameBody(game, game.player1, conf.assetsUrl, template, function(body) {
          sendMessage(addresses[0], game.id, false, body);
        });
        gameBody(game, game.player2, conf.assetsUrl, template, function(body) {
          sendMessage(addresses[1], game.id, false, body);
        });
      });

    // Not enough emails to create a game
    } else {
      console.log('Error: 2 mails are needed to create a game.');
      return;
    }

  }

  function sendMessage(playerEmail, gameId, reply, htmlBody, cb) {
    var subject = 'Cursendus ~ [battle id: ' + gameId + ']';
    if (reply) {
      subject = 'Re: ' + subject;
    }
    transport.sendMail({
        from: 'Cursendus <'+ conf.emailParams.email +'>',
        to: playerEmail,
        subject: subject,
        text: 'TODO',
        html: htmlBody
    }, cb);
  }

  transport = nodemailer.createTransport('SMTP', {
    service: 'Gmail',
    auth: {
      XOAuthToken: nodemailer.createXOAuthGenerator({
          user: conf.emailParams.email,
          token: conf.emailParams.oauthToken,
          tokenSecret: conf.emailParams.oauthTokenSecret
      })
    }
  });

  pubsub.on('message', function(channel, messageStr) {
    var message = JSON.parse(messageStr);
    console.log('subject', message.subject)
    console.log('text', message.text)
    console.log('from', message.from)
    console.log('to', message.to)
    console.log('cc', message.cc)
    return handleMessage(message);
  });

  pubsub.subscribe('game:emails');
};

module.exports = new SmtpView;
<|endoftext|>


<commit_before>
// Construct map, center if no location provided
var map = L.map('map', { maxZoom: 13 } );
var hash = new L.Hash(map);
if (!window.location.hash) {
    map.setView([37.958, -120.976], 8);
}

// Make the base map; a raster tile relief map from ESRI
var esriRelief = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}';

var basemap = L.tileLayer(esriRelief, {
        attribution: 'ESRI shaded relief, NHDPlus v2',
        maxZoom: 13
});
basemap.addTo(map);

// Add a single GeoJSON vector file for state boundaries
// This was loaded statically as a script; could also be AJAX
var stateLayer = new L.geoJson(usStates);
stateLayer.setStyle({ "color": "#444",
                      "weight": 1,
                      "fill": false,
                      "opacity": 1.0 });
stateLayer.addTo(map);

var nlcdlayer = L.tileLayer('/nlcd/{z}/{x}/{y}.png',{tms:true}).addTo(map);

var requestsPool = {
  requests: {}, //list of urls
  timeouts: {},
  timeout:  1000*60*10, //In milliseconds
  fetch: function(url) {
    if(requestsPool.exists(url))
      return requestsPool.requests[url];

    requestsPool.timeouts[url] = setTimeout(function(u) {
        requestsPool.remove(u);
    }.bind(this, url), requestsPool.timeout); //Defining the timeout

    requestsPool.requests[url] = $.getJSON(url);
    return requestsPool.requests[url];
  },
  exists: function(url) {
    return requestsPool.requests.hasOwnProperty(url); //Return the Timeout ID if present or undefined
  },
  remove: function(url) {
    requestsPool.cancel(url);
    delete requestsPool.requests[url];
  },
  cancel: function(url) {
    clearTimeout(requestsPool.timeouts[url]); //cancel the timeout
    delete requestsPool.timeouts[url];
  }
}

function StyleTheRivers(feature){
  requestsPool.fetch('/gauges/reachflow/'+feature.properties.huc8)
  .done(function(val){
    $('.h'+feature.properties.huc8).css('stroke', (val.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*val.drank)]:'gray' );
    $('.h'+feature.properties.huc8).css('stroke-width', ((val.drank!==null)?(6*val.drank).toString():'2')+'px' );
  });
}
//$.getJSON('/gauges/reachflow/'+feature.properties.huc8, function(data){

// Style the river lines; width depends on its Strahler number
function riverStyle(feature) {
  return "stroke-width: " + feature.properties.strahler * map.getZoom()/13 + "px;stroke:#FF00DE;";
}

function riverClass(feature){
  StyleTheRivers(feature);
  return "river h" + feature.properties.huc8;
}

// Make the river overlay layer, vector tiles from our TileStache/Gunicorn server
var geojsonURL = "/rivers/{z}/{x}/{y}.json";
var riverLayer = new L.TileLayer.d3_geoJSON(geojsonURL, {
  class: riverClass,
  style: riverStyle
});
map.addLayer(riverLayer);

map.on('dragend', function(e) {
  //$('#spinnerBox').fadeIn();
  getStations();
});

var markers = new L.FeatureGroup();

var grad_colours = ['#b2182b','#d6604d','#f4a582','#fddbc7','#f7f7f7','#d1e5f0','#92c5de','#4393c3','#2166ac']

//L.control.layers(basemap,stateLayer,nlcdlayer).addTo(map);

function getStations() {
  // Clear markers before getting new ones
  markers.clearLayers();

  // Get map bounds from Leaflet.  getBounds() returns an object
  var bbox = map.getBounds();

  var addy = "/gauges/list/xmin/ymin/xmax/ymax";
  addy     = addy.replace("xmin",bbox._southWest.lng);
  addy     = addy.replace("ymin",bbox._southWest.lat);
  addy     = addy.replace("xmax",bbox._northEast.lng);
  addy     = addy.replace("ymax",bbox._northEast.lat);

  //use jQuery's getJSON() to call the SODA API for NYC 311
  $.getJSON(addy, function(data) {
    //iterate over each 311 complaint, add a marker to the map
    _.each(data, function(marker){
      var markerItem = L.circleMarker(
        [marker.lat,marker.lng],
        {
          radius:      5,
          color:       'black',
          fillColor:   (marker.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*marker.drank)]:'gray',
          fillOpacity: 1
        }
      );
      markerItem.on('mouseover', function(){
        $('#headerbar').html(marker.name);
        $('#bottomright').html(
          'Stage: ' + marker.svalue + ' ft
' +
          ''+marker.sdt+'
' +
          'Discharge: ' + marker.dvalue + ' cfs
' +
          ''+marker.ddt+'
' +
          'Rank: ' + marker.drank.toFixed(2) + '
'
          );
        console.log(marker);
      });

      // markerItem.bindPopup(
      //   '
' + marker.complaint_type + '
'
      //   + (new Date(marker.created_date)).toDateString()
      //   + ((marker.incident_address != null) ? '
' + marker.incident_address : '')
      // );

      markers.addLayer(markerItem);
    });
    map.addLayer(markers);
  });
}

$('.nlcdgrad').hover(function(e){
  var classname = $(e.target).data('classname');
  $('#nlcdexplanation').html(classname);
}, function(){
  $('#nlcdexplanation').html('NLCD Legend (hover over colours for details)');
})

/*var counties = new L.geoJson();
counties.addTo(map);
$.getJSON({
  dataType: "json",
  url:      "counties.json",
  success:  function(data) {
    $(data.features).each(function(key, data) {
        counties.addData(data);
    });
}
}).error(function() {});
*/
<commit_msg>Layers<commit_after>
// Construct map, center if no location provided
var map = L.map('map', { maxZoom: 13 } );
var hash = new L.Hash(map);
if (!window.location.hash) {
    map.setView([37.958, -120.976], 8);
}

// Make the base map; a raster tile relief map from ESRI
var esriRelief = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}';

var basemap = L.tileLayer(esriRelief, {
  attribution: 'ESRI shaded relief, NHDPlus v2',
  maxZoom: 13
});
basemap.addTo(map);

// Add a single GeoJSON vector file for state boundaries
// This was loaded statically as a script; could also be AJAX
var stateLayer = new L.geoJson(usStates);
stateLayer.setStyle({ "color": "#444",
                      "weight": 1,
                      "fill": false,
                      "opacity": 1.0 });
stateLayer.addTo(map);

var nlcdlayer = L.tileLayer('/nlcd/{z}/{x}/{y}.png',{tms:true}).addTo(map);

var requestsPool = {
  requests: {}, //list of urls
  timeouts: {},
  timeout:  1000*60*10, //In milliseconds
  fetch: function(url) {
    if(requestsPool.exists(url))
      return requestsPool.requests[url];

    requestsPool.timeouts[url] = setTimeout(function(u) {
        requestsPool.remove(u);
    }.bind(this, url), requestsPool.timeout); //Defining the timeout

    requestsPool.requests[url] = $.getJSON(url);
    return requestsPool.requests[url];
  },
  exists: function(url) {
    return requestsPool.requests.hasOwnProperty(url); //Return the Timeout ID if present or undefined
  },
  remove: function(url) {
    requestsPool.cancel(url);
    delete requestsPool.requests[url];
  },
  cancel: function(url) {
    clearTimeout(requestsPool.timeouts[url]); //cancel the timeout
    delete requestsPool.timeouts[url];
  }
}

function StyleTheRivers(feature){
  requestsPool.fetch('/gauges/reachflow/'+feature.properties.huc8)
  .done(function(val){
    $('.h'+feature.properties.huc8).css('stroke', (val.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*val.drank)]:'gray' );
    $('.h'+feature.properties.huc8).css('stroke-width', ((val.drank!==null)?(6*val.drank).toString():'2')+'px' );
  });
}
//$.getJSON('/gauges/reachflow/'+feature.properties.huc8, function(data){

// Style the river lines; width depends on its Strahler number
function riverStyle(feature) {
  return "stroke-width: " + feature.properties.strahler * map.getZoom()/13 + "px;stroke:#FF00DE;";
}

function riverClass(feature){
  StyleTheRivers(feature);
  return "river h" + feature.properties.huc8;
}

// Make the river overlay layer, vector tiles from our TileStache/Gunicorn server
var geojsonURL = "/rivers/{z}/{x}/{y}.json";
var riverLayer = new L.TileLayer.d3_geoJSON(geojsonURL, {
  class: riverClass,
  style: riverStyle
});
map.addLayer(riverLayer);

map.on('dragend', function(e) {
  //$('#spinnerBox').fadeIn();
  getStations();
});

var markers = new L.FeatureGroup();

var grad_colours = ['#b2182b','#d6604d','#f4a582','#fddbc7','#f7f7f7','#d1e5f0','#92c5de','#4393c3','#2166ac']

var baseLayers = {
  "Terrain": basemap,
};

var overlays = {
  "NLCD":           nlcdlayer,
  "Rivers":         riverLayer,
  "Gauge Stations": markers
};

L.control.layers(baseLayers, overlays).addTo(map);

function getStations() {
  // Clear markers before getting new ones
  markers.clearLayers();

  // Get map bounds from Leaflet.  getBounds() returns an object
  var bbox = map.getBounds();

  var addy = "/gauges/list/xmin/ymin/xmax/ymax";
  addy     = addy.replace("xmin",bbox._southWest.lng);
  addy     = addy.replace("ymin",bbox._southWest.lat);
  addy     = addy.replace("xmax",bbox._northEast.lng);
  addy     = addy.replace("ymax",bbox._northEast.lat);

  //use jQuery's getJSON() to call the SODA API for NYC 311
  $.getJSON(addy, function(data) {
    //iterate over each 311 complaint, add a marker to the map
    _.each(data, function(marker){
      var markerItem = L.circleMarker(
        [marker.lat,marker.lng],
        {
          radius:      5,
          color:       'black',
          fillColor:   (marker.drank!==null)?grad_colours[Math.floor((grad_colours.length-1)*marker.drank)]:'gray',
          fillOpacity: 1
        }
      );
      markerItem.on('mouseover', function(){
        $('#headerbar').html(marker.name);
        $('#bottomright').html(
          'Stage: ' + marker.svalue + ' ft
' +
          ''+marker.sdt+'
' +
          'Discharge: ' + marker.dvalue + ' cfs
' +
          ''+marker.ddt+'
' +
          'Rank: ' + marker.drank.toFixed(2) + '
'
          );
        console.log(marker);
      });

      // markerItem.bindPopup(
      //   '
' + marker.complaint_type + '
'
      //   + (new Date(marker.created_date)).toDateString()
      //   + ((marker.incident_address != null) ? '
' + marker.incident_address : '')
      // );

      markers.addLayer(markerItem);
    });
    map.addLayer(markers);
  });
}

$('.nlcdgrad').hover(function(e){
  var classname = $(e.target).data('classname');
  $('#nlcdexplanation').html(classname);
}, function(){
  $('#nlcdexplanation').html('NLCD Legend (hover over colours for details)');
})

/*var counties = new L.geoJson();
counties.addTo(map);
$.getJSON({
  dataType: "json",
  url:      "counties.json",
  success:  function(data) {
    $(data.features).each(function(key, data) {
        counties.addData(data);
    });
}
}).error(function() {});
*/
<|endoftext|>


<commit_before>class RainbowText extends Phaser.Text {

	constructor(game, x, y, text) {

		super(game, x, y, text, { font: "45px Arial", fill: "#ff0044", align: "center" });

		this._speed = 125; //ms
		this._colorIndex = 0;
		this._colors = ['#ee4035', '#f37736', '#fdf498', '#7bc043', '#0392cf'];

		this.colorize();
		this.startTimer();

		this.game.stage.addChild(this);

	}

	startTimer() {
		this.game.time.events.loop(this._speed, this.colorize, this).timer.start();
	}

	colorize() {

		for (let i = 0; i < this.text.length; i++) {

			if (this._colorIndex === this._colors.length) {
				this._colorIndex = 0;
			}

			this.addColor(this._colors[this._colorIndex], i);
			this._colorIndex++;

		}

	}

}

export default RainbowText;<commit_msg>remove unused class<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env node

// Modules
var connect = require('connect'),
    fs = require('fs'),
    http = require('http'),
    path = require('path'),
    serveStatic = require('serve-static'),
    serveIndex = require('serve-index');

// Variables
var app = connect(),
    hookFile = 'web-server-hook.js';

function main(port, rootPath, indexFile) {
    var hook = {
        config: function() {},
        postConfig: function() {}
    };

    rootPath = path.resolve(rootPath);

    if (fs.existsSync(path.resolve(hookFile))) {
        hook = require('./' + hookFile);
    }

    if (undefined !== hook.config) {
        hook.config(app, port, rootPath);
    }

    app.use(serveStatic(rootPath, {'index': [indexFile]}));
    app.use(serveIndex(rootPath, {'icons': true, 'view': 'details'}));

    if (undefined !== hook.postConfig) {
        hook.postConfig(app, port, rootPath);
    }

    if (undefined != hook.createServer) {
        hook.createServer(app, port, rootPath);
    } else {
        http.createServer(app).listen(port, function() {
            console.log('Static server started at http://localhost:%d/', port);
        });
    }
}

module.exports = main;
<commit_msg>Use process.env.PWD to resolve server hook path<commit_after>#!/usr/bin/env node

// Modules
var connect = require('connect'),
    fs = require('fs'),
    http = require('http'),
    path = require('path'),
    serveStatic = require('serve-static'),
    serveIndex = require('serve-index');

// Variables
var app = connect(),
    hookFile = path.join(process.env.PWD, 'web-server-hook.js');

function main(port, rootPath, indexFile) {
    var hook = {
        config: function() {},
        postConfig: function() {}
    };

    rootPath = path.resolve(rootPath);

    if (fs.existsSync(hookFile)) {
        hook = require(hookFile);
    }

    if (undefined !== hook.config) {
        hook.config(app, port, rootPath);
    }

    app.use(serveStatic(rootPath, {'index': [indexFile]}));
    app.use(serveIndex(rootPath, {'icons': true, 'view': 'details'}));

    if (undefined !== hook.postConfig) {
        hook.postConfig(app, port, rootPath);
    }

    if (undefined != hook.createServer) {
        hook.createServer(app, port, rootPath);
    } else {
        http.createServer(app).listen(port, function() {
            console.log('Static server started at http://localhost:%d/', port);
        });
    }
}

module.exports = main;
<|endoftext|>


<commit_before>var async = require("async");
var Promise = require("bluebird");
var mkdirp = Promise.promisify(require("mkdirp"));
var rimraf = Promise.promisify(require("rimraf"));
var fs = require("fs");
var DefaultBuilder = require("truffle-default-builder");
var PuddingLoader = require("ether-pudding/loader");
var BuildError = require("./errors/builderror");
var child_process = require("child_process");
var _ = require("lodash");

class CommandBuilder {
  constructor(command) {
    this.command = command;
  }

  build(options, callback) {
    console.log("Running `" + this.command + "`...")

    var cmd = child_process.spawn(this.command, {
      detached: false,
      cwd: options.working_directory,
      env: _.merge(process.env, {
        WORKING_DIRECTORY: options.working_directory,
        NODE_ENV: options.environment,
        BUILD_DESTINATION_DIRECTORY: options.destination_directory,
        BUILD_CONTRACTS_DIRECTORY: options.contracts_directory,
        WEB3_PROVIDER_LOCATION: "http://" + options.rpc.host + ":" + options.rpc.port
      })
    });

    cmd.stdout.on('data', (data) => {
      console.log(`${data}`);
    });

    cmd.stderr.on('data', (data) => {
      console.log(`build error: ${data}`);
    });

    cmd.on('close', (code) => {
      var error = null;
      if (code !== 0) {
        error = `Command exited with code ${code}`;
      }
      callback(error);
    });
  }
}

var Build = {
  clean: function(destination, callback) {
    // Clean first.
    rimraf(destination + '/*').then(function() {
      return mkdirp(destination);
    }).then(function() {
      callback();
    }).catch(callback);
  },

  get_contract_data: function(config, callback) {
    if (config.app.resolved.include_contracts === false) {
      return callback(null, []);
    }

    var warning = "Warning: No compiled contracts found. App will be built without compiled contracts.";

    if (fs.existsSync(config.contracts.build_directory) == false) {
      console.log(warning);
      callback(null, []);
    } else {
      PuddingLoader.contract_data(config.contracts.build_directory, function(err, contracts) {
        if (err) return callback(err);

        if (contracts.length == 0) {
          console.log(warning);
        }

        callback(null, contracts);
      });
    }
  },

  // Note: key is a legacy parameter that will eventually be removed.
  // It's specific to the default builder and we should phase it out.
  build: function(config, key, callback) {
    if (typeof key == "function") {
      callback = key;
      key = "build";
    }

    var builder = config.app.resolved.build;

    if (typeof builder == "string") {
      builder = new CommandBuilder(builder);
    } else if (typeof builder !== "function") {
      // If the builder's an object and it doesn't have
      // a proper build function, then assume it's configuration
      // for the default builder.
      if (builder.hasOwnProperty("build") == false || typeof builder.build !== "function") {
        builder = new DefaultBuilder(config.app.resolved.build, key, config.app.resolved.processors);
      }
    } else {
      // If they've only provided a build function, use that.
      builder = {
        build: builder
      };
    }

    // Use our own clean method unless the builder supplies one.
    var clean = this.clean;
    if (builder.hasOwnProperty("clean")) {
      clean = builder.clean;
    }

    clean(config.build.directory, (err) => {
      if (err) return callback(err);

      this.get_contract_data(config, function(err, contracts) {
        if (err) return callback(err);

        var options = {
          working_directory: config.working_dir,
          contracts: contracts,
          contracts_directory: config.contracts.build_directory,
          rpc: config.app.resolved.rpc,
          environment: config.environment,
          destination_directory: config.build.directory,
        };

        builder.build(options, function(err) {
          if (!err) return callback();

          if (typeof err == "string") {
            err = new BuildError(err);
          }

          callback(err);
        });
      });
    });
  },

  // Deprecated: Specific to default builder.
  dist: function(config, callback) {
    this.build(config, "dist", callback);
  }
}

module.exports = Build;
<commit_msg>Allow for no build to be specified.<commit_after>var async = require("async");
var Promise = require("bluebird");
var mkdirp = Promise.promisify(require("mkdirp"));
var rimraf = Promise.promisify(require("rimraf"));
var fs = require("fs");
var DefaultBuilder = require("truffle-default-builder");
var PuddingLoader = require("ether-pudding/loader");
var BuildError = require("./errors/builderror");
var child_process = require("child_process");
var _ = require("lodash");

class CommandBuilder {
  constructor(command) {
    this.command = command;
  }

  build(options, callback) {
    console.log("Running `" + this.command + "`...")

    var cmd = child_process.spawn(this.command, {
      detached: false,
      cwd: options.working_directory,
      env: _.merge(process.env, {
        WORKING_DIRECTORY: options.working_directory,
        NODE_ENV: options.environment,
        BUILD_DESTINATION_DIRECTORY: options.destination_directory,
        BUILD_CONTRACTS_DIRECTORY: options.contracts_directory,
        WEB3_PROVIDER_LOCATION: "http://" + options.rpc.host + ":" + options.rpc.port
      })
    });

    cmd.stdout.on('data', (data) => {
      console.log(`${data}`);
    });

    cmd.stderr.on('data', (data) => {
      console.log(`build error: ${data}`);
    });

    cmd.on('close', (code) => {
      var error = null;
      if (code !== 0) {
        error = `Command exited with code ${code}`;
      }
      callback(error);
    });
  }
}

var Build = {
  clean: function(destination, callback) {
    // Clean first.
    rimraf(destination + '/*').then(function() {
      return mkdirp(destination);
    }).then(function() {
      callback();
    }).catch(callback);
  },

  get_contract_data: function(config, callback) {
    if (config.app.resolved.include_contracts === false) {
      return callback(null, []);
    }

    var warning = "Warning: No compiled contracts found. App will be built without compiled contracts.";

    if (fs.existsSync(config.contracts.build_directory) == false) {
      console.log(warning);
      callback(null, []);
    } else {
      PuddingLoader.contract_data(config.contracts.build_directory, function(err, contracts) {
        if (err) return callback(err);

        if (contracts.length == 0) {
          console.log(warning);
        }

        callback(null, contracts);
      });
    }
  },

  // Note: key is a legacy parameter that will eventually be removed.
  // It's specific to the default builder and we should phase it out.
  build: function(config, key, callback) {
    if (typeof key == "function") {
      callback = key;
      key = "build";
    }

    var builder = config.app.resolved.build;

    // No builder specified. Ignore the build then.
    if (typeof builder == "undefined") {
      if (config.argv.quietDeploy == null) {
        console.log(`No build configuration specified. Not building.`);
      }
      return callback();
    }

    if (typeof builder == "string") {
      builder = new CommandBuilder(builder);
    } else if (typeof builder !== "function") {
      // If the builder's an object and it doesn't have
      // a proper build function, then assume it's configuration
      // for the default builder.
      if (builder.hasOwnProperty("build") == false || typeof builder.build !== "function") {
        builder = new DefaultBuilder(config.app.resolved.build, key, config.app.resolved.processors);
      }
    } else {
      // If they've only provided a build function, use that.
      builder = {
        build: builder
      };
    }

    // Use our own clean method unless the builder supplies one.
    var clean = this.clean;
    if (builder.hasOwnProperty("clean")) {
      clean = builder.clean;
    }

    clean(config.build.directory, (err) => {
      if (err) return callback(err);

      this.get_contract_data(config, function(err, contracts) {
        if (err) return callback(err);

        var options = {
          working_directory: config.working_dir,
          contracts: contracts,
          contracts_directory: config.contracts.build_directory,
          rpc: config.app.resolved.rpc,
          environment: config.environment,
          destination_directory: config.build.directory,
        };

        builder.build(options, function(err) {
          if (!err) return callback();

          if (typeof err == "string") {
            err = new BuildError(err);
          }

          callback(err);
        });
      });
    });
  },

  // Deprecated: Specific to default builder.
  dist: function(config, callback) {
    this.build(config, "dist", callback);
  }
}

module.exports = Build;
<|endoftext|>


<commit_before>#!/usr/bin/env nodejs
var _ = require('lodash');
var Promise = require('bluebird');
var debug = require('debug')('parserectomy');
var moment = require('moment');
var nconf = require('nconf');

var mongo = require('../lib/mongo');
var timutils = require('../lib/timeutils');

var cfgFile = "config/settings.json";
nconf.argv().env().file({ file: cfgFile });

/*
 * example:
 *
 * mongodb="mongodb://10.0.2.2/facebook" KEYS="interactions-interactions,rmap" DEBUG=* START=2017-10-01 mongo-scripts/parserctomy.js
 *
 */

function cleanABlock(keyinfo, std) {
    var discrimK = keyinfo.discrimK;
    var tbremK = keyinfo.tbremK;
    var blockSize = 2000;

    var selector = {
        "savingTime": { "$gt": new Date(std) }
    }
    _.set(selector, discrimK, { "$exists": true });

    return mongo
        .readLimit(nconf.get('schema').htmls, selector, {}, blockSize, 0)
        .map(function(he) {
            return _.omit(he, tbremK);
        })
        .then(function(htelems) {
            if(_.size(htelems)) {
                debug("sample: from %s %s begin with %d fields",
                    htelems[0].id, htelems[0].savingTime,
                    _.size(htelems[0]));
                return mongo
                    .updateMany(nconf.get('schema').htmls, htelems)
                    .catch(function(error) {
                        debug("Error in update (redo): %s", error);
                        return [ null ];
                    });
            }
        })
        .then(function(htelems) {
            if(!_.size(htelems))
                return -1;
            return _.size(htelems);
        });
}

/* comma separared string, like: "postType,type" */
function importKeys(csStr) {
    debug("Splitting string KEYS [%s] expecting a string with 0 or more commas and 0 or more dash", csStr);
    var f = csStr.split('-');
    var alls = f[1].split(',');
    return {
        discrimK: f[0],
        tbremK: alls
    };
};

/* YYYY-MM-DD expected here */
function importStartDate(dateStr) {
    debug("Parsing string $since [%s] expecting a YYYY-MM-DD", dateStr);
    var dat = moment(dateStr);
    return dat;
};

debug("KEYS format is discrimKey-keytoremove1,keytoremove2");
var keys = importKeys(nconf.get('KEYS'));
var startDay = importStartDate(nconf.get('since'));

debug("Addressing keys: %j since %s", keys, startDay);

/* thanks stackoverflow https://stackoverflow.com/questions/24660096/correct-way-to-write-loops-for-promise */
var promiseFor = Promise.method(function(condition, action, value) {
    if (!condition(value)) return value;
    return action(value).then(promiseFor.bind(null, condition, action));
});

promiseFor(function(numbers) {
    return numbers >= 0;
}, function(count) {
    return cleanABlock(keys, startDay);
}, 0).then(function() {
    debug("operation complete!");
});

<commit_msg>cleaned even more the tool to clean parser mistakes<commit_after>#!/usr/bin/env nodejs
var _ = require('lodash');
var Promise = require('bluebird');
var debug = require('debug')('parserectomy');
var moment = require('moment');
var nconf = require('nconf');

var mongo = require('../lib/mongo');
var timutils = require('../lib/timeutils');

var cfgFile = "config/settings.json";
nconf.argv().env().file({ file: cfgFile });

/*
 *
 * mongodb="mongodb://10.0.2.2/facebook" KEYS="interactions-interactions,rmap" DEBUG=* since=2017-10-01 mongo-scripts/parserctomy.js
 *                                             ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
 *                                     discriminative key/   \keys to be removed
 *
 * it removed the keys 'interactions' and 'rmap' from all the object with 'interactions'
 *
 * YYYY-MM-DD expected here */

function manageState(state) {
    var timewindow = 4; // hours
    var shifts = state.shifts + 1;
    var startM  = moment(nconf.get('since')).add( timewindow * (shifts -1), 'h');
    var endM  = moment(nconf.get('since')).add( timewindow * shifts, 'h');

    if(nconf.get('until') && moment(nconf.get('until')).isAfter(startM)) {
        debug("until date trigger: %s isAfter %s", nconf.get('until'), startM.format() );
        process.exit();
    }

    return {
        start: startM.toISOString(),
        end: endM.toISOString(),
        shifts: shifts,
    };
};

debug("KEYS format is discrimKey-keytoremove1,keytoremove2");
var keys = importKeys(nconf.get('KEYS'));
debug("keys: %j", keys);

/* thanks stackoverflow https://stackoverflow.com/questions/24660096/correct-way-to-write-loops-for-promise */
var promiseFor = Promise.method(function(condition, action, value) {
    if (!condition(value)) return value;
    return action(value).then(promiseFor.bind(null, condition, action));
});

promiseFor(function(timew) {

    /* if `start` is arrive in the future, its over */
    return moment(timew.start).isBefore();

},  cleanABlock,
    manageState({ shifts: 1 })
).then(function(completed) {
    debug("operation complete after %d day shift", completed.shifts);
});

function cleanABlock(state) {
    var discrimK = keys.discrimK;
    var tbremK = keys.tbremK;

    var selector = {
        "savingTime": { "$gt": new Date(state.start), "$lt": new Date(state.end) }
    }
    _.set(selector, discrimK, { "$exists": true });

    return mongo
        .read(nconf.get('schema').htmls, selector)
        .map(function(he) {
            return _.omit(he, tbremK);
        })
        .then(function(htelems) {
            if(_.size(htelems)) {
                debug("sample: from %s %s begin with %d fields",
                    htelems[0].id, htelems[0].savingTime,
                    _.size(htelems[0]));
                return mongo
                    .updateMany(nconf.get('schema').htmls, htelems)
                    .return(state);
            } else {
                return manageState(state);
            }
        })
        .catch(function(error) {
            debug("Error in update, wait 2000ms and redo: %s", error);
            return Promise
                .delay(2000)
                .return(state);
        })
}

/* comma separared string, like: "postType,type" */
function importKeys(csStr) {
    debug("Splitting string KEYS [%s] expecting a string with 0 or more commas and 0 or more dash", csStr);
    var f = csStr.split('-');
    var alls = f[1].split(',');
    return {
        discrimK: f[0],
        tbremK: alls
    };
};

<|endoftext|>


<commit_before>/**
 * This file generates binary files for https://github.com/anvaka/allnpmviz3d:
 *
 * + links.bin
 * + positions.bin
 * + labels.json
 */
var fs = require('fs');

var posFileName = process.argv[2];
var graphFileName = process.argv[3];

if (!posFileName) {
  console.log('I need positition file `*.pos3d as second argument`');
  return -1;
}
if (!graphFileName) {
  console.log('I need graph file, produced by convertToGraph.js file');
  return -2;
}

var nodes = JSON.parse(fs.readFileSync(posFileName, 'utf8'));

savePositions(nodes);
saveLinks(nodes);
saveLabels(nodes);

function savePositions(nodes) {
  var buf = new Buffer(nodes.length * 4 * 3);
  nodes.forEach(function(element, i) {
    var idx = i * 4 * 3;
    buf.writeInt32LE(element.pos.x, idx);
    buf.writeInt32LE(element.pos.y, idx + 4);
    buf.writeInt32LE(element.pos.z, idx + 8);
  });

  fs.writeFileSync('positions.bin', buf);
}

function saveLabels(nodes) {
  var labels = [];
  nodes.forEach(function(element, i) {
    labels.push(element.node);
  });
  fs.writeFileSync('labels.json', JSON.stringify(labels), 'utf8');
}

function saveLinks(nodes) {
  var graph = JSON.parse(fs.readFileSync(graphFileName, 'utf8'));
  var nodeMap = Object.create(null);

  nodes.forEach(function(element, i) {
    nodeMap[element.node] = i;
  });

  var linkMap = Object.create(null);

  graph.links.forEach(function (link) {
    if (typeof nodeMap[link.fromId] !== 'number') {
      console.log('skipping', link);
    }

    var store = linkMap[link.fromId];
    if (!store) {
      store = linkMap[link.fromId] = [];
    }
    var nodeIdx = nodeMap[link.toId];
    if (typeof nodeIdx !== 'number') {
      console.log('skipping', link);
    }

    store.push(nodeIdx);
  });

  var buf = new Buffer((nodes.length + graph.links.length) * 4);
  var idx = 0;

  nodes.forEach(function(element, i) {
    var nodeId =  nodeMap[element.node] + 1; // + 1 so that we avoid 0
    buf.writeInt32LE(-nodeId, idx);
    idx += 4;
    var adjacent = linkMap[element.node];
    if (adjacent) {
      adjacent.forEach(function (element) {
        buf.writeInt32LE(element, idx);
        idx += 4;
      });
    }
  });
  fs.writeFileSync('links.bin', buf);
}
<commit_msg>Make sure when skipping something we are truly skipping it<commit_after>/**
 * This file generates binary files for https://github.com/anvaka/allnpmviz3d:
 *
 * + links.bin
 * + positions.bin
 * + labels.json
 */
var fs = require('fs');

var posFileName = process.argv[2];
var graphFileName = process.argv[3];

if (!posFileName) {
  console.log('I need positition file `*.pos3d as second argument`');
  return -1;
}
if (!graphFileName) {
  console.log('I need graph file, produced by convertToGraph.js file');
  return -2;
}

var nodes = JSON.parse(fs.readFileSync(posFileName, 'utf8'));

savePositions(nodes);
saveLinks(nodes);
saveLabels(nodes);

function savePositions(nodes) {
  var buf = new Buffer(nodes.length * 4 * 3);
  nodes.forEach(function(element, i) {
    var idx = i * 4 * 3;
    buf.writeInt32LE(element.pos.x, idx);
    buf.writeInt32LE(element.pos.y, idx + 4);
    buf.writeInt32LE(element.pos.z, idx + 8);
  });

  fs.writeFileSync('positions.bin', buf);
}

function saveLabels(nodes) {
  var labels = [];
  nodes.forEach(function(element, i) {
    labels.push(element.node);
  });
  fs.writeFileSync('labels.json', JSON.stringify(labels), 'utf8');
}

function saveLinks(nodes) {
  var graph = JSON.parse(fs.readFileSync(graphFileName, 'utf8'));
  var nodeMap = Object.create(null);

  nodes.forEach(function(element, i) {
    nodeMap[element.node] = i;
  });

  var linkMap = Object.create(null);

  graph.links.forEach(function (link) {
    if (typeof nodeMap[link.fromId] !== 'number') {
      console.log('skipping', link);
      return;
    }

    var store = linkMap[link.fromId];
    if (!store) {
      store = linkMap[link.fromId] = [];
    }
    var nodeIdx = nodeMap[link.toId];
    if (typeof nodeIdx !== 'number') {
      console.log('skipping', link);
      return;
    }

    store.push(nodeIdx);
  });

  var buf = new Buffer((nodes.length + graph.links.length) * 4);
  var idx = 0;

  nodes.forEach(function(element, i) {
    var nodeId =  nodeMap[element.node] + 1; // + 1 so that we avoid 0
    buf.writeInt32LE(-nodeId, idx);
    idx += 4;
    var adjacent = linkMap[element.node];
    if (adjacent) {
      adjacent.forEach(function (element) {
        buf.writeInt32LE(element, idx);
        idx += 4;
      });
    }
  });
  fs.writeFileSync('links.bin', buf);
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

// Only run on the first of the month
const today = new Date();
if (process.env.NODE_ENV === 'production' && today.getDate() !== 1) {
  console.log('NODE_ENV is production and today is not the first of month, script aborted!');
  process.exit();
}

process.env.PORT = 3066;

import _ from 'lodash';
import moment from 'moment';
import Promise from 'bluebird';
import debugLib from 'debug';
import models, { sequelize } from '../../server/models';
import emailLib from '../../server/lib/email';
import config from 'config';
import { exportTransactions } from '../../server/lib/transactions';
import { getHostedGroups, getBackersStats, sumTransactions, getTransactions } from '../../server/lib/hostlib';

const d = new Date;
d.setMonth(d.getMonth() - 1);
const month = moment(d).format('MMMM');

const csv_filename = `${moment(d).format('YYYYMM')}-transactions.csv`;

const startDate = new Date(d.getFullYear(), d.getMonth(), 1);
const endDate = new Date(d.getFullYear(), d.getMonth()+1, 1);

console.log("startDate", startDate,"endDate", endDate);

const debug = debugLib('monthlyreport');

const {
  User,
  Transaction
} = models;

const init = () => {

  const startTime = new Date;

  let previewCondition = '';
  if (process.env.DEBUG && process.env.DEBUG.match(/preview/))
    previewCondition = "AND u.username IN ('adminwwc', 'host-org')";

  const query = `SELECT u.id, u.currency, u.username, u."firstName", u."lastName" FROM "Users" u LEFT JOIN "UserGroups" ug ON ug."UserId" = u.id WHERE ug.role='HOST' AND ug."deletedAt" IS NULL and u."deletedAt" IS NULL ${previewCondition} GROUP BY u.id`;

  sequelize.query(query, {
    model: models.User,
    type: sequelize.QueryTypes.SELECT
  })
  .tap(hosts => {
      console.log(`Preparing the ${month} report for ${hosts.length} hosts`);
  })
  .then(hosts => Promise.map(hosts, processHost))
  .then(() => {
    const timeLapsed = Math.round((new Date - startTime)/1000);
    console.log(`Total run time: ${timeLapsed}s`);
    process.exit(0)
  });
}

const getHostStats = (host, groupids) => {

  const dateRange = {
    createdAt: { $gte: startDate, $lt: endDate }
  };

  const where = {
    GroupId: { $in: groupids }
  };

  return Promise.all([
    sumTransactions('netAmountInGroupCurrency', where, host.currency),                      // total host balance
    sumTransactions('netAmountInGroupCurrency', { ...where, ...dateRange}, host.currency),   // delta host balance last month
    sumTransactions('amount', { type: 'DONATION', ...where, ...dateRange}, host.currency), // total donations last month
    sumTransactions('netAmountInGroupCurrency', { type: 'DONATION', ...where, ...dateRange}, host.currency), // total net amount received last month
    sumTransactions('netAmountInGroupCurrency', { type: 'EXPENSE', ...where, ...dateRange}, host.currency),  // total net amount paid out last month
    sumTransactions("hostFeeInTxnCurrency", {...where, ...dateRange}, host.currency),
    sumTransactions("paymentProcessorFeeInTxnCurrency", {...where, ...dateRange}, host.currency),
    sumTransactions("platformFeeInTxnCurrency", {...where, ...dateRange}, host.currency),
    getBackersStats(groupids, startDate, endDate)
  ]);
}

const processHost = (host) => {

  const data = {};
  let groupsById = {}, attachment;

  data.host = host;
  data.reportDate = endDate;
  data.month = month;
  data.config = _.pick(config, 'host');

  return getHostedGroups(host.id)
    .tap(groups => groupsById = _.indexBy(groups, "id"))
    .then(() => getTransactions(Object.keys(groupsById), startDate, endDate))
    .tap(transactions => {
      data.transactions = transactions;
      return exportTransactions(transactions)
       .then(csv => {
          attachment = {
            filename: csv_filename,
            content: csv
          }
        })
    })
    .then(transactions => transactions.map(t => {
      const r = t.info;
      r.group = groupsById[r.GroupId].dataValues;
      return r;
    }))
    .then(() => getHostStats(host, Object.keys(groupsById)))
    .then(stats => {
      data.stats = {
        totalCollectives: Object.keys(groupsById).length,
        balance: stats[0],
        delta: stats[1],
        totalNewDonations: stats[2],
        totalNetAmountReceivedForCollectives: stats[3],
        totalNewExpenses: stats[4],
        totalNewHostFees: stats[5],
        paymentProcessorFees: stats[6],
        platformFees: stats[7],
        backers: stats[8]
      };
      data.stats.totalNetAmountReceived = {
        totalInHostCurrency: data.stats.totalNetAmountReceivedForCollectives.totalInHostCurrency + data.stats.totalNewHostFees.totalInHostCurrency
      };
    })
    .then(() => sendEmail(host, data, attachment))
    .catch(e => {
      console.error("Error in processing host", host.username, e);
    });
};

const sendEmail = (recipient, data, attachment) => {
    debug("Sending email to ", recipient.dataValues);
    // debug("email data transactions", data.transactions);
    debug("email data stats", data.stats);
    debug("email data stats.backers", data.stats.backers);
    data.recipient = recipient;
    if (process.env.ONLY && recipient.email !== process.env.ONLY) {
      debug("Skipping ", recipient.email);
      return Promise.resolve();
    }
    if (process.env.SEND_EMAIL_TO) {
      recipient.email = process.env.SEND_EMAIL_TO;
    }
    const options = {
      attachments: [ attachment ]
    }
    return emailLib.send('host.monthlyreport', recipient.email, data, options);
}

init();
<commit_msg>eslint<commit_after>#!/usr/bin/env node

// Only run on the first of the month
const today = new Date();
if (process.env.NODE_ENV === 'production' && today.getDate() !== 1) {
  console.log('NODE_ENV is production and today is not the first of month, script aborted!');
  process.exit();
}

process.env.PORT = 3066;

import _ from 'lodash';
import moment from 'moment';
import Promise from 'bluebird';
import debugLib from 'debug';
import models, { sequelize } from '../../server/models';
import emailLib from '../../server/lib/email';
import config from 'config';
import { exportTransactions } from '../../server/lib/transactions';
import { getHostedGroups, getBackersStats, sumTransactions, getTransactions } from '../../server/lib/hostlib';

const d = new Date;
d.setMonth(d.getMonth() - 1);
const month = moment(d).format('MMMM');

const csv_filename = `${moment(d).format('YYYYMM')}-transactions.csv`;

const startDate = new Date(d.getFullYear(), d.getMonth(), 1);
const endDate = new Date(d.getFullYear(), d.getMonth()+1, 1);

console.log("startDate", startDate,"endDate", endDate);

const debug = debugLib('monthlyreport');

const init = () => {

  const startTime = new Date;

  let previewCondition = '';
  if (process.env.DEBUG && process.env.DEBUG.match(/preview/))
    previewCondition = "AND u.username IN ('adminwwc', 'host-org')";

  const query = `SELECT u.id, u.currency, u.username, u."firstName", u."lastName" FROM "Users" u LEFT JOIN "UserGroups" ug ON ug."UserId" = u.id WHERE ug.role='HOST' AND ug."deletedAt" IS NULL and u."deletedAt" IS NULL ${previewCondition} GROUP BY u.id`;

  sequelize.query(query, {
    model: models.User,
    type: sequelize.QueryTypes.SELECT
  })
  .tap(hosts => {
      console.log(`Preparing the ${month} report for ${hosts.length} hosts`);
  })
  .then(hosts => Promise.map(hosts, processHost))
  .then(() => {
    const timeLapsed = Math.round((new Date - startTime)/1000);
    console.log(`Total run time: ${timeLapsed}s`);
    process.exit(0)
  });
}

const getHostStats = (host, groupids) => {

  const dateRange = {
    createdAt: { $gte: startDate, $lt: endDate }
  };

  const where = {
    GroupId: { $in: groupids }
  };

  return Promise.all([
    sumTransactions('netAmountInGroupCurrency', where, host.currency),                      // total host balance
    sumTransactions('netAmountInGroupCurrency', { ...where, ...dateRange}, host.currency),   // delta host balance last month
    sumTransactions('amount', { type: 'DONATION', ...where, ...dateRange}, host.currency), // total donations last month
    sumTransactions('netAmountInGroupCurrency', { type: 'DONATION', ...where, ...dateRange}, host.currency), // total net amount received last month
    sumTransactions('netAmountInGroupCurrency', { type: 'EXPENSE', ...where, ...dateRange}, host.currency),  // total net amount paid out last month
    sumTransactions("hostFeeInTxnCurrency", {...where, ...dateRange}, host.currency),
    sumTransactions("paymentProcessorFeeInTxnCurrency", {...where, ...dateRange}, host.currency),
    sumTransactions("platformFeeInTxnCurrency", {...where, ...dateRange}, host.currency),
    getBackersStats(groupids, startDate, endDate)
  ]);
}

const processHost = (host) => {

  const data = {};
  let groupsById = {}, attachment;

  data.host = host;
  data.reportDate = endDate;
  data.month = month;
  data.config = _.pick(config, 'host');

  return getHostedGroups(host.id)
    .tap(groups => groupsById = _.indexBy(groups, "id"))
    .then(() => getTransactions(Object.keys(groupsById), startDate, endDate))
    .tap(transactions => {
      data.transactions = transactions;
      return exportTransactions(transactions)
       .then(csv => {
          attachment = {
            filename: csv_filename,
            content: csv
          }
        })
    })
    .then(transactions => transactions.map(t => {
      const r = t.info;
      r.group = groupsById[r.GroupId].dataValues;
      return r;
    }))
    .then(() => getHostStats(host, Object.keys(groupsById)))
    .then(stats => {
      data.stats = {
        totalCollectives: Object.keys(groupsById).length,
        balance: stats[0],
        delta: stats[1],
        totalNewDonations: stats[2],
        totalNetAmountReceivedForCollectives: stats[3],
        totalNewExpenses: stats[4],
        totalNewHostFees: stats[5],
        paymentProcessorFees: stats[6],
        platformFees: stats[7],
        backers: stats[8]
      };
      data.stats.totalNetAmountReceived = {
        totalInHostCurrency: data.stats.totalNetAmountReceivedForCollectives.totalInHostCurrency + data.stats.totalNewHostFees.totalInHostCurrency
      };
    })
    .then(() => sendEmail(host, data, attachment))
    .catch(e => {
      console.error("Error in processing host", host.username, e);
    });
};

const sendEmail = (recipient, data, attachment) => {
    debug("Sending email to ", recipient.dataValues);
    // debug("email data transactions", data.transactions);
    debug("email data stats", data.stats);
    debug("email data stats.backers", data.stats.backers);
    data.recipient = recipient;
    if (process.env.ONLY && recipient.email !== process.env.ONLY) {
      debug("Skipping ", recipient.email);
      return Promise.resolve();
    }
    if (process.env.SEND_EMAIL_TO) {
      recipient.email = process.env.SEND_EMAIL_TO;
    }
    const options = {
      attachments: [ attachment ]
    }
    return emailLib.send('host.monthlyreport', recipient.email, data, options);
}

init();
<|endoftext|>


<commit_before>'use strict'

const StatsCollector = require('toolbag/lib/plugins/stats_collector')
const UdpReporter = require('toolbag/lib/plugins/udp_reporter')

module.exports = function (defaults, callback) {
  callback(null, {
    plugins: [
      {
        plugin: UdpReporter,
        options: {
          id: 'udp reporter',
          socketType: 'udp4',
          port: 5001,
          host: 'localhost'
        }
      },
      {
        plugin: StatsCollector,
        options: {
          enabled: true,
          period: 1000,
          eventLoopLimit: 30,
          features: {
            process: true,
            system: true,
            cpu: true,
            memory: true,
            gc: false,
            handles: false,
            requests: false,
            eventLoop: true,
            meta: {
              tags: ['nodezoo-search']
            }
          }
        }
      }
    ]
  })
}
<commit_msg>toolbag file updated<commit_after>'use strict'

const StatsCollector = require('toolbag-plugin-stats-collector')
const UdpReporter = require('toolbag-plugin-udp-reporter')

module.exports = function (defaults, callback) {
  callback(null, {
    plugins: [
      {
        plugin: UdpReporter,
        options: {
          id: 'udp reporter',
          socketType: 'udp4',
          port: 5001,
          host: 'localhost'
        }
      },
      {
        plugin: StatsCollector,
        options: {
          enabled: true,
          period: 1000,
          eventLoopLimit: 30,
          features: {
            process: true,
            system: true,
            cpu: true,
            memory: true,
            gc: false,
            handles: false,
            requests: false,
            eventLoop: true,
            meta: {
              tags: ['nodezoo-search']
            }
          }
        }
      }
    ]
  })
}
<|endoftext|>


<commit_before>// ==UserScript==
// @name           Amazon personal filter
// @namespace      curipha
// @description    Obscure annoying contents from search result and best sellers
// @include        http://www.amazon.co.jp/*
// @include        https://www.amazon.co.jp/*
// @version        0.1.1
// @grant          none
// @noframes
// ==/UserScript==

(function() {
  'use strict';

  if (document.contentType !== 'text/html') return;

  var opacity = 0.2;
  var pattern = /(無料|期間限定|(試|立ち?)読|(試|ため)し|スターター|STARTER|ダイジェスト|分冊|単話|(1話|ばら)売り|雑誌|Web版|未分類|プチ(キス|デザ|ララ)|ハーレクイン|([^0-9０-９][0０]|創刊)号|[Vv]ol[\s．\.]*[0０]([^0-9０-９]|$))/;

  var opaque = function(list_selector, item_selector, title_func) {
    var gettitle = title_func || (function(elem) { return elem.getAttribute('title') || elem.textContent });

    return function() {
      var result = document.body.querySelectorAll(list_selector);
      for (var item of result) {
        var title = item.querySelector(item_selector);
        if (title) {
          if (pattern.test(gettitle(title).trim())) {
            item.style.opacity = opacity;
          }
          else {
            if (item.style.opacity == opacity) item.style.opacity = 1;
          }
        }
      }
    };
  };

  // Search result
  if (document.getElementById('searchTemplate')) {
    var mo_sr = new MutationObserver(opaque('#searchTemplate .s-result-item', 'h2'));
    mo_sr.observe(document.body, { childList: true, subtree: true });
  }
  if (document.getElementById('mainResults')) {
    var mo_sr2 = new MutationObserver(opaque('#mainResults [id^="result_"]', 'h3 .lrg'));
    mo_sr2.observe(document.body, { childList: true });
  }

  // Best sellers
  if (document.getElementById('zg_col1')) {
    var mo_bs = new MutationObserver(opaque('#zg_col1 .zg_item_compact', '.a-col-right .a-link-normal'));
    mo_bs.observe(document.body, { childList: true });
  }

  // Personalized item list
  var mo_il = new MutationObserver(opaque('.s9hl', 'a.title[title]'));
  mo_il.observe(document.body, { childList: true });
  var mo_il2 = new MutationObserver(opaque('#buttonWrapper .shoveler-cell', '.p13n-link div[class^="p13n-sc-"]'));
  mo_il2.observe(document.body, { childList: true, subtree: true });
})();
<commit_msg>Add support for carousel item card<commit_after>// ==UserScript==
// @name           Amazon personal filter
// @namespace      curipha
// @description    Obscure annoying contents from search result and best sellers
// @include        http://www.amazon.co.jp/*
// @include        https://www.amazon.co.jp/*
// @version        0.1.1
// @grant          none
// @noframes
// ==/UserScript==

(function() {
  'use strict';

  if (document.contentType !== 'text/html') return;

  var opacity = 0.2;
  var pattern = /(無料|期間限定|(試|立ち?)読|(試|ため)し|スターター|STARTER|ダイジェスト|分冊|単話|(1話|ばら)売り|雑誌|Web版|未分類|プチ(キス|デザ|ララ)|ハーレクイン|([^0-9０-９][0０]|創刊)号|[Vv]ol[\s．\.]*[0０]([^0-9０-９]|$))/;

  var opaque = function(list_selector, item_selector, title_func) {
    var gettitle = title_func || (function(elem) { return elem.getAttribute('title') || elem.textContent });

    return function() {
      var result = document.body.querySelectorAll(list_selector);
      for (var item of result) {
        var title = item.querySelector(item_selector);
        if (title) {
          if (pattern.test(gettitle(title).trim())) {
            item.style.opacity = opacity;
          }
          else {
            if (item.style.opacity == opacity) item.style.opacity = 1;
          }
        }
      }
    };
  };

  // Search result
  if (document.getElementById('searchTemplate')) {
    var mo_sr = new MutationObserver(opaque('#searchTemplate .s-result-item', 'h2'));
    mo_sr.observe(document.body, { childList: true, subtree: true });
  }
  if (document.getElementById('mainResults')) {
    var mo_sr2 = new MutationObserver(opaque('#mainResults [id^="result_"]', 'h3 .lrg'));
    mo_sr2.observe(document.body, { childList: true });
  }

  // Best sellers
  if (document.getElementById('zg_col1')) {
    var mo_bs = new MutationObserver(opaque('#zg_col1 .zg_item_compact', '.a-col-right .a-link-normal'));
    mo_bs.observe(document.body, { childList: true });
  }

  // Personalized item list
  var mo_il = new MutationObserver(opaque('.s9hl', 'a.title[title]'));
  mo_il.observe(document.body, { childList: true });
  var mo_il2 = new MutationObserver(opaque('#buttonWrapper .shoveler-cell', '.p13n-link div[class^="p13n-sc-"]'));
  mo_il2.observe(document.body, { childList: true, subtree: true });
  var mo_il3 = new MutationObserver(opaque('#sims-carousel-holder .a-carousel-card', '.p13n-sc-truncated'));
  mo_il3.observe(document.body, { childList: true });
})();
<|endoftext|>


<commit_before>'use strict';

var sockets = require.main.require('./src/socket.io/plugins');
var categoryNotifications = require('./categoryNotifications');

sockets.categoryNotifications = {};

sockets.categoryNotifications.subscribe = function(socket, data, callback) {
	if (!socket.uid || !data || !data.cid) {
		return callback(new Error('[[error:invalid-data]]'));
	}
	categoryNotifications.subscribe(socket.uid, data.cid, callback);
};

sockets.categoryNotifications.unsubscribe = function(socket, data, callback) {
	if (!socket.uid || !data || !data.cid) {
		return callback(new Error('[[error:invalid-data]]'));
	}

	categoryNotifications.unsubscribe(socket.uid, data.cid, callback);
};

sockets.categoryNotifications.isSubscribed = function(socket, data, callback) {
	if (!socket.uid || !data || !data.cid) {
		return callback(new Error('[[error:invalid-data]]'));
	}
	categoryNotifications.isSubscribed(socket.uid, data.cid, callback);
};
<commit_msg>ignore invalid cid<commit_after>'use strict';

var sockets = require.main.require('./src/socket.io/plugins');
var categoryNotifications = require('./categoryNotifications');

sockets.categoryNotifications = {};

sockets.categoryNotifications.subscribe = function(socket, data, callback) {
	if (!socket.uid || !data || !data.cid) {
		return callback(new Error('[[error:invalid-data]]'));
	}
	categoryNotifications.subscribe(socket.uid, data.cid, callback);
};

sockets.categoryNotifications.unsubscribe = function(socket, data, callback) {
	if (!socket.uid || !data || !data.cid) {
		return callback(new Error('[[error:invalid-data]]'));
	}

	categoryNotifications.unsubscribe(socket.uid, data.cid, callback);
};

sockets.categoryNotifications.isSubscribed = function(socket, data, callback) {
	if (!socket.uid || !data) {
		return callback(new Error('[[error:invalid-data]]'));
	}
	if (!data.cid) {
		return callback();
	}
	categoryNotifications.isSubscribed(socket.uid, data.cid, callback);
};
<|endoftext|>


<commit_before>/* global module, __dirname */
'use strict'

const pkg = require('./package.json')
const webpack = require('webpack')
const path = require('path')
const url = require('url')

const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin
const DedupePlugin = webpack.optimize.DedupePlugin
const DefinePlugin = webpack.DefinePlugin
// const HotModuleReplacementPlugin = webpack.HotModuleReplacementPlugin
const NormalModuleReplacementPlugin = webpack.NormalModuleReplacementPlugin
const OccurenceOrderPlugin = webpack.optimize.OccurenceOrderPlugin
const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlPlugin = require('./scripts/webpack/html-plugin')

const isProduction = (process.env.NODE_ENV === 'production')
const isDevelopment = (process.env.NODE_ENV === 'development')
const isTest = (process.env.NODE_ENV === 'test')

const outputFolder = 'build/'
const urlLoaderLimit = 10000
const publicPath = '/'
if (isDevelopment) {
	// We use "homepage" field to infer "public path" at which the app is served.
	// Webpack needs to know it to put the right

						${context.css && `<link rel="stylesheet" href="${publicPath}${context.css}">`}

					`,
				}
			},
			isDev: isDevelopment,
		}),

		// Ignore the "full" schema in js-yaml's module, because it brings in esprima
		// to support the !!js/function type. We don't use and have no need for it, so
		// tell webpack to ignore it.
		new NormalModuleReplacementPlugin(/schema\/default_full$/, result => {
			result.request = result.request.replace('default_full', 'default_safe')
		}),

		new DefinePlugin({
			VERSION: JSON.stringify(pkg.version),
			DEVELOPMENT: isDevelopment,
			PRODUCTION: isProduction,
			TESTING: isTest,
			APP_BASE: JSON.stringify(publicPath),
			'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
		}),

		new CommonsChunkPlugin({
			names: ['react', 'common'],
			filename: '[name].[hash].js',
		}),
	],

	module: {
		loaders: [
			{
				test: /\.js$/,
				// allow babel to run on lodash-es
				exclude: /node_modules/,
				loaders: ['babel-loader?cacheDirectory'],
			},
			{
				test: /\.worker.js$/,
				// allow babel to run on lodash-es
				exclude: /node_modules/,
				loaders: ['worker-loader', 'babel-loader?cacheDirectory'],
			},
			{
				test: /\.json$/,
				loaders: ['json-loader'],
			},
			{
				test: /\.(otf|eot|ttf|woff2?)$/,
				loader: 'url-loader',
				query: {limit: urlLoaderLimit},
			},
			{
				test: /\.(jpe?g|png|gif)$/,
				loader: 'url-loader',
				query: {limit: urlLoaderLimit},
			},
		],
	},

	worker: {
		output: {
			filename: '[hash].worker.js',
			chunkFilename: '[id].[hash].worker.js',
		},
	},
}

// dev specific stuff
if (isDevelopment) {
	// debugging option
	config.devtool = 'eval'

	// add dev server and hotloading clientside code
	// config.entry.unshift(
	// 	'react-hot-loader/patch',
	// 	`webpack-dev-server/client?http://${config.hostname}:${config.port}`,
	// 	'webpack/hot/only-dev-server'
	// )

	config.devServer.port = config.port
	config.devServer.host = config.hostname

	// add dev plugins
	// config.plugins.push(new HotModuleReplacementPlugin())

	// Add style loaders
	let extractor = new ExtractTextPlugin(config.output.cssFilename, {allChunks: true})
	config.plugins = config.plugins.concat([extractor])
	config.module.loaders.push({test: /\.css$/, loader: extractor.extract('style', ['css'])})
	config.module.loaders.push({test: /\.scss$/, loader: extractor.extract('style', ['css!sass'])})

	let identName = '[path][name]·[local]·[hash:base64:5]'
	config.module.loaders.push({test: /\.module.css$/, loader: extractor.extract('style', [`css?modules&localIdentName=${identName}`])})
	config.module.loaders.push({test: /\.module.scss$/, loader: extractor.extract('style', [`css?modules&localIdentName=${identName}!sass`])})
}

else if (isTest) {
	config.module.loaders.push({test: /\.css$/, loader: 'style!css'})
	config.module.loaders.push({test: /\.module.css$/, loader: 'style!css?modules'})
	config.module.loaders.push({test: /\.scss$/, loader: 'style!css!sass'})
	config.module.loaders.push({test: /\.module.scss$/, loader: 'style!css?modules!sass'})
}

// production
else if (isProduction) {
	config.devtool = 'source-map'
	config.stats.children = false

	// minify in production
	let extractor = new ExtractTextPlugin(config.output.cssFilename, {allChunks: true})
	config.plugins = config.plugins.concat([
		new DedupePlugin(),
		new OccurenceOrderPlugin(true),
		new UglifyJsPlugin({
			compress: {
				warnings: false,
				pure_getters: true, // eslint-disable-line camelcase
				screw_ie8: true, // eslint-disable-line camelcase
				unsafe: true,
			},
			mangle: {
				screw_ie8: true, // eslint-disable-line camelcase
			},
			output: {
				comments: false,
				screw_ie8: true, // eslint-disable-line camelcase
			},
		}),
		extractor,
	])

	config.module.loaders.push({
		test: /\.css$/,
		loader: extractor.extract('style', ['css']),
	})
	config.module.loaders.push({
		test: /\.scss$/,
		loader: extractor.extract('style', ['css', 'sass']),
	})

	config.module.loaders.push({
		test: /\.module.css$/,
		loader: extractor.extract('style', ['css?modules']),
	})
	config.module.loaders.push({
		test: /\.module.scss$/,
		loader: extractor.extract('style', ['css?modules', 'sass']),
	})
}

else {
	throw new Error('Unknown environment! Not development, production, nor test!')
}

module.exports = config
<commit_msg>add comments to webpackrc<commit_after>/* global module, __dirname */
'use strict'

const pkg = require('./package.json')
const webpack = require('webpack')
const path = require('path')
const url = require('url')

const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin
const DedupePlugin = webpack.optimize.DedupePlugin
const DefinePlugin = webpack.DefinePlugin
// const HotModuleReplacementPlugin = webpack.HotModuleReplacementPlugin
const NormalModuleReplacementPlugin = webpack.NormalModuleReplacementPlugin
const OccurenceOrderPlugin = webpack.optimize.OccurenceOrderPlugin
const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlPlugin = require('./scripts/webpack/html-plugin')

const isProduction = (process.env.NODE_ENV === 'production')
const isDevelopment = (process.env.NODE_ENV === 'development')
const isTest = (process.env.NODE_ENV === 'test')

const outputFolder = 'build/'
const urlLoaderLimit = 10000
const publicPath = '/'
if (isDevelopment) {
	// We use "homepage" field to infer "public path" at which the app is served.
	// Webpack needs to know it to put the right

						${context.css && `<link rel="stylesheet" href="${publicPath}${context.css}">`}

					`,
				}
			},
			isDev: isDevelopment,
		}),

		// Ignore the "full" schema in js-yaml's module, because it brings in esprima
		// to support the !!js/function type. We don't use and have no need for it, so
		// tell webpack to ignore it.
		new NormalModuleReplacementPlugin(/schema\/default_full$/, result => {
			result.request = result.request.replace('default_full', 'default_safe')
		}),

		// DefinePlugin makes some variables available to the code.
		new DefinePlugin({
			VERSION: JSON.stringify(pkg.version),
			DEVELOPMENT: isDevelopment,
			PRODUCTION: isProduction,
			TESTING: isTest,
			// APP_BASE is used in react-router, to set its base appropriately
			// across both local dev and gh-pages.
			APP_BASE: JSON.stringify(publicPath),
			'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
		}),

		// Extract the common libraries into a single file so that the chunks
		// don't need to individually bundle them.
		new CommonsChunkPlugin({
			names: ['react', 'common'],
			filename: '[name].[hash].js',
		}),
	],

	module: {
		loaders: [
			{
				test: /\.js$/,
				// allow babel to run on lodash-es
				exclude: /node_modules/,
				loaders: ['babel-loader?cacheDirectory'],
			},
			{
				test: /\.worker.js$/,
				// allow babel to run on lodash-es
				exclude: /node_modules/,
				loaders: ['worker-loader', 'babel-loader?cacheDirectory'],
			},
			{
				test: /\.json$/,
				loaders: ['json-loader'],
			},
			{
				test: /\.(otf|eot|ttf|woff2?)$/,
				loader: 'url-loader',
				query: {limit: urlLoaderLimit},
			},
			{
				test: /\.(jpe?g|png|gif)$/,
				loader: 'url-loader',
				query: {limit: urlLoaderLimit},
			},
		],
	},

	worker: {
		output: {
			filename: '[hash].worker.js',
			chunkFilename: '[id].[hash].worker.js',
		},
	},
}

// dev specific stuff
if (isDevelopment) {
	// debugging option
	config.devtool = 'eval'

	// add dev server and hotloading clientside code
	// config.entry.unshift(
	// 	'react-hot-loader/patch',
	// 	`webpack-dev-server/client?http://${config.hostname}:${config.port}`,
	// 	'webpack/hot/only-dev-server'
	// )

	config.devServer.port = config.port
	config.devServer.host = config.hostname

	// add dev plugins
	// config.plugins.push(new HotModuleReplacementPlugin())

	// Add style loaders
	let extractor = new ExtractTextPlugin(config.output.cssFilename, {allChunks: true})
	config.plugins = config.plugins.concat([extractor])
	config.module.loaders.push({test: /\.css$/, loader: extractor.extract('style', ['css'])})
	config.module.loaders.push({test: /\.scss$/, loader: extractor.extract('style', ['css!sass'])})

	let identName = '[path][name]·[local]·[hash:base64:5]'
	config.module.loaders.push({test: /\.module.css$/, loader: extractor.extract('style', [`css?modules&localIdentName=${identName}`])})
	config.module.loaders.push({test: /\.module.scss$/, loader: extractor.extract('style', [`css?modules&localIdentName=${identName}!sass`])})
}

else if (isTest) {
	config.module.loaders.push({test: /\.css$/, loader: 'style!css'})
	config.module.loaders.push({test: /\.module.css$/, loader: 'style!css?modules'})
	config.module.loaders.push({test: /\.scss$/, loader: 'style!css!sass'})
	config.module.loaders.push({test: /\.module.scss$/, loader: 'style!css?modules!sass'})
}

// production
else if (isProduction) {
	config.devtool = 'source-map'
	config.stats.children = false

	// minify in production
	let extractor = new ExtractTextPlugin(config.output.cssFilename, {allChunks: true})
	config.plugins = config.plugins.concat([
		new DedupePlugin(),
		new OccurenceOrderPlugin(true),
		new UglifyJsPlugin({
			compress: {
				warnings: false,
				pure_getters: true, // eslint-disable-line camelcase
				screw_ie8: true, // eslint-disable-line camelcase
				unsafe: true,
			},
			mangle: {
				screw_ie8: true, // eslint-disable-line camelcase
			},
			output: {
				comments: false,
				screw_ie8: true, // eslint-disable-line camelcase
			},
		}),
		extractor,
	])

	config.module.loaders.push({
		test: /\.css$/,
		loader: extractor.extract('style', ['css']),
	})
	config.module.loaders.push({
		test: /\.scss$/,
		loader: extractor.extract('style', ['css', 'sass']),
	})

	config.module.loaders.push({
		test: /\.module.css$/,
		loader: extractor.extract('style', ['css?modules']),
	})
	config.module.loaders.push({
		test: /\.module.scss$/,
		loader: extractor.extract('style', ['css?modules', 'sass']),
	})
}

else {
	throw new Error('Unknown environment! Not development, production, nor test!')
}

module.exports = config
<|endoftext|>