<commit_before>// A javascript library for constructing toy wooden train track designs in SVG
// a track object consists of multiple track sections
// a track section is a continuous section of track elements
// there are different types of track element: (S)traight, (R)ight, (L)eft
// works with d3 v2 (see www.d3js.org)
// TODO: calculate the dimensions of a track / section
// TODO: allow all element lengths to be scaled in all dimensions!

// constants
var gridSize=100;
var trackWidth=20;
var sin45 = Math.sqrt(2)/2; // sin(45deg)

// derived values
function outsideRadius() {
  return gridSize+trackWidth/2;
}

function insideRadius() {
  return gridSize-trackWidth/2;
}

function curvePath(side, direction, radius, angle) {
  return " a " + radius + ", " + radius + " 0 " + ((side==1) ? "0,1 " : "0,0 ") + direction*(Math.sin(angle)*radius) + ", " + (side*(1-Math.cos(angle))*radius)
}

// objects

function Track(sections) {
  this.sections = sections;
}

Track.prototype.draw = function(svg) {
  // draw new track
  for (i=0; i<this.sections.length;i++) {
    this.sections[i].draw(svg);
  }
}

function Section() {
  this.pieces=new Array();
}

// TODO: get rid of hard code translation - calculate dimensions or provide attributes
Section.prototype.draw = function(svg) {
  if (this.pieces.length>0) {
    var element = svg.append("g")
          .attr("transform","translate(300,200)")
          .attr("fill","lightgrey")
          .attr("stroke", "white")
          .attr("stroke-width",2);
    for(i=0;i<this.pieces.length;i++){
      element=this.pieces[i].draw(element);
    }
  }
}

// track pieces

function Straight(size) {
  this.size = size; // multiple of gridsize, e.g. 2, 1, 2/3, 1/2, 1/3
}

Straight.prototype.draw = function(svg) {
  svg.append("path").attr("d", "M 0 0 v -" + trackWidth/2 +
    " h " + this.size*gridSize +
    " v " + trackWidth +
    " h -" + this.size*gridSize + " z ");
  svg.append("path").attr("d", "M 0 -" + trackWidth/4 +
    " h " + this.size*gridSize +
    " m 0," + trackWidth/2 +
    " h -" + this.size*gridSize);
  return svg.append("g").attr("transform", "translate(" + this.size*gridSize + ",0)");
}

function Bend(flip) {
  this.flip = flip; // 1 : "R", -1 : "L"
}

Bend.prototype.draw = function(svg) {
  svg.append("path").attr("d", "M 0 0 v " + (-1*this.flip*trackWidth/2) +
    curvePath(this.flip, 1, gridSize+trackWidth/2, Math.PI/4) +
    " l -" + (sin45*trackWidth) + " " + (this.flip*sin45*trackWidth) +
    curvePath(-1*this.flip, -1, gridSize-trackWidth/2, Math.PI/4) +
    " z");
  svg.append("path").attr("d", "M 0 "+ (-1*this.flip*trackWidth/4) +
    curvePath(this.flip, 1, gridSize+trackWidth/4, Math.PI/4) +
    " l -" + (sin45*trackWidth/2) + " " + (this.flip*sin45*trackWidth/2) +
    curvePath(this.flip*-1, -1, gridSize-trackWidth/4, Math.PI/4));
  return svg.append("g").attr("transform", "translate(" + (sin45*gridSize) +"," + (this.flip*(1-sin45)*gridSize) +")").append("g").attr("transform","rotate(" + this.flip*45 + ")");
}

function Junction(flip, exit) {
  this.flip = flip; // 1 : "R", -1: "L"
  this.exit = exit; // "B" | "C"
}

Junction.prototype.draw = function(svg) {
  svg.append("path").attr("d", "M 0 0 v " + (-1*this.flip*trackWidth/2) +
    " h " + (2/3)*gridSize +
    " v " + (this.flip*trackWidth) +
    " h -" + ((2/3)*gridSize-(Math.sqrt(2*trackWidth*gridSize))) +
    " a " + outsideRadius() + ", " + outsideRadius() + " 0 " + ((this.flip==1) ? "0,1 " : "0,0 ") + ((sin45*outsideRadius())-(Math.sqrt(2*gridSize*trackWidth))) + ", " + (this.flip*(insideRadius()-(sin45*outsideRadius()))) +
    " l -" + (sin45*trackWidth) + " " + (this.flip*sin45*trackWidth) +
    curvePath(-1*this.flip, -1, gridSize-trackWidth/2, Math.PI/4) +
    " z");
  svg.append("path").attr("d", "M 0 -"+trackWidth/4+" h " + 2*gridSize/3 + " m 0," + trackWidth/2 + " h -" + 2*gridSize/3);
  svg.append("path").attr("d", "M 0 "+(-1*this.flip*trackWidth/4)+
    curvePath(this.flip, 1, gridSize+trackWidth/4, Math.PI/4) +
    " l -" + (sin45*trackWidth/2) + " " + (this.flip*sin45*trackWidth/2) +
    curvePath(this.flip*-1, -1, gridSize-trackWidth/4, Math.PI/4)).attr("fill", "none");
  if (this.exit=="C") {
    return svg.append("g").attr("transform", "translate(" + (sin45*gridSize) +"," + (this.flip*(1-sin45)*gridSize) +")").append("g").attr("transform","rotate(" + this.flip*45 + ")");
  } else { // default exit is "B"
    return svg.append("g").attr("transform", "translate(" + (2/3)*gridSize + ",0)");
  }
}

function Crossover(flip, exit) {
  this.flip = flip; // 1 : "R", -1: "L"
  this.exit = exit; // "B" | "C"
}

Crossover.prototype.draw = function(svg) {
  var truncatedWidth = ((gridSize/(Math.cos(Math.PI/8)))-gridSize+(trackWidth/2));
  svg.append("path").attr("d", "M 0 0 v " + this.flip*trackWidth/2 +
    curvePath(this.flip, 1, gridSize-(trackWidth/2), Math.PI/4) +
    " l " + (sin45*truncatedWidth) + " " + (-1*this.flip*sin45*truncatedWidth) +
    " v " + -1*this.flip*truncatedWidth +
    " a " + (gridSize-(trackWidth/2)) + ", " + (gridSize-(trackWidth/2)) + " 0, " + (this.flip==1?"0 1 ":"0 0 ") + (-1*sin45*(gridSize-(trackWidth/2))) + ", " + (-1*this.flip*(1-sin45)*(gridSize-(trackWidth/2))) +
    " l -" + (sin45*truncatedWidth) + " " + (this.flip*sin45*truncatedWidth) +
    " z");
  svg.append("path").attr("d", "M 0 " + this.flip*trackWidth/4 +
    curvePath(this.flip, 1, gridSize-(trackWidth/4), Math.PI/4) +
    " l " + (sin45*trackWidth/2) + " " + (-1*this.flip*sin45*trackWidth/2) +
    curvePath(-1*this.flip, -1, gridSize+(trackWidth/4), Math.PI/4));
  svg.append("path").attr("d", "M " + sin45*(truncatedWidth-3*trackWidth/4) + " " + -1*this.flip*((truncatedWidth-trackWidth/2)+(sin45*(truncatedWidth-3*trackWidth/4))) +
    " a " + (gridSize+(trackWidth/4)) + ", " + (gridSize+(trackWidth/4)) + " 0, " + (this.flip==1?"0 0 ":"0 1 ") + (sin45*(gridSize+(trackWidth/4))) + ", " + (this.flip*(1-sin45)*(gridSize+(trackWidth/4))) +
    " v " + -1*this.flip*trackWidth/2 +
    " a " + (gridSize-(trackWidth/4)) + ", " + (gridSize-(trackWidth/4)) + " 0, " + (this.flip==1?"0 1 ":"0 0") + (-1*sin45*(gridSize-(trackWidth/4))) + ", " + (-1*this.flip*(1-sin45)*(gridSize-(trackWidth/4)))).attr("fill", "none");
  if (this.exit=="C") {
    return svg.append("g").attr("transform", "translate(" + 2*gridSize*Math.sin(Math.PI/8) + "," + this.flip * 2 *((gridSize/Math.cos(Math.PI/8))-gridSize)+ ")");
  } else { // default exit is "B"
    return svg.append("g").attr("transform", "translate(" + (sin45*gridSize) +"," + (this.flip*(1-sin45)*gridSize) +")").append("g").attr("transform","rotate(" + this.flip*45 + ")");
  }
}
<commit_msg>tidied up the code, fixed some problems with rough edges on the pieces<commit_after>// A javascript library for constructing toy wooden train track designs in SVG
// a track object consists of multiple track sections
// a track section is a continuous section of track elements
// there are different types of track element: (S)traight, (R)ight, (L)eft
// works with d3 v2 (see www.d3js.org)
// TODO: calculate the dimensions of a track / section
// TODO: allow all element lengths to be scaled in all dimensions!

// constants
var gridSize=100;
var trackWidth=20;
var sin45 = Math.sqrt(2)/2; // sin(45deg)

// derived values
function outsideRadius() {
  return gridSize+trackWidth/2;
}

function insideRadius() {
  return gridSize-trackWidth/2;
}

/*
starting position facing along x axis...
side = {1,-1} - 1: bend right, -1: bend left
direction = {1, -1} - 1: forwards, -1: backwards
orbit = {1,0} - 1: clockwise, 0: anti-clockwise
radius = radius of curve (pixels)
angle = angle of curve (radians)
*/
function curvePath(side, direction, orbit, radius, angle) {
  return " a " + radius + ", " + radius + " 0 0, " + orbit + " " + direction*(Math.sin(angle)*radius) + ", " + (side*(1-Math.cos(angle))*radius)
}

// objects

function Track(sections) {
  this.sections = sections;
}

Track.prototype.draw = function(svg) {
  // draw new track
  for (i=0; i<this.sections.length;i++) {
    this.sections[i].draw(svg);
  }
}

function Section() {
  this.pieces=new Array();
}

// TODO: get rid of hard code translation - calculate dimensions or provide attributes
Section.prototype.draw = function(svg) {
  if (this.pieces.length>0) {
    var element = svg.append("g")
          .attr("transform","translate(300,200)")
          .attr("fill","lightgrey")
          .attr("stroke", "white")
          .attr("stroke-width",2);
    for(i=0;i<this.pieces.length;i++){
      element=this.pieces[i].draw(element);
    }
  }
}

// track pieces

function Straight(size) {
  this.size = size; // multiple of gridsize, e.g. 2, 1, 2/3, 1/2, 1/3
}

Straight.prototype.draw = function(svg) {
  // draw track
  svg.append("path").attr("d", "M 0 0 v -" + trackWidth/2 +
    " h " + this.size*gridSize +
    " v " + trackWidth +
    " h -" + this.size*gridSize + " z ");
  // draw rails
  svg.append("path").attr("d", "M 0 -" + trackWidth/4 +
    " h " + this.size*gridSize +
    " m 0," + trackWidth/2 +
    " h -" + this.size*gridSize);
  return svg.append("g").attr("transform", "translate(" + this.size*gridSize + ",0)");
}

function Bend(flip) {
  this.flip = flip; // 1 : "R", -1 : "L"
}

Bend.prototype.draw = function(svg) {
  // draw track
  svg.append("path").attr("d", "M 0 0 v " + (-1*this.flip*trackWidth/2) +
    curvePath(this.flip, 1, (this.flip==1?1:0), gridSize+trackWidth/2, Math.PI/4) +
    " l -" + (sin45*trackWidth) + " " + (this.flip*sin45*trackWidth) +
    curvePath(-1*this.flip, -1, (this.flip==1?0:1), gridSize-trackWidth/2, Math.PI/4) +
    " z");
  // draw rails
  svg.append("path").attr("d", "M 0 "+ (-1*this.flip*trackWidth/4) +
    curvePath(this.flip, 1, (this.flip==1?1:0), gridSize+trackWidth/4, Math.PI/4) +
    " l -" + (sin45*trackWidth/2) + " " + (this.flip*sin45*trackWidth/2) +
    curvePath(this.flip*-1, -1, (this.flip==1?0:1), gridSize-trackWidth/4, Math.PI/4));
  return svg.append("g").attr("transform", "translate(" + (sin45*gridSize) +"," + (this.flip*(1-sin45)*gridSize) +")").append("g").attr("transform","rotate(" + this.flip*45 + ")");
}

