<commit_before>var colour = require('colors'); //Muahaha useless but fun to play with
var https = require('https');
var kid = "PG2FQO" //Pulled someone's 'kid' ('k-id', not kid >:|) off twitter (via https://twitter.com/balkumar/status/632149668726607872) Use your own... (or be malicious, I take no responibility...)
var json = ''; //Prepare the json response, might come in chunks...

console.log("Fetching ".yellow + kid.inverse + "'s status in the system...".yellow)

https.get('https://invites.oneplus.net/index.php?r=share/view&kid=' + kid, function(res) {
  res.on('data', function(chunk) {
    json += chunk;
  });

  res.on('end', function() {
    var jRes = JSON.parse(json)
    var jData = jRes.data
    console.log("==================================================".rainbow); //I had to
    console.log((jData.kid).inverse + " has ".yellow + (jData.ref_count).toString().inverse + " refferals total.".yellow); //Refferals
    console.log("and has ".yellow + (jData.credits).toString().inverse + " 'credits' (whatever that means...)".yellow); //Credits ?
    console.log("and is ranked @ ".yellow + (numberWithCommas(jData.rank)).inverse + " out of a total of ".yellow + (numberWithCommas(jData.total)).inverse + " others".yellow); //Rank + Total
    console.log("and was created on ".yellow + (timeConverter(jData.create_at)).inverse ); //When the kid registered
    if (jData.parent != ""){ console.log("and their 'parent' is ".yellow + (jData.parent).red ); } //Check if the 'kid' has a 'parent' (uh)
    if (jData.referer != undefined){ console.log("and their 'referer' was '".yellow + (jData.referer).inverse + "'".yellow); } //Check if the 'kid' was reffered by an external source
    if (jData.ip != undefined){ console.log("and their IP address is ".yellow + (jData.ip).red + " (security flaw?)".red); } // silly 1+
    if (jData.userIp != undefined){ console.log("and their IP address is ".yellow + (jData.userIp).red + " (security flaw?)".red); } // 1+ pls
    console.log("==================================================".rainbow); //This project is for fun ok?
  });

}).on('error', function(e) {
  console.log("Got error: " + e.message);
  process.exit(1);
});

//Thanks http://stackoverflow.com/questions/847185/convert-a-unix-timestamp-to-time-in-javascript
function timeConverter(UNIX_timestamp){
  var a = new Date(UNIX_timestamp * 1000);
  var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
  var year = a.getFullYear();
  var month = months[a.getMonth()];
  var date = a.getDate();
  var hour = a.getHours();
  var min = a.getMinutes();
  var sec = a.getSeconds();
  var time = date + ' ' + month + ' ' + year + ' @ ' + hour + ':' + min + ':' + sec ;
  return time;
}
//Thanks http://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
<commit_msg>Some semi-colons here and there<commit_after>var colour = require('colors'); //Muahaha useless but fun to play with
var https = require('https');
var kid = "PG2FQO"; //Pulled someone's 'kid' ('k-id', not kid >:|) off twitter (via https://twitter.com/balkumar/status/632149668726607872) Use your own... (or be malicious, I take no responibility...)
var json = ''; //Prepare the json response, might come in chunks...

console.log("Fetching ".yellow + kid.inverse + "'s status in the system...".yellow);

https.get('https://invites.oneplus.net/index.php?r=share/view&kid=' + kid, function(res) {
  res.on('data', function(chunk) {
    json += chunk;
  });

  res.on('end', function() {
    var jRes = JSON.parse(json);
    var jData = jRes.data;
    console.log("==================================================".rainbow); //I had to
    console.log((jData.kid).inverse + " has ".yellow + (jData.ref_count).toString().inverse + " refferals total.".yellow); //Refferals
    console.log("and has ".yellow + (jData.credits).toString().inverse + " 'credits' (whatever that means...)".yellow); //Credits ?
    console.log("and is ranked @ ".yellow + (numberWithCommas(jData.rank)).inverse + " out of a total of ".yellow + (numberWithCommas(jData.total)).inverse + " others".yellow); //Rank + Total
    console.log("and was created on ".yellow + (timeConverter(jData.create_at)).inverse ); //When the kid registered
    if (jData.parent != ""){ console.log("and their 'parent' is ".yellow + (jData.parent).red ); } //Check if the 'kid' has a 'parent' (uh)
    if (jData.referer !== undefined){ console.log("and their 'referer' was '".yellow + (jData.referer).inverse + "'".yellow); } //Check if the 'kid' was reffered by an external source
    if (jData.ip !== undefined){ console.log("and their IP address is ".yellow + (jData.ip).red + " (security flaw?)".red); } // silly 1+
    if (jData.userIp !== undefined){ console.log("and their IP address is ".yellow + (jData.userIp).red + " (security flaw?)".red); } // 1+ pls
    console.log("==================================================".rainbow); //This project is for fun ok?
  });

}).on('error', function(e) {
  console.log("Got error: " + e.message);
  process.exit(1);
});

//Thanks http://stackoverflow.com/questions/847185/convert-a-unix-timestamp-to-time-in-javascript
function timeConverter(UNIX_timestamp){
  var a = new Date(UNIX_timestamp * 1000);
  var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
  var year = a.getFullYear();
  var month = months[a.getMonth()];
  var date = a.getDate();
  var hour = a.getHours();
  var min = a.getMinutes();
  var sec = a.getSeconds();
  var time = date + ' ' + month + ' ' + year + ' @ ' + hour + ':' + min + ':' + sec ;
  return time;
}
//Thanks http://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
<|endoftext|>


<commit_before>$(function(){
  numClicked();
  opClicked();
  doAllTheMaths();
  clearAll();
  toggleNegative();
});

var nums = [];
var parsedNums = [];
var hasBeenToggled, toggled;

function clearAll(){
  $('#clearAll').on('click', function(){
    nums = [];
    parsedNums = [];
    $('input').val('');
    hasBeenToggled = 0;
  });
}

function toggleNegative(){
  hasBeenToggled = 0;
  // toggled;
  $('#plus-minus').on('click', function(){
    if(!hasBeenToggled){
      hasBeenToggled ++;
      toggled = parseInt(nums.join("")) * -1;
      nums = [];
      $('input').val(toggled);
      console.log(toggled);
    }
    else{
      $('input').val(toggled * -1);
      toggled = toggled * -1;
      console.log(toggled);
    }
  });
}

function numClicked(){
  $(".number").on("click", function(){
    nums.push($(this).text().trim());
    console.log(nums);
    $('input').val(nums.join(""));
  });
}

var ops = [], result;
function opClicked(){
  var $op;
  $(".ops").on("click", function(){
    $op = $(this).attr('value');
    console.log($op);
    var numSet = toggled ? toggled: parseInt(nums.join(''));
    toggled = '';
    console.log(toggled);
    nums = [];
    parsedNums.push(numSet);
    console.log(numSet);
    console.log(parsedNums);
    if(!ops[0] && $op !== "="){
      ops.push($op);
    }
    else{
      opToPass = ops.pop();
      if($op !== "=")
      ops.push($op);
      console.log(opToPass);
    }
    if(parsedNums.length === 2){
      result = calculate(opToPass)[0];
      console.log(result);
      $('input').val(result);
    }
  });
}

function calculate(opToPass){
  var result;
  switch (opToPass) {
    case "+":
      result = parsedNums.reduce(function(a, b){
        return a + b;
      });
      break;
    case "-":
      result = parsedNums.reduce(function(a, b){
        return a - b;
      });
      break;
    case "/":
      result = parsedNums.reduce(function(a, b){
        return a / b;
      });
      break;
    case "*":
      result = parsedNums.reduce(function(a, b){
        return a * b;
      });
      break;
    case "=":
        console.log(opToPass);
      break;
    default:
  }
  parsedNums = [];
  parsedNums.push(result);
  return parsedNums;
}

function doAllTheMaths(){
  $('#equals').on('click', function(){
    console.log(result);
    parsedNums = [];
    nums[0] = result;
    $('input').val(nums[0]);
  });
}
<commit_msg>include percentage op with chaining<commit_after>$(function(){
  numClicked();
  opClicked();
  doAllTheMaths();
  clearAll();
  toggleNegative();
  toPercent();
});

var nums = [];
var parsedNums = [];
var hasBeenToggled, toggled, percentage;

function clearAll(){
  $('#clearAll').on('click', function(){
    nums = [];
    parsedNums = [];
    $('input').val('');
    hasBeenToggled = 0;
  });
}

function toggleNegative(){
  hasBeenToggled = 0;
  $('#plus-minus').on('click', function(){
    if(!hasBeenToggled){
      hasBeenToggled ++;
      toggled = parseInt(nums.join("")) * -1;
      nums = [];
      $('input').val(toggled);
      console.log(toggled);
    }
    else{
      $('input').val(toggled * -1);
      toggled = toggled * -1;
      console.log(toggled);
    }
  });
}

function toPercent(){
  $('#percent').on('click', function(){
    percentage = parseInt(nums.join("")) / 100;
    console.log(percentage);
    nums = [];
    $('input').val(percentage);
  });
}

function numClicked(){
  $(".number").on("click", function(){
    nums.push($(this).text().trim());
    console.log(nums);
    $('input').val(nums.join(""));
  });
}

var ops = [], result;
function opClicked(){
  var $op;
  $(".ops").on("click", function(){
    $op = $(this).attr('value');
    console.log($op);
    var numSet = toggled || percentage ? toggled || percentage: parseInt(nums.join(''));
    toggled = '';
    percentage = '';
    console.log(toggled);
    nums = [];
    parsedNums.push(numSet);
    console.log(numSet);
    console.log(parsedNums);
    if(!ops[0] && $op !== "="){
      ops.push($op);
    }
    else{
      opToPass = ops.pop();
      if($op !== "=")
      ops.push($op);
      console.log(opToPass);
    }
    if(parsedNums.length === 2){
      result = calculate(opToPass)[0];
      console.log(result);
      $('input').val(result);
    }
  });
}

function calculate(opToPass){
  var result;
  switch (opToPass) {
    case "+":
      result = parsedNums.reduce(function(a, b){
        return a + b;
      });
      break;
    case "-":
      result = parsedNums.reduce(function(a, b){
        return a - b;
      });
      break;
    case "/":
      result = parsedNums.reduce(function(a, b){
        return a / b;
      });
      break;
    case "*":
      result = parsedNums.reduce(function(a, b){
        return a * b;
      });
      break;
    case "=":
        console.log(opToPass);
      break;
    default:
  }
  parsedNums = [];
  parsedNums.push(result);
  return parsedNums;
}

function doAllTheMaths(){
  $('#equals').on('click', function(){
    console.log(result);
    parsedNums = [];
    nums[0] = result;
    $('input').val(nums[0]);
  });
}
<|endoftext|>