function Junction(flip, exit) {
  this.flip = flip; // 1 : "R", -1: "L"
  this.exit = exit; // "B" | "C"
}

Junction.prototype.draw = function(svg) {
  // draw track
  svg.append("path").attr("d", "M 0 0 v " + (-1*this.flip*trackWidth/2) +
    " h " + (2/3)*gridSize +
    " v " + (this.flip*trackWidth) +
    " h -" + ((2/3)*gridSize-(Math.sqrt(2*trackWidth*gridSize))) +
    " a " + outsideRadius() + ", " + outsideRadius() + " 0 " + ((this.flip==1) ? "0,1 " : "0,0 ") + ((sin45*outsideRadius())-(Math.sqrt(2*gridSize*trackWidth))) + ", " + (this.flip*(insideRadius()-(sin45*outsideRadius()))) +
    " l -" + (sin45*trackWidth) + " " + (this.flip*sin45*trackWidth) +
    curvePath(-1*this.flip, -1, (this.flip==1?0:1), gridSize-trackWidth/2, Math.PI/4) +
    " z");
  // draw rails
  svg.append("path").attr("d", "M 0 -"+trackWidth/4+" h " + 2*gridSize/3 + " m 0," + trackWidth/2 + " h -" + 2*gridSize/3);
  svg.append("path").attr("d", "M 0 "+(-1*this.flip*trackWidth/4)+
    curvePath(this.flip, 1, (this.flip==1?1:0), gridSize+trackWidth/4, Math.PI/4) +
    " l -" + (sin45*trackWidth/2) + " " + (this.flip*sin45*trackWidth/2) +
    curvePath(this.flip*-1, -1, (this.flip==1?0:1), gridSize-trackWidth/4, Math.PI/4)).attr("fill", "none");
  if (this.exit=="C") {
    return svg.append("g").attr("transform", "translate(" + (sin45*gridSize) +"," + (this.flip*(1-sin45)*gridSize) +")").append("g").attr("transform","rotate(" + this.flip*45 + ")");
  } else { // default exit is "B"
    return svg.append("g").attr("transform", "translate(" + (2/3)*gridSize + ",0)");
  }
}

function Crossover(flip, exit) {
  this.flip = flip; // 1 : "R", -1: "L"
  this.exit = exit; // "B" | "C"
}

Crossover.prototype.draw = function(svg) {
  // draw track
  var truncatedWidth = ((gridSize/(Math.cos(Math.PI/8)))-gridSize+(trackWidth/2));
  svg.append("path").attr("d", "M 0 0 v " + this.flip*trackWidth/2 +
    curvePath(this.flip, 1, (this.flip==1?1:0), gridSize-(trackWidth/2), Math.PI/4) +
    " l " + (sin45*truncatedWidth) + " " + (-1*this.flip*sin45*truncatedWidth) +
    " v " + -1*this.flip*truncatedWidth +
    " a " + (gridSize-(trackWidth/2)) + ", " + (gridSize-(trackWidth/2)) + " 0, " + (this.flip==1?"0 1 ":"0 0 ") + (-1*sin45*(gridSize-(trackWidth/2))) + ", " + (-1*this.flip*(1-sin45)*(gridSize-(trackWidth/2))) +
    " l -" + (sin45*truncatedWidth) + " " + (this.flip*sin45*truncatedWidth) +
    " z");
  // draw rails
  svg.append("path").attr("d", "M 0 " + this.flip*trackWidth/4 +
    curvePath(this.flip, 1, (this.flip==1?1:0), gridSize-(trackWidth/4), Math.PI/4) +
    " l " + (sin45*trackWidth/2) + " " + (-1*this.flip*sin45*trackWidth/2) +
    curvePath(-1*this.flip, -1, (this.flip==1?0:1), gridSize+(trackWidth/4), Math.PI/4) + " z");
  svg.append("path").attr("d", "M " + sin45*(truncatedWidth-3*trackWidth/4) + " " + -1*this.flip*((truncatedWidth-trackWidth/2)+(sin45*(truncatedWidth-3*trackWidth/4))) +
    " a " + (gridSize+(trackWidth/4)) + ", " + (gridSize+(trackWidth/4)) + " 0, " + (this.flip==1?"0 0 ":"0 1 ") + (sin45*(gridSize+(trackWidth/4))) + ", " + (this.flip*(1-sin45)*(gridSize+(trackWidth/4))) +
    " v " + -1*this.flip*trackWidth/2 +
    " a " + (gridSize-(trackWidth/4)) + ", " + (gridSize-(trackWidth/4)) + " 0, " + (this.flip==1?"0 1 ":"0 0") + (-1*sin45*(gridSize-(trackWidth/4))) + ", " + (-1*this.flip*(1-sin45)*(gridSize-(trackWidth/4))) + " z").attr("fill", "none");
  if (this.exit=="C") {
    var x = gridSize*Math.sin(Math.PI/8);
    var y = gridSize*Math.cos(Math.PI/8);
    return svg.append("g").attr("transform", "translate(" + 2*x + "," + this.flip*2*(gridSize-y) + ")");
  } else { // default exit is "B"
    return svg.append("g").attr("transform", "translate(" + (sin45*gridSize) +"," + (this.flip*(1-sin45)*gridSize) +")").append("g").attr("transform","rotate(" + this.flip*45 + ")");
  }
}
<|endoftext|>


<commit_before>'use strict';

exports.list = function list(phrase1, phrase2, options) {

  options = options || {};

  options.ignoreCase = options.ignoreCase || false;
  options.minWordLength = options.minWordLength || 0;
  options.ignoreCommonWords = options.ignoreCommonWords || false;

  if (options.ignoreCase) {
    phrase1 = phrase1.toLowerCase();
    phrase2 = phrase2.toLowerCase();
  }

  var compare1 = tokenize(sanitize(phrase1)),
    compare2 = tokenize(sanitize(phrase2)),
    answer = [];

  if (options.ignoreCommonWords) {
    compare1 = removeCommonWords(compare1);
    compare2 = removeCommonWords(compare2);
  }

  compare1.forEach(function(element) {
    if (compare2.indexOf(element) > -1) {
      answer.push(element);
    }
  });

  answer = answer.filter(onlyUnique);

  if (options.minWordLength) {
    answer = answer.filter(getWordsWithMinLen.bind(this, options.minWordLength));
  }

  return answer;

}