<commit_before>/* eslint no-loop-func: 0 */

var path = require('path');
var gulp = require('gulp');
var rename = require('gulp-rename');
var run = require('../');
var util = require('./util');

describe('gulp-run', function gulpRunTestCase() {
  var inputFileName = path.join(__dirname, '_resource/input.txt');

  // it('includes `node_modules/.bin` on the PATH', function includeNodeModulesTest(done) {
  //   var nodeModulesPath = path.join(__dirname, '..', '..', '.bin');
  //
  //   run('echo $PATH', { verbosity: 0 }).exec()
  //     .pipe(util.compare(new RegExp('^' + nodeModulesPath)))
  //     .on('finish', done)
  //   ;
  // });

  // it('lets you set the initial cwd of the command', function cwdTest(done) {
  //   run('pwd', { cwd: '/', verbosity: 0 }).exec()
  //     .pipe(util.compare('/\n'))
  //     .on('finish', done)
  //   ;
  // });

  // describe.skip('verbosity levels', function verbosityTestCase() {
  //   var colors = require('gulp-util').colors;
  //   var output = '';
  //   var stdoutWrite = process.stdout.write;
  //
  //   before(function handleBefore() {
  //     process.stdout.write = function write(chunk, enc, callback) {
  //       output += chunk.toString(enc);
  //
  //       if (typeof callback === 'function') {
  //         process.nextTick(callback);
  //       }
  //     };
  //   });
  //
  //   after(function handleAfter() {
  //     process.stdout.write = stdoutWrite;
  //   });
  //
  //   beforeEach(function handleBeforeEach() {
  //     output = '';
  //   });
  //
  //   it('verbosity 0 never prints', function neverPrintTest(done) {
  //     (new run.Command('echo "testing verbosity:0"', { verbosity: 0 }))
  //       .exec(function handleExec() {
  //         output.should.match(/^$/);
  //
  //         done();
  //       })
  //     ;
  //   });
  //
  //   it('verbosity 1 prints stderr when the command is done', function stdErrPrintTest(done) {
  //     (new run.Command('echo "testing verbosity:1"', { verbosity: 1 }))
  //       .exec(function handleExec() {
  //         output = colors.stripColor(output);
  //         output.should.match(/\$ echo "testing verbosity:1" # Silenced\s*\n/);
  //
  //         done();
  //       })
  //     ;
  //   });
  //
  //   it(
  //     'verbosity 2 prints stderr and stdout when the command is done',
  //     function stdErrAndStdOutTest(done) {
  //       (new run.Command('echo "testing verbosity:2"', { verbosity: 2 }))
  //         .exec(function handleExec() {
  //           output = colors.stripColor(output);
  //           output.should.match(/\$ echo "testing verbosity:2"\s*\ntesting verbosity:2/);
  //
  //           done();
  //         })
  //       ;
  //     }
  //   );
  //
  //   it('verbosity 3 prints stderr and stdout in real time', function printAllTest(done) {
  //     (new run.Command('echo "testing verbosity:3"', { verbosity: 3 }))
  //       .exec(function handleExec() {
  //         output = colors.stripColor(output);
  //         output.should.match(/\$ echo "testing verbosity:3"\s*\ntesting verbosity:3/);
  //
  //         done();
  //       })
  //     ;
  //   });
  // });

  describe('in a vinyl pipeline', function vinylPipelineTestCase() {
    // it('works with buffers', function bufferTest(done) {
    //   // use awk to extract the even lines of a file
    //   gulp.src(inputFileName, { buffer: true })
    //     .pipe(run('awk "NR % 2 == 0"', {
    //       verbosity: 0
    //     }))
    //     .pipe(util.compare('2\n4\n6\n8\n10\n12\n'))
    //     .on('finish', done)
    //   ;
    // });

    // it('works with streams', function streamTest(done) {
    //   // use awk to extract the even lines of a file
    //   gulp.src(inputFileName, { buffer: false })
    //     .pipe(run('awk "NR % 2 == 0"', {
    //       verbosity: 0
    //     }))
    //     .pipe(util.compare('2\n4\n6\n8\n10\n12\n'))
    //     .on('finish', done)
    //   ;
    // });

    // it('supports command templates, i.e. `echo <%= file.path %>`', function templateTest(done) {
    //   gulp.src(inputFileName)
    //     .pipe(run('echo <%= file.path %>', {
    //       verbosity: 0
    //     }))
    //     .pipe(util.compare(inputFileName + '\n'))
    //     .on('finish', done)
    //   ;
    // });

    // it('emits an `error` event on a failed command', function errorTest(done) {
    //   gulp.src(inputFileName)
    //     .pipe(run('exit 1', { verbosity: 0 }))
    //     .on('error', util.noop(done))
    //   ;
    // });

    it('maintains metadata of incoming file', function metaDataTest(done) {
      gulp.src(inputFileName)
        .pipe(util.inspect(function handleInspect(file) {
          file.custom = 'custom metadata';
        }))
        .pipe(run('cat', {
          verbosity: 0
        }))
        .pipe(util.inspect(function captureInspect(file) {
          file.custom.should.equal('custom metadata');
        }))
        .on('finish', done)
      ;
    });
  });

  describe('direct execution (`.exec`)', function execTestCase() {
    it('is asynchronous (this test sleeps for 1s)', function asyncTest(done) {
      var semaphore = new util.Semaphore(2, done);
      var startTime = process.hrtime()[0];
      var index;

      for (index = 0; index < 2; index += 1) {
        run('sleep 1', { verbosity: 0 })
          .exec(function handleExec() {
            var delta = process.hrtime()[0] - startTime;
            delta.should.equal(1);
            semaphore.done();
          })
        ;
      }
    });

    it('returns a vinyl stream wrapping stdout', function wrappingStdOutTest(done) {
      run('echo Hello World', { verbosity: 0 })
        .exec()
        .pipe(util.compare('Hello World\n'))
        .on('finish', done)
      ;
    });

    it('emits an `error` event on a failed command', function emitErrorTest(done) {
      run('exit 1', { verbosity: 0 })
        .exec()
        .on('error', util.noop(done))
      ;
    });

    it('closes the stream when done', function streamCloseTest(done) {
      run('echo Hello World', { verbosity: 0 })
        .exec()
        .on('finish', done)
      ;
    });
  });

  describe('issues', function issuesTestCase() {
    it('#18 - file names and paths', function issue18(done) {
      run('echo hello world', { cwd: './', verbosity: 0 }).exec()
        .pipe(rename('dest.txt'))
        .on('finish', done)
      ;
    });

    it('#35 - no callback if command not found', function commandNotFoundTest(done) {
      run('nonexistant', { verbosity: 0 })
        .exec()
        .on('error', function handleError() {
          done();
        })
      ;
    });
  });
});
<commit_msg>Isolate travis ci error<commit_after>/* eslint no-loop-func: 0 */

// var path = require('path');
// var gulp = require('gulp');
var rename = require('gulp-rename');
var run = require('../');
var util = require('./util');

describe('gulp-run', function gulpRunTestCase() {
  // var inputFileName = path.join(__dirname, '_resource/input.txt');

  // it('includes `node_modules/.bin` on the PATH', function includeNodeModulesTest(done) {
  //   var nodeModulesPath = path.join(__dirname, '..', '..', '.bin');
  //
  //   run('echo $PATH', { verbosity: 0 }).exec()
  //     .pipe(util.compare(new RegExp('^' + nodeModulesPath)))
  //     .on('finish', done)
  //   ;
  // });

  // it('lets you set the initial cwd of the command', function cwdTest(done) {
  //   run('pwd', { cwd: '/', verbosity: 0 }).exec()
  //     .pipe(util.compare('/\n'))
  //     .on('finish', done)
  //   ;
  // });

  // describe.skip('verbosity levels', function verbosityTestCase() {
  //   var colors = require('gulp-util').colors;
  //   var output = '';
  //   var stdoutWrite = process.stdout.write;
  //
  //   before(function handleBefore() {
  //     process.stdout.write = function write(chunk, enc, callback) {
  //       output += chunk.toString(enc);
  //
  //       if (typeof callback === 'function') {
  //         process.nextTick(callback);
  //       }
  //     };
  //   });
  //
  //   after(function handleAfter() {
  //     process.stdout.write = stdoutWrite;
  //   });
  //
  //   beforeEach(function handleBeforeEach() {
  //     output = '';
  //   });
  //
  //   it('verbosity 0 never prints', function neverPrintTest(done) {
  //     (new run.Command('echo "testing verbosity:0"', { verbosity: 0 }))
  //       .exec(function handleExec() {
  //         output.should.match(/^$/);
  //
  //         done();
  //       })
  //     ;
  //   });
  //
  //   it('verbosity 1 prints stderr when the command is done', function stdErrPrintTest(done) {
  //     (new run.Command('echo "testing verbosity:1"', { verbosity: 1 }))
  //       .exec(function handleExec() {
  //         output = colors.stripColor(output);
  //         output.should.match(/\$ echo "testing verbosity:1" # Silenced\s*\n/);
  //
  //         done();
  //       })
  //     ;
  //   });
  //
  //   it(
  //     'verbosity 2 prints stderr and stdout when the command is done',
  //     function stdErrAndStdOutTest(done) {
  //       (new run.Command('echo "testing verbosity:2"', { verbosity: 2 }))
  //         .exec(function handleExec() {
  //           output = colors.stripColor(output);
  //           output.should.match(/\$ echo "testing verbosity:2"\s*\ntesting verbosity:2/);
  //
  //           done();
  //         })
  //       ;
  //     }
  //   );
  //
  //   it('verbosity 3 prints stderr and stdout in real time', function printAllTest(done) {
  //     (new run.Command('echo "testing verbosity:3"', { verbosity: 3 }))
  //       .exec(function handleExec() {
  //         output = colors.stripColor(output);
  //         output.should.match(/\$ echo "testing verbosity:3"\s*\ntesting verbosity:3/);
  //
  //         done();
  //       })
  //     ;
  //   });
  // });

  describe('in a vinyl pipeline', function vinylPipelineTestCase() {
    // it('works with buffers', function bufferTest(done) {
    //   // use awk to extract the even lines of a file
    //   gulp.src(inputFileName, { buffer: true })
    //     .pipe(run('awk "NR % 2 == 0"', {
    //       verbosity: 0
    //     }))
    //     .pipe(util.compare('2\n4\n6\n8\n10\n12\n'))
    //     .on('finish', done)
    //   ;
    // });

    // it('works with streams', function streamTest(done) {
    //   // use awk to extract the even lines of a file
    //   gulp.src(inputFileName, { buffer: false })
    //     .pipe(run('awk "NR % 2 == 0"', {
    //       verbosity: 0
    //     }))
    //     .pipe(util.compare('2\n4\n6\n8\n10\n12\n'))
    //     .on('finish', done)
    //   ;
    // });

    // it('supports command templates, i.e. `echo <%= file.path %>`', function templateTest(done) {
    //   gulp.src(inputFileName)
    //     .pipe(run('echo <%= file.path %>', {
    //       verbosity: 0
    //     }))
    //     .pipe(util.compare(inputFileName + '\n'))
    //     .on('finish', done)
    //   ;
    // });

    // it('emits an `error` event on a failed command', function errorTest(done) {
    //   gulp.src(inputFileName)
    //     .pipe(run('exit 1', { verbosity: 0 }))
    //     .on('error', util.noop(done))
    //   ;
    // });

  //   it('maintains metadata of incoming file', function metaDataTest(done) {
  //     gulp.src(inputFileName)
  //       .pipe(util.inspect(function handleInspect(file) {
  //         file.custom = 'custom metadata';
  //       }))
  //       .pipe(run('cat', {
  //         verbosity: 0
  //       }))
  //       .pipe(util.inspect(function captureInspect(file) {
  //         file.custom.should.equal('custom metadata');
  //       }))
  //       .on('finish', done)
  //     ;
  //   });
  });

  describe('direct execution (`.exec`)', function execTestCase() {
    it('is asynchronous (this test sleeps for 1s)', function asyncTest(done) {
      var semaphore = new util.Semaphore(2, done);
      var startTime = process.hrtime()[0];
      var index;

      for (index = 0; index < 2; index += 1) {
        run('sleep 1', { verbosity: 0 })
          .exec(function handleExec() {
            var delta = process.hrtime()[0] - startTime;
            delta.should.equal(1);
            semaphore.done();
          })
        ;
      }
    });

    it('returns a vinyl stream wrapping stdout', function wrappingStdOutTest(done) {
      run('echo Hello World', { verbosity: 0 })
        .exec()
        .pipe(util.compare('Hello World\n'))
        .on('finish', done)
      ;
    });

    it('emits an `error` event on a failed command', function emitErrorTest(done) {
      run('exit 1', { verbosity: 0 })
        .exec()
        .on('error', util.noop(done))
      ;
    });

    it('closes the stream when done', function streamCloseTest(done) {
      run('echo Hello World', { verbosity: 0 })
        .exec()
        .on('finish', done)
      ;
    });
  });

  describe('issues', function issuesTestCase() {
    it('#18 - file names and paths', function issue18(done) {
      run('echo hello world', { cwd: './', verbosity: 0 }).exec()
        .pipe(rename('dest.txt'))
        .on('finish', done)
      ;
    });

    it('#35 - no callback if command not found', function commandNotFoundTest(done) {
      run('nonexistant', { verbosity: 0 })
        .exec()
        .on('error', function handleError() {
          done();
        })
      ;
    });
  });
});
<|endoftext|>


<commit_before>const ACTIVE_CLASS_NAME = 'active';
const LOADING_CLASS_NAME = 'load';

//Elements
const submitButton = document.getElementById('submitToHover');
const sliderContainer = document.getElementById('wrapper');

initSubmitButton();

function initSubmitButton() {
  if (isLoggedIn()) {
    submitButton.setAttribute("value", "Розпочати");
  } else {
    submitButton.setAttribute("value", "Увійти та розпочати");
  }
}

function validate(value) {
  if (parseLink(value)) {
    submitButton.classList.add(ACTIVE_CLASS_NAME);
  } else {
    submitButton.classList.remove(ACTIVE_CLASS_NAME);
  }
}

function loginIfNeededAndLoad(link, gender, sortType) {
  if (isLoggedIn()) {
    loadComments(link, gender, sortType);
  } else {
    VK.Auth.login(function (response) {
      if (response.session) {
        loadComments(link, gender, sortType);
      }
    })
  }

  return false;
}

function loadComments(link, gender, sortType) {
  submitButton.classList.add(LOADING_CLASS_NAME);
  let {groupId, postId} = parseLink(link);
  getAllComments(groupId, postId, function (comments) {
    comments = filterWithPhoto(comments);
    comments = getFilterGenderStrategy(gender)(comments);
    comments = getSortStrategy(sortType)(comments);

    initSlider(comments);
    nextComment();

    if (comments) {
      sliderContainer.style.display = 'block';
      window.scrollTo(0, sliderContainer.scrollHeight);
      submitButton.classList.remove(LOADING_CLASS_NAME);
    }
  });
}

function getFilterGenderStrategy(gender) {
  switch (gender) {
    case '1':
      return function (comments) {
        return filterByGender(comments, 1);
      };

    case '2':
      return function (comments) {
        return filterByGender(comments, 2);
      };

    default:
      return self;
  }
}

function getSortStrategy(type) {
  switch (type) {
    case 'likes':
      return sortByLikes;

    case 'random':
      return shuffle;

    default:
      return self;
  }
}

function self(object) {
  return object;
}<commit_msg>Fixed link validation in mozilla<commit_after>const ACTIVE_CLASS_NAME = 'active';
const LOADING_CLASS_NAME = 'load';

//Elements
const SUBMIT_BUTTON = document.getElementById('submitToHover');
const SLIDER_CONTAINER = document.getElementById('wrapper');
const LINK = document.getElementById("link");

validate(LINK.value);
initSubmitButton();

function initSubmitButton() {
  if (isLoggedIn()) {
    SUBMIT_BUTTON.setAttribute("value", "Розпочати");
  } else {
    SUBMIT_BUTTON.setAttribute("value", "Увійти та розпочати");
  }
}

function validate(value) {
  if (parseLink(value)) {
    SUBMIT_BUTTON.classList.add(ACTIVE_CLASS_NAME);
  } else {
    SUBMIT_BUTTON.classList.remove(ACTIVE_CLASS_NAME);
  }
}

function loginIfNeededAndLoad(link, gender, sortType) {
  if (isLoggedIn()) {
    loadComments(link, gender, sortType);
  } else {
    VK.Auth.login(function (response) {
      if (response.session) {
        loadComments(link, gender, sortType);
      }
    })
  }

  return false;
}

function loadComments(link, gender, sortType) {
  SUBMIT_BUTTON.classList.add(LOADING_CLASS_NAME);
  let {groupId, postId} = parseLink(link);
  getAllComments(groupId, postId, function (comments) {
    comments = filterWithPhoto(comments);
    comments = getFilterGenderStrategy(gender)(comments);
    comments = getSortStrategy(sortType)(comments);

    initSlider(comments);
    nextComment();

    if (comments) {
      SLIDER_CONTAINER.style.display = 'block';
      window.scrollTo(0, SLIDER_CONTAINER.scrollHeight);
      SUBMIT_BUTTON.classList.remove(LOADING_CLASS_NAME);
    }
  });
}

function getFilterGenderStrategy(gender) {
  switch (gender) {
    case '1':
      return function (comments) {
        return filterByGender(comments, 1);
      };

    case '2':
      return function (comments) {
        return filterByGender(comments, 2);
      };

    default:
      return self;
  }
}

function getSortStrategy(type) {
  switch (type) {
    case 'likes':
      return sortByLikes;

    case 'random':
      return shuffle;

    default:
      return self;
  }
}

function self(object) {
  return object;
}<|endoftext|>


<commit_before>// Load in dependencies
var Keyboard = require('./keyboard');
var Mouse = require('./mouse');

// Define bind method
function bind(context, fn) {
  return function bindFn () {
    return fn.apply(context, arguments);
  };
}

// Define our constructor
function GoogleMusic(win) {
  // If win was not provided, complain
  if (!win) {
    throw new Error('`win` was not provided to the `GoogleMusic` constructor');
  }

  // Localize reference to window and document
  this.win = win;
  this.doc = win.document;

  // Initialize a keyboard and mouse
  this.keyboard = new Keyboard(win);
  this.mouse = new Mouse(win);

  // For each of the prototype sections
  var proto = GoogleMusic._protoObj;
  for (var protoKey in proto) {
    if (proto.hasOwnProperty(protoKey)) {
      // Define a key on our object
      this[protoKey] = {};

      // For each of the keys on the section, define a function that invokes on this original context
      var section = proto[protoKey];
      for (var sectionKey in section) {
        if (section.hasOwnProperty(sectionKey)) {
          this[protoKey][sectionKey] = bind(this, section[sectionKey]);
        }
      }

      // If there was an `init` method, run it
      if (this[protoKey].init) {
        this[protoKey].init();
      }
    }
  }
}
// Define a prototype that will have magical invocation
var proto = GoogleMusic._protoObj = {};

// Create a volume API
proto.volume = {
  // Query required elements
  init: function () {
    this.volume._sliderEl = this.doc.querySelector('#vslider');
  },

  // Get the current volume level.
  getVolume: function () {
    return parseInt(this.volume._sliderEl.getAttribute('aria-valuenow'), 10);
  },

  // Set the volume level (0 - 100).
  setVolume: function (vol) {
    var current = this.volume.getVolume();

    if (vol > current) {
      this.volume.increaseVolume(vol - current);
    } else if (vol < current) {
      this.volume.decreaseVolume(current - vol);
    }
  },

  // Increase the volume by an amount (default of 1)
  increaseVolume: function (amount) {
    if (amount === undefined) {
      amount = 1;
    }

    for (var i = 0; i < amount; i++) {
      this.keyboard.sendKey(this.volume._sliderEl, Keyboard.KEY_UP);
    }
  },

  // Decrease the volume by an amount (default of 1)
  decreaseVolume: function (amount) {
    if (amount === undefined) {
      amount = 1;
    }

    for (var i = 0; i < amount; i++) {
      this.keyboard.sendKey(this.volume._sliderEl, Keyboard.KEY_DOWN);
    }
  }
};