function sanitize(word) {
  var punctuationRegex = /[\.,\/\?#!$%\^&\*;:{}=_`~()]/g;
  return word.replace(punctuationRegex, '');
}

function tokenize(word) {
  return word.split(' ');
}

function onlyUnique(value, index, self) {
  return self.indexOf(value) === index;
}

function removeCommonWords(words) {
  var commonWords = [
    'a', 'an', 'the', 'this', 'that', 'there', 'it',
    'in', 'on', 'for', 'not', 'your', 'you', 'at',
    'to', 'is', 'us', 'out', 'by', 'I' ];
  // a, an, the, this, that, there, it
  // on, for, not, your, you, at, to, is, us, out, by, I

  return words.filter(function(element) {
    return commonWords.indexOf(element) < 0;
  });
}

function getWordsWithMinLen(minLen, word) {
  return word.length >= minLen;
}

if (process.env.NODE_ENV === 'test') {
  exports.sanitize = sanitize;
  exports.tokenize = tokenize;
  exports.getWordsWithMinLen = getWordsWithMinLen;
}
<commit_msg>refactor: add comments to regex - #5<commit_after>'use strict';

exports.list = function list(phrase1, phrase2, options) {

  options = options || {};

  options.ignoreCase = options.ignoreCase || false;
  options.minWordLength = options.minWordLength || 0;
  options.ignoreCommonWords = options.ignoreCommonWords || false;

  if (options.ignoreCase) {
    phrase1 = phrase1.toLowerCase();
    phrase2 = phrase2.toLowerCase();
  }

  var compare1 = tokenize(sanitize(phrase1)),
    compare2 = tokenize(sanitize(phrase2)),
    answer = [];

  if (options.ignoreCommonWords) {
    compare1 = removeCommonWords(compare1);
    compare2 = removeCommonWords(compare2);
  }

  compare1.forEach(function(element) {
    if (compare2.indexOf(element) > -1) {
      answer.push(element);
    }
  });

  answer = answer.filter(onlyUnique);

  if (options.minWordLength) {
    answer = answer.filter(getWordsWithMinLen.bind(this, options.minWordLength));
  }

  return answer;

}

function sanitize(word) {
  // matches common punctuations:
  // . , / ? # ! $ % ^ & * ; : { } = _ ` ~ ( )
  // does not match hyphen: -
  var punctuationRegex = /[\.,\/\?#!$%\^&\*;:{}=_`~()]/g;
  return word.replace(punctuationRegex, '');
}

function tokenize(word) {
  return word.split(' ');
}

function onlyUnique(value, index, self) {
  return self.indexOf(value) === index;
}

function removeCommonWords(words) {
  var commonWords = [
    'a', 'an', 'the', 'this', 'that', 'there', 'it',
    'in', 'on', 'for', 'not', 'your', 'you', 'at',
    'to', 'is', 'us', 'out', 'by', 'I' ];
  // a, an, the, this, that, there, it
  // on, for, not, your, you, at, to, is, us, out, by, I

  return words.filter(function(element) {
    return commonWords.indexOf(element) < 0;
  });
}

function getWordsWithMinLen(minLen, word) {
  return word.length >= minLen;
}

if (process.env.NODE_ENV === 'test') {
  exports.sanitize = sanitize;
  exports.tokenize = tokenize;
  exports.getWordsWithMinLen = getWordsWithMinLen;
}
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var os = require('os');
var cluster = require('cluster');

var async = require('async');
var PoolLogger = require('./libs/logUtil.js');
var CliListener = require('./libs/cliListener.js');
var RedisBlocknotifyListener = require('./libs/redisblocknotifyListener.js');
var PoolWorker = require('./libs/poolWorker.js');
var PaymentProcessor = require('./libs/paymentProcessor.js');
var Website = require('./libs/website.js');
var ProfitSwitch = require('./libs/profitSwitch.js');

var algos = require('stratum-pool/lib/algoProperties.js');

JSON.minify = JSON.minify || require("node-json-minify");

if (!fs.existsSync('config.json')){
    console.log('config.json file does not exist. Read the installation/setup instructions.');
    return;
}

var portalConfig = JSON.parse(JSON.minify(fs.readFileSync("config.json", {encoding: 'utf8'})));
var poolConfigs;

var logger = new PoolLogger({
    logLevel: portalConfig.logLevel
});

try {
    require('newrelic');
    if (cluster.isMaster)
        logger.debug('NewRelic', 'Monitor', 'New Relic initiated');
} catch(e) {}

//Try to give process ability to handle 100k concurrent connections
try{
    var posix = require('posix');
    try {
        posix.setrlimit('nofile', { soft: 100000, hard: 100000 });
    }
    catch(e){
        if (cluster.isMaster)
            logger.warning('POSIX', 'Connection Limit', '(Safe to ignore) Must be ran as root to increase resource limits');
    }
}
catch(e){
    if (cluster.isMaster)
        logger.debug('POSIX', 'Connection Limit', '(Safe to ignore) POSIX module not installed and resource (connection) limit was not raised');
}

if (cluster.isWorker){

    switch(process.env.workerType){
        case 'pool':
            new PoolWorker(logger);
            break;
        case 'paymentProcessor':
            new PaymentProcessor(logger);
            break;
        case 'website':
            new Website(logger);
            break;
        case 'profitSwitch':
            new ProfitSwitch(logger);
            break;
    }

    return;
}

//Read all pool configs from pool_configs and join them with their coin profile
var buildPoolConfigs = function(){
    var configs = {};
    var configDir = 'pool_configs/';

    var poolConfigFiles = [];

    /* Get filenames of pool config json files that are enabled */
    fs.readdirSync(configDir).forEach(function(file){
        if (!fs.existsSync(configDir + file) || path.extname(configDir + file) !== '.json') return;
        var poolOptions = JSON.parse(JSON.minify(fs.readFileSync(configDir + file, {encoding: 'utf8'})));
        if (!poolOptions.enabled) return;
        poolOptions.fileName = file;
        poolConfigFiles.push(poolOptions);
    });

    /* Ensure no pool uses any of the same ports as another pool */
    for (var i = 0; i < poolConfigFiles.length; i++){
        var ports = Object.keys(poolConfigFiles[i].ports);
        for (var f = 0; f < poolConfigFiles.length; f++){
            if (f === i) continue;
            var portsF = Object.keys(poolConfigFiles[f].ports);
            for (var g = 0; g < portsF.length; g++){
                if (ports.indexOf(portsF[g]) !== -1){
                    logger.error('Master', poolConfigFiles[f].fileName, 'Has same configured port of ' + portsF[g] + ' as ' + poolConfigFiles[i].fileName);
                    process.exit(1);
                    return;
                }
            }

            if (poolConfigFiles[f].coin === poolConfigFiles[i].coin){
                logger.error('Master', poolConfigFiles[f].fileName, 'Pool has same configured coin file coins/' + poolConfigFiles[f].coin + ' as ' + poolConfigFiles[i].fileName + ' pool');
                process.exit(1);
                return;
            }

        }
    }

    poolConfigFiles.forEach(function(poolOptions){

        poolOptions.coinFileName = poolOptions.coin;

        var coinFilePath = 'coins/' + poolOptions.coinFileName;
        if (!fs.existsSync(coinFilePath)){
            logger.error('Master', poolOptions.coinFileName, 'could not find file: ' + coinFilePath);
            return;
        }

        var coinProfile = JSON.parse(JSON.minify(fs.readFileSync(coinFilePath, {encoding: 'utf8'})));
        poolOptions.coin = coinProfile;

        if (poolOptions.coin.name in configs){

            logger.error('Master', poolOptions.fileName, 'coins/' + poolOptions.coinFileName
                + ' has same configured coin name ' + poolOptions.coin.name + ' as coins/'
                + configs[poolOptions.coin.name].coinFileName + ' used by pool config '
                + configs[poolOptions.coin.name].fileName);

            process.exit(1);
            return;
        }

        configs[poolOptions.coin.name] = poolOptions;

        if (!(coinProfile.algorithm in algos)){
            logger.error('Master', coinProfile.name, 'Cannot run a pool for unsupported algorithm "' + coinProfile.algorithm + '"');
            delete configs[poolOptions.coin.name];
        }

    });
    return configs;
};

var spawnPoolWorkers = function(){

    Object.keys(poolConfigs).forEach(function(coin){
        var p = poolConfigs[coin];

        if (!Array.isArray(p.daemons) || p.daemons.length < 1){
            logger.error('Master', coin, 'No daemons configured so a pool cannot be started for this coin.');
            delete poolConfigs[coin];
        }
    });

    if (Object.keys(poolConfigs).length === 0){
        logger.warning('Master', 'PoolSpawner', 'No pool configs exists or are enabled in pool_configs folder. No pools spawned.');
        return;
    }

    var serializedConfigs = JSON.stringify(poolConfigs);

    var numForks = (function(){
        if (!portalConfig.clustering || !portalConfig.clustering.enabled)
            return 1;
        if (portalConfig.clustering.forks === 'auto')
            return os.cpus().length;
        if (!portalConfig.clustering.forks || isNaN(portalConfig.clustering.forks))
            return 1;
        return portalConfig.clustering.forks;
    })();

    var poolWorkers = {};

    var createPoolWorker = function(forkId){
        var worker = cluster.fork({
            workerType: 'pool',
            forkId: forkId,
            pools: serializedConfigs,
            portalConfig: JSON.stringify(portalConfig)
        });
        worker.forkId = forkId;
        worker.type = 'pool';
        poolWorkers[forkId] = worker;
        worker.on('exit', function(code, signal){
            logger.error('Master', 'PoolSpanwer', 'Fork ' + forkId + ' died, spawning replacement worker...');
            setTimeout(function(){
                createPoolWorker(forkId);
            }, 2000);
        }).on('message', function(msg){
            switch(msg.type){
                case 'banIP':
                    Object.keys(cluster.workers).forEach(function(id) {
                        if (cluster.workers[id].type === 'pool'){
                            cluster.workers[id].send({type: 'banIP', ip: msg.ip});
                        }
                    });
                    break;
            }
        });
    };

    var i = 0;
    var spawnInterval = setInterval(function(){
        createPoolWorker(i);
        i++;
        if (i === numForks){
            clearInterval(spawnInterval);
            logger.debug('Master', 'PoolSpawner', 'Spawned ' + Object.keys(poolConfigs).length + ' pool(s) on ' + numForks + ' thread(s)');
        }
    }, 250);

};

var startCliListener = function(){

    var cliPort = portalConfig.cliPort;

    var listener = new CliListener(cliPort);
    listener.on('log', function(text){
        logger.debug('Master', 'CLI', text);
    }).on('command', function(command, params, options, reply){

        switch(command){
            case 'blocknotify':
                Object.keys(cluster.workers).forEach(function(id) {
                    cluster.workers[id].send({type: 'blocknotify', coin: params[0], hash: params[1]});
                });
                reply('Pool workers notified');
                break;
            case 'coinswitch':
                processCoinSwitchCommand(params, options, reply);
                break;
            case 'reloadpool':
                Object.keys(cluster.workers).forEach(function(id) {
                    cluster.workers[id].send({type: 'reloadpool', coin: params[0] });
                });
                reply('reloaded pool ' + params[0]);
                break;
            default:
                reply('unrecognized command "' + command + '"');
                break;
        }
    }).start();
};

var processCoinSwitchCommand = function(params, options, reply){

    var logSystem = 'CLI';
    var logComponent = 'coinswitch';

    var replyError = function(msg){
        reply(msg);
        logger.error(logSystem, logComponent, msg);
    };

    if (!params[0]) {
        replyError('Coin name required');
        return;
    }

    if (!params[1] && !options.algorithm){
        replyError('If switch key is not provided then algorithm options must be specified');
        return;
    }
    else if (params[1] && !portalConfig.switching[params[1]]){
        replyError('Switch key not recognized: ' + params[1]);
        return;
    }
    else if (options.algorithm && !Object.keys(portalConfig.switching).filter(function(s){
        return portalConfig.switching[s].algorithm === options.algorithm;
    })[0]){
        replyError('No switching options contain the algorithm ' + options.algorithm);
        return;
    }

    var messageCoin = params[0].toLowerCase();
    var newCoin = Object.keys(poolConfigs).filter(function(p){
        return p.toLowerCase() === messageCoin;
    })[0];

    if (!newCoin){
        replyError('Switch message to coin that is not recognized: ' + messageCoin);
        return;
    }

    var switchNames = [];

    if (params[1]) {
        switchNames.push(params[1]);
    }
    else{
        for (var name in portalConfig.switching){
            if (portalConfig.switching[name].enabled && portalConfig.switching[name].algorithm === options.algorithm)
                switchNames.push(name);
        }
    }

    switchNames.forEach(function(name){
        if (poolConfigs[newCoin].coin.algorithm !== portalConfig.switching[name].algorithm){
            replyError('Cannot switch a '
                + portalConfig.switching[name].algorithm
                + ' algo pool to coin ' + newCoin + ' with ' + poolConfigs[newCoin].coin.algorithm + ' algo');
            return;
        }

        Object.keys(cluster.workers).forEach(function (id) {
            cluster.workers[id].send({type: 'coinswitch', coin: newCoin, switchName: name });
        });
    });

    reply('Switch message sent to pool workers');

};

var startRedisBlockListener = function(){
    //block notify options
    //setup block notify here and use IPC to tell appropriate pools

    if (!portalConfig.redisBlockNotifyListener.enabled) return;

    var listener = new RedisBlocknotifyListener(portalConfig.redisBlockNotifyListener);
    listener.on('log', function(text){
        logger.debug('Master', 'blocknotify', text);
    }).on('hash', function (message) {
        var ipcMessage = {type:'blocknotify', coin: message.coin, hash: message.hash};
        Object.keys(cluster.workers).forEach(function(id) {
            cluster.workers[id].send(ipcMessage);
        });
    });
    listener.start();
};

var startPaymentProcessor = function(){

    var enabledForAny = false;
    for (var pool in poolConfigs){
        var p = poolConfigs[pool];
        var enabled = p.enabled && p.paymentProcessing && p.paymentProcessing.enabled;
        if (enabled){
            enabledForAny = true;
            break;
        }
    }

    if (!enabledForAny)
        return;

    var worker = cluster.fork({
        workerType: 'paymentProcessor',
        pools: JSON.stringify(poolConfigs)
    });
    worker.on('exit', function(code, signal){
        logger.error('Master', 'Payment Processor', 'Payment processor died, spawning replacement...');
        setTimeout(function(){
            startPaymentProcessor(poolConfigs);
        }, 2000);
    });
};

var startWebsite = function(){

    if (!portalConfig.website.enabled) return;

    var worker = cluster.fork({
        workerType: 'website',
        pools: JSON.stringify(poolConfigs),
        portalConfig: JSON.stringify(portalConfig)
    });
    worker.on('exit', function(code, signal){
        logger.error('Master', 'Website', 'Website process died, spawning replacement...');
        setTimeout(function(){
            startWebsite(portalConfig, poolConfigs);
        }, 2000);
    });
};

var startProfitSwitch = function(){

    if (!portalConfig.profitSwitch || !portalConfig.profitSwitch.enabled){
        //logger.error('Master', 'Profit', 'Profit auto switching disabled');
        return;
    }

    var worker = cluster.fork({
        workerType: 'profitSwitch',
        pools: JSON.stringify(poolConfigs),
        portalConfig: JSON.stringify(portalConfig)
    });
    worker.on('exit', function(code, signal){
        logger.error('Master', 'Profit', 'Profit switching process died, spawning replacement...');
        setTimeout(function(){
            startWebsite(portalConfig, poolConfigs);
        }, 2000);
    });
};

(function init(){

    poolConfigs = buildPoolConfigs();

    spawnPoolWorkers();

    startPaymentProcessor();

    startRedisBlockListener();

    startWebsite();

    startProfitSwitch();

    startCliListener();

})();
<commit_msg>Coin names are now converted to lowercase.<commit_after>var fs = require('fs');
var path = require('path');
var os = require('os');
var cluster = require('cluster');

var async = require('async');
var PoolLogger = require('./libs/logUtil.js');
var CliListener = require('./libs/cliListener.js');
var RedisBlocknotifyListener = require('./libs/redisblocknotifyListener.js');
var PoolWorker = require('./libs/poolWorker.js');
var PaymentProcessor = require('./libs/paymentProcessor.js');
var Website = require('./libs/website.js');
var ProfitSwitch = require('./libs/profitSwitch.js');

var algos = require('stratum-pool/lib/algoProperties.js');

JSON.minify = JSON.minify || require("node-json-minify");

if (!fs.existsSync('config.json')){
    console.log('config.json file does not exist. Read the installation/setup instructions.');
    return;
}

var portalConfig = JSON.parse(JSON.minify(fs.readFileSync("config.json", {encoding: 'utf8'})));
var poolConfigs;

var logger = new PoolLogger({
    logLevel: portalConfig.logLevel
});

try {
    require('newrelic');
    if (cluster.isMaster)
        logger.debug('NewRelic', 'Monitor', 'New Relic initiated');
} catch(e) {}

//Try to give process ability to handle 100k concurrent connections
try{
    var posix = require('posix');
    try {
        posix.setrlimit('nofile', { soft: 100000, hard: 100000 });
    }
    catch(e){
        if (cluster.isMaster)
            logger.warning('POSIX', 'Connection Limit', '(Safe to ignore) Must be ran as root to increase resource limits');
    }
}
catch(e){
    if (cluster.isMaster)
        logger.debug('POSIX', 'Connection Limit', '(Safe to ignore) POSIX module not installed and resource (connection) limit was not raised');
}

if (cluster.isWorker){

    switch(process.env.workerType){
        case 'pool':
            new PoolWorker(logger);
            break;
        case 'paymentProcessor':
            new PaymentProcessor(logger);
            break;
        case 'website':
            new Website(logger);
            break;
        case 'profitSwitch':
            new ProfitSwitch(logger);
            break;
    }

    return;
}

//Read all pool configs from pool_configs and join them with their coin profile
var buildPoolConfigs = function(){
    var configs = {};
    var configDir = 'pool_configs/';

    var poolConfigFiles = [];

    /* Get filenames of pool config json files that are enabled */
    fs.readdirSync(configDir).forEach(function(file){
        if (!fs.existsSync(configDir + file) || path.extname(configDir + file) !== '.json') return;
        var poolOptions = JSON.parse(JSON.minify(fs.readFileSync(configDir + file, {encoding: 'utf8'})));
        if (!poolOptions.enabled) return;
        poolOptions.fileName = file;
        poolConfigFiles.push(poolOptions);
    });

    /* Ensure no pool uses any of the same ports as another pool */
    for (var i = 0; i < poolConfigFiles.length; i++){
        var ports = Object.keys(poolConfigFiles[i].ports);
        for (var f = 0; f < poolConfigFiles.length; f++){
            if (f === i) continue;
            var portsF = Object.keys(poolConfigFiles[f].ports);
            for (var g = 0; g < portsF.length; g++){
                if (ports.indexOf(portsF[g]) !== -1){
                    logger.error('Master', poolConfigFiles[f].fileName, 'Has same configured port of ' + portsF[g] + ' as ' + poolConfigFiles[i].fileName);
                    process.exit(1);
                    return;
                }
            }

            if (poolConfigFiles[f].coin === poolConfigFiles[i].coin){
                logger.error('Master', poolConfigFiles[f].fileName, 'Pool has same configured coin file coins/' + poolConfigFiles[f].coin + ' as ' + poolConfigFiles[i].fileName + ' pool');
                process.exit(1);
                return;
            }

        }
    }

    poolConfigFiles.forEach(function(poolOptions){

        poolOptions.coinFileName = poolOptions.coin;

        var coinFilePath = 'coins/' + poolOptions.coinFileName;
        if (!fs.existsSync(coinFilePath)){
            logger.error('Master', poolOptions.coinFileName, 'could not find file: ' + coinFilePath);
            return;
        }

        var coinProfile = JSON.parse(JSON.minify(fs.readFileSync(coinFilePath, {encoding: 'utf8'})));
        poolOptions.coin = coinProfile;
        poolOptions.coin.name = poolOptions.coin.name.toLowerCase();

        if (poolOptions.coin.name in configs){

            logger.error('Master', poolOptions.fileName, 'coins/' + poolOptions.coinFileName
                + ' has same configured coin name ' + poolOptions.coin.name + ' as coins/'
                + configs[poolOptions.coin.name].coinFileName + ' used by pool config '
                + configs[poolOptions.coin.name].fileName);

            process.exit(1);
            return;
        }

        configs[poolOptions.coin.name] = poolOptions;

        if (!(coinProfile.algorithm in algos)){
            logger.error('Master', coinProfile.name, 'Cannot run a pool for unsupported algorithm "' + coinProfile.algorithm + '"');
            delete configs[poolOptions.coin.name];
        }

    });
    return configs;
};

var spawnPoolWorkers = function(){

    Object.keys(poolConfigs).forEach(function(coin){
        var p = poolConfigs[coin];

        if (!Array.isArray(p.daemons) || p.daemons.length < 1){
            logger.error('Master', coin, 'No daemons configured so a pool cannot be started for this coin.');
            delete poolConfigs[coin];
        }
    });

    if (Object.keys(poolConfigs).length === 0){
        logger.warning('Master', 'PoolSpawner', 'No pool configs exists or are enabled in pool_configs folder. No pools spawned.');
        return;
    }

    var serializedConfigs = JSON.stringify(poolConfigs);

    var numForks = (function(){
        if (!portalConfig.clustering || !portalConfig.clustering.enabled)
            return 1;
        if (portalConfig.clustering.forks === 'auto')
            return os.cpus().length;
        if (!portalConfig.clustering.forks || isNaN(portalConfig.clustering.forks))
            return 1;
        return portalConfig.clustering.forks;
    })();

    var poolWorkers = {};

    var createPoolWorker = function(forkId){
        var worker = cluster.fork({
            workerType: 'pool',
            forkId: forkId,
            pools: serializedConfigs,
            portalConfig: JSON.stringify(portalConfig)
        });
        worker.forkId = forkId;
        worker.type = 'pool';
        poolWorkers[forkId] = worker;
        worker.on('exit', function(code, signal){
            logger.error('Master', 'PoolSpanwer', 'Fork ' + forkId + ' died, spawning replacement worker...');
            setTimeout(function(){
                createPoolWorker(forkId);
            }, 2000);
        }).on('message', function(msg){
            switch(msg.type){
                case 'banIP':
                    Object.keys(cluster.workers).forEach(function(id) {
                        if (cluster.workers[id].type === 'pool'){
                            cluster.workers[id].send({type: 'banIP', ip: msg.ip});
                        }
                    });
                    break;
            }
        });
    };

    var i = 0;
    var spawnInterval = setInterval(function(){
        createPoolWorker(i);
        i++;
        if (i === numForks){
            clearInterval(spawnInterval);
            logger.debug('Master', 'PoolSpawner', 'Spawned ' + Object.keys(poolConfigs).length + ' pool(s) on ' + numForks + ' thread(s)');
        }
    }, 250);

};

var startCliListener = function(){

    var cliPort = portalConfig.cliPort;

    var listener = new CliListener(cliPort);
    listener.on('log', function(text){
        logger.debug('Master', 'CLI', text);
    }).on('command', function(command, params, options, reply){

        switch(command){
            case 'blocknotify':
                Object.keys(cluster.workers).forEach(function(id) {
                    cluster.workers[id].send({type: 'blocknotify', coin: params[0], hash: params[1]});
                });
                reply('Pool workers notified');
                break;
            case 'coinswitch':
                processCoinSwitchCommand(params, options, reply);
                break;
            case 'reloadpool':
                Object.keys(cluster.workers).forEach(function(id) {
                    cluster.workers[id].send({type: 'reloadpool', coin: params[0] });
                });
                reply('reloaded pool ' + params[0]);
                break;
            default:
                reply('unrecognized command "' + command + '"');
                break;
        }
    }).start();
};

var processCoinSwitchCommand = function(params, options, reply){

    var logSystem = 'CLI';
    var logComponent = 'coinswitch';

    var replyError = function(msg){
        reply(msg);
        logger.error(logSystem, logComponent, msg);
    };

    if (!params[0]) {
        replyError('Coin name required');
        return;
    }

    if (!params[1] && !options.algorithm){
        replyError('If switch key is not provided then algorithm options must be specified');
        return;
    }
    else if (params[1] && !portalConfig.switching[params[1]]){
        replyError('Switch key not recognized: ' + params[1]);
        return;
    }
    else if (options.algorithm && !Object.keys(portalConfig.switching).filter(function(s){
        return portalConfig.switching[s].algorithm === options.algorithm;
    })[0]){
        replyError('No switching options contain the algorithm ' + options.algorithm);
        return;
    }

    var messageCoin = params[0].toLowerCase();
    var newCoin = Object.keys(poolConfigs).filter(function(p){
        return p.toLowerCase() === messageCoin;
    })[0];

    if (!newCoin){
        replyError('Switch message to coin that is not recognized: ' + messageCoin);
        return;
    }

    var switchNames = [];

    if (params[1]) {
        switchNames.push(params[1]);
    }
    else{
        for (var name in portalConfig.switching){
            if (portalConfig.switching[name].enabled && portalConfig.switching[name].algorithm === options.algorithm)
                switchNames.push(name);
        }
    }

    switchNames.forEach(function(name){
        if (poolConfigs[newCoin].coin.algorithm !== portalConfig.switching[name].algorithm){
            replyError('Cannot switch a '
                + portalConfig.switching[name].algorithm
                + ' algo pool to coin ' + newCoin + ' with ' + poolConfigs[newCoin].coin.algorithm + ' algo');
            return;
        }

        Object.keys(cluster.workers).forEach(function (id) {
            cluster.workers[id].send({type: 'coinswitch', coin: newCoin, switchName: name });
        });
    });

    reply('Switch message sent to pool workers');

};

var startRedisBlockListener = function(){
    //block notify options
    //setup block notify here and use IPC to tell appropriate pools

    if (!portalConfig.redisBlockNotifyListener.enabled) return;

    var listener = new RedisBlocknotifyListener(portalConfig.redisBlockNotifyListener);
    listener.on('log', function(text){
        logger.debug('Master', 'blocknotify', text);
    }).on('hash', function (message) {
        var ipcMessage = {type:'blocknotify', coin: message.coin, hash: message.hash};
        Object.keys(cluster.workers).forEach(function(id) {
            cluster.workers[id].send(ipcMessage);
        });
    });
    listener.start();
};

var startPaymentProcessor = function(){

    var enabledForAny = false;
    for (var pool in poolConfigs){
        var p = poolConfigs[pool];
        var enabled = p.enabled && p.paymentProcessing && p.paymentProcessing.enabled;
        if (enabled){
            enabledForAny = true;
            break;
        }
    }

    if (!enabledForAny)
        return;

    var worker = cluster.fork({
        workerType: 'paymentProcessor',
        pools: JSON.stringify(poolConfigs)
    });
    worker.on('exit', function(code, signal){
        logger.error('Master', 'Payment Processor', 'Payment processor died, spawning replacement...');
        setTimeout(function(){
            startPaymentProcessor(poolConfigs);
        }, 2000);
    });
};

var startWebsite = function(){

    if (!portalConfig.website.enabled) return;

    var worker = cluster.fork({
        workerType: 'website',
        pools: JSON.stringify(poolConfigs),
        portalConfig: JSON.stringify(portalConfig)
    });
    worker.on('exit', function(code, signal){
        logger.error('Master', 'Website', 'Website process died, spawning replacement...');
        setTimeout(function(){
            startWebsite(portalConfig, poolConfigs);
        }, 2000);
    });
};

var startProfitSwitch = function(){

    if (!portalConfig.profitSwitch || !portalConfig.profitSwitch.enabled){
        //logger.error('Master', 'Profit', 'Profit auto switching disabled');
        return;
    }

    var worker = cluster.fork({
        workerType: 'profitSwitch',
        pools: JSON.stringify(poolConfigs),
        portalConfig: JSON.stringify(portalConfig)
    });
    worker.on('exit', function(code, signal){
        logger.error('Master', 'Profit', 'Profit switching process died, spawning replacement...');
        setTimeout(function(){
            startWebsite(portalConfig, poolConfigs);
        }, 2000);
    });
};

(function init(){

    poolConfigs = buildPoolConfigs();

    spawnPoolWorkers();

    startPaymentProcessor();

    startRedisBlockListener();

    startWebsite();

    startProfitSwitch();

    startCliListener();

})();
<|endoftext|>


<commit_before>/**
 * See README file for documentation.
 */

var dataGrids = [];

$(function() {

    function init(g) {

        var defaults = {
            // Server-side storage:
            // session: {
            //    loadFrom: '/slickgrid/dummy.json',
            //    saveTo: '/slickgrid/session/save'
            // },
            // Client-side storage:
            // session: true,
            // No session handling:
            session: false,
            grid: {
                defaultMinWidth: 68,
                forceFitColumns: (g.columns.length <= 8),
                rowHeight: 21,
                showTotalsHeader: true,
                showTotalsFooter: true,
                syncColumnCellResize: true
            },
            columnPicker: {
                fadeSpeed: 150,
                showSyncResize: false
            },
            view: {
                hideTotalsOnFilter: true,
                updateTotalsOnFilter: false
            }
        };

        // Generate column defaults
        for (var i = 0, cols = g.columns.length; i < cols; i++) {
            var converted = convertName(g.columns[i]);
            g.columns[i].field = g.columns[i].field || converted;
            g.columns[i].id = g.columns[i].id || converted;
            g.columns[i].sortable = (typeof g.columns[i].sortable == 'boolean') ? g.columns[i].sortable : true;
        }

        g.options = $.extend(true, {}, defaults, g.options);
        g.container = $(g.container);

        var sessionIsActive = g.options.session;

        // Init Session
        if (sessionIsActive) {
            g.Session = new Slick.Session(g.id, g.columns, g.options.session);
            g.columns = g.Session.getColumns();
        }

        // Init DataView, Grid, ColumnPicker
        g.View = new Slick.Data.DataView(g.container);
        g.Grid = new Slick.Grid(g.container, g.View.rows, g.columns, g.options.grid, g.totals);
        g.ColumnPicker = new Slick.Controls.ColumnPicker(g.Grid, g.options.columnPicker);

        if (sessionIsActive) {
            g.Session.setGrid(g.Grid);
            g.Grid.onSetAllColumns = g.Session.saveColumns;
        }

        g.Grid.onColumnsReordered = function() {
            if (sessionIsActive) {
                g.Session.saveColumns();
            }
            if (g.options.view.updateTotalsOnFilter) {
                g.View.calculateTotals();
            }
        }

        g.View.setGrid(g.Grid);
        g.View.setColumnPicker(g.ColumnPicker);
        g.View.drawControls();
        g.View.setItems(g.data);

        // Detect and save sort algorithm per column.
        g.View.detectSort();

        g.Grid.onSort = function(column, ascending) {
            g.View.onSort(column, ascending);
            if (sessionIsActive) {
                g.Session.saveSort(column, ascending);
            }
        };
        g.View.defaultSort();

        // Update autosized column widths on window resize.
        $(window).resize(function() {
            if (g.Grid.getOptions().forceFitColumns) {
                g.Grid.autosizeColumns();
            }
        });
    }

    for (var i = 0; i < dataGrids.length; i++) {
        init(dataGrids[i]);
    }

    function convertName(column) {
        if (!column.name) {
            throw new Error('Missing "name" definition in SlickGrid column.');
        }
        if (column.field) {
            return column.field;
        }
        if (column.id) {
            return column.id;
        }
        return column.name.toLowerCase().replace(/[\s\-]/ig, '_').replace(/[^_a-z0-9]/ig, '');
    }

});
<commit_msg>Forgot to wire up view options in init.js.<commit_after>/**
 * See README file for documentation.
 */

var dataGrids = [];

$(function() {

    function init(g) {

        var defaults = {
            // Server-side storage:
            // session: {
            //    loadFrom: '/slickgrid/dummy.json',
            //    saveTo: '/slickgrid/session/save'
            // },
            // Client-side storage:
            // session: true,
            // No session handling:
            session: false,
            grid: {
                defaultMinWidth: 68,
                forceFitColumns: (g.columns.length <= 8),
                rowHeight: 21,
                showTotalsHeader: true,
                showTotalsFooter: true,
                syncColumnCellResize: true
            },
            columnPicker: {
                fadeSpeed: 150,
                showSyncResize: false
            },
            view: {
                hideTotalsOnFilter: true,
                updateTotalsOnFilter: false
            }
        };

        // Generate column defaults
        for (var i = 0, cols = g.columns.length; i < cols; i++) {
            var converted = convertName(g.columns[i]);
            g.columns[i].field = g.columns[i].field || converted;
            g.columns[i].id = g.columns[i].id || converted;
            g.columns[i].sortable = (typeof g.columns[i].sortable == 'boolean') ? g.columns[i].sortable : true;
        }

        g.options = $.extend(true, {}, defaults, g.options);
        g.container = $(g.container);

        var sessionIsActive = g.options.session;

        // Init Session
        if (sessionIsActive) {
            g.Session = new Slick.Session(g.id, g.columns, g.options.session);
            g.columns = g.Session.getColumns();
        }

        // Init DataView, Grid, ColumnPicker
        g.View = new Slick.Data.DataView(g.container, g.options.view);
        g.Grid = new Slick.Grid(g.container, g.View.rows, g.columns, g.options.grid, g.totals);
        g.ColumnPicker = new Slick.Controls.ColumnPicker(g.Grid, g.options.columnPicker);

        if (sessionIsActive) {
            g.Session.setGrid(g.Grid);
            g.Grid.onSetAllColumns = g.Session.saveColumns;
        }

        g.Grid.onColumnsReordered = function() {
            if (sessionIsActive) {
                g.Session.saveColumns();
            }
            if (g.options.view.updateTotalsOnFilter) {
                g.View.calculateTotals();
            }
        }

        g.View.setGrid(g.Grid);
        g.View.setColumnPicker(g.ColumnPicker);
        g.View.drawControls();
        g.View.setItems(g.data);

        // Detect and save sort algorithm per column.
        g.View.detectSort();

        g.Grid.onSort = function(column, ascending) {
            g.View.onSort(column, ascending);
            if (sessionIsActive) {
                g.Session.saveSort(column, ascending);
            }
        };
        g.View.defaultSort();

        // Update autosized column widths on window resize.
        $(window).resize(function() {
            if (g.Grid.getOptions().forceFitColumns) {
                g.Grid.autosizeColumns();
            }
        });
    }

    for (var i = 0; i < dataGrids.length; i++) {
        init(dataGrids[i]);
    }

    function convertName(column) {
        if (!column.name) {
            throw new Error('Missing "name" definition in SlickGrid column.');
        }
        if (column.field) {
            return column.field;
        }
        if (column.id) {
            return column.id;
        }
        return column.name.toLowerCase().replace(/[\s\-]/ig, '_').replace(/[^_a-z0-9]/ig, '');
    }

});
<|endoftext|>


<commit_before>/*global $,cyberDojo*/

var cyberDojo = (function(cd, $) {
  "use strict";

  cd.bindAllLineNumbers = function() {
    $.each(cd.filenames(), function(_, filename) {
      cd.bindLineNumbers(filename);
    });
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.bindLineNumbers = function(filename) {
    var numbers = cd.lineNumbersFor(filename);
    cd.bindLineNumbersEvents(filename);
    numbers.attr('readonly', 'true');
    numbers.html(cd.lineNumbers);
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.lineNumbersFor = function(filename) {
    return cd.id(filename + '_line_numbers');
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.bindLineNumbersEvents = function(filename) {
    var content = cd.fileContentFor(filename);
    var numbers = cd.lineNumbersFor(filename);
    cd.bindLineNumbersFromTo(content, numbers);
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.bindLineNumbersFromTo = function(content, numbers) {
    var synchScroll = function() {
      numbers.scrollTop(content.scrollTop());
    };
    content.bind({
      keydown   : synchScroll,
      scroll    : synchScroll,
      mousewheel: synchScroll,
      mousemove : synchScroll,
      mousedown : synchScroll,
      mouseup   : synchScroll
    });
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.lineNumbers = (function() {
    var number, lines = '';
    for (number = 1; number < 999; number += 1) {
      lines += '
' + number + '
';
    }
    return lines;
  })();

  return cd;
})(cyberDojo || {}, $);
<commit_msg>refactoring - added comment<commit_after>/*global $,cyberDojo*/

var cyberDojo = (function(cd, $) {
  "use strict";

  cd.bindAllLineNumbers = function() {
    $.each(cd.filenames(), function(_, filename) {
      cd.bindLineNumbers(filename);
    });
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.bindLineNumbers = function(filename) {
    var numbers = cd.lineNumbersFor(filename);
    cd.bindLineNumbersEvents(filename);
    numbers.attr('readonly', 'true');
    numbers.html(cd.lineNumbers);
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.lineNumbersFor = function(filename) {
    return cd.id(filename + '_line_numbers');
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.bindLineNumbersEvents = function(filename) {
    var content = cd.fileContentFor(filename);
    var numbers = cd.lineNumbersFor(filename);
    cd.bindLineNumbersFromTo(content, numbers);
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.bindLineNumbersFromTo = function(content, numbers) {
    var synchScroll = function() {
      numbers.scrollTop(content.scrollTop());
    };
    content.bind({
      keydown   : synchScroll,
      scroll    : synchScroll,
      mousewheel: synchScroll,
      mousemove : synchScroll,
      mousedown : synchScroll,
      mouseup   : synchScroll
    });
  };

  //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  cd.lineNumbers = (function() {
    // This is used to be 9999 lines but profiling revealed this
    // to be a hotspot. Reducing 9999 to 999 shaved about 2
    // seconds off the typical user-perceived reponse time.
    var number, lines = '';
    for (number = 1; number < 999; number += 1) {
      lines += '
' + number + '
';
    }
    return lines;
  })();

  return cd;
})(cyberDojo || {}, $);
<|endoftext|>


<commit_before>define([
  'extensions/views/graph/component',
  'modernizr'
],
function (Component, Modernizr) {

  /**
   * Graph component that intercepts and normalises user interaction events
   */
  var Hover = Component.extend({

    modernizr: Modernizr,

    events: function () {
      if (this.modernizr.touch) {

        _.bindAll(this, 'onTouchStartBody');
        $('body').on('touchstart', this.onTouchStartBody);

        return {
          'touchstart .hover': 'onTouchStart'
        }
      } else {
        return {
          'mousemove .hover': 'onMouseMove'
        }
      }
    },

    dispose: function () {
      if (this.modernizr.touch) {
        $('body').off('touchstart', this.onTouchStartBody);
      }
      Component.prototype.dispose.apply(this, arguments);
    },

    render: function () {
      if (!this.hoverEl) {
        this.hoverEl = $('

').addClass('hover').appendTo(this.$el);
      }
    },

    onMouseMove: function (e) {
      var scaleFactor = this.graph.scaleFactor();

      var offset = this.$el.offset();
      var scaleFactor = this.graph.scaleFactor();
      var x = (e.pageX - offset.left) / scaleFactor - this.margin.left;
      var y = (e.pageY - offset.top) / scaleFactor - this.margin.top;

      if (!this.bodyListener) {
        this.bodyListener = true;
        var that = this;
        $('body').one('mousemove', function () {
          that.bodyListener = false;
          that.collection.selectItem(null, null);
        });
      }

      this.selectPoint(x, y);
      return false;
    },

    onTouchStartBody: function (e) {
      if (this.ignoreNextBodyTouchStartEvent) {
        this.ignoreNextBodyTouchStartEvent = false;
      } else {
        this.collection.selectItem(null, null);
      }
    },

    onTouchStart: function (e) {
      var touch = e.originalEvent.touches[0];
      var offset = this.$el.offset();
      var scaleFactor = this.graph.scaleFactor();
      var x = (touch.pageX - offset.left) / scaleFactor - this.margin.left;
      var y = (touch.pageY - offset.top) / scaleFactor - this.margin.top;

      this.ignoreNextBodyTouchStartEvent = true;
      this.selectPoint(x, y, {
        toggle: true
      });
    },

    /**
     * Triggers a graph 'hover' event for a specific coordinate.
     */
    selectPoint: function (x, y, options) {
      var slice = this.getSlice(x, y);
      this.graph.trigger('hover', _.extend({
        x: x,
        y: y,
        slice: slice
      }, options));
    },

    /**
     * Finds 'slice' of the graph for a specific coordinate.
     * The graph area is divided in 9 slices counted in reading direction:
     * 0-2: top; 3-5: middle; 6-8: bottom.
     * 0,3,6: left; 1,4,7: centre; 2,5,8: right.
     * The main graph area therefore is slice 4.
     */
    getSlice: function (x, y) {
      return (y >= this.graph.innerHeight ? 6 : y < 0 ? 0 : 3) +
             (x >= this.graph.innerWidth ? 2 : x < 0 ? 0 : 1);
    }

  });

  return Hover;
});
<commit_msg>optimise graph interaction touch listeners<commit_after>define([
  'extensions/views/graph/component',
  'modernizr'
],
function (Component, Modernizr) {

  /**
   * Graph component that intercepts and normalises user interaction events
   */
  var Hover = Component.extend({

    modernizr: Modernizr,

    events: function () {
      if (this.modernizr.touch) {
        return {
          'touchstart .hover': 'onTouchStart'
        }
      } else {
        return {
          'mousemove .hover': 'onMouseMove'
        }
      }
    },

    dispose: function () {
      if (this.modernizr.touch) {
        $('body').off('touchstart', this.onTouchStartBody);
      }
      Component.prototype.dispose.apply(this, arguments);
    },

    render: function () {
      if (!this.hoverEl) {
        this.hoverEl = $('

').addClass('hover').appendTo(this.$el);
      }
    },

    attachBodyListener: function (eventName) {
      if (this.bodyListener) {
        return;
      }
      this.bodyListener = true;
      var that = this;
      $('body').one(eventName, function () {
        that.bodyListener = false;
        that.collection.selectItem(null, null);
      });
    },

    onMouseMove: function (e) {
      var scaleFactor = this.graph.scaleFactor();

      var offset = this.$el.offset();
      var scaleFactor = this.graph.scaleFactor();
      var x = (e.pageX - offset.left) / scaleFactor - this.margin.left;
      var y = (e.pageY - offset.top) / scaleFactor - this.margin.top;

      this.attachBodyListener('mousemove');
      this.selectPoint(x, y);
      return false;
    },

    onTouchStart: function (e) {
      var touch = e.originalEvent.touches[0];
      var offset = this.$el.offset();
      var scaleFactor = this.graph.scaleFactor();
      var x = (touch.pageX - offset.left) / scaleFactor - this.margin.left;
      var y = (touch.pageY - offset.top) / scaleFactor - this.margin.top;

      this.attachBodyListener('touchstart');
      this.selectPoint(x, y, {
        toggle: true
      });
      return false;
    },

    /**
     * Triggers a graph 'hover' event for a specific coordinate.
     */
    selectPoint: function (x, y, options) {
      var slice = this.getSlice(x, y);
      this.graph.trigger('hover', _.extend({
        x: x,
        y: y,
        slice: slice
      }, options));
    },

    /**
     * Finds 'slice' of the graph for a specific coordinate.
     * The graph area is divided in 9 slices counted in reading direction:
     * 0-2: top; 3-5: middle; 6-8: bottom.
     * 0,3,6: left; 1,4,7: centre; 2,5,8: right.
     * The main graph area therefore is slice 4.
     */
    getSlice: function (x, y) {
      return (y >= this.graph.innerHeight ? 6 : y < 0 ? 0 : 3) +
             (x >= this.graph.innerWidth ? 2 : x < 0 ? 0 : 1);
    }

  });

  return Hover;
});
<|endoftext|>


<commit_before>/**
 * The Tiger layer module for use on canvas.
 *
 * @return TigersLayer class (extends CanvasLayerClass)
 */
define([
  'abstract/layer/CartoDBLayerClass',
  'text!map/cartocss/tigerCartoCSS.cartocss'
], function(CartoDBLayerClass, TigerCartoCSS) {

  'use strict';

  var TigersLayer = CartoDBLayerClass.extend({

    options: {
      sql: 'SELECT the_geom_webmercator, cartodb_id, the_geom, tcl_name as name, area_ha, tx2_tcl, \'tiger_conservation_landscapes\' as layer '+

        'FROM tiger_conservation_landscapes '+

        'UNION '+
        'SELECT the_geom_webmercator, cartodb_id, the_geom, name,  area_ha, area_ha as tx2_tcl, \'tal_corridor\' as layer '+
        'FROM tal_corridor ',
      infowindow: true,
      interactivity: 'name, area_ha',
      analysis: true,
      cartocss: TigerCartoCSS
    }
  });

  return TigersLayer;

});
<commit_msg>added analisis functionality<commit_after>/**
 * The Tiger layer module for use on canvas.
 *
 * @return TigersLayer class (extends CanvasLayerClass)
 */
define([
  'abstract/layer/CartoDBLayerClass',
  'text!map/cartocss/tigerCartoCSS.cartocss'
], function(CartoDBLayerClass, TigerCartoCSS) {

  'use strict';

  var TigersLayer = CartoDBLayerClass.extend({

    options: {
      sql: 'SELECT the_geom_webmercator, cartodb_id, the_geom, tcl_name as name, area_ha, tx2_tcl, \'tiger_conservation_landscapes\' AS tablename, \'tiger_conservation_landscapes\' as layer, {analysis} AS analysis '+

        'FROM tiger_conservation_landscapes '+

        'UNION '+
        'SELECT the_geom_webmercator, cartodb_id, the_geom, name,  area_ha, area_ha as tx2_tcl, \'tal_corridor\' AS tablename, \'tal_corridor\' as layer, {analysis} AS analysis '+
        'FROM tal_corridor ',
      infowindow: true,
      interactivity: 'cartodb_id, tablename, layer, name, area_ha, analysis',
      analysis: true,
      cartocss: TigerCartoCSS
    }
  });

  return TigersLayer;

});
<|endoftext|>


<commit_before>/* global require, module */

var uglifyJavaScript = require('broccoli-uglify-js');
var replace = require('broccoli-replace');
var compileES6 = require('broccoli-es6-concatenator');
var pickFiles = require('broccoli-static-compiler');
var env = require('broccoli-env').getEnv();
var getEnvJSON = require('./config/environment');

var p = require('ember-cli/lib/preprocessors');
var preprocessCss = p.preprocessCss;
var preprocessTemplates = p.preprocessTemplates;
var preprocessJs = p.preprocessJs;

module.exports = function (broccoli) {

  var prefix = '<%= modulePrefix %>';
  var rootURL = '/';

  // index.html

  var indexHTML = pickFiles('app', {
    srcDir: '/',
    files: ['index.html'],
    destDir: '/'
  });

  indexHTML = replace(indexHTML, {
    files: ['index.html'],
    patterns: [{ match: /\{\{ENV\}\}/g, replacement: getEnvJSON.bind(env)}]
  });

  var testsIndexHTML = pickFiles('tests', {
    srcDir: '/',
    files: ['index.html'],
    destDir: '/tests'
  });

  testsIndexHTML = replace(testsIndexHTML, {
    files: ['tests/index.html'],
    patterns: [{ match: /\{\{ENV\}\}/g, replacement: getEnvJSON.bind(env)}]
  });

  // sourceTrees, appAndDependencies for CSS and JavaScript

  var app = pickFiles('app', {
    srcDir: '/',
    destDir: prefix
  });

  app = preprocessTemplates(app);

  var config = pickFiles('config', { // Don't pick anything, just watch config folder
    srcDir: '/',
    files: [],
    destDir: '/'
  });

  var sourceTrees = [app, config, 'vendor'].concat(broccoli.bowerTrees());

  if (env !== 'production') {
    var tests = pickFiles('tests', {
      srcDir: '/',
      destDir: prefix + '/tests'
    });

    tests = preprocessTemplates(tests);
    sourceTrees.push(tests);
  }

  var appAndDependencies = new broccoli.MergedTree(sourceTrees);

  // JavaScript

  var legacyFilesToAppend = [
    'jquery.js',
    'handlebars.js',
    'ember.js',
    'ic-ajax/main.js',
    'ember-data.js',
    'ember-resolver.js',
    'ember-shim.js'
  ];

  if (env !== 'production') {
    legacyFilesToAppend.push(
      'qunit/qunit/qunit.js',
      'qunit-shim.js',
      'ember-qunit/dist/named-amd/main.js'
    );
  }

  var applicationJs = preprocessJs(appAndDependencies, '/', prefix);

  applicationJs = compileES6(applicationJs, {
    loaderFile: 'loader/loader.js',
    ignoredModules: [
      'ember/resolver',
      'ember-qunit'
    ],
    inputFiles: [
      prefix + '/**/*.js'
    ],
    legacyFilesToAppend: legacyFilesToAppend,

    wrapInEval: env !== 'production',
    outputFile: '/assets/app.js'
  });

  if (env === 'production') {
    applicationJs = uglifyJavaScript(applicationJs, {
      mangle: false,
      compress: false
    });
  }

  // Styles

  var styles = preprocessCss(sourceTrees, prefix + '/styles', '/assets');

  var qunitStyles = pickFiles('vendor', {
    srcDir: '/qunit/qunit',
    files: ['qunit.css'],
    destDir: '/assets/'
  });

  // Ouput

  var outputTrees = [
    indexHTML,
    applicationJs,
    'public',
    styles
  ];

  if (env !== 'production') {
    outputTrees.push(qunitStyles, testsIndexHTML);
  }

  return outputTrees;
};
<commit_msg>Remove spaces<commit_after>/* global require, module */

var uglifyJavaScript = require('broccoli-uglify-js');
var replace = require('broccoli-replace');
var compileES6 = require('broccoli-es6-concatenator');
var pickFiles = require('broccoli-static-compiler');
var env = require('broccoli-env').getEnv();
var getEnvJSON = require('./config/environment');

var p = require('ember-cli/lib/preprocessors');
var preprocessCss = p.preprocessCss;
var preprocessTemplates = p.preprocessTemplates;
var preprocessJs = p.preprocessJs;

module.exports = function (broccoli) {

  var prefix = '<%= modulePrefix %>';
  var rootURL = '/';

  // index.html

  var indexHTML = pickFiles('app', {
    srcDir: '/',
    files: ['index.html'],
    destDir: '/'
  });

  indexHTML = replace(indexHTML, {
    files: ['index.html'],
    patterns: [{ match: /\{\{ENV\}\}/g, replacement: getEnvJSON.bind(env)}]
  });

  var testsIndexHTML = pickFiles('tests', {
    srcDir: '/',
    files: ['index.html'],
    destDir: '/tests'
  });

  testsIndexHTML = replace(testsIndexHTML, {
    files: ['tests/index.html'],
    patterns: [{ match: /\{\{ENV\}\}/g, replacement: getEnvJSON.bind(env)}]
  });

  // sourceTrees, appAndDependencies for CSS and JavaScript

  var app = pickFiles('app', {
    srcDir: '/',
    destDir: prefix
  });

  app = preprocessTemplates(app);

  var config = pickFiles('config', { // Don't pick anything, just watch config folder
    srcDir: '/',
    files: [],
    destDir: '/'
  });

  var sourceTrees = [app, config, 'vendor'].concat(broccoli.bowerTrees());

  if (env !== 'production') {
    var tests = pickFiles('tests', {
      srcDir: '/',
      destDir: prefix + '/tests'
    });

    tests = preprocessTemplates(tests);
    sourceTrees.push(tests);
  }

  var appAndDependencies = new broccoli.MergedTree(sourceTrees);

  // JavaScript

  var legacyFilesToAppend = [
    'jquery.js',
    'handlebars.js',
    'ember.js',
    'ic-ajax/main.js',
    'ember-data.js',
    'ember-resolver.js',
    'ember-shim.js'
  ];

  if (env !== 'production') {
    legacyFilesToAppend.push(
      'qunit/qunit/qunit.js',
      'qunit-shim.js',
      'ember-qunit/dist/named-amd/main.js'
    );
  }

  var applicationJs = preprocessJs(appAndDependencies, '/', prefix);

  applicationJs = compileES6(applicationJs, {
    loaderFile: 'loader/loader.js',
    ignoredModules: [
      'ember/resolver',
      'ember-qunit'
    ],
    inputFiles: [
      prefix + '/**/*.js'
    ],
    legacyFilesToAppend: legacyFilesToAppend,

    wrapInEval: env !== 'production',
    outputFile: '/assets/app.js'
  });

  if (env === 'production') {
    applicationJs = uglifyJavaScript(applicationJs, {
      mangle: false,
      compress: false
    });
  }

  // Styles

  var styles = preprocessCss(sourceTrees, prefix + '/styles', '/assets');

  var qunitStyles = pickFiles('vendor', {
    srcDir: '/qunit/qunit',
    files: ['qunit.css'],
    destDir: '/assets/'
  });

  // Ouput

  var outputTrees = [
    indexHTML,
    applicationJs,
    'public',
    styles
  ];

  if (env !== 'production') {
    outputTrees.push(qunitStyles, testsIndexHTML);
  }

  return outputTrees;
};
<|endoftext|>


<commit_before>// Eloquent JavaScript

// Run this file in your terminal using `node my_solution.js`. Make sure it works before moving on!

// Program Structure
// Write your own variable and do something to it.

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board

// Functions

// Complete the `minimum` exercise.

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods, and a quirk below.<commit_msg>Add file for modlue 7.2<commit_after>// Eloquent JavaScript

// Run this file in your terminal using `node my_solution.js`. Make sure it works before moving on!

// Program Structure
// Write your own variable and do something to it.
var cat_name = "Finn"
console.log(cat_name, "is a great cat.")

// prompt("What's your favorite food?")
// alert("That's my favorite food too!")

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board

// Functions

// Complete the `minimum` exercise.

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods, and a quirk below.

// Introduction
// Did you learn anything new about JavaScript or programming in general?
// I don'y know much about JavaScript, so there were definitely some new things here. One of the most interesting things was the fact that JavaScript is very "forgiving" in terms of what it will allow. It does seem like that will be difficult at first, but I'm interested to see how that will also give you the ability to be more flexible later on.

// Are there any concepts you feel uncomfortable with?
// Not in particular. As I said, I don't really have experience with this language, but nothing in the introduction seemed too crazy.

// Chapter 1
// Identify two similarities and two differences between JavaScript and Ruby syntax with regard to numbers, arithmetic, strings, booleans, and various operators.
//Similarities:
  // 1. The arithmetic operators are the same.
  // 2. Strings are handled in the same way.
// Differences
  // 1. In JavaScript you have to include the keyword "var" to declare a variable.
  // 2. The automatic type conversion in JavaScript seems very different from Ruby. I believe Ruby will raise an error any time you try to apply mathematical operations on dissimilar object types (except in a few cases).

// Chapter 2
// What is an expression?
// Anything that produces a value.

// What is the purpose of semicolons in JavaScript? Are they always required?
// It markes the end of an expression. They are not always required, but the rules regarding when they are not required are complicated.

// What causes a variable to return undefined?
// Undefined is returned when an operation doesn't yield a meaningful value.

// Write your own variable and do something to it in the eloquent.js file.
// See above.

// What does console.log do and when would you use it? What Ruby method(s) is this similar to?
// It prints something to the console. This is similar to p, print, and puts in Ruby.

// Write a short program that asks for a user to input their favorite food. After they hit return, have the program respond with "Hey! That's my favorite too!" (You will probably need to run this in the Chrome console (Links to an external site.) rather than node since node does not support prompt or alert). Paste your program into the eloquent.js file.
// See above.

// Describe while and for loops
// While and for loops do the same thing. They will continue to loop until a specified condition is met. For is a shorter version of while, but they function the same.

// What other similarities or differences between Ruby and JavaScript did you notice in this section?
// The main thing for me is that most of the concepts are essentially the same. While loops, if/else statements, etc. For the most part, it's just the syntax that is different.

// Complete at least one of the exercises (Looping a Triangle, FizzBuzz, of Chess Board) in the eloquent.js file.

// Looping a triangle

var counter = 1
while (counter <= 7) {
  console.log("#".repeat(counter ++));
}

// for (var i = 1; i < 101; console.log(i++)) {
//   if (i % 3 == 0 && i % 5 == 0) { console.log("FizzBuzz")};
//     else if (i % 3 == 0 ) { console.log("Fizz") };
//       else if (i % 5 == 0) { console.log("Buzz")};
//         else if (i % 3 != 0 || i % 5 != 0) { console.log(i) };
// }

switch
<|endoftext|>


<commit_before>
//imports
var fs = require('fs');
var utils = getContext('gina.utils');
var GINA_PATH = _( getPath('gina.core') );
//var Config = require( _( GINA_PATH + '/config') );
var readline = require('readline');
var rl = readline.createInterface(process.stdin, process.stdout);

function iniProject(name) {

    var self = this;
    self.task = 'init';//important for later in config init

    var init = function(name) {
        self.root = getPath('root');
        self.name = name;

        if ( !isValidName() ) {
            console.error('[ '+name+' ] is not a valid project name. Please, try something else: [a-Z0-9].');
            process.exit(1)
        }

        var file = new _(self.root + '/project.json');
        var exists = file.existsSync();
        if ( !exists ) {
            createFile( file.toString() )
        } else {
            console.log('[ aborted ] a project already exists in this location: '+ file);
            process.exit(0)
        }
    }

    var isValidName = function() {
        var patt = /[a-z0-9]/gi;
        return patt.test(bundle)
    }

    var createFile = function(target) {
        var conf = GINA_PATH +'/template/conf/project.json';
        var contentFile = require(conf);
        var dic = {
            "project" : self.name
        };

        contentFile = whisper(dic, contentFile);//data
        fs.writeFileSync(target, JSON.stringify(contentFile, null, 4));
        console.log('project [ '+ self.name +' ] ready');
        process.exit(0)
    }

    init(name)
};
module.exports = iniProject<commit_msg>fixed project init<commit_after>
//imports
var fs = require('fs');
var utils = getContext('gina.utils');
var GINA_PATH = _( getPath('gina.core') );
//var Config = require( _( GINA_PATH + '/config') );
var readline = require('readline');
var rl = readline.createInterface(process.stdin, process.stdout);

function iniProject(name) {

    var self = this;
    self.task = 'init';//important for later in config init

    var init = function(name) {
        self.root = getPath('root');
        self.name = name;

        if ( !isValidName() ) {
            console.error('[ '+name+' ] is not a valid project name. Please, try something else: [a-Z0-9].');
            process.exit(1)
        }

        var file = new _(self.root + '/project.json');
        var exists = file.existsSync();
        if ( !exists ) {
            createFile( file.toString() )
        } else {
            console.log('[ aborted ] a project already exists in this location: '+ file);
            process.exit(0)
        }
    }

    var isValidName = function() {
        var patt = /[a-z0-9]/gi;
        return patt.test(name)
    }

    var createFile = function(target) {
        var conf = GINA_PATH +'/template/conf/project.json';
        var contentFile = require(conf);
        var dic = {
            "project" : self.name
        };

        contentFile = whisper(dic, contentFile);//data
        fs.writeFileSync(target, JSON.stringify(contentFile, null, 4));
        console.log('project [ '+ self.name +' ] ready');
        process.exit(0)
    }

    init(name)
};
module.exports = iniProject<|endoftext|>


<commit_before>import Constants from 'vtk.js/Sources/Common/Core/DataArray/Constants';
import macro from 'vtk.js/Sources/macro';
import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';

const { DefaultDataType } = Constants;
const TUPLE_HOLDER = [];

// ----------------------------------------------------------------------------
// Global methods
// ----------------------------------------------------------------------------

function createRangeHelper() {
  let min = Number.MAX_VALUE;
  let max = -Number.MAX_VALUE;
  let count = 0;
  let sum = 0;

  return {
    add(value) {
      if (min > value) {
        min = value;
      }
      if (max < value) {
        max = value;
      }
      count++;
      sum += value;
    },
    get() {
      return { min, max, count, sum, mean: sum / count };
    },
    getRange() {
      return { min, max };
    },
  };
}

function computeRange(values, component = 0, numberOfComponents = 1) {
  const helper = createRangeHelper();
  const size = values.length;
  let value = 0;

  if (component < 0 && numberOfComponents > 1) {
    // Compute magnitude
    for (let i = 0; i < size; i += numberOfComponents) {
      value = 0;
      for (let j = 0; j < numberOfComponents; j++) {
        value += values[i + j] * values[i + j];
      }
      value **= 0.5;
      helper.add(value);
    }
    return helper.getRange();
  }

  const offset = component < 0 ? 0 : component;
  for (let i = offset; i < size; i += numberOfComponents) {
    helper.add(values[i]);
  }

  return helper.getRange();
}

function ensureRangeSize(rangeArray, size = 0) {
  const ranges = rangeArray || [];
  // Pad ranges with null value to get the
  while (ranges.length <= size) {
    ranges.push(null);
  }
  return ranges;
}

function getDataType(typedArray) {
  return Object.prototype.toString
    .call(typedArray)
    .split(' ')[1]
    .slice(0, -1);
}

function getMaxNorm(normArray) {
  const numComps = normArray.getNumberOfComponents();
  let maxNorm = 0.0;
  for (let i = 0; i < normArray.getNumberOfTuples(); ++i) {
    const norm = vtkMath.norm(normArray.getTuple(i), numComps);
    if (norm > maxNorm) {
      maxNorm = norm;
    }
  }
  return maxNorm;
}

// ----------------------------------------------------------------------------
// Static API
// ----------------------------------------------------------------------------

export const STATIC = {
  computeRange,
  createRangeHelper,
  getDataType,
  getMaxNorm,
};

// ----------------------------------------------------------------------------
// vtkDataArray methods
// ----------------------------------------------------------------------------

function vtkDataArray(publicAPI, model) {
  // Set our className
  model.classHierarchy.push('vtkDataArray');

  function dataChange() {
    model.ranges = null;
    publicAPI.modified();
  }

  publicAPI.getElementComponentSize = () => model.values.BYTES_PER_ELEMENT;

  // Description:
  // Return the data component at the location specified by tupleIdx and
  // compIdx.
  publicAPI.getComponent = (tupleIdx, compIdx = 0) =>
    model.values[tupleIdx * model.numberOfComponents + compIdx];

  // Description:
  // Set the data component at the location specified by tupleIdx and compIdx
  // to value.
  // Note that i is less than NumberOfTuples and j is less than
  //  NumberOfComponents. Make sure enough memory has been allocated
  // (use SetNumberOfTuples() and SetNumberOfComponents()).
  publicAPI.setComponent = (tupleIdx, compIdx, value) => {
    if (value !== model.values[tupleIdx * model.numberOfComponents + compIdx]) {
      model.values[tupleIdx * model.numberOfComponents + compIdx] = value;
      dataChange();
    }
  };

  publicAPI.getData = () => model.values;

  publicAPI.getRange = (componentIndex = -1) => {
    const rangeIdx =
      componentIndex < 0 ? model.numberOfComponents : componentIndex;
    let range = null;

    if (!model.ranges) {
      model.ranges = ensureRangeSize(model.ranges, model.numberOfComponents);
    }
    range = model.ranges[rangeIdx];

    if (range) {
      model.rangeTuple[0] = range.min;
      model.rangeTuple[1] = range.max;
      return model.rangeTuple;
    }

    // Need to compute ranges...
    range = computeRange(
      model.values,
      componentIndex,
      model.numberOfComponents
    );
    model.ranges[rangeIdx] = range;
    model.rangeTuple[0] = range.min;
    model.rangeTuple[1] = range.max;
    return model.rangeTuple;
  };

  publicAPI.setTuple = (idx, tuple) => {
    const offset = idx * model.numberOfComponents;
    for (let i = 0; i < model.numberOfComponents; i++) {
      model.values[offset + i] = tuple[i];
    }
  };

  publicAPI.getTuple = (idx, tupleToFill = TUPLE_HOLDER) => {
    const numberOfComponents = model.numberOfComponents || 1;
    if (tupleToFill.length !== numberOfComponents) {
      tupleToFill.length = numberOfComponents;
    }
    const offset = idx * numberOfComponents;
    // Check most common component sizes first
    // to avoid doing a for loop if possible
    if (numberOfComponents === 1) {
      tupleToFill[0] = model.values[offset];
    } else if (numberOfComponents === 2) {
      tupleToFill[0] = model.values[offset];
      tupleToFill[1] = model.values[offset + 1];
    } else if (numberOfComponents === 3) {
      tupleToFill[0] = model.values[offset];
      tupleToFill[1] = model.values[offset + 1];
      tupleToFill[2] = model.values[offset + 2];
    } else if (numberOfComponents === 4) {
      tupleToFill[0] = model.values[offset];
      tupleToFill[1] = model.values[offset + 1];
      tupleToFill[2] = model.values[offset + 2];
      tupleToFill[3] = model.values[offset + 3];
    } else {
      for (let i = 0; i < numberOfComponents; i++) {
        tupleToFill[i] = model.values[offset + i];
      }
    }
    return tupleToFill;
  };

  publicAPI.getTupleLocation = (idx = 1) => idx * model.numberOfComponents;
  publicAPI.getNumberOfComponents = () => model.numberOfComponents;
  publicAPI.getNumberOfValues = () => model.values.length;
  publicAPI.getNumberOfTuples = () =>
    model.values.length / model.numberOfComponents;
  publicAPI.getDataType = () => model.dataType;
  /* eslint-disable no-use-before-define */
  publicAPI.newClone = () =>
    newInstance({
      empty: true,
      name: model.name,
      dataType: model.dataType,
      numberOfComponents: model.numberOfComponents,
    });
  /* eslint-enable no-use-before-define */

  publicAPI.getName = () => {
    if (!model.name) {
      publicAPI.modified();
      model.name = `vtkDataArray${publicAPI.getMTime()}`;
    }
    return model.name;
  };

  publicAPI.setData = (typedArray, numberOfComponents) => {
    model.values = typedArray;
    model.size = typedArray.length;
    model.dataType = getDataType(typedArray);
    if (numberOfComponents) {
      model.numberOfComponents = numberOfComponents;
    }
    if (model.size % model.numberOfComponents !== 0) {
      model.numberOfComponents = 1;
    }
    dataChange();
  };

  // Override serialization support
  publicAPI.getState = () => {
    const jsonArchive = Object.assign({}, model, {
      vtkClass: publicAPI.getClassName(),
    });

    // Convert typed array to regular array
    jsonArchive.values = Array.from(jsonArchive.values);
    delete jsonArchive.buffer;

    // Clean any empty data
    Object.keys(jsonArchive).forEach((keyName) => {
      if (!jsonArchive[keyName]) {
        delete jsonArchive[keyName];
      }
    });

    // Sort resulting object by key name
    const sortedObj = {};
    Object.keys(jsonArchive)
      .sort()
      .forEach((name) => {
        sortedObj[name] = jsonArchive[name];
      });

    // Remove mtime
    if (sortedObj.mtime) {
      delete sortedObj.mtime;
    }

    return sortedObj;
  };
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
  name: '',
  numberOfComponents: 1,
  size: 0,
  dataType: DefaultDataType,
  rangeTuple: [0, 0],
  // values: null,
  // ranges: null,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  if (!model.empty && !model.values && !model.size) {
    throw new TypeError(
      'Cannot create vtkDataArray object without: size > 0, values'
    );
  }

  if (!model.values) {
    model.values = new window[model.dataType](model.size);
  } else if (Array.isArray(model.values)) {
    model.values = window[model.dataType].from(model.values);
  }

  if (model.values) {
    model.size = model.values.length;
    model.dataType = getDataType(model.values);
  }

  // Object methods
  macro.obj(publicAPI, model);
  macro.set(publicAPI, model, ['name', 'numberOfComponents']);

  // Object specific methods
  vtkDataArray(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkDataArray');

// ----------------------------------------------------------------------------

export default Object.assign({ newInstance, extend }, STATIC, Constants);
<commit_msg>fix(DataArray): Speedup getDataType()<commit_after>import Constants from 'vtk.js/Sources/Common/Core/DataArray/Constants';
import macro from 'vtk.js/Sources/macro';
import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';

const { DefaultDataType } = Constants;
const TUPLE_HOLDER = [];

// ----------------------------------------------------------------------------
// Global methods
// ----------------------------------------------------------------------------

function createRangeHelper() {
  let min = Number.MAX_VALUE;
  let max = -Number.MAX_VALUE;
  let count = 0;
  let sum = 0;

  return {
    add(value) {
      if (min > value) {
        min = value;
      }
      if (max < value) {
        max = value;
      }
      count++;
      sum += value;
    },
    get() {
      return { min, max, count, sum, mean: sum / count };
    },
    getRange() {
      return { min, max };
    },
  };
}

function computeRange(values, component = 0, numberOfComponents = 1) {
  const helper = createRangeHelper();
  const size = values.length;
  let value = 0;

  if (component < 0 && numberOfComponents > 1) {
    // Compute magnitude
    for (let i = 0; i < size; i += numberOfComponents) {
      value = 0;
      for (let j = 0; j < numberOfComponents; j++) {
        value += values[i + j] * values[i + j];
      }
      value **= 0.5;
      helper.add(value);
    }
    return helper.getRange();
  }

  const offset = component < 0 ? 0 : component;
  for (let i = offset; i < size; i += numberOfComponents) {
    helper.add(values[i]);
  }

  return helper.getRange();
}

function ensureRangeSize(rangeArray, size = 0) {
  const ranges = rangeArray || [];
  // Pad ranges with null value to get the
  while (ranges.length <= size) {
    ranges.push(null);
  }
  return ranges;
}

function getDataType(typedArray) {
  // Expects toString() to return "[object ...Array]"
  return Object.prototype.toString.call(typedArray).slice(8, -1);
}

function getMaxNorm(normArray) {
  const numComps = normArray.getNumberOfComponents();
  let maxNorm = 0.0;
  for (let i = 0; i < normArray.getNumberOfTuples(); ++i) {
    const norm = vtkMath.norm(normArray.getTuple(i), numComps);
    if (norm > maxNorm) {
      maxNorm = norm;
    }
  }
  return maxNorm;
}

// ----------------------------------------------------------------------------
// Static API
// ----------------------------------------------------------------------------

export const STATIC = {
  computeRange,
  createRangeHelper,
  getDataType,
  getMaxNorm,
};

// ----------------------------------------------------------------------------
// vtkDataArray methods
// ----------------------------------------------------------------------------

function vtkDataArray(publicAPI, model) {
  // Set our className
  model.classHierarchy.push('vtkDataArray');

  function dataChange() {
    model.ranges = null;
    publicAPI.modified();
  }

  publicAPI.getElementComponentSize = () => model.values.BYTES_PER_ELEMENT;

  // Description:
  // Return the data component at the location specified by tupleIdx and
  // compIdx.
  publicAPI.getComponent = (tupleIdx, compIdx = 0) =>
    model.values[tupleIdx * model.numberOfComponents + compIdx];

  // Description:
  // Set the data component at the location specified by tupleIdx and compIdx
  // to value.
  // Note that i is less than NumberOfTuples and j is less than
  //  NumberOfComponents. Make sure enough memory has been allocated
  // (use SetNumberOfTuples() and SetNumberOfComponents()).
  publicAPI.setComponent = (tupleIdx, compIdx, value) => {
    if (value !== model.values[tupleIdx * model.numberOfComponents + compIdx]) {
      model.values[tupleIdx * model.numberOfComponents + compIdx] = value;
      dataChange();
    }
  };

  publicAPI.getData = () => model.values;

  publicAPI.getRange = (componentIndex = -1) => {
    const rangeIdx =
      componentIndex < 0 ? model.numberOfComponents : componentIndex;
    let range = null;

    if (!model.ranges) {
      model.ranges = ensureRangeSize(model.ranges, model.numberOfComponents);
    }
    range = model.ranges[rangeIdx];

    if (range) {
      model.rangeTuple[0] = range.min;
      model.rangeTuple[1] = range.max;
      return model.rangeTuple;
    }

    // Need to compute ranges...
    range = computeRange(
      model.values,
      componentIndex,
      model.numberOfComponents
    );
    model.ranges[rangeIdx] = range;
    model.rangeTuple[0] = range.min;
    model.rangeTuple[1] = range.max;
    return model.rangeTuple;
  };

  publicAPI.setTuple = (idx, tuple) => {
    const offset = idx * model.numberOfComponents;
    for (let i = 0; i < model.numberOfComponents; i++) {
      model.values[offset + i] = tuple[i];
    }
  };

  publicAPI.getTuple = (idx, tupleToFill = TUPLE_HOLDER) => {
    const numberOfComponents = model.numberOfComponents || 1;
    if (tupleToFill.length !== numberOfComponents) {
      tupleToFill.length = numberOfComponents;
    }
    const offset = idx * numberOfComponents;
    // Check most common component sizes first
    // to avoid doing a for loop if possible
    if (numberOfComponents === 1) {
      tupleToFill[0] = model.values[offset];
    } else if (numberOfComponents === 2) {
      tupleToFill[0] = model.values[offset];
      tupleToFill[1] = model.values[offset + 1];
    } else if (numberOfComponents === 3) {
      tupleToFill[0] = model.values[offset];
      tupleToFill[1] = model.values[offset + 1];
      tupleToFill[2] = model.values[offset + 2];
    } else if (numberOfComponents === 4) {
      tupleToFill[0] = model.values[offset];
      tupleToFill[1] = model.values[offset + 1];
      tupleToFill[2] = model.values[offset + 2];
      tupleToFill[3] = model.values[offset + 3];
    } else {
      for (let i = 0; i < numberOfComponents; i++) {
        tupleToFill[i] = model.values[offset + i];
      }
    }
    return tupleToFill;
  };

  publicAPI.getTupleLocation = (idx = 1) => idx * model.numberOfComponents;
  publicAPI.getNumberOfComponents = () => model.numberOfComponents;
  publicAPI.getNumberOfValues = () => model.values.length;
  publicAPI.getNumberOfTuples = () =>
    model.values.length / model.numberOfComponents;
  publicAPI.getDataType = () => model.dataType;
  /* eslint-disable no-use-before-define */
  publicAPI.newClone = () =>
    newInstance({
      empty: true,
      name: model.name,
      dataType: model.dataType,
      numberOfComponents: model.numberOfComponents,
    });
  /* eslint-enable no-use-before-define */

  publicAPI.getName = () => {
    if (!model.name) {
      publicAPI.modified();
      model.name = `vtkDataArray${publicAPI.getMTime()}`;
    }
    return model.name;
  };

  publicAPI.setData = (typedArray, numberOfComponents) => {
    model.values = typedArray;
    model.size = typedArray.length;
    model.dataType = getDataType(typedArray);
    if (numberOfComponents) {
      model.numberOfComponents = numberOfComponents;
    }
    if (model.size % model.numberOfComponents !== 0) {
      model.numberOfComponents = 1;
    }
    dataChange();
  };

  // Override serialization support
  publicAPI.getState = () => {
    const jsonArchive = Object.assign({}, model, {
      vtkClass: publicAPI.getClassName(),
    });

    // Convert typed array to regular array
    jsonArchive.values = Array.from(jsonArchive.values);
    delete jsonArchive.buffer;

    // Clean any empty data
    Object.keys(jsonArchive).forEach((keyName) => {
      if (!jsonArchive[keyName]) {
        delete jsonArchive[keyName];
      }
    });

    // Sort resulting object by key name
    const sortedObj = {};
    Object.keys(jsonArchive)
      .sort()
      .forEach((name) => {
        sortedObj[name] = jsonArchive[name];
      });

    // Remove mtime
    if (sortedObj.mtime) {
      delete sortedObj.mtime;
    }

    return sortedObj;
  };
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
  name: '',
  numberOfComponents: 1,
  size: 0,
  dataType: DefaultDataType,
  rangeTuple: [0, 0],
  // values: null,
  // ranges: null,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
  Object.assign(model, DEFAULT_VALUES, initialValues);

  if (!model.empty && !model.values && !model.size) {
    throw new TypeError(
      'Cannot create vtkDataArray object without: size > 0, values'
    );
  }

  if (!model.values) {
    model.values = new window[model.dataType](model.size);
  } else if (Array.isArray(model.values)) {
    model.values = window[model.dataType].from(model.values);
  }

  if (model.values) {
    model.size = model.values.length;
    model.dataType = getDataType(model.values);
  }

  // Object methods
  macro.obj(publicAPI, model);
  macro.set(publicAPI, model, ['name', 'numberOfComponents']);

  // Object specific methods
  vtkDataArray(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkDataArray');

// ----------------------------------------------------------------------------

export default Object.assign({ newInstance, extend }, STATIC, Constants);
<|endoftext|>