// Create a playback API and constants
GoogleMusic.Playback = {
  // Playback states
  STOPPED: 0,
  PAUSED: 1,
  PLAYING: 2,

  // Repeat modes
  LIST_REPEAT: 'LIST_REPEAT',
  SINGLE_REPEAT: 'SINGLE_REPEAT',
  NO_REPEAT: 'NO_REPEAT',

  // Shuffle modes
  ALL_SHUFFLE: 'ALL_SHUFFLE',
  NO_SHUFFLE: 'NO_SHUFFLE'
};
proto.playback = {
  // Query references to the media playback elements
  init: function () {
    this.playback._sliderEl = this.doc.getElementById('slider');
    this.playback._playPauseEl = this.doc.querySelector('button[data-id="play-pause"]');
    this.playback._forwardEl = this.doc.querySelector('button[data-id="forward"]');
    this.playback._rewindEl = this.doc.querySelector('button[data-id="rewind"]');
    this.playback._shuffleEl = this.doc.querySelector('button[data-id="shuffle"]');
    this.playback._repeatEl = this.doc.querySelector('button[data-id="repeat"]');
  },

  // Time functions
  getPlaybackTime: function () {
    return parseInt(this.playback._sliderEl.getAttribute('aria-valuenow'), 10);
  },

  setPlaybackTime: function (milliseconds) {
    var percent = milliseconds / parseFloat(this.playback._sliderEl.getAttribute('aria-valuemax'));
    var lower = this.playback._sliderEl.offsetLeft + 6;
    var upper = this.playback._sliderEl.offsetLeft + this.playback._sliderEl.clientWidth - 6;
    var x = lower + percent * (upper - lower);

    this.mouse.clickAtLocation(this.playback._sliderEl, x, 0);
  },

  // Playback functions
  playPause: function () { this.playback._playPauseEl.click(); },
  forward: function () { this.playback._forwardEl.click(); },
  rewind: function () { this.playback._rewindEl.click(); },

  getShuffle: function () { return this.playback._shuffleEl.value; },
  toggleShuffle: function () { this.playback._shuffleEl.click(); },

  getRepeat: function () {
    return this.playback._repeatEl.value;
  },

  changeRepeat: function (mode) {
    if (!mode) {
      // Toggle between repeat modes once
      this.playback._repeatEl.click();
    } else {
      // Toggle between repeat modes until the desired mode is activated
      while (this.playback.getRepeat() !== mode) {
        this.playback._repeatEl.click();
      }
    }
  },

  // Taken from the Google Play Music page
  toggleVisualization: function () {
    this.win.SJBpost('toggleVisualization');
  }
};

// Create a rating API
proto.rating = {
  // Determine whether the rating system is thumbs or stars
  isStarsRatingSystem: function () {
    return this.doc.querySelector('.rating-container.stars') !== null;
  },

  // Get current rating
  getRating: function () {
    var el = this.doc.querySelector('.player-rating-container li.selected');

    if (el) {
      return el.getAttribute('data-rating');
    } else {
      return 0;
    }
  },

  // Thumbs up
  toggleThumbsUp: function () {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="5"]');

    if (el) {
      el.click();
    }
  },

  // Thumbs down
  toggleThumbsDown: function () {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="1"]');

    if (el) {
      el.click();
    }
  },

  // Set a star rating
  setStarRating: function (rating) {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="' + rating + '"]');

    if (el) {
      el.click();
    }
  }
};

// Miscellaneous functions
proto.extras = {
  // Get a shareable URL of the song on Google Play Music
  getSongURL: function () {
    var albumEl = this.doc.querySelector('.player-album');
    var artistEl = this.doc.querySelector('.player-artist');

    var urlTemplate = 'https://play.google.com/music/m/';
    var url = null;

    var parseID = function (id) {
      return id.substring(0, id.indexOf('/'));
    };

    if (albumEl === null && artistEl === null) {
      return null;
    }

    var albumId = parseID(albumEl.dataset.id);
    var artistId = parseID(artistEl.dataset.id);

    if (albumId) {
      url = urlTemplate + albumId;
    } else if (artistId) {
      url = urlTemplate + artistId;
    }

    return url;
  }
};

proto.hooks = {
  init: function () {
    // Save context for bindings
    var that = this;

    // Define mutation observer for reuse
    var MutationObserver = this.win.MutationObserver || this.win.WebKitMutationObserver;

    var lastTitle = '';
    var lastArtist = '';
    var lastAlbum = '';

    var addObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        for (var i = 0; i < m.addedNodes.length; i++) {
          var target = m.addedNodes[i];
          var name = target.id || target.className;

          if (name === 'text-wrapper')  {
            var title = that.doc.querySelector('#playerSongTitle');
            var artist = that.doc.querySelector('#player-artist');
            var album = that.doc.querySelector('.player-album');
            var art = that.doc.querySelector('#playingAlbumArt');
            var duration = parseInt(that.doc.querySelector('#player #slider').getAttribute('aria-valuemax'), 10) / 1000;

            title = (title) ? title.innerText : 'Unknown';
            artist = (artist) ? artist.innerText : 'Unknown';
            album = (album) ? album.innerText : 'Unknown';
            art = (art) ? art.src : null;

            // The art may be a protocol-relative URL, so normalize it to HTTPS
            if (art && art.slice(0, 2) === '//') {
              art = 'https:' + art;
            }

            // Make sure that this is the first of the notifications for the
            // insertion of the song information elements.
            if (lastTitle !== title || lastArtist !== artist || lastAlbum !== album) {
              that.win.GoogleMusicApp.notifySong(title, artist, album, art, duration);

              lastTitle = title;
              lastArtist = artist;
              lastAlbum = album;
            }
          }
        }
      });
    });

    var shuffleObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'shuffle') {
          that.win.GoogleMusicApp.shuffleChanged(target.value);
        }
      });
    });

    var repeatObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'repeat') {
          that.win.GoogleMusicApp.repeatChanged(target.value);
        }
      });
    });

    var playbackObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'play-pause') {
          var mode;
          var playing = target.classList.contains('playing');

          if (playing) {
            mode = GoogleMusic.Playback.PLAYING;
          } else {
            // If there is a current song, then the player is paused
            if (that.doc.querySelector('#playerSongInfo').childNodes.length) {
              mode = GoogleMusic.Playback.PAUSED;
            } else {
              mode = GoogleMusic.Playback.STOPPED;
            }
          }

          that.win.GoogleMusicApp.playbackChanged(mode);
        }
      });
    });

    var playbackTimeObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.id;

        if (id === 'slider') {
          var currentTime = parseInt(target.getAttribute('aria-valuenow'), 10);
          var totalTime = parseInt(target.getAttribute('aria-valuemax'), 10);
          that.win.GoogleMusicApp.playbackTimeChanged(currentTime, totalTime);
        }
      });
    });

    var ratingObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;

        if (target.classList.contains('selected')) {
          that.win.GoogleMusicApp.ratingChanged(target.dataset.rating);
        }
      });
    });

    addObserver.observe(this.doc.querySelector('#playerSongInfo'), {
      childList: true,
      subtree: true
    });
    shuffleObserver.observe(this.doc.querySelector('#player button[data-id="shuffle"]'), {
      attributes: true
    });
    repeatObserver.observe(this.doc.querySelector('#player button[data-id="repeat"]'), {
      attributes: true
    });
    playbackObserver.observe(this.doc.querySelector('#player button[data-id="play-pause"]'), {
      attributes: true
    });
    playbackTimeObserver.observe(this.doc.querySelector('#player #slider'), {
      attributes: true
    });
    ratingObserver.observe(this.doc.querySelector('#player .player-rating-container'), {
      attributes: true,
      subtree: true
    });
  }
};

// Export our constructor
module.exports = GoogleMusic;
<commit_msg>Moving to event emitter for inheritance<commit_after>// Load in dependencies
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Keyboard = require('./keyboard');
var Mouse = require('./mouse');

// Define bind method
function bind(context, fn) {
  return function bindFn () {
    return fn.apply(context, arguments);
  };
}

// Define our constructor
function GoogleMusic(win) {
  // If win was not provided, complain
  if (!win) {
    throw new Error('`win` was not provided to the `GoogleMusic` constructor');
  }

  // Inherit from EventEmitter
  EventEmitter.call(this);

  // Localize reference to window and document
  this.win = win;
  this.doc = win.document;

  // Initialize a keyboard and mouse
  this.keyboard = new Keyboard(win);
  this.mouse = new Mouse(win);

  // For each of the prototype sections
  var proto = GoogleMusic._protoObj;
  for (var protoKey in proto) {
    if (proto.hasOwnProperty(protoKey)) {
      // Define a key on our object
      this[protoKey] = {};

      // For each of the keys on the section, define a function that invokes on this original context
      var section = proto[protoKey];
      for (var sectionKey in section) {
        if (section.hasOwnProperty(sectionKey)) {
          this[protoKey][sectionKey] = bind(this, section[sectionKey]);
        }
      }

      // If there was an `init` method, run it
      if (this[protoKey].init) {
        this[protoKey].init();
      }
    }
  }
}
// Inherit from EventEmitter normally
util.inherits(GoogleMusic, EventEmitter);

// Define a "prototype" that will have magical invocation
var proto = GoogleMusic._protoObj = {};

// Create a volume API
proto.volume = {
  // Query required elements
  init: function () {
    this.volume._sliderEl = this.doc.querySelector('#vslider');
  },

  // Get the current volume level.
  getVolume: function () {
    return parseInt(this.volume._sliderEl.getAttribute('aria-valuenow'), 10);
  },

  // Set the volume level (0 - 100).
  setVolume: function (vol) {
    var current = this.volume.getVolume();

    if (vol > current) {
      this.volume.increaseVolume(vol - current);
    } else if (vol < current) {
      this.volume.decreaseVolume(current - vol);
    }
  },

  // Increase the volume by an amount (default of 1)
  increaseVolume: function (amount) {
    if (amount === undefined) {
      amount = 1;
    }

    for (var i = 0; i < amount; i++) {
      this.keyboard.sendKey(this.volume._sliderEl, Keyboard.KEY_UP);
    }
  },

  // Decrease the volume by an amount (default of 1)
  decreaseVolume: function (amount) {
    if (amount === undefined) {
      amount = 1;
    }

    for (var i = 0; i < amount; i++) {
      this.keyboard.sendKey(this.volume._sliderEl, Keyboard.KEY_DOWN);
    }
  }
};

// Create a playback API and constants
GoogleMusic.Playback = {
  // Playback states
  STOPPED: 0,
  PAUSED: 1,
  PLAYING: 2,

  // Repeat modes
  LIST_REPEAT: 'LIST_REPEAT',
  SINGLE_REPEAT: 'SINGLE_REPEAT',
  NO_REPEAT: 'NO_REPEAT',

  // Shuffle modes
  ALL_SHUFFLE: 'ALL_SHUFFLE',
  NO_SHUFFLE: 'NO_SHUFFLE'
};
proto.playback = {
  // Query references to the media playback elements
  init: function () {
    this.playback._sliderEl = this.doc.getElementById('slider');
    this.playback._playPauseEl = this.doc.querySelector('button[data-id="play-pause"]');
    this.playback._forwardEl = this.doc.querySelector('button[data-id="forward"]');
    this.playback._rewindEl = this.doc.querySelector('button[data-id="rewind"]');
    this.playback._shuffleEl = this.doc.querySelector('button[data-id="shuffle"]');
    this.playback._repeatEl = this.doc.querySelector('button[data-id="repeat"]');
  },

  // Time functions
  getPlaybackTime: function () {
    return parseInt(this.playback._sliderEl.getAttribute('aria-valuenow'), 10);
  },

  setPlaybackTime: function (milliseconds) {
    var percent = milliseconds / parseFloat(this.playback._sliderEl.getAttribute('aria-valuemax'));
    var lower = this.playback._sliderEl.offsetLeft + 6;
    var upper = this.playback._sliderEl.offsetLeft + this.playback._sliderEl.clientWidth - 6;
    var x = lower + percent * (upper - lower);

    this.mouse.clickAtLocation(this.playback._sliderEl, x, 0);
  },

  // Playback functions
  playPause: function () { this.playback._playPauseEl.click(); },
  forward: function () { this.playback._forwardEl.click(); },
  rewind: function () { this.playback._rewindEl.click(); },

  getShuffle: function () { return this.playback._shuffleEl.value; },
  toggleShuffle: function () { this.playback._shuffleEl.click(); },

  getRepeat: function () {
    return this.playback._repeatEl.value;
  },

  changeRepeat: function (mode) {
    if (!mode) {
      // Toggle between repeat modes once
      this.playback._repeatEl.click();
    } else {
      // Toggle between repeat modes until the desired mode is activated
      while (this.playback.getRepeat() !== mode) {
        this.playback._repeatEl.click();
      }
    }
  },

  // Taken from the Google Play Music page
  toggleVisualization: function () {
    this.win.SJBpost('toggleVisualization');
  }
};

// Create a rating API
proto.rating = {
  // Determine whether the rating system is thumbs or stars
  isStarsRatingSystem: function () {
    return this.doc.querySelector('.rating-container.stars') !== null;
  },

  // Get current rating
  getRating: function () {
    var el = this.doc.querySelector('.player-rating-container li.selected');

    if (el) {
      return el.getAttribute('data-rating');
    } else {
      return 0;
    }
  },

  // Thumbs up
  toggleThumbsUp: function () {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="5"]');

    if (el) {
      el.click();
    }
  },

  // Thumbs down
  toggleThumbsDown: function () {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="1"]');

    if (el) {
      el.click();
    }
  },

  // Set a star rating
  setStarRating: function (rating) {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="' + rating + '"]');

    if (el) {
      el.click();
    }
  }
};

// Miscellaneous functions
proto.extras = {
  // Get a shareable URL of the song on Google Play Music
  getSongURL: function () {
    var albumEl = this.doc.querySelector('.player-album');
    var artistEl = this.doc.querySelector('.player-artist');

    var urlTemplate = 'https://play.google.com/music/m/';
    var url = null;

    var parseID = function (id) {
      return id.substring(0, id.indexOf('/'));
    };

    if (albumEl === null && artistEl === null) {
      return null;
    }

    var albumId = parseID(albumEl.dataset.id);
    var artistId = parseID(artistEl.dataset.id);

    if (albumId) {
      url = urlTemplate + albumId;
    } else if (artistId) {
      url = urlTemplate + artistId;
    }

    return url;
  }
};

proto.hooks = {
  init: function () {
    // Save context for bindings
    var that = this;

    // Define mutation observer for reuse
    var MutationObserver = this.win.MutationObserver || this.win.WebKitMutationObserver;

    var lastTitle = '';
    var lastArtist = '';
    var lastAlbum = '';

    var addObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        for (var i = 0; i < m.addedNodes.length; i++) {
          var target = m.addedNodes[i];
          var name = target.id || target.className;

          if (name === 'text-wrapper')  {
            var title = that.doc.querySelector('#playerSongTitle');
            var artist = that.doc.querySelector('#player-artist');
            var album = that.doc.querySelector('.player-album');
            var art = that.doc.querySelector('#playingAlbumArt');
            var duration = parseInt(that.doc.querySelector('#player #slider').getAttribute('aria-valuemax'), 10) / 1000;

            title = (title) ? title.innerText : 'Unknown';
            artist = (artist) ? artist.innerText : 'Unknown';
            album = (album) ? album.innerText : 'Unknown';
            art = (art) ? art.src : null;

            // The art may be a protocol-relative URL, so normalize it to HTTPS
            if (art && art.slice(0, 2) === '//') {
              art = 'https:' + art;
            }

            // Make sure that this is the first of the notifications for the
            // insertion of the song information elements.
            if (lastTitle !== title || lastArtist !== artist || lastAlbum !== album) {
              that.win.GoogleMusicApp.notifySong(title, artist, album, art, duration);

              lastTitle = title;
              lastArtist = artist;
              lastAlbum = album;
            }
          }
        }
      });
    });

    var shuffleObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'shuffle') {
          that.win.GoogleMusicApp.shuffleChanged(target.value);
        }
      });
    });

    var repeatObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'repeat') {
          that.win.GoogleMusicApp.repeatChanged(target.value);
        }
      });
    });

    var playbackObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'play-pause') {
          var mode;
          var playing = target.classList.contains('playing');

          if (playing) {
            mode = GoogleMusic.Playback.PLAYING;
          } else {
            // If there is a current song, then the player is paused
            if (that.doc.querySelector('#playerSongInfo').childNodes.length) {
              mode = GoogleMusic.Playback.PAUSED;
            } else {
              mode = GoogleMusic.Playback.STOPPED;
            }
          }

          that.win.GoogleMusicApp.playbackChanged(mode);
        }
      });
    });

    var playbackTimeObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.id;

        if (id === 'slider') {
          var currentTime = parseInt(target.getAttribute('aria-valuenow'), 10);
          var totalTime = parseInt(target.getAttribute('aria-valuemax'), 10);
          that.win.GoogleMusicApp.playbackTimeChanged(currentTime, totalTime);
        }
      });
    });

    var ratingObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;

        if (target.classList.contains('selected')) {
          that.win.GoogleMusicApp.ratingChanged(target.dataset.rating);
        }
      });
    });

    addObserver.observe(this.doc.querySelector('#playerSongInfo'), {
      childList: true,
      subtree: true
    });
    shuffleObserver.observe(this.doc.querySelector('#player button[data-id="shuffle"]'), {
      attributes: true
    });
    repeatObserver.observe(this.doc.querySelector('#player button[data-id="repeat"]'), {
      attributes: true
    });
    playbackObserver.observe(this.doc.querySelector('#player button[data-id="play-pause"]'), {
      attributes: true
    });
    playbackTimeObserver.observe(this.doc.querySelector('#player #slider'), {
      attributes: true
    });
    ratingObserver.observe(this.doc.querySelector('#player .player-rating-container'), {
      attributes: true,
      subtree: true
    });
  }
};

// Export our constructor
module.exports = GoogleMusic;
<|endoftext|>


<commit_before>const assert = require('assert');
const configMergeLoader = require('../index.js');
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const rimraf = require('rimraf');

describe('Config Merge Loader', function() {
  it('should return a function', function() {
    assert.equal(typeof configMergeLoader, 'function');
  });

  describe('when called via webpack', function() {
    beforeEach(function(done) {
      rimraf(path.resolve(__dirname, 'dist/entry.js'), function(err) {
        if (err) { return done(err); }

        done();
      });
    });

    const options = {
      entry: path.resolve(__dirname, 'cases/test.js'),
      target: 'node',
      output: {
        filename: 'entry.js',
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'commonjs2'
      },
      resolveLoader: {
        alias: {
          'config-merge-loader': path.resolve(__dirname, '../', 'index.js')
        }
      },
      module: {
        rules: [
          {
            test: /\.json$/, use: 'json-loader'
          },
          {
            test: /base\.json$/,
            use: [
              {
                loader: 'config-merge-loader',
                query: {
                  override: 'override.json'
                }
              }
            ]
          }
        ]
      }
    };

    const compile = webpack(options);

    it('should generate an entry.js file', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        assert.ok(fs.existsSync(path.resolve(__dirname, 'dist/entry.js')));
        done();
      });
    });

    it('should compile without errors', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        assert.ok(stats.hasErrors() === false);
        done();
      });
    });

    it('base.js should provide properly merged results', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        const modules = stats.toJson('normal').modules;
        const moduleIndex = modules.findIndex(function(module) {
          return module.name === './test/cases/lib/base.json';
        });
        const moduleSource = modules[moduleIndex].source;
        const expectedSource = 'module.exports = {\n\t"a": 2,\n\t"b": ' +
          '{\n\t\t"a": 2,\n\t\t"b": 1\n\t},\n\t"c": 1\n};';

        assert.equal(moduleSource, expectedSource);
        done();
      });
    });
  });

  describe('when chained with yaml-loader', function() {
    beforeEach(function(done) {
      rimraf(path.resolve(__dirname, 'dist/entry-yaml.js'), function(err) {
        if (err) { return done(err); }

        done();
      });
    });

    const options = {
      entry: path.resolve(__dirname, 'cases/test-yaml.js'),
      target: 'node',
      output: {
        filename: 'entry-yaml.js',
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'commonjs2'
      },
      resolveLoader: {
        alias: {
          'config-merge-loader': path.resolve(__dirname, '../', 'index.js')
        }
      },
      module: {
        rules: [
          {
            test: /\.yml$/, use: [
              { loader: 'json-loader' },
              { loader: 'yaml-loader' }
            ]
          },
          {
            test: /base\.yml$/,
            use: [
              {
                loader: 'config-merge-loader',
                query: {
                  override: 'override.yml'
                }
              },
              { loader: 'yaml-loader' }
            ]
          }
        ]
      }
    };

    const compile = webpack(options);

    it('should generate an entry-yaml.js file', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        assert.ok(fs.existsSync(path.resolve(__dirname, 'dist/entry-yaml.js')));
        done();
      });
    });

    it('should compile without errors', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        assert.ok(stats.hasErrors() === false);
        done();
      });
    });

    it('base.js should provide properly merged results', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        const modules = stats.toJson('normal').modules;
        const moduleIndex = modules.findIndex(function(module) {
          return module.name === './test/cases/lib/base.yml';
        });
        const moduleSource = modules[moduleIndex].source;
        const expectedSource = 'module.exports = {\n\t"a": 2,\n\t"b": ' +
          '{\n\t\t"a": 2,\n\t\t"b": 1\n\t},\n\t"c": 1\n};';

        assert.equal(moduleSource, expectedSource);
        done();
      });
    });
  });
});
<commit_msg>Add test for namespaced objects<commit_after>const assert = require('assert');
const configMergeLoader = require('../index.js');
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const rimraf = require('rimraf');

describe('Config Merge Loader', function() {
  it('should return a function', function() {
    assert.equal(typeof configMergeLoader, 'function');
  });

  describe('when called via webpack', function() {
    beforeEach(function(done) {
      rimraf(path.resolve(__dirname, 'dist/entry.js'), function(err) {
        if (err) { return done(err); }

        done();
      });
    });

    const options = {
      entry: path.resolve(__dirname, 'cases/test.js'),
      target: 'node',
      output: {
        filename: 'entry.js',
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'commonjs2'
      },
      resolveLoader: {
        alias: {
          'config-merge-loader': path.resolve(__dirname, '../', 'index.js')
        }
      },
      module: {
        rules: [
          {
            test: /\.json$/, use: 'json-loader'
          },
          {
            test: /base\.json$/,
            use: [
              {
                loader: 'config-merge-loader',
                query: {
                  override: 'override.json'
                }
              }
            ]
          }
        ]
      }
    };

    const compile = webpack(options);

    it('should generate an entry.js file', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        assert.ok(fs.existsSync(path.resolve(__dirname, 'dist/entry.js')));
        done();
      });
    });

    it('should compile without errors', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        assert.ok(stats.hasErrors() === false);
        done();
      });
    });

    it('base.js should provide properly merged results', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        const modules = stats.toJson('normal').modules;
        const moduleIndex = modules.findIndex(function(module) {
          return module.name === './test/cases/lib/base.json';
        });
        const moduleSource = modules[moduleIndex].source;
        const expectedSource = 'module.exports = {\n\t"a": 2,\n\t"b": ' +
          '{\n\t\t"a": 2,\n\t\t"b": 1\n\t},\n\t"c": 1\n};';

        assert.equal(moduleSource, expectedSource);
        done();
      });
    });
  });

  describe('when chained with yaml-loader', function() {
    beforeEach(function(done) {
      rimraf(path.resolve(__dirname, 'dist/entry-yaml.js'), function(err) {
        if (err) { return done(err); }

        done();
      });
    });

    const options = {
      entry: path.resolve(__dirname, 'cases/test-yaml.js'),
      target: 'node',
      output: {
        filename: 'entry-yaml.js',
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'commonjs2'
      },
      resolveLoader: {
        alias: {
          'config-merge-loader': path.resolve(__dirname, '../', 'index.js')
        }
      },
      module: {
        rules: [
          {
            test: /\.yml$/, use: [
              { loader: 'json-loader' },
              { loader: 'yaml-loader' }
            ]
          },
          {
            test: /base\.yml$/,
            use: [
              {
                loader: 'config-merge-loader',
                query: {
                  override: 'override.yml'
                }
              },
              { loader: 'yaml-loader' }
            ]
          }
        ]
      }
    };

    const compile = webpack(options);

    it('should generate an entry-yaml.js file', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        assert.ok(fs.existsSync(path.resolve(__dirname, 'dist/entry-yaml.js')));
        done();
      });
    });

    it('should compile without errors', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        assert.ok(stats.hasErrors() === false);
        done();
      });
    });

    it('base.js should provide properly merged results', function(done) {
      compile.run(function(err, stats) {
        if(err) return done(err);

        const modules = stats.toJson('normal').modules;
        const moduleIndex = modules.findIndex(function(module) {
          return module.name === './test/cases/lib/base.yml';
        });
        const moduleSource = modules[moduleIndex].source;
        const expectedSource = 'module.exports = {\n\t"a": 2,\n\t"b": ' +
          '{\n\t\t"a": 2,\n\t\t"b": 1\n\t},\n\t"c": 1\n};';

        assert.equal(moduleSource, expectedSource);
        done();
      });
    });
  });

  describe('when supplied name spaces', function() {
    beforeEach(function(done) {
      rimraf(path.resolve(__dirname, 'dist/entry-yaml.js'), function(err) {
        if (err) { return done(err); }

        done();
      });
    });

    const options = {
      entry: path.resolve(__dirname, 'cases/test-yaml.js'),
      target: 'node',
      output: {
        filename: 'entry-yaml.js',
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'commonjs2'
      },
      resolveLoader: {
        alias: {
          'config-merge-loader': path.resolve(__dirname, '../', 'index.js')
        }
      },
      module: {
        rules: [
          {
            test: /\.yml$/, use: [
              { loader: 'json-loader' },
              { loader: 'yaml-loader' }
            ]
          },
          {
            test: /base\-namespaced\.yml$/,
            use: [
              {
                loader: 'config-merge-loader',
                query: {
                  defaultNamespace: 'locale',
                  override: 'override-namespaced.yml',
                  overrideNamespace: 'override'
                }
              },
              { loader: 'yaml-loader' }
            ]
          }
        ]
      }
    };

    const compile = webpack(options);
    it('should merge the properties under the name space and apply them to ' +
      'the default namespace', function(done) {
      if (err) { return done(err); }

      const modules = stats.toJson('normal').modules;
      const moduleIndex = modules.findIndex(function(module) {
        return module.name === './test/cases/lib/base.yml';
      });
      const moduleSource = modules[moduleIndex].source;
      const expectedSource = 'module.exports = {\n\t "locale": {\n\t\t"a": 2,' +
        '\n\t\t"b": {\n\t\t\t"a": 2,\n\t\t\t"b": 1\n\t\t},\n\t\t"c": 1\n\t}\n};';

      assert.equal(moduleSource, expectedSource);

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


<commit_before>
window.onload = function() {
  var jscode = document.getElementById("jscode");
  if (location.hash.length > 1) {
    try {
      var code = atob(location.hash.slice(1))
    } catch(e) {
      // presumable b64 error
      var code = location.hash.slice(1);
    }
    jscode.value = code;
  }

  // Add event listener on generate-button
  var btnGenerate = document.getElementById("btnGenerate");
  btnGenerate.addEventListener("click", function() {
    var jscode = document.getElementById("jscode");
    if (jscode.value != "") {
      try {
      var ast = esprima.parse(jscode.value);
      } catch(e) {
        alert("Error when parsing source code: " + e.message)
      }
      var g = new BasicBlockView(ast);
      //window.g = g;
      var svg = Viz(g.toDot(), 'svg');
      var svgarea = document.getElementById("svgarea");
      svgarea.innerHTML = svg;
      // Ugliest hack to rewrite SVG file so the text is perfectly aligned. I feel bad..a bit :-)
      alignSvg(svgarea.children[0]);
    }
  });
  document.getElementById('files').addEventListener('change', handleFile, false);
};

 function handleFile(evt) {
    var files = evt.target.files;
    for (var i = 0, f; f = files[i]; i++) {
      if (!f.type.match('text.*')) {
        console.log("Skipped invalid file format " + f.type );
        continue;
      }

      var reader = new FileReader();
      reader.onload = (function(aFile) {
        return function(aEvt) {
          document.getElementById("jscode").value = aEvt.target.result;
        };
      })(f);
      reader.readAsText(f);

      //console.log("Stopping after first file..");
      break;
    }
 }

function alignSvg(svgTree) {
    var iter = document.createNodeIterator(svgTree, NodeFilter.SHOW_ALL, null, false);
    var node;
    while (node = iter.nextNode()) {
      if (node.nodeType == Node.ELEMENT_NODE) {
        if ( node.id.startsWith("node")) {
          // An element with an id like "node1", and so forth is a code block
          if ((node.children.length > 2)&& (node.children[1].tagName == "polygon")) {
            var pointsArr = node.children[1].getAttribute("points").split(" ");
            var minp = Infinity;
            // for x,y in points. take min x value above zero. round and add +5.
            // for all text children: take this value for x, and .removeAttribute("text-anchor")
            for (var pNo in pointsArr) {
              var tp = pointsArr[pNo];
              var po = tp.split(",");
              var x = parseInt(po[0]);
              // var y = po[1]; // never used
              if ((x < minp) && (x > -1)) { minp = x; }
            }
            var newX = Math.round(minp) + 5;
            for (var cNo in node.children) {
              var cn = node.children[cNo];
              if (cn.tagName == "text") {
                cn.removeAttribute("text-anchor");
                cn.setAttribute("x", newX);
            }
          }
        }
      }
    }
  }

}<commit_msg>added file format for JS -.-<commit_after>
window.onload = function() {
  var jscode = document.getElementById("jscode");
  if (location.hash.length > 1) {
    try {
      var code = atob(location.hash.slice(1))
    } catch(e) {
      // presumable b64 error
      var code = location.hash.slice(1);
    }
    jscode.value = code;
  }

  // Add event listener on generate-button
  var btnGenerate = document.getElementById("btnGenerate");
  btnGenerate.addEventListener("click", function() {
    var jscode = document.getElementById("jscode");
    if (jscode.value != "") {
      try {
      var ast = esprima.parse(jscode.value);
      } catch(e) {
        alert("Error when parsing source code: " + e.message)
      }
      var g = new BasicBlockView(ast);
      //window.g = g;
      var svg = Viz(g.toDot(), 'svg');
      var svgarea = document.getElementById("svgarea");
      svgarea.innerHTML = svg;
      // Ugliest hack to rewrite SVG file so the text is perfectly aligned. I feel bad..a bit :-)
      alignSvg(svgarea.children[0]);
    }
  });
  document.getElementById('files').addEventListener('change', handleFile, false);
};

 function handleFile(evt) {
    var files = evt.target.files;
    for (var i = 0, f; f = files[i]; i++) {
      if ((!f.type.match('text.*')) && (!f.type.match("application.*"))) {
        console.log("Skipped invalid file format " + f.type );
        continue;
      }

      var reader = new FileReader();
      reader.onload = (function(aFile) {
        return function(aEvt) {
          document.getElementById("jscode").value = aEvt.target.result;
        };
      })(f);
      reader.readAsText(f);

      //console.log("Stopping after first file..");
      break;
    }
 }

function alignSvg(svgTree) {
    var iter = document.createNodeIterator(svgTree, NodeFilter.SHOW_ALL, null, false);
    var node;
    while (node = iter.nextNode()) {
      if (node.nodeType == Node.ELEMENT_NODE) {
        if ( node.id.startsWith("node")) {
          // An element with an id like "node1", and so forth is a code block
          if ((node.children.length > 2)&& (node.children[1].tagName == "polygon")) {
            var pointsArr = node.children[1].getAttribute("points").split(" ");
            var minp = Infinity;
            // for x,y in points. take min x value above zero. round and add +5.
            // for all text children: take this value for x, and .removeAttribute("text-anchor")
            for (var pNo in pointsArr) {
              var tp = pointsArr[pNo];
              var po = tp.split(",");
              var x = parseInt(po[0]);
              // var y = po[1]; // never used
              if ((x < minp) && (x > -1)) { minp = x; }
            }
            var newX = Math.round(minp) + 5;
            for (var cNo in node.children) {
              var cn = node.children[cNo];
              if (cn.tagName == "text") {
                cn.removeAttribute("text-anchor");
                cn.setAttribute("x", newX);
            }
          }
        }
      }
    }
  }

}<|endoftext|>


<commit_before>/* ========================================================= ***/
/** ================== INCLUDE NEEDED MODULES =============== **/
/*** ========================================================= */
var http = require("http");

/* ========================================================= ***/
/** ================= ENDPOINT WIDE FUNCTIONS =============== **/
/*** ========================================================= */

//simular to SQL LIMIT
var page = function(num, qty){
    if(typeof qty != "undefined"){
        return this.filter("per_page", qty).filter("page", num);
    }
    else{
        return this.filter("page", num);
    }
}

//simular to SQL ORDER BY
var order = function(field, dir){

    if(arguments.length<0){
        throw new Error("MUST SUPPLY AT LEAST ONE ARGUMENT TO SELECT");
    }

    if(typeof field === "string"){

        if(typeof dir == "undefined"){
            dir = "desc";
        }

        dir = dir.toLowerCase();

        if(dir!="desc"&&dir!="asc"){
            throw new Error("ORDER DIRECTION CAN MUST BE desc or asc");
        }

        return this.filter("order", field+"__"+dir);
    }
    else {
        for(var i=0; i<arguments.length; i++){

            var arg = arguments[i];

            var field = "";
            var direction = "";

            if(Object.prototype.toString.call( arg ) == '[object Array]'){
                field = arg[0];
                direction = arg[1];
            }
            else if(Object.prototype.toString.call( arg ) == '[object Object]'){
                field = arg.field;
                direction = arg.direction;
            }
            else{
                throw new Error("INVALID ARGUMENT ON ORDER");
            }

            this.filter("order", field+"__"+direction);

        }
        return this;
    }

}

var fields = function(){
    if(arguments.length<0){
        throw new Error("MUST SUPPLY AT LEAST ONE ARGUMENT TO SELECT");
    }

    for(var i=0; i<arguments.length; i++){
        this.filter("fields", arguments[i]);
    }

    return this;
}

/* =================================================================== */

//Global add parms function, also used directly to currate the where clause
var filter = function(field, value, operator){

    if(typeof operator != "undefined" && operator != "="){
        if(field!="order"){
            operatorCheck(operator);
            field = field+"__"+operator;
        }
        else if(operator=="asc"||operator=="desc"){
            value = value+"__"+operator;
        }
        else{
            throw new Error("("+operator+") is not a valid operator for "+field);
        }
    }

    //UNSET A FILTER
    if(value==null && typeof this.queryObj[field] != "undefined"){
        this.queryObj[field] = undefined;
    }
    //ADD TO A LIST FILTER
    else if(field=="fields"||field=="order"){
        var list = [];

        if(typeof this.queryObj[field] != "undefined"){
            list = this.queryObj[field];
        }

        list[list.length] = value;

        this.queryObj[field] = list;
    }
    //SET/OVERWRITE A SIMPLE FILTER
    else{
        this.queryObj[field] = value;
    }

	return this;
}

//CONFIRM THAT THE OPERATOR IS VALID
var operatorCheck = function(operator){
    if(false){
        throw new Error("NEED ERROR MESSAGE");
    }
}

//CALL OUT TO THE API
var call = function(callback, fail){
	keyCheck(this.apikey);

    //passed object
    if(typeof callback == "object"){
        fail = callback.fail;
        callback = callback.callback;
    }

    //passed a new callback function
    if(typeof callback != "undefined"){
        this.success = callback;
    }
    //didn't pass a new call back function, use old one
    else if(typeof this.success != "undefined"){
        callback = this.success;
    }
    //AH! no callback
    else{
        throw new Error("YOU MUST DEFINED A SUCCESS FUNTION BEFORE PERFORMING CALL");
    }

    //passed a new failure function
	if(typeof failure != "undefined"){
		this.failure = fail;
	}
    //didn't pass a new failure function
    else if(typeof this.failure != "undefined"){
        fail = this.failure;
    }
    //AH! no failure function. Lets fail! HA!
    else{
        throw new Error("YOU MUST DEFINED A FAILRE FUNTION BEFORE PERFORMING CALL");
    }

    this.query = queryString(this.queryObj);
    var endpoint = basepoint+this.collection+"/?apikey="+this.apikey+this.query

    //console.log(endpoint);

	http.get(endpoint, function(res){
		var data = "";
		res.on("data", function(chunk){
			data+=chunk;
		});
		res.on("end", function(){
            data = JSON.parse(data);
            data.status = "success";
            data.error = undefined;
			callback(data);
		})
	}).on("error", function(e){
        var data = {
            status: "error",
            error: e,
            results: []
        }
        fail(data);
    });
}

var setKey = function(key){
    if(typeof key != "undefined"){
        this.apikey = key;
    }
}

/* ========================================================= ***/
/** ==================== BASIC OBJECT DATA ================== **/
/*** ========================================================= */

var basepoint = "http://congress.api.sunlightfoundation.com/";
var baseObj = {

    //BASE DATA
	apikey : undefined,
	collection: "",
	query: "",
    queryObj: {}, //used to stage

    //CORE FUNCTIONS
	call: call,
	setKey: setKey,
	filter: filter,
    page: page,
    order: order,
    fields: fields,

    //CALLBACK FUNCTIONS
    success: undefined,
    failure: function(data){
        console.log("ERROR: "+data.error.message);
    }
}

/* ========================================================= ***/
/** ==================== BACKEND UTILITIES ================== **/
/*** ========================================================= */

//CONFIRM THAT THE APIKEY HAS BEEN SET
var keyCheck = function(key){
    if(key==undefined){
        throw new Error("YOU MUST USE INIT TO DEFINE YOUR SUNLIGHT FONDATION API KEY!");
    }
}

var queryString = function(query){
    var baseuri = "";
    var keys = Object.keys(query);

    for(var i=0; i<keys.length; i++){
        var key = keys[i];
        var value = query[key];
        baseuri += "&"+key+"="+value;
    }

    return baseuri;
}

/* ========================================================= ***/
/** ====================== THE GRAND INIT =================== **/
/*** ========================================================= */

//INIT THE MODULE WITH YOU SUNLIGHT FUNDATION KEY
module.exports.init = function(slk){
	baseObj.apikey = slk;
}

/* ========================================================= ***/
/** ========================= ENDPOINTS ===================== **/
/*** ========================================================= */

/* =============================================== **
** DOCS: http://sunlightlabs.github.com/congress/  **
** =============================================== */

//Roll call votes in Congress, back to 2009. Updated within minutes of votes.
module.exports.votes = function(slk){

	var obj = extend(true, {}, baseObj);
	obj.setKey(slk);
	obj.collection = "votes";

	return obj;
}

//Committee hearings in Congress. Updated as hearings are announced.
module.exports.hearings = function(slk){

	var obj = extend(true, {}, baseObj);
	obj.setKey(slk);
	obj.collection = "hearings";

	return obj;
}

//To-the-minute updates from the floor of the House and Senate.
module.exports.floorUpdates = function(slk){

	var obj = extend(true, {}, baseObj);
	obj.setKey(slk);
	obj.collection = "floor_updates";

	return obj;
}

//Legislation in the House and Senate, back to 2009. Updated daily.
module.exports.bills  = function(slk){

	var obj = extend(true, {}, baseObj);
	obj.setKey(slk);
	obj.collection = "bills";

	return obj;
}

//Full text search over legislation.
module.exports.billsSearch  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "bills/search";

    return obj;
}

//Current legislators' names, IDs, biography, and social media.
module.exports.legislators  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "legislators";

    return obj;
}

//Find representatives and senators for a latitude/longitude or zip.
module.exports.legislatorsLocate  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "legislators/locate";

    return obj;
}

//Find congressional districts for a latitude/longitude or zip
module.exports.districtsLocate  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "districts/locate";

    return obj;
}

//Current committees, subcommittees, and their membership.
module.exports.committees  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "committees";

    return obj;
}

//Bills scheduled for debate in the future, as announced by party leadership.
module.exports.upcomingBills  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "upcoming_bills";

    return obj;
}

/* ========================================================= ***/
/** =================== JQUERY EXTEND PORT ================== **/
/*** ========================================================= */

/* =============================================================================================== **
** Suggested By: http://stackoverflow.com/questions/9399365/deep-extend-like-jquerys-for-nodejs    **
** From: https://github.com/jquery/jquery/blob/master/src/core.js                                  **
** =============================================================================================== */

function extend() {
    var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {},
    i = 1,
    length = arguments.length,
    deep = false,
    toString = Object.prototype.toString,
    hasOwn = Object.prototype.hasOwnProperty,
    push = Array.prototype.push,
    slice = Array.prototype.slice,
    trim = String.prototype.trim,
    indexOf = Array.prototype.indexOf,
    class2type = {
        "[object Boolean]": "boolean",
        "[object Number]": "number",
        "[object String]": "string",
        "[object Function]": "function",
        "[object Array]": "array",
        "[object Date]": "date",
        "[object RegExp]": "regexp",
        "[object Object]": "object"
    },
    jQuery = {
        isFunction: function (obj) {
            return jQuery.type(obj) === "function"
        },
        isArray: Array.isArray ||
        function (obj) {
            return jQuery.type(obj) === "array"
        },
        isWindow: function (obj) {
            return obj != null && obj == obj.window
        },
        isNumeric: function (obj) {
            return !isNaN(parseFloat(obj)) && isFinite(obj)
        },
        type: function (obj) {
            return obj == null ? String(obj) : class2type[toString.call(obj)] || "object"
        },
        isPlainObject: function (obj) {
            if (!obj || jQuery.type(obj) !== "object" || obj.nodeType) {
              	return false
            }
            try {
              	if (obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
                	return false
              	}
            }
            catch (e) {
      	        return false
            }
            var key;
            for (key in obj) {}
            return key === undefined || hasOwn.call(obj, key)
        }
    };
    if (typeof target === "boolean") {
    	deep = target;
    	target = arguments[1] || {};
        i = 2;
    }
    if (typeof target !== "object" && !jQuery.isFunction(target)) {
    	target = {}
    }
    if (length === i) {
        target = this;
    	--i;
    }
    for (i; i < length; i++) {
        if ((options = arguments[i]) != null) {
          	for (name in options) {
            	src = target[name];
            	copy = options[name];
            	if (target === copy) {
              		continue
            	}
            	if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
              		if (copyIsArray) {
                		copyIsArray = false;
                		clone = src && jQuery.isArray(src) ? src : []
              		} else {
                		clone = src && jQuery.isPlainObject(src) ? src : {};
              		}
              		// WARNING: RECURSION
              		target[name] = extend(deep, clone, copy);
            	}
            	else if (copy !== undefined) {
              		target[name] = copy;
            	}
        	}
        }
    }
    return target;
}<commit_msg>Tweaked error messages and fixed typos<commit_after>/* ========================================================= ***/
/** ================== INCLUDE NEEDED MODULES =============== **/
/*** ========================================================= */
var http = require("http");

/* ========================================================= ***/
/** ================= ENDPOINT WIDE FUNCTIONS =============== **/
/*** ========================================================= */

//simular to SQL LIMIT
var page = function(num, qty){
    if(typeof qty != "undefined"){
        return this.filter("per_page", qty).filter("page", num);
    }
    else{
        return this.filter("page", num);
    }
}

//simular to SQL ORDER BY
var order = function(field, dir){

    if(arguments.length<0){
        throw new Error("MUST SUPPLY AT LEAST ONE ARGUMENT");
    }

    if(typeof field === "string"){

        if(typeof dir == "undefined"){
            dir = "desc";
        }

        dir = dir.toLowerCase();

        if(dir!="desc"&&dir!="asc"){
            throw new Error("ORDER DIRECTION MUST BE desc or asc");
        }

        return this.filter("order", field+"__"+dir);
    }
    else {
        for(var i=0; i<arguments.length; i++){

            var arg = arguments[i];

            var field = "";
            var direction = "";

            if(Object.prototype.toString.call( arg ) == '[object Array]'){
                field = arg[0];
                direction = arg[1];
            }
            else if(Object.prototype.toString.call( arg ) == '[object Object]'){
                field = arg.field;
                direction = arg.direction;
            }
            else{
                throw new Error("INVALID ORDER ARGUMENT");
            }

            this.filter("order", field+"__"+direction);

        }
        return this;
    }

}

var fields = function(){
    if(arguments.length<0){
        throw new Error("MUST SUPPLY AT LEAST ONE FIELD");
    }

    for(var i=0; i<arguments.length; i++){
        this.filter("fields", arguments[i]);
    }

    return this;
}

/* =================================================================== */

//Global add parms function, also used directly to currate the where clause
var filter = function(field, value, operator){

    if(typeof operator != "undefined" && operator != "="){
        if(field!="order"){
            operatorCheck(operator);
            field = field+"__"+operator;
        }
        else if(operator=="asc"||operator=="desc"){
            value = value+"__"+operator;
        }
        else{
            throw new Error("("+operator+") is not a valid operator for "+field);
        }
    }

    //UNSET A FILTER
    if(value==null && typeof this.queryObj[field] != "undefined"){
        this.queryObj[field] = undefined;
    }
    //ADD TO A LIST FILTER
    else if(field=="fields"||field=="order"){
        var list = [];

        if(typeof this.queryObj[field] != "undefined"){
            list = this.queryObj[field];
        }

        list[list.length] = value;

        this.queryObj[field] = list;
    }
    //SET/OVERWRITE A SIMPLE FILTER
    else{
        this.queryObj[field] = value;
    }

	return this;
}

//CONFIRM THAT THE OPERATOR IS VALID
var operatorCheck = function(operator){
    if(false){
        throw new Error("NEED ERROR MESSAGE");
    }
}

//CALL OUT TO THE API
var call = function(callback, fail){
	keyCheck(this.apikey);

    //passed object
    if(typeof callback == "object"){
        fail = callback.fail;
        callback = callback.callback;
    }

    //passed a new callback function
    if(typeof callback != "undefined"){
        this.success = callback;
    }
    //didn't pass a new call back function, use old one
    else if(typeof this.success != "undefined"){
        callback = this.success;
    }
    //AH! no callback
    else{
        throw new Error("YOU MUST DEFINE A SUCCESS FUNCTION BEFORE PERFORMING CALL");
    }

    //passed a new failure function
	if(typeof failure != "undefined"){
		this.failure = fail;
	}
    //didn't pass a new failure function
    else if(typeof this.failure != "undefined"){
        fail = this.failure;
    }
    //AH! no failure function. Lets fail! HA!
    else{
        throw new Error("YOU MUST DEFINE A FAILURE FUNCTION BEFORE PERFORMING CALL");
    }

    this.query = queryString(this.queryObj);
    var endpoint = basepoint+this.collection+"/?apikey="+this.apikey+this.query

    //console.log(endpoint);

	http.get(endpoint, function(res){
		var data = "";
		res.on("data", function(chunk){
			data+=chunk;
		});
		res.on("end", function(){
            data = JSON.parse(data);
            data.status = "success";
            data.error = undefined;
			callback(data);
		})
	}).on("error", function(e){
        var data = {
            status: "error",
            error: e,
            results: []
        }
        fail(data);
    });
}

var setKey = function(key){
    if(typeof key != "undefined"){
        this.apikey = key;
    }
}

/* ========================================================= ***/
/** ==================== BASIC OBJECT DATA ================== **/
/*** ========================================================= */

var basepoint = "http://congress.api.sunlightfoundation.com/";
var baseObj = {

    //BASE DATA
	apikey : undefined,
	collection: "",
	query: "",
    queryObj: {}, //used to stage

    //CORE FUNCTIONS
	call: call,
	setKey: setKey,
	filter: filter,
    page: page,
    order: order,
    fields: fields,

    //CALLBACK FUNCTIONS
    success: undefined,
    failure: function(data){
        console.log("ERROR: "+data.error.message);
    }
}

/* ========================================================= ***/
/** ==================== BACKEND UTILITIES ================== **/
/*** ========================================================= */

//CONFIRM THAT THE APIKEY HAS BEEN SET
var keyCheck = function(key){
    if(key==undefined){
        throw new Error("YOU MUST USE .init() TO DEFINE YOUR SUNLIGHT FOUNDATION API KEY!");
    }
}

var queryString = function(query){
    var baseuri = "";
    var keys = Object.keys(query);

    for(var i=0; i<keys.length; i++){
        var key = keys[i];
        var value = query[key];
        baseuri += "&"+key+"="+value;
    }

    return baseuri;
}

/* ========================================================= ***/
/** ====================== THE GRAND INIT =================== **/
/*** ========================================================= */

//INIT THE MODULE WITH YOU SUNLIGHT FUNDATION KEY
module.exports.init = function(slk){
	baseObj.apikey = slk;
}

/* ========================================================= ***/
/** ========================= ENDPOINTS ===================== **/
/*** ========================================================= */

/* =============================================== **
** DOCS: http://sunlightlabs.github.com/congress/  **
** =============================================== */

//Roll call votes in Congress, back to 2009. Updated within minutes of votes.
module.exports.votes = function(slk){

	var obj = extend(true, {}, baseObj);
	obj.setKey(slk);
	obj.collection = "votes";

	return obj;
}

//Committee hearings in Congress. Updated as hearings are announced.
module.exports.hearings = function(slk){

	var obj = extend(true, {}, baseObj);
	obj.setKey(slk);
	obj.collection = "hearings";

	return obj;
}

//To-the-minute updates from the floor of the House and Senate.
module.exports.floorUpdates = function(slk){

	var obj = extend(true, {}, baseObj);
	obj.setKey(slk);
	obj.collection = "floor_updates";

	return obj;
}

//Legislation in the House and Senate, back to 2009. Updated daily.
module.exports.bills  = function(slk){

	var obj = extend(true, {}, baseObj);
	obj.setKey(slk);
	obj.collection = "bills";

	return obj;
}

//Full text search over legislation.
module.exports.billsSearch  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "bills/search";

    return obj;
}

//Current legislators' names, IDs, biography, and social media.
module.exports.legislators  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "legislators";

    return obj;
}

//Find representatives and senators for a latitude/longitude or zip.
module.exports.legislatorsLocate  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "legislators/locate";

    return obj;
}

//Find congressional districts for a latitude/longitude or zip
module.exports.districtsLocate  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "districts/locate";

    return obj;
}

//Current committees, subcommittees, and their membership.
module.exports.committees  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "committees";

    return obj;
}

//Bills scheduled for debate in the future, as announced by party leadership.
module.exports.upcomingBills  = function(slk){

    var obj = extend(true, {}, baseObj);
    obj.setKey(slk);
    obj.collection = "upcoming_bills";

    return obj;
}

/* ========================================================= ***/
/** =================== JQUERY EXTEND PORT ================== **/
/*** ========================================================= */

/* =============================================================================================== **
** Suggested By: http://stackoverflow.com/questions/9399365/deep-extend-like-jquerys-for-nodejs    **
** From: https://github.com/jquery/jquery/blob/master/src/core.js                                  **
** =============================================================================================== */

function extend() {
    var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {},
    i = 1,
    length = arguments.length,
    deep = false,
    toString = Object.prototype.toString,
    hasOwn = Object.prototype.hasOwnProperty,
    push = Array.prototype.push,
    slice = Array.prototype.slice,
    trim = String.prototype.trim,
    indexOf = Array.prototype.indexOf,
    class2type = {
        "[object Boolean]": "boolean",
        "[object Number]": "number",
        "[object String]": "string",
        "[object Function]": "function",
        "[object Array]": "array",
        "[object Date]": "date",
        "[object RegExp]": "regexp",
        "[object Object]": "object"
    },
    jQuery = {
        isFunction: function (obj) {
            return jQuery.type(obj) === "function"
        },
        isArray: Array.isArray ||
        function (obj) {
            return jQuery.type(obj) === "array"
        },
        isWindow: function (obj) {
            return obj != null && obj == obj.window
        },
        isNumeric: function (obj) {
            return !isNaN(parseFloat(obj)) && isFinite(obj)
        },
        type: function (obj) {
            return obj == null ? String(obj) : class2type[toString.call(obj)] || "object"
        },
        isPlainObject: function (obj) {
            if (!obj || jQuery.type(obj) !== "object" || obj.nodeType) {
              	return false
            }
            try {
              	if (obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
                	return false
              	}
            }
            catch (e) {
      	        return false
            }
            var key;
            for (key in obj) {}
            return key === undefined || hasOwn.call(obj, key)
        }
    };
    if (typeof target === "boolean") {
    	deep = target;
    	target = arguments[1] || {};
        i = 2;
    }
    if (typeof target !== "object" && !jQuery.isFunction(target)) {
    	target = {}
    }
    if (length === i) {
        target = this;
    	--i;
    }
    for (i; i < length; i++) {
        if ((options = arguments[i]) != null) {
          	for (name in options) {
            	src = target[name];
            	copy = options[name];
            	if (target === copy) {
              		continue
            	}
            	if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
              		if (copyIsArray) {
                		copyIsArray = false;
                		clone = src && jQuery.isArray(src) ? src : []
              		} else {
                		clone = src && jQuery.isPlainObject(src) ? src : {};
              		}
              		// WARNING: RECURSION
              		target[name] = extend(deep, clone, copy);
            	}
            	else if (copy !== undefined) {
              		target[name] = copy;
            	}
        	}
        }
    }
    return target;
}<|endoftext|>


<commit_before>const assert = require('assert');
const configMergeLoader = require('../index.js');

describe('Config Merge Loader', function() {
  it('should return a function', function() {
    assert.equal(typeof configMergeLoader, 'function');
  });
});
<commit_msg>Test that when called, the loader returns a string<commit_after>const assert = require('assert');
const configMergeLoader = require('../index.js');

describe('Config Merge Loader', function() {
  it('should return a function', function() {
    assert.equal(typeof configMergeLoader, 'function');
  });

  describe('when called', function() {
    const loaderInput = 'Loader Content';

    it('should return as string', function() {
      const loaderResult = configMergeLoader(loaderInput);
      assert.equal(typeof loaderResult, 'string');
    });
  });
});
<|endoftext|>