<commit_before>

// test helper object
window.TEST = {
  // note some unique members of the Modernizr object
  inputs    : ['input','inputtypes'],
  audvid    : ['video','audio'],
  API       : ['addTest'],
  privates  : ['_enableHTML5','_version','_fontfaceready'],
  deprecated : [
                { oldish : 'crosswindowmessaging', newish : 'postmessage'},
                { oldish : 'historymanagement', newish : 'history'},
              ],

  // utility methods
  inArray: function(elem, array) {
      if (array.indexOf) {
          return array.indexOf(elem);
      }
      for (var i = 0, length = array.length; i < length; i++) {
          if (array[i] === elem) {
              return i;
          }
      }
      return -1;
  },
  trim : function(str){
    return str.replace(/^\s*/, "").replace(/\s*$/, "");
  }
};

test("globals set up",2, function() {

	ok(window.Modernizr, 'global modernizr object created');

	var remainingGlobals = getMembers(window);

	// thx opera for globalizing IDs...
	for (var len = remainingGlobals.length; len-- ;){
	  if (document.getElementById(remainingGlobals[len])){
	    remainingGlobals.splice(len,1);
	  }
	}

	var count = remainingGlobals.length - window.__globals.length
	    // jQuery and $ are included before the first globals are grabbed, so not included here.
	     - (window.TEST   ? 1 : 0)
       - (window.backuphtml      ? 1 : 0)
       - (window.cbfunc ? 1 : 0)
       - ('onhashchange' in window && !window.onhashchange ? 1 : 0)

	ok( ! (count > 1) , 'no more than one global object created');

	/*  * /
	var arr = [];
	var x = $.each(remainingGlobals,function(k,v){
	  if ( $.inArray(v,window.__globals) === -1) arr.push(v);
	});

	alert(remainingGlobals.length + ', ' + window.__globals.length + ' : ('+arr.length+') '+  arr.join(', '));
  /* */

});

test("document.documentElement is valid and correct",1, function() {
	equals(document.documentElement,document.getElementsByTagName('html')[0]);
});

test("no-js class is gone.", function() {
  expect(3);

	equals(document.documentElement.className.indexOf('no-js') , -1,
	       'no-js is gone.');

	ok(/\bjs /.test(document.documentElement.className),
	   'html.js class is present')

	if (document.querySelector){
	  ok(document.querySelector('html.js') == document.documentElement,
	     "document.querySelector('html.js') matches.");
	}
});

test('html shim worked', function(){
  expect(2);

  // the exact test we use in the script
  var elem = document.createElement("div");
  elem.innerHTML = "<elem style='color:red'></elem>";

  ok( elem.childNodes.length === 1 , 'unknown elements dont collapse');

  document.body.appendChild(elem);
  ok( elem.childNodes[0].style.color == 'red', 'unknown elements are styleable')

});

test('html classes are looking good',function(){

  var classes = TEST.trim(document.documentElement.className).split(/\s+/);

  var modprops = getMembers(Modernizr).length,
      newprops = modprops;

  // decrement for the properties that are private
  for (var i = -1, len = TEST.privates.length; ++i < len;){
    if (Modernizr[TEST.privates[i]] != undefined) newprops--;
  }

  // decrement for the non-boolean objects
  for (var i = -1, len = TEST.inputs.length; ++i < len;){
    if (Modernizr[TEST.inputs[i]] != undefined) newprops--;
  }

  // decrement for deprecated ones.
  $.each( TEST.deprecated, function(key, val){
    newprops--;
  });

  equals(classes.length,newprops,'equal number of classes and global object props');

  for (var i = 0, len = classes.length, aclass; i <len; i++){
    aclass = classes[i];

    if (aclass === 'js') continue;

    if (aclass.indexOf('no-') === 0){
      aclass = aclass.replace('no-','');

      equals(Modernizr[aclass], false,
            aclass + ' is correctly false in the classes and object')

    } else {
      equals(Modernizr[aclass], true,
             aclass + ' is correctly true in the classes and object')
    }
  }

  for (var i = 0, len = classes.length, aclass; i <len; i++){
    equals(classes[i],classes[i].toLowerCase(),'all classes are lowerCase.');
  }

  equals(/[^\s]no-/.test(document.documentElement.className),false,
         'whitespace between all classes.');

})

test('Modernizr properties are looking good',function(){

  var count = 0,
      nobool = TEST.API.concat(TEST.inputs)
                .concat(TEST.audvid).concat(TEST.privates);

  for (var prop in window.Modernizr){
    if (window.Modernizr.hasOwnProperty(prop)){

      if (TEST.inArray(prop,nobool) >= 0) continue;

      ok(Modernizr[prop] === true || Modernizr[prop] === false,
        'Modernizr.'+prop+' is a straight up boolean');

      equals(prop,prop.toLowerCase(),'all properties are lowerCase.')
    }
  }
})

test('Modernizr.addTest()',9,function(){
  Modernizr.addTest('testtrue',function(){
    return true;
  });

  Modernizr.addTest('testtruthy',function(){
    return 100;
  });

  Modernizr.addTest('testfalse',function(){
    return false;
  });

  Modernizr.addTest('testfalsy',function(){
    return undefined;
  });

  ok(document.documentElement.className.indexOf(' testtrue') >= 0,'positive class added');
  equals(Modernizr.testtrue,true,'positive prop added');

  ok(document.documentElement.className.indexOf(' testtruthy') >= 0,'positive class added');
  equals(Modernizr.testtruthy,true,'positive prop added');

  ok(document.documentElement.className.indexOf(' no-testfalse') >= 0,'negative class added');
  equals(Modernizr.testfalse,false,'negative prop added');

  ok(document.documentElement.className.indexOf(' no-testfalsy') >= 0,'negative class added');
  equals(Modernizr.testfalsy,false,'negative prop added');

  Modernizr.addTest('camelCase',function(){
     return true;
   });

  ok(document.documentElement.className.indexOf(' camelCase') === -1,
     'camelCase test name toLowerCase()\'d');

})

test('Modernizr.audio and Modernizr.video',function(){

  for (var i = -1, len = TEST.audvid.length; ++i < len;){
    var prop = TEST.audvid[i];

    if (Modernizr[prop].toString() == 'true'){

      ok(Modernizr[prop],                             'Modernizr.'+prop+' is truthy.');
      equals(Modernizr[prop] == true,true,            'Modernizr.'+prop+' is == true')
      equals(typeof Modernizr[prop] === 'object',true,'Moderizr.'+prop+' is truly an object');
      equals(Modernizr[prop] !== true,true,           'Modernizr.'+prop+' is !== true')

    } else {

      equals(Modernizr[prop] != true,true,            'Modernizr.'+prop+' is != true')
    }
  }

})

asyncTest('async @font-face test',4,function(){

  // we do this to verify our callback indeed will run.
  start();
  ok(Modernizr._fontfaceready,'passing a method to Modernizr._fontfaceready')
  stop();

  Modernizr._fontfaceready(function(bool){

    ok(bool === true || bool === false,'passed argument is a boolean');
    equals(bool,Modernizr.fontface,'Modernizr prop matches passed arg');

    var expectedclass = (Modernizr.fontface ? '' : 'no-') + 'fontface';

    ok(document.documentElement.className.indexOf(' '+expectedclass) >= 0,
       'correct class added to documentElement');

    start();
  });

})

test('Modernizr results match expected values',function(){

  // i'm bringing over a few tests from inside Modernizr.js
  equals(!!document.createElement('canvas').getContext,Modernizr.canvas,'canvas test consistent');

  equals(!!window.Worker,Modernizr.webworkers,'web workers test consistent')

});

/**
 * We're going to test the current browser results against the www.findmebyip.com data tables
 * These tables are originaly sourced from Modernizr results but get enough eyeballs to perhaps
 * trust them more.
 * However, as testing has shown, there are many inconsistencies in their results.

 * Regardless, having *a* baseline to test feature detection results against is worthwhile,
 * even if its flawed.
 * In the future, I'd like to test against the whencaniuse.com tables.
*/

$(function fmbip() {

  var isDataAdded = false;
  var testbed = document.getElementById('testbed');

  // return 0-based column number, considering colspans and such
  $.fn.getColNum = function () {
    var spans = this.eq(0).prevAll().map(function () {
      return $(this).attr('colspan') || 1
    }).get().join('+');

    return eval('(' + spans + ')');
  };

  $.fn.grabColNum = function (n, wid) {
    var elem = $(this).is('td,th') ? $(this).siblings().andSelf().eq(0) : $(this).find('td,th').eq(0);
    wid = wid || 0;

    //console.log('inside grabcol',elem,wid, elem.nextAll().andSelf().slice(n,n+1 + wid))
    return elem.nextAll().andSelf().slice(n, n + 1 + wid);
  };

  // takes a given table cell and removes the entire column associated with it
  $.fn.removeColumn = function(){
    return this.each(function () {
      var span = $(this).attr('colspan');
      var skip = $(this).getColNum();
      var rows = $(this).closest('table').find('thead,tbody').find('tr');
      rows.each(function () {
        var counter = span; // 4
        var elem = $(this).children().eq(skip);

        (function loop() {
          var elemspan = $(elem).attr('colspan') || 1;
          elem = elem.next();
          elem.prev().remove();

          if (counter - elemspan == 0) return;
          else {
            counter--;
            loop();
          }
        })()
      })
    })
  };

  // determine the modernizr property we're testing.
  // also we'll handle video/audio/input here
  function getModernizrProperty(testname) {
    var splitz = testname.split(':');
    splitz[0] = dict[splitz[0]] || splitz[0];
    var modresult = Modernizr[splitz[0]];

    if (splitz[1] !== undefined) {
      if (Modernizr.inputtypes[splitz[1]] !== undefined) {
        modresult = Modernizr.inputtypes;
      }
      modresult = modresult[splitz[1]];
    }
    return modresult;
  }

  // hacky translation lookup when replace(/\s+/g, '').toLowerCase() isnt good enough
  var dict = {
    'postmessage': 'crosswindowmessaging',
    'cssfontface': 'fontface',
    'multiplebackgrounds': 'multiplebgs',
    'webdatabase': 'websqldatabase',
    'workers': 'webworkers',
    'form': 'input'
  }

  function testAgainstTables() {

    if (testAgainstTables.isRun) return;
    testAgainstTables.isRun = true;

    // remove css3 selectors
    $('#css3-selectors').next().andSelf().remove();

    // remove the mac columns.. kinda useless to us.
    $('thead th:contains(MAC)').removeColumn();

    test('Results match fmbip data', function () {

      // find the matching browser..
      $('thead').each(function () {
        var elem = $(this).find('th:contains(' + sniff.browser.toUpperCase() + ')'),
            pos = elem.getColNum(),
            wid = elem.attr('colspan'),

            // ver is an array of the browser versions of this matching browser.
            ver = elem.closest('tr').next().grabColNum(pos, wid - 1).map(function () {
              return $.trim($(this).text());
            }).get(),

            rows = $(this).closest('table').find('tbody tr');

        rows.each(function () {
          var thistest = $(this).find('td,th').eq(0).text().replace(/\s+/g, '').toLowerCase();
              thistest = dict[test] || thistest;

          var modresult = getModernizrProperty(thistest),
              that = this;

          // insert a loop here to loop over the versions.
          $.each(ver, function (k, v) {

            // add one on each iteration
            var start = $(that).grabColNum(pos + k),
                bool = $.trim(start.text()) == 'Y',
                thisver = v;

            // chrome 6 should succeed on everything chrome 5 did
            if (sniff.version > thisver && modresult !== undefined) {

              if (bool === true) {
                ok( !! modresult === true, thistest + ' matches expected result for ' + sniff.browser + ' on ' + sniff.version + ' vs ' + thisver);
                if (( !! modresult === true) !== bool) start.addClass('wrong');
              }
            }

            // ie6 should fail on everything ie7 does.
            if (sniff.version < thisver && modresult !== undefined) {

              if (bool === false) {
                ok( !! modresult === false, thistest + ' matches expected result for ' + sniff.browser + ' on ' + sniff.version + ' vs ' + thisver)
                if (( !! modresult !== true) !== false) start.addClass('wrong');
              }
            }

            // if ff3.5 is being tested. it should match every result in the table here.
            if (parseFloat(sniff.version) == thisver && modresult !== undefined) {
              ok( !! modresult === bool, thistest + ' matches expected result for ' + sniff.browser + ' on ' + sniff.version + ' vs ' + thisver);

              if (( !! modresult === bool) !== true) start.addClass('wrong');
            }

          }); // version each loop
        }) // eo rows each
      }) // eo thead each
    }); // test!

  } // eo testAgainstTables();

  // thx jquery
  function uaMatch(ua) {
    ua = ua.toLowerCase();

    var match = /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) || /(msie) ([\w.]+)/.exec(ua) || !/compatible/.test(ua) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || [];

    return {
      browser: match[1] || "",
      version: match[2] || "0"
    };
  }

  // e.g. sniff.browser == 'webkit' && sniff.version == '534.0'
  var sniff = uaMatch(navigator.userAgent);

  // browser version
  // this gnarly code is exactly the reason why Modernizr exists.
  if (sniff.browser == 'webkit') {
    var chrome = navigator.userAgent.match(/Chrome\/(.*?)(\s|$)/);
    var safari = navigator.userAgent.match(/Safari\/(.*?)(\s|$)/);

    if (chrome) {
      sniff = {
        browser: 'chrome',
        version: chrome[1]
      }
    } else if (safari) {
      sniff = {
        browser: 'safari',
        version: safari[1]
      }
    }
  } else if (sniff.browser == 'mozilla') {
    var firefox = navigator.userAgent.match(/(?:firefox|minefield)\/(.*?)(?:\s|$)/i);
    sniff.browser = 'firefox';
    sniff.version = firefox[1];
  }

  // fire it off
  $('#testbed button').click(function() {
    $(this).hide().next().show();
    var script = document.createElement('script');
    script.onerror = function () {
      isDataAdded = true;
      testbed.innerHTML += backuphtml;
      testAgainstTables();
    }
    script.src = 'http://jsonpify.com/api?url=http://www.findmebyip.com/litmus/&format=string&jsonp=cbfunc';
    document.body.appendChild(script);

    // opera is weak with script onerror
    setTimeout(function(){
      if ( isDataAdded) return;
      script.onerror();
    },1200);
  });

  window.cbfunc = function (data) {
    isDataAdded = true;

    var html = data.replace(/\s+|\n/g, ' ').match(/(<h2 id="css3-properties.*)<div class="data-notes/)[1];
    testbed.innerHTML += html;

    testAgainstTables();
  };

})
<commit_msg>remove @font-face tests from test suite as it is no longer ASYNC and has reducd api footprint.<commit_after>

// test helper object
window.TEST = {
  // note some unique members of the Modernizr object
  inputs    : ['input','inputtypes'],
  audvid    : ['video','audio'],
  API       : ['addTest'],
  privates  : ['_enableHTML5','_version','_fontfaceready'],
  deprecated : [
                { oldish : 'crosswindowmessaging', newish : 'postmessage'},
                { oldish : 'historymanagement', newish : 'history'},
              ],

  // utility methods
  inArray: function(elem, array) {
      if (array.indexOf) {
          return array.indexOf(elem);
      }
      for (var i = 0, length = array.length; i < length; i++) {
          if (array[i] === elem) {
              return i;
          }
      }
      return -1;
  },
  trim : function(str){
    return str.replace(/^\s*/, "").replace(/\s*$/, "");
  }
};

test("globals set up",2, function() {

	ok(window.Modernizr, 'global modernizr object created');

	var remainingGlobals = getMembers(window);

	// thx opera for globalizing IDs...
	for (var len = remainingGlobals.length; len-- ;){
	  if (document.getElementById(remainingGlobals[len])){
	    remainingGlobals.splice(len,1);
	  }
	}

	var count = remainingGlobals.length - window.__globals.length
	    // jQuery and $ are included before the first globals are grabbed, so not included here.
	     - (window.TEST   ? 1 : 0)
       - (window.backuphtml      ? 1 : 0)
       - (window.cbfunc ? 1 : 0)
       - ('onhashchange' in window && !window.onhashchange ? 1 : 0)

	ok( ! (count > 1) , 'no more than one global object created');

	/*  * /
	var arr = [];
	var x = $.each(remainingGlobals,function(k,v){
	  if ( $.inArray(v,window.__globals) === -1) arr.push(v);
	});

	alert(remainingGlobals.length + ', ' + window.__globals.length + ' : ('+arr.length+') '+  arr.join(', '));
  /* */

});

test("document.documentElement is valid and correct",1, function() {
	equals(document.documentElement,document.getElementsByTagName('html')[0]);
});

test("no-js class is gone.", function() {
  expect(3);

	equals(document.documentElement.className.indexOf('no-js') , -1,
	       'no-js is gone.');

	ok(/\bjs /.test(document.documentElement.className),
	   'html.js class is present')

	if (document.querySelector){
	  ok(document.querySelector('html.js') == document.documentElement,
	     "document.querySelector('html.js') matches.");
	}
});

test('html shim worked', function(){
  expect(2);

  // the exact test we use in the script
  var elem = document.createElement("div");
  elem.innerHTML = "<elem style='color:red'></elem>";

  ok( elem.childNodes.length === 1 , 'unknown elements dont collapse');

  document.body.appendChild(elem);
  ok( elem.childNodes[0].style.color == 'red', 'unknown elements are styleable')

});

test('html classes are looking good',function(){

  var classes = TEST.trim(document.documentElement.className).split(/\s+/);

  var modprops = getMembers(Modernizr).length,
      newprops = modprops;

  // decrement for the properties that are private
  for (var i = -1, len = TEST.privates.length; ++i < len;){
    if (Modernizr[TEST.privates[i]] != undefined) newprops--;
  }

  // decrement for the non-boolean objects
  for (var i = -1, len = TEST.inputs.length; ++i < len;){
    if (Modernizr[TEST.inputs[i]] != undefined) newprops--;
  }

  // decrement for deprecated ones.
  $.each( TEST.deprecated, function(key, val){
    newprops--;
  });

  equals(classes.length,newprops,'equal number of classes and global object props');

  for (var i = 0, len = classes.length, aclass; i <len; i++){
    aclass = classes[i];

    if (aclass === 'js') continue;

    if (aclass.indexOf('no-') === 0){
      aclass = aclass.replace('no-','');

      equals(Modernizr[aclass], false,
            aclass + ' is correctly false in the classes and object')

    } else {
      equals(Modernizr[aclass], true,
             aclass + ' is correctly true in the classes and object')
    }
  }

  for (var i = 0, len = classes.length, aclass; i <len; i++){
    equals(classes[i],classes[i].toLowerCase(),'all classes are lowerCase.');
  }

  equals(/[^\s]no-/.test(document.documentElement.className),false,
         'whitespace between all classes.');

})

test('Modernizr properties are looking good',function(){

  var count = 0,
      nobool = TEST.API.concat(TEST.inputs)
                .concat(TEST.audvid).concat(TEST.privates);

  for (var prop in window.Modernizr){
    if (window.Modernizr.hasOwnProperty(prop)){

      if (TEST.inArray(prop,nobool) >= 0) continue;

      ok(Modernizr[prop] === true || Modernizr[prop] === false,
        'Modernizr.'+prop+' is a straight up boolean');

      equals(prop,prop.toLowerCase(),'all properties are lowerCase.')
    }
  }
})

test('Modernizr.addTest()',9,function(){
  Modernizr.addTest('testtrue',function(){
    return true;
  });

  Modernizr.addTest('testtruthy',function(){
    return 100;
  });

  Modernizr.addTest('testfalse',function(){
    return false;
  });

  Modernizr.addTest('testfalsy',function(){
    return undefined;
  });

  ok(document.documentElement.className.indexOf(' testtrue') >= 0,'positive class added');
  equals(Modernizr.testtrue,true,'positive prop added');

  ok(document.documentElement.className.indexOf(' testtruthy') >= 0,'positive class added');
  equals(Modernizr.testtruthy,true,'positive prop added');

  ok(document.documentElement.className.indexOf(' no-testfalse') >= 0,'negative class added');
  equals(Modernizr.testfalse,false,'negative prop added');

  ok(document.documentElement.className.indexOf(' no-testfalsy') >= 0,'negative class added');
  equals(Modernizr.testfalsy,false,'negative prop added');

  Modernizr.addTest('camelCase',function(){
     return true;
   });

  ok(document.documentElement.className.indexOf(' camelCase') === -1,
     'camelCase test name toLowerCase()\'d');

})

test('Modernizr.audio and Modernizr.video',function(){

  for (var i = -1, len = TEST.audvid.length; ++i < len;){
    var prop = TEST.audvid[i];

    if (Modernizr[prop].toString() == 'true'){

      ok(Modernizr[prop],                             'Modernizr.'+prop+' is truthy.');
      equals(Modernizr[prop] == true,true,            'Modernizr.'+prop+' is == true')
      equals(typeof Modernizr[prop] === 'object',true,'Moderizr.'+prop+' is truly an object');
      equals(Modernizr[prop] !== true,true,           'Modernizr.'+prop+' is !== true')

    } else {

      equals(Modernizr[prop] != true,true,            'Modernizr.'+prop+' is != true')
    }
  }

});

test('Modernizr results match expected values',function(){

  // i'm bringing over a few tests from inside Modernizr.js
  equals(!!document.createElement('canvas').getContext,Modernizr.canvas,'canvas test consistent');

  equals(!!window.Worker,Modernizr.webworkers,'web workers test consistent')

});

/**
 * We're going to test the current browser results against the www.findmebyip.com data tables
 * These tables are originaly sourced from Modernizr results but get enough eyeballs to perhaps
 * trust them more.
 * However, as testing has shown, there are many inconsistencies in their results.

 * Regardless, having *a* baseline to test feature detection results against is worthwhile,
 * even if its flawed.
 * In the future, I'd like to test against the whencaniuse.com tables.
*/

$(function fmbip() {

  var isDataAdded = false;
  var testbed = document.getElementById('testbed');

  // return 0-based column number, considering colspans and such
  $.fn.getColNum = function () {
    var spans = this.eq(0).prevAll().map(function () {
      return $(this).attr('colspan') || 1
    }).get().join('+');

    return eval('(' + spans + ')');
  };

  $.fn.grabColNum = function (n, wid) {
    var elem = $(this).is('td,th') ? $(this).siblings().andSelf().eq(0) : $(this).find('td,th').eq(0);
    wid = wid || 0;

    //console.log('inside grabcol',elem,wid, elem.nextAll().andSelf().slice(n,n+1 + wid))
    return elem.nextAll().andSelf().slice(n, n + 1 + wid);
  };

  // takes a given table cell and removes the entire column associated with it
  $.fn.removeColumn = function(){
    return this.each(function () {
      var span = $(this).attr('colspan');
      var skip = $(this).getColNum();
      var rows = $(this).closest('table').find('thead,tbody').find('tr');
      rows.each(function () {
        var counter = span; // 4
        var elem = $(this).children().eq(skip);

        (function loop() {
          var elemspan = $(elem).attr('colspan') || 1;
          elem = elem.next();
          elem.prev().remove();

          if (counter - elemspan == 0) return;
          else {
            counter--;
            loop();
          }
        })()
      })
    })
  };

  // determine the modernizr property we're testing.
  // also we'll handle video/audio/input here
  function getModernizrProperty(testname) {
    var splitz = testname.split(':');
    splitz[0] = dict[splitz[0]] || splitz[0];
    var modresult = Modernizr[splitz[0]];

    if (splitz[1] !== undefined) {
      if (Modernizr.inputtypes[splitz[1]] !== undefined) {
        modresult = Modernizr.inputtypes;
      }
      modresult = modresult[splitz[1]];
    }
    return modresult;
  }

  // hacky translation lookup when replace(/\s+/g, '').toLowerCase() isnt good enough
  var dict = {
    'postmessage': 'crosswindowmessaging',
    'cssfontface': 'fontface',
    'multiplebackgrounds': 'multiplebgs',
    'webdatabase': 'websqldatabase',
    'workers': 'webworkers',
    'form': 'input'
  }

  function testAgainstTables() {

    if (testAgainstTables.isRun) return;
    testAgainstTables.isRun = true;

    // remove css3 selectors
    $('#css3-selectors').next().andSelf().remove();

    // remove the mac columns.. kinda useless to us.
    $('thead th:contains(MAC)').removeColumn();

    test('Results match fmbip data', function () {

      // find the matching browser..
      $('thead').each(function () {
        var elem = $(this).find('th:contains(' + sniff.browser.toUpperCase() + ')'),
            pos = elem.getColNum(),
            wid = elem.attr('colspan'),

            // ver is an array of the browser versions of this matching browser.
            ver = elem.closest('tr').next().grabColNum(pos, wid - 1).map(function () {
              return $.trim($(this).text());
            }).get(),

            rows = $(this).closest('table').find('tbody tr');

        rows.each(function () {
          var thistest = $(this).find('td,th').eq(0).text().replace(/\s+/g, '').toLowerCase();
              thistest = dict[test] || thistest;

          var modresult = getModernizrProperty(thistest),
              that = this;

          // insert a loop here to loop over the versions.
          $.each(ver, function (k, v) {

            // add one on each iteration
            var start = $(that).grabColNum(pos + k),
                bool = $.trim(start.text()) == 'Y',
                thisver = v;

            // chrome 6 should succeed on everything chrome 5 did
            if (sniff.version > thisver && modresult !== undefined) {

              if (bool === true) {
                ok( !! modresult === true, thistest + ' matches expected result for ' + sniff.browser + ' on ' + sniff.version + ' vs ' + thisver);
                if (( !! modresult === true) !== bool) start.addClass('wrong');
              }
            }

            // ie6 should fail on everything ie7 does.
            if (sniff.version < thisver && modresult !== undefined) {

              if (bool === false) {
                ok( !! modresult === false, thistest + ' matches expected result for ' + sniff.browser + ' on ' + sniff.version + ' vs ' + thisver)
                if (( !! modresult !== true) !== false) start.addClass('wrong');
              }
            }

            // if ff3.5 is being tested. it should match every result in the table here.
            if (parseFloat(sniff.version) == thisver && modresult !== undefined) {
              ok( !! modresult === bool, thistest + ' matches expected result for ' + sniff.browser + ' on ' + sniff.version + ' vs ' + thisver);

              if (( !! modresult === bool) !== true) start.addClass('wrong');
            }

          }); // version each loop
        }) // eo rows each
      }) // eo thead each
    }); // test!

  } // eo testAgainstTables();

  // thx jquery
  function uaMatch(ua) {
    ua = ua.toLowerCase();

    var match = /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) || /(msie) ([\w.]+)/.exec(ua) || !/compatible/.test(ua) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || [];

    return {
      browser: match[1] || "",
      version: match[2] || "0"
    };
  }

  // e.g. sniff.browser == 'webkit' && sniff.version == '534.0'
  var sniff = uaMatch(navigator.userAgent);

  // browser version
  // this gnarly code is exactly the reason why Modernizr exists.
  if (sniff.browser == 'webkit') {
    var chrome = navigator.userAgent.match(/Chrome\/(.*?)(\s|$)/);
    var safari = navigator.userAgent.match(/Safari\/(.*?)(\s|$)/);

    if (chrome) {
      sniff = {
        browser: 'chrome',
        version: chrome[1]
      }
    } else if (safari) {
      sniff = {
        browser: 'safari',
        version: safari[1]
      }
    }
  } else if (sniff.browser == 'mozilla') {
    var firefox = navigator.userAgent.match(/(?:firefox|minefield)\/(.*?)(?:\s|$)/i);
    sniff.browser = 'firefox';
    sniff.version = firefox[1];
  }

  // fire it off
  $('#testbed button').click(function() {
    $(this).hide().next().show();
    var script = document.createElement('script');
    script.onerror = function () {
      isDataAdded = true;
      testbed.innerHTML += backuphtml;
      testAgainstTables();
    }
    script.src = 'http://jsonpify.com/api?url=http://www.findmebyip.com/litmus/&format=string&jsonp=cbfunc';
    document.body.appendChild(script);

    // opera is weak with script onerror
    setTimeout(function(){
      if ( isDataAdded) return;
      script.onerror();
    },1200);
  });

  window.cbfunc = function (data) {
    isDataAdded = true;

    var html = data.replace(/\s+|\n/g, ' ').match(/(<h2 id="css3-properties.*)<div class="data-notes/)[1];
    testbed.innerHTML += html;

    testAgainstTables();
  };

})
<|endoftext|>


<commit_before>/*! show-js-error | © 2016 Denis Seleznev | MIT License */
/* exported showJSError */
var showJSError = {
    /**
     * Initialize.
     *
     * @param {Object} [settings]
     * @param {String} [settings.title]
     * @param {String} [settings.userAgent]
     * @param {String} [settings.copyText]
     * @param {String} [settings.sendText]
     * @param {String} [settings.sendUrl]
     * @param {String} [settings.additionalText]
     * @param {Boolean} [settings.helpLinks]
     */
    init: function(settings) {
        var that = this;

        this.settings = settings || {};

        if (this._inited) {
            return;
        }

        this._inited = true;
        this._isLast = true;
        this._i = 0;
        this._buffer = [];

        // Chrome or Firefox
        this._hasViewSource = !!window.chrome || typeof InstallTrigger !== 'undefined';

        this._onerror = function(e) {
            that._buffer.push(e);
            if (that._isLast) {
                that._i = that._buffer.length - 1;
            }

            that._update();
        };

        this._onerrorLoading = function(e) {
            if (!e.bubbles && e.target && e.target.tagName) {
                that._onerror(that._errorLoading(e));
            }
        };

        if (window.addEventListener) {
            window.addEventListener('error', this._onerror, false);

            if (this.settings.errorLoading) {
                window.addEventListener('error', this._onerrorLoading, true);
            }
        } else {
            this._oldOnError = window.onerror;

            window.onerror = function(message, filename, lineno, colno, error) {
                this._onerror({
                    message: message,
                    filename: filename,
                    lineno: lineno,
                    colno: colno,
                    error: error
                });

                if (typeof that._oldOnError === 'function') {
                    that._oldOnError.apply(window, arguments);
                }
            };
        }
    },
    /**
     * Destructor.
     */
    destruct: function() {
        if (!this._inited) { return; }

        if (window.addEventListener) {
            window.removeEventListener('error', this._onerror, false);

            if (this.settings.errorLoading) {
                window.removeEventListener('error', this._onerrorLoading, true);
            }
        } else {
            window.onerror = this._oldOnError || null;
            delete this._oldOnError;
        }

        if (document.body && this._container) {
            document.body.removeChild(this._container);
        }

        this._buffer = [];

        this._inited = false;
    },
    /**
     * Show error message.
     *
     * @param {String|Object|Error} err
     */
    show: function(err) {
        if (typeof err !== 'undefined') {
            this._buffer.push(typeof err === 'object' ? err : new Error(err));
        }

        this._update();
        this._show();
    },
    /**
     * Hide error message.
     */
    hide: function() {
        if (this._container) {
            this._container.className = this.elemClass('');
        }
    },
    /**
     * Copy error message to clipboard.
     */
    copyText: function() {
        var err = this._buffer[this._i],
            text = this._getDetailedMessage(err),
            body = document.body,
            textarea = this.elem({
                name: 'textarea',
                tag: 'textarea',
                props: {
                    innerHTML: text
                },
                container: body
            });

        try {
            textarea.select();
            document.execCommand('copy');
        } catch (e) {
            alert('Copying text is not supported in this browser.');
        }

        body.removeChild(textarea);
    },
    /**
     * Create a elem.
     *
     * @param {Object} data
     * @param {String} data.name
     * @param {DOMElement} data.container
     * @param {String} [data.tag]
     * @param {Object} [data.props]
     * @returns {DOMElement}
     */
    elem: function(data) {
        var el = document.createElement(data.tag || 'div'),
            props = data.props;

        for (var i in props) {
            if (props.hasOwnProperty(i)) {
                el[i] = props[i];
            }
        }

        el.className = this.elemClass(data.name);

        data.container.appendChild(el);

        return el;
    },
    /**
     * Build className for elem.
     *
     * @param {String} [name]
     * @param {String} [mod]
     * @returns {String}
     */
    elemClass: function(name, mod) {
        var cl = 'show-js-error';
        if (name) {
            cl += '__' + name;
        }

        if (mod) {
            cl += ' ' + cl + '_' + mod;
        }

        return cl;
    },
    /**
     * Escape HTML.
     *
     * @param {String} text
     * @returns {String}
     */
    escapeHTML: function(text) {
        return (text || '').replace(/[&<>"'\/]/g, function(sym) {
            return {
                '&': '&',
                '<': '<',
                '>': '>',
                '"': '"',
                '\'': ''',
                '/': '/'
            }[sym];
        });
    },
    /**
     * Toggle view (shortly/detail).
     */
    toggleDetailed: function() {
        var body = this._body;
        if (body) {
            if (this._toggleDetailed) {
                this._toggleDetailed = false;
                body.className = this.elemClass('body');
            } else {
                this._toggleDetailed = true;
                body.className = this.elemClass('body', 'detailed');
            }
        }
    },
    _append: function() {
        var that = this;

        this._container = document.createElement('div');
        this._container.className = this.elemClass('');

        this._title = this.elem({
            name: 'title',
            props: {
                innerHTML: this._getTitle()
            },
            container: this._container
        });

        this._body = this.elem({
            name: 'body',
            container: this._container
        });

        this._message = this.elem({
            name: 'message',
            props: {
                onclick: function() {
                    that.toggleDetailed();
                }
            },
            container: this._body
        });

        if (this.settings.helpLinks) {
            this._helpLinks = this.elem({
                name: 'help',
                container: this._body
            });

            this._mdn = this.elem({
                tag: 'a',
                name: 'mdn',
                props: {
                    target: '_blank',
                    innerHTML: 'MDN'
                },
                container: this._helpLinks
            });

            this._stackoverflow = this.elem({
                tag: 'a',
                name: 'stackoverflow',
                props: {
                    target: '_blank',
                    innerHTML: 'Stack Overflow'
                },
                container: this._helpLinks
            });
        }

        this._filename = this.elem({
            name: 'filename',
            container: this._body
        });

        if (this.settings.userAgent) {
            this._ua = this.elem({
                name: 'ua',
                container: this._body
            });
        }

        if (this.settings.additionalText) {
            this._additionalText = this.elem({
                name: 'additional-text',
                container: this._body
            });
        }

        this.elem({
            name: 'close',
            props: {
                innerHTML: '×',
                onclick: function() {
                    that.hide();
                }
            },
            container: this._container
        });

        this._actions = this.elem({
            name: 'actions',
            container: this._container
        });

        this.elem({
            tag: 'input',
            name: 'copy',
            props: {
                type: 'button',
                value: this.settings.copyText || 'Copy',
                onclick: function() {
                    that.copyText();
                }
            },
            container: this._actions
        });

        if (this.settings.sendUrl) {
            this._sendLink = this.elem({
                tag: 'a',
                name: 'send-link',
                props: {
                    href: '',
                    target: '_blank'
                },
                container: this._actions
            });

            this._send = this.elem({
                tag: 'input',
                name: 'send',
                props: {
                    type: 'button',
                    value: this.settings.sendText || 'Send'
                },
                container: this._sendLink
            });
        }

        this._arrows = this.elem({
            tag: 'span',
            name: 'arrows',
            container: this._actions
        });

        this._prev = this.elem({
            tag: 'input',
            name: 'prev',
            props: {
                type: 'button',
                value: '←',
                onclick: function() {
                    that._isLast = false;
                    if (that._i) {
                        that._i--;
                    }

                    that._update();
                }
            },
            container: this._arrows
        });

        this._next = this.elem({
            tag: 'input',
            name: 'next',
            props: {
                type: 'button',
                value: '→',
                onclick: function() {
                    that._isLast = false;
                    if (that._i < that._buffer.length - 1) {
                        that._i++;
                    }

                    that._update();
                }
            },
            container: this._arrows
        });

        this._num = this.elem({
            tag: 'span',
            name: 'num',
            props: {
                innerHTML: this._i + 1
            },
            container: this._arrows
        });

        var append = function() {
            document.body.appendChild(that._container);
        };

        if (document.body) {
            append();
        } else {
            if (document.addEventListener) {
                document.addEventListener('DOMContentLoaded', append, false);
            } else if (document.attachEvent) {
                document.attachEvent('onload', append);
            }
        }
    },
    _errorLoading: function(e) {
        var tagName = (e.target.tagName || '').toLowerCase(),
            preparedTagName = {
                img: 'image',
                link: 'css'
            }[tagName];

        return {
            title: 'Error loading',
            message: 'Error loading ' + (preparedTagName || tagName),
            filename: e.target.src || e.target.href
        };
    },
    _getDetailedMessage: function(err) {
        var settings = this.settings,
            screen = typeof window.screen === 'object' ? window.screen : {},
            orientation = screen.orientation || screen.mozOrientation || screen.msOrientation || '',
            props = [
                ['Title', err.title || this._getTitle()],
                ['Message', this._getMessage(err)],
                ['Filename', this._getFilenameWithPosition(err)],
                ['Stack', this._getStack(err)],
                ['Page url', window.location.href],
                ['Refferer', document.referrer],
                ['User-agent', settings.userAgent || navigator.userAgent],
                ['Screen size', [screen.width, screen.height, screen.colorDepth].join('×')],
                ['Screen orientation', typeof orientation === 'string' ? orientation : orientation.type],
                ['Cookie enabled', navigator.cookieEnabled]
            ];

        var text = '';
        for (var i = 0; i < props.length; i++) {
            var item = props[i];
            text += item[0] + ': ' + item[1] + '\n';
        }

        if (settings.templateDetailedMessage) {
            text = settings.templateDetailedMessage.replace(/\{message\}/, text);
        }

        return text;
    },
    _getExtFilename: function(e) {
        var filename = e.filename,
            html = this.escapeHTML(this._getFilenameWithPosition(e));

        if (filename && filename.search(/^(https?|file):/) > -1) {
            return '' + html + '';
        } else {
            return html;
        }
    },
    _get: function(value, defaultValue) {
        return typeof value !== 'undefined' ? value : defaultValue;
    },
    _getFilenameWithPosition: function(e) {
        var text = e.filename || '';
        if (typeof e.lineno !== 'undefined') {
            text += ':' + this._get(e.lineno, '');
            if (typeof e.colno !== 'undefined') {
                text += ':' + this._get(e.colno, '');
            }
        }

        return text;
    },
    _getMessage: function(e) {
        var msg = e.message;

        // IE
        if (e.error && e.error.name && 'number' in e.error) {
            msg = e.error.name + ': ' + msg;
        }

        return msg;
    },
    _getStack: function(err) {
        return (err.error && err.error.stack) || err.stack || '';
    },
    _getTitle: function() {
        return this.settings.title || 'JavaScript error';
    },
    _show: function() {
        this._container.className = this.elemClass('', 'visible');
    },
    _highlightLinks: function(text) {
        var that = this;

        return text.replace(/(at | \(|@)(https?|file)(:.*?)(?=:\d+:\d+\)?$)/gm, function($0, $1, $2, $3) {
            var url = $2 + $3;

            return $1 + '' + url + '';
        });
    },
    _getViewSource: function(url) {
        return this._hasViewSource && url.search(/^file:/) === -1 ? 'view-source:' : '';
    },
    _update: function() {
        if (!this._appended) {
            this._append();
            this._appended = true;
        }

        var e = this._buffer[this._i],
            stack = this._getStack(e),
            filename;

        if (stack) {
            filename = this._highlightLinks(this.escapeHTML(stack));
        } else {
            filename = this._getExtFilename(e);
        }

        this._title.innerHTML = this.escapeHTML(e.title || this._getTitle());

        this._message.innerHTML = this.escapeHTML(this._getMessage(e));

        this._filename.innerHTML = filename;

        if (this._ua) {
            this._ua.innerHTML = this.escapeHTML(this.settings.userAgent);
        }

        if (this._additionalText) {
            this._additionalText.innerHTML = this.escapeHTML(this.settings.additionalText);
        }

        if (this._sendLink) {
            this._sendLink.href = this.settings.sendUrl
                .replace(/\{title\}/, encodeURIComponent(this._getMessage(e)))
                .replace(/\{body\}/, encodeURIComponent(this._getDetailedMessage(e)));
        }

        if (this._buffer.length > 1) {
            this._arrows.className = this.elemClass('arrows', 'visible');
        }

        if (this._helpLinks) {
            this._mdn.href = 'https://developer.mozilla.org/en-US/search?q=' + encodeURIComponent(e.message || e.stack || '');
            this._stackoverflow.href = 'https://stackoverflow.com/search?q=' + encodeURIComponent('[js] ' + (e.message || e.stack || ''));
        }

        this._prev.disabled = !this._i;
        this._num.innerHTML = (this._i + 1) + ' / ' + this._buffer.length;
        this._next.disabled = this._i === this._buffer.length - 1;

        this._show();
    }
};
<commit_msg>Remove settings.errorLoading<commit_after>/*! show-js-error | © 2016 Denis Seleznev | MIT License */
/* exported showJSError */
var showJSError = {
    /**
     * Initialize.
     *
     * @param {Object} [settings]
     * @param {String} [settings.title]
     * @param {String} [settings.userAgent]
     * @param {String} [settings.copyText]
     * @param {String} [settings.sendText]
     * @param {String} [settings.sendUrl]
     * @param {String} [settings.additionalText]
     * @param {Boolean} [settings.helpLinks]
     */
    init: function(settings) {
        var that = this;

        this.settings = settings || {};

        if (this._inited) {
            return;
        }

        this._inited = true;
        this._isLast = true;
        this._i = 0;
        this._buffer = [];

        // Chrome or Firefox
        this._hasViewSource = !!window.chrome || typeof InstallTrigger !== 'undefined';

        this._onerror = function(e) {
            that._buffer.push(e);
            if (that._isLast) {
                that._i = that._buffer.length - 1;
            }

            that._update();
        };

        if (window.addEventListener) {
            window.addEventListener('error', this._onerror, false);
        } else {
            this._oldOnError = window.onerror;

            window.onerror = function(message, filename, lineno, colno, error) {
                this._onerror({
                    message: message,
                    filename: filename,
                    lineno: lineno,
                    colno: colno,
                    error: error
                });

                if (typeof that._oldOnError === 'function') {
                    that._oldOnError.apply(window, arguments);
                }
            };
        }
    },
    /**
     * Destructor.
     */
    destruct: function() {
        if (!this._inited) { return; }

        if (window.addEventListener) {
            window.removeEventListener('error', this._onerror, false);
        } else {
            window.onerror = this._oldOnError || null;
            delete this._oldOnError;
        }

        if (document.body && this._container) {
            document.body.removeChild(this._container);
        }

        this._buffer = [];

        this._inited = false;
    },
    /**
     * Show error message.
     *
     * @param {String|Object|Error} err
     */
    show: function(err) {
        if (typeof err !== 'undefined') {
            this._buffer.push(typeof err === 'object' ? err : new Error(err));
        }

        this._update();
        this._show();
    },
    /**
     * Hide error message.
     */
    hide: function() {
        if (this._container) {
            this._container.className = this.elemClass('');
        }
    },
    /**
     * Copy error message to clipboard.
     */
    copyText: function() {
        var err = this._buffer[this._i],
            text = this._getDetailedMessage(err),
            body = document.body,
            textarea = this.elem({
                name: 'textarea',
                tag: 'textarea',
                props: {
                    innerHTML: text
                },
                container: body
            });

        try {
            textarea.select();
            document.execCommand('copy');
        } catch (e) {
            alert('Copying text is not supported in this browser.');
        }

        body.removeChild(textarea);
    },
    /**
     * Create a elem.
     *
     * @param {Object} data
     * @param {String} data.name
     * @param {DOMElement} data.container
     * @param {String} [data.tag]
     * @param {Object} [data.props]
     * @returns {DOMElement}
     */
    elem: function(data) {
        var el = document.createElement(data.tag || 'div'),
            props = data.props;

        for (var i in props) {
            if (props.hasOwnProperty(i)) {
                el[i] = props[i];
            }
        }

        el.className = this.elemClass(data.name);

        data.container.appendChild(el);

        return el;
    },
    /**
     * Build className for elem.
     *
     * @param {String} [name]
     * @param {String} [mod]
     * @returns {String}
     */
    elemClass: function(name, mod) {
        var cl = 'show-js-error';
        if (name) {
            cl += '__' + name;
        }

        if (mod) {
            cl += ' ' + cl + '_' + mod;
        }

        return cl;
    },
    /**
     * Escape HTML.
     *
     * @param {String} text
     * @returns {String}
     */
    escapeHTML: function(text) {
        return (text || '').replace(/[&<>"'\/]/g, function(sym) {
            return {
                '&': '&',
                '<': '<',
                '>': '>',
                '"': '"',
                '\'': ''',
                '/': '/'
            }[sym];
        });
    },
    /**
     * Toggle view (shortly/detail).
     */
    toggleDetailed: function() {
        var body = this._body;
        if (body) {
            if (this._toggleDetailed) {
                this._toggleDetailed = false;
                body.className = this.elemClass('body');
            } else {
                this._toggleDetailed = true;
                body.className = this.elemClass('body', 'detailed');
            }
        }
    },
    _append: function() {
        var that = this;

        this._container = document.createElement('div');
        this._container.className = this.elemClass('');

        this._title = this.elem({
            name: 'title',
            props: {
                innerHTML: this._getTitle()
            },
            container: this._container
        });

        this._body = this.elem({
            name: 'body',
            container: this._container
        });

        this._message = this.elem({
            name: 'message',
            props: {
                onclick: function() {
                    that.toggleDetailed();
                }
            },
            container: this._body
        });

        if (this.settings.helpLinks) {
            this._helpLinks = this.elem({
                name: 'help',
                container: this._body
            });

            this._mdn = this.elem({
                tag: 'a',
                name: 'mdn',
                props: {
                    target: '_blank',
                    innerHTML: 'MDN'
                },
                container: this._helpLinks
            });

            this._stackoverflow = this.elem({
                tag: 'a',
                name: 'stackoverflow',
                props: {
                    target: '_blank',
                    innerHTML: 'Stack Overflow'
                },
                container: this._helpLinks
            });
        }

        this._filename = this.elem({
            name: 'filename',
            container: this._body
        });

        if (this.settings.userAgent) {
            this._ua = this.elem({
                name: 'ua',
                container: this._body
            });
        }

        if (this.settings.additionalText) {
            this._additionalText = this.elem({
                name: 'additional-text',
                container: this._body
            });
        }

        this.elem({
            name: 'close',
            props: {
                innerHTML: '×',
                onclick: function() {
                    that.hide();
                }
            },
            container: this._container
        });

        this._actions = this.elem({
            name: 'actions',
            container: this._container
        });

        this.elem({
            tag: 'input',
            name: 'copy',
            props: {
                type: 'button',
                value: this.settings.copyText || 'Copy',
                onclick: function() {
                    that.copyText();
                }
            },
            container: this._actions
        });

        if (this.settings.sendUrl) {
            this._sendLink = this.elem({
                tag: 'a',
                name: 'send-link',
                props: {
                    href: '',
                    target: '_blank'
                },
                container: this._actions
            });

            this._send = this.elem({
                tag: 'input',
                name: 'send',
                props: {
                    type: 'button',
                    value: this.settings.sendText || 'Send'
                },
                container: this._sendLink
            });
        }

        this._arrows = this.elem({
            tag: 'span',
            name: 'arrows',
            container: this._actions
        });

        this._prev = this.elem({
            tag: 'input',
            name: 'prev',
            props: {
                type: 'button',
                value: '←',
                onclick: function() {
                    that._isLast = false;
                    if (that._i) {
                        that._i--;
                    }

                    that._update();
                }
            },
            container: this._arrows
        });

        this._next = this.elem({
            tag: 'input',
            name: 'next',
            props: {
                type: 'button',
                value: '→',
                onclick: function() {
                    that._isLast = false;
                    if (that._i < that._buffer.length - 1) {
                        that._i++;
                    }

                    that._update();
                }
            },
            container: this._arrows
        });

        this._num = this.elem({
            tag: 'span',
            name: 'num',
            props: {
                innerHTML: this._i + 1
            },
            container: this._arrows
        });

        var append = function() {
            document.body.appendChild(that._container);
        };

        if (document.body) {
            append();
        } else {
            if (document.addEventListener) {
                document.addEventListener('DOMContentLoaded', append, false);
            } else if (document.attachEvent) {
                document.attachEvent('onload', append);
            }
        }
    },
    _getDetailedMessage: function(err) {
        var settings = this.settings,
            screen = typeof window.screen === 'object' ? window.screen : {},
            orientation = screen.orientation || screen.mozOrientation || screen.msOrientation || '',
            props = [
                ['Title', err.title || this._getTitle()],
                ['Message', this._getMessage(err)],
                ['Filename', this._getFilenameWithPosition(err)],
                ['Stack', this._getStack(err)],
                ['Page url', window.location.href],
                ['Refferer', document.referrer],
                ['User-agent', settings.userAgent || navigator.userAgent],
                ['Screen size', [screen.width, screen.height, screen.colorDepth].join('×')],
                ['Screen orientation', typeof orientation === 'string' ? orientation : orientation.type],
                ['Cookie enabled', navigator.cookieEnabled]
            ];

        var text = '';
        for (var i = 0; i < props.length; i++) {
            var item = props[i];
            text += item[0] + ': ' + item[1] + '\n';
        }

        if (settings.templateDetailedMessage) {
            text = settings.templateDetailedMessage.replace(/\{message\}/, text);
        }

        return text;
    },
    _getExtFilename: function(e) {
        var filename = e.filename,
            html = this.escapeHTML(this._getFilenameWithPosition(e));

        if (filename && filename.search(/^(https?|file):/) > -1) {
            return '' + html + '';
        } else {
            return html;
        }
    },
    _get: function(value, defaultValue) {
        return typeof value !== 'undefined' ? value : defaultValue;
    },
    _getFilenameWithPosition: function(e) {
        var text = e.filename || '';
        if (typeof e.lineno !== 'undefined') {
            text += ':' + this._get(e.lineno, '');
            if (typeof e.colno !== 'undefined') {
                text += ':' + this._get(e.colno, '');
            }
        }

        return text;
    },
    _getMessage: function(e) {
        var msg = e.message;

        // IE
        if (e.error && e.error.name && 'number' in e.error) {
            msg = e.error.name + ': ' + msg;
        }

        return msg;
    },
    _getStack: function(err) {
        return (err.error && err.error.stack) || err.stack || '';
    },
    _getTitle: function() {
        return this.settings.title || 'JavaScript error';
    },
    _show: function() {
        this._container.className = this.elemClass('', 'visible');
    },
    _highlightLinks: function(text) {
        var that = this;

        return text.replace(/(at | \(|@)(https?|file)(:.*?)(?=:\d+:\d+\)?$)/gm, function($0, $1, $2, $3) {
            var url = $2 + $3;

            return $1 + '' + url + '';
        });
    },
    _getViewSource: function(url) {
        return this._hasViewSource && url.search(/^file:/) === -1 ? 'view-source:' : '';
    },
    _update: function() {
        if (!this._appended) {
            this._append();
            this._appended = true;
        }

        var e = this._buffer[this._i],
            stack = this._getStack(e),
            filename;

        if (stack) {
            filename = this._highlightLinks(this.escapeHTML(stack));
        } else {
            filename = this._getExtFilename(e);
        }

        this._title.innerHTML = this.escapeHTML(e.title || this._getTitle());

        this._message.innerHTML = this.escapeHTML(this._getMessage(e));

        this._filename.innerHTML = filename;

        if (this._ua) {
            this._ua.innerHTML = this.escapeHTML(this.settings.userAgent);
        }

        if (this._additionalText) {
            this._additionalText.innerHTML = this.escapeHTML(this.settings.additionalText);
        }

        if (this._sendLink) {
            this._sendLink.href = this.settings.sendUrl
                .replace(/\{title\}/, encodeURIComponent(this._getMessage(e)))
                .replace(/\{body\}/, encodeURIComponent(this._getDetailedMessage(e)));
        }

        if (this._buffer.length > 1) {
            this._arrows.className = this.elemClass('arrows', 'visible');
        }

        if (this._helpLinks) {
            this._mdn.href = 'https://developer.mozilla.org/en-US/search?q=' + encodeURIComponent(e.message || e.stack || '');
            this._stackoverflow.href = 'https://stackoverflow.com/search?q=' + encodeURIComponent('[js] ' + (e.message || e.stack || ''));
        }

        this._prev.disabled = !this._i;
        this._num.innerHTML = (this._i + 1) + ' / ' + this._buffer.length;
        this._next.disabled = this._i === this._buffer.length - 1;

        this._show();
    }
};
<|endoftext|>


<commit_before>export default [
  {
    type: 'select',
    input: true,
    weight: 100,
    key: 'currency',
    label: 'Currency',
    tooltip: 'The currency to use in currency formatting. Possible values are (ISO-4217) currency codes.',
    defaultValue: 'USD',
    dataSrc: 'values',
    data: {
      values: [
        { label: 'US Dollar (USD)', value: 'USD' },
        { label: 'Euro (EUR)', value: 'EUR' },
        { label: 'Pound Sterling (GBP)', value: 'GBP' },
        { label: 'Australian Dollar (AUD)', value: 'AUD' },
        { label: 'Afghani (AFN)', value: 'AFN' },
        { label: 'Lek (ALL)', value: 'ALL' },
        { label: 'Algerian Dinar (DZD)', value: 'DZD' },
        { label: 'Kwanza (AOA)', value: 'AOA' },
        { label: 'East Caribbean Dollar (XCD)', value: 'XCD' },
        { label: 'Argentine Peso (ARS)', value: 'ARS' },
        { label: 'Armenian Dram (AMD)', value: 'AMD' },
        { label: 'Aruban Florin (AWG)', value: 'AWG' },
        { label: 'Azerbaijan Manat (AZN)', value: 'AZN' },
        { label: 'Bahamian Dollar (BSD)', value: 'BSD' },
        { label: 'Bahraini Dinar (BHD)', value: 'BHD' },
        { label: 'Taka (BDT)', value: 'BDT' },
        { label: 'Barbados Dollar (BBD)', value: 'BBD' },
        { label: 'Belarusian Ruble (BYN)', value: 'BYN' },
        { label: 'Belize Dollar (BZD)', value: 'BZD' },
        { label: 'CFA Franc BCEAO (XOF)', value: 'XOF' },
        { label: 'Bermudian Dollar (BMD)', value: 'BMD' },
        { label: 'Indian Rupee (INR)', value: 'INR' },
        { label: 'Ngultrum (BTN)', value: 'BTN' },
        { label: 'Boliviano (BOB)', value: 'BOB' },
        { label: 'Mvdol (BOV)', value: 'BOV' },
        { label: 'Convertible Mark (BAM)', value: 'BAM' },
        { label: 'Pula (BWP)', value: 'BWP' },
        { label: 'Norwegian Krone (NOK)', value: 'NOK' },
        { label: 'Brazilian Real (BRL)', value: 'BRL' },
        { label: 'Brunei Dollar (BND)', value: 'BND' },
        { label: 'Bulgarian Lev (BGN)', value: 'BGN' },
        { label: 'Burundi Franc (BIF)', value: 'BIF' },
        { label: 'Cabo Verde Escudo (CVE)', value: 'CVE' },
        { label: 'Riel (KHR)', value: 'KHR' },
        { label: 'CFA Franc BEAC (XAF)', value: 'XAF' },
        { label: 'Canadian Dollar (CAD)', value: 'CAD' },
        { label: 'Cayman Islands Dollar (KYD)', value: 'KYD' },
        { label: 'Chilean Peso (CLP)', value: 'CLP' },
        { label: 'Unidad de Fomento (CLF)', value: 'CLF' },
        { label: 'Yuan Renminbi (CNY)', value: 'CNY' },
        { label: 'Colombian Peso (COP)', value: 'COP' },
        { label: 'Unidad de Valor Real (COU)', value: 'COU' },
        { label: 'Comorian Franc (KMF)', value: 'KMF' },
        { label: 'Congolese Franc (CDF)', value: 'CDF' },
        { label: 'New Zealand Dollar (NZD)', value: 'NZD' },
        { label: 'Costa Rican Colon (CRC)', value: 'CRC' },
        { label: 'Kuna (HRK)', value: 'HRK' },
        { label: 'Cuban Peso (CUP)', value: 'CUP' },
        { label: 'Peso Convertible (CUC)', value: 'CUC' },
        { label: 'Netherlands Antillean Guilder (ANG)', value: 'ANG' },
        { label: 'Czech Koruna (CZK)', value: 'CZK' },
        { label: 'Danish Krone (DKK)', value: 'DKK' },
        { label: 'Djibouti Franc (DJF)', value: 'DJF' },
        { label: 'Dominican Peso (DOP)', value: 'DOP' },
        { label: 'Egyptian Pound (EGP)', value: 'EGP' },
        { label: 'El Salvador Colon (SVC)', value: 'SVC' },
        { label: 'Nakfa (ERN)', value: 'ERN' },
        { label: 'Ethiopian Birr (ETB)', value: 'ETB' },
        { label: 'Falkland Islands Pound (FKP)', value: 'FKP' },
        { label: 'Fiji Dollar (FJD)', value: 'FJD' },
        { label: 'CFP Franc (XPF)', value: 'XPF' },
        { label: 'Dalasi (GMD)', value: 'GMD' },
        { label: 'Lari (GEL)', value: 'GEL' },
        { label: 'Ghana Cedi (GHS)', value: 'GHS' },
        { label: 'Gibraltar Pound (GIP)', value: 'GIP' },
        { label: 'Quetzal (GTQ)', value: 'GTQ' },
        { label: 'Guinean Franc (GNF)', value: 'GNF' },
        { label: 'Guyana Dollar (GYD)', value: 'GYD' },
        { label: 'Gourde (HTG)', value: 'HTG' },
        { label: 'Lempira (HNL)', value: 'HNL' },
        { label: 'Hong Kong Dollar (HKD)', value: 'HKD' },
        { label: 'Forint (HUF)', value: 'HUF' },
        { label: 'Iceland Krona (ISK)', value: 'ISK' },
        { label: 'Indian Rupee (INR)', value: 'INR' },
        { label: 'Rupiah (IDR)', value: 'IDR' },
        { label: 'SDR (Special Drawing Right) (XDR)', value: 'XDR' },
        { label: 'Iranian Rial (IRR)', value: 'IRR' },
        { label: 'Iraqi Dinar (IQD)', value: 'IQD' },
        { label: 'New Israeli Sheqel (ILS)', value: 'ILS' },
        { label: 'Jamaican Dollar (JMD)', value: 'JMD' },
        { label: 'Yen (JPY)', value: 'JPY' },
        { label: 'Jordanian Dinar (JOD)', value: 'JOD' },
        { label: 'Tenge (KZT)', value: 'KZT' },
        { label: 'Kenyan Shilling (KES)', value: 'KES' },
        { label: 'North Korean Won (KPW)', value: 'KPW' },
        { label: 'Won (KRW)', value: 'KRW' },
        { label: 'Kuwaiti Dinar (KWD)', value: 'KWD' },
        { label: 'Som (KGS)', value: 'KGS' },
        { label: 'Lao Kip (LAK)', value: 'LAK' },
        { label: 'Lebanese Pound (LBP)', value: 'LBP' },
        { label: 'Loti (LSL)', value: 'LSL' },
        { label: 'Rand (ZAR)', value: 'ZAR' },
        { label: 'Liberian Dollar (LRD)', value: 'LRD' },
        { label: 'Libyan Dinar (LYD)', value: 'LYD' },
        { label: 'Swiss Franc (CHF)', value: 'CHF' },
        { label: 'Pataca (MOP)', value: 'MOP' },
        { label: 'Denar (MKD)', value: 'MKD' },
        { label: 'Malagasy Ariary (MGA)', value: 'MGA' },
        { label: 'Malawi Kwacha (MWK)', value: 'MWK' },
        { label: 'Malaysian Ringgit (MYR)', value: 'MYR' },
        { label: 'Rufiyaa (MVR)', value: 'MVR' },
        { label: 'Ouguiya (MRU)', value: 'MRU' },
        { label: 'Mauritius Rupee (MUR)', value: 'MUR' },
        { label: 'ADB Unit of Account (XUA)', value: 'XUA' },
        { label: 'Mexican Peso (MXN)', value: 'MXN' },
        { label: 'Mexican Unidad de Inversion (UDI) (MXV)', value: 'MXV' },
        { label: 'Moldovan Leu (MDL)', value: 'MDL' },
        { label: 'Tugrik (MNT)', value: 'MNT' },
        { label: 'Moroccan Dirham (MAD)', value: 'MAD' },
        { label: 'Mozambique Metical (MZN)', value: 'MZN' },
        { label: 'Kyat (MMK)', value: 'MMK' },
        { label: 'Namibia Dollar (NAD)', value: 'NAD' },
        { label: 'Nepalese Rupee (NPR)', value: 'NPR' },
        { label: 'Cordoba Oro (NIO)', value: 'NIO' },
        { label: 'Naira (NGN)', value: 'NGN' },
        { label: 'Rial Omani (OMR)', value: 'OMR' },
        { label: 'Pakistan Rupee (PKR)', value: 'PKR' },
        { label: 'Balboa (PAB)', value: 'PAB' },
        { label: 'Kina (PGK)', value: 'PGK' },
        { label: 'Guarani (PYG)', value: 'PYG' },
        { label: 'Sol (PEN)', value: 'PEN' },
        { label: 'Philippine Peso (PHP)', value: 'PHP' },
        { label: 'Zloty (PLN)', value: 'PLN' },
        { label: 'Qatari Rial (QAR)', value: 'QAR' },
        { label: 'Romanian Leu (RON)', value: 'RON' },
        { label: 'Russian Ruble (RUB)', value: 'RUB' },
        { label: 'Rwanda Franc (RWF)', value: 'RWF' },
        { label: 'Saint Helena Pound (SHP)', value: 'SHP' },
        { label: 'Tala (WST)', value: 'WST' },
        { label: 'Dobra (STN)', value: 'STN' },
        { label: 'Saudi Riyal (SAR)', value: 'SAR' },
        { label: 'Serbian Dinar (RSD)', value: 'RSD' },
        { label: 'Seychelles Rupee (SCR)', value: 'SCR' },
        { label: 'Leone (SLL)', value: 'SLL' },
        { label: 'Singapore Dollar (SGD)', value: 'SGD' },
        { label: 'Sucre (XSU)', value: 'XSU' },
        { label: 'Solomon Islands Dollar (SBD)', value: 'SBD' },
        { label: 'Somali Shilling (SOS)', value: 'SOS' },
        { label: 'South Sudanese Pound (SSP)', value: 'SSP' },
        { label: 'Sri Lanka Rupee (LKR)', value: 'LKR' },
        { label: 'Sudanese Pound (SDG)', value: 'SDG' },
        { label: 'Surinam Dollar (SRD)', value: 'SRD' },
        { label: 'Lilangeni (SZL)', value: 'SZL' },
        { label: 'Swedish Krona (SEK)', value: 'SEK' },
        { label: 'WIR Euro (CHE)', value: 'CHE' },
        { label: 'WIR Franc (CHW)', value: 'CHW' },
        { label: 'Syrian Pound (SYP)', value: 'SYP' },
        { label: 'New Taiwan Dollar (TWD)', value: 'TWD' },
        { label: 'Somoni (TJS)', value: 'TJS' },
        { label: 'Tanzanian Shilling (TZS)', value: 'TZS' },
        { label: 'Baht (THB)', value: 'THB' },
        { label: 'Pa’anga (TOP)', value: 'TOP' },
        { label: 'Trinidad and Tobago Dollar (TTD)', value: 'TTD' },
        { label: 'Tunisian Dinar (TND)', value: 'TND' },
        { label: 'Turkish Lira (TRY)', value: 'TRY' },
        { label: 'Turkmenistan New Manat (TMT)', value: 'TMT' },
        { label: 'Uganda Shilling (UGX)', value: 'UGX' },
        { label: 'Hryvnia (UAH)', value: 'UAH' },
        { label: 'UAE Dirham (AED)', value: 'AED' },
        { label: 'US Dollar (Next day) (USN)', value: 'USN' },
        { label: 'Peso Uruguayo (UYU)', value: 'UYU' },
        { label: 'Uruguay Peso en Unidades Indexadas (UYI)', value: 'UYI' },
        { label: 'Unidad Previsional (UYW)', value: 'UYW' },
        { label: 'Uzbekistan Sum (UZS)', value: 'UZS' },
        { label: 'Vatu (VUV)', value: 'VUV' },
        { label: 'Bolívar Soberano (VES)', value: 'VES' },
        { label: 'Dong (VND)', value: 'VND' },
        { label: 'Yemeni Rial (YER)', value: 'YER' },
        { label: 'Zambian Kwacha (ZMW)', value: 'ZMW' },
        { label: 'Zimbabwe Dollar (ZWL),', value:  'ZWL' }
      ]
    }
  }
];
<commit_msg> increase weight for currency control.<commit_after>export default [
  {
    type: 'select',
    input: true,
    weight: 50,
    key: 'currency',
    label: 'Currency',
    tooltip: 'The currency to use in currency formatting. Possible values are (ISO-4217) currency codes.',
    defaultValue: 'USD',
    dataSrc: 'values',
    data: {
      values: [
        { label: 'US Dollar (USD)', value: 'USD' },
        { label: 'Euro (EUR)', value: 'EUR' },
        { label: 'Pound Sterling (GBP)', value: 'GBP' },
        { label: 'Australian Dollar (AUD)', value: 'AUD' },
        { label: 'Afghani (AFN)', value: 'AFN' },
        { label: 'Lek (ALL)', value: 'ALL' },
        { label: 'Algerian Dinar (DZD)', value: 'DZD' },
        { label: 'Kwanza (AOA)', value: 'AOA' },
        { label: 'East Caribbean Dollar (XCD)', value: 'XCD' },
        { label: 'Argentine Peso (ARS)', value: 'ARS' },
        { label: 'Armenian Dram (AMD)', value: 'AMD' },
        { label: 'Aruban Florin (AWG)', value: 'AWG' },
        { label: 'Azerbaijan Manat (AZN)', value: 'AZN' },
        { label: 'Bahamian Dollar (BSD)', value: 'BSD' },
        { label: 'Bahraini Dinar (BHD)', value: 'BHD' },
        { label: 'Taka (BDT)', value: 'BDT' },
        { label: 'Barbados Dollar (BBD)', value: 'BBD' },
        { label: 'Belarusian Ruble (BYN)', value: 'BYN' },
        { label: 'Belize Dollar (BZD)', value: 'BZD' },
        { label: 'CFA Franc BCEAO (XOF)', value: 'XOF' },
        { label: 'Bermudian Dollar (BMD)', value: 'BMD' },
        { label: 'Indian Rupee (INR)', value: 'INR' },
        { label: 'Ngultrum (BTN)', value: 'BTN' },
        { label: 'Boliviano (BOB)', value: 'BOB' },
        { label: 'Mvdol (BOV)', value: 'BOV' },
        { label: 'Convertible Mark (BAM)', value: 'BAM' },
        { label: 'Pula (BWP)', value: 'BWP' },
        { label: 'Norwegian Krone (NOK)', value: 'NOK' },
        { label: 'Brazilian Real (BRL)', value: 'BRL' },
        { label: 'Brunei Dollar (BND)', value: 'BND' },
        { label: 'Bulgarian Lev (BGN)', value: 'BGN' },
        { label: 'Burundi Franc (BIF)', value: 'BIF' },
        { label: 'Cabo Verde Escudo (CVE)', value: 'CVE' },
        { label: 'Riel (KHR)', value: 'KHR' },
        { label: 'CFA Franc BEAC (XAF)', value: 'XAF' },
        { label: 'Canadian Dollar (CAD)', value: 'CAD' },
        { label: 'Cayman Islands Dollar (KYD)', value: 'KYD' },
        { label: 'Chilean Peso (CLP)', value: 'CLP' },
        { label: 'Unidad de Fomento (CLF)', value: 'CLF' },
        { label: 'Yuan Renminbi (CNY)', value: 'CNY' },
        { label: 'Colombian Peso (COP)', value: 'COP' },
        { label: 'Unidad de Valor Real (COU)', value: 'COU' },
        { label: 'Comorian Franc (KMF)', value: 'KMF' },
        { label: 'Congolese Franc (CDF)', value: 'CDF' },
        { label: 'New Zealand Dollar (NZD)', value: 'NZD' },
        { label: 'Costa Rican Colon (CRC)', value: 'CRC' },
        { label: 'Kuna (HRK)', value: 'HRK' },
        { label: 'Cuban Peso (CUP)', value: 'CUP' },
        { label: 'Peso Convertible (CUC)', value: 'CUC' },
        { label: 'Netherlands Antillean Guilder (ANG)', value: 'ANG' },
        { label: 'Czech Koruna (CZK)', value: 'CZK' },
        { label: 'Danish Krone (DKK)', value: 'DKK' },
        { label: 'Djibouti Franc (DJF)', value: 'DJF' },
        { label: 'Dominican Peso (DOP)', value: 'DOP' },
        { label: 'Egyptian Pound (EGP)', value: 'EGP' },
        { label: 'El Salvador Colon (SVC)', value: 'SVC' },
        { label: 'Nakfa (ERN)', value: 'ERN' },
        { label: 'Ethiopian Birr (ETB)', value: 'ETB' },
        { label: 'Falkland Islands Pound (FKP)', value: 'FKP' },
        { label: 'Fiji Dollar (FJD)', value: 'FJD' },
        { label: 'CFP Franc (XPF)', value: 'XPF' },
        { label: 'Dalasi (GMD)', value: 'GMD' },
        { label: 'Lari (GEL)', value: 'GEL' },
        { label: 'Ghana Cedi (GHS)', value: 'GHS' },
        { label: 'Gibraltar Pound (GIP)', value: 'GIP' },
        { label: 'Quetzal (GTQ)', value: 'GTQ' },
        { label: 'Guinean Franc (GNF)', value: 'GNF' },
        { label: 'Guyana Dollar (GYD)', value: 'GYD' },
        { label: 'Gourde (HTG)', value: 'HTG' },
        { label: 'Lempira (HNL)', value: 'HNL' },
        { label: 'Hong Kong Dollar (HKD)', value: 'HKD' },
        { label: 'Forint (HUF)', value: 'HUF' },
        { label: 'Iceland Krona (ISK)', value: 'ISK' },
        { label: 'Indian Rupee (INR)', value: 'INR' },
        { label: 'Rupiah (IDR)', value: 'IDR' },
        { label: 'SDR (Special Drawing Right) (XDR)', value: 'XDR' },
        { label: 'Iranian Rial (IRR)', value: 'IRR' },
        { label: 'Iraqi Dinar (IQD)', value: 'IQD' },
        { label: 'New Israeli Sheqel (ILS)', value: 'ILS' },
        { label: 'Jamaican Dollar (JMD)', value: 'JMD' },
        { label: 'Yen (JPY)', value: 'JPY' },
        { label: 'Jordanian Dinar (JOD)', value: 'JOD' },
        { label: 'Tenge (KZT)', value: 'KZT' },
        { label: 'Kenyan Shilling (KES)', value: 'KES' },
        { label: 'North Korean Won (KPW)', value: 'KPW' },
        { label: 'Won (KRW)', value: 'KRW' },
        { label: 'Kuwaiti Dinar (KWD)', value: 'KWD' },
        { label: 'Som (KGS)', value: 'KGS' },
        { label: 'Lao Kip (LAK)', value: 'LAK' },
        { label: 'Lebanese Pound (LBP)', value: 'LBP' },
        { label: 'Loti (LSL)', value: 'LSL' },
        { label: 'Rand (ZAR)', value: 'ZAR' },
        { label: 'Liberian Dollar (LRD)', value: 'LRD' },
        { label: 'Libyan Dinar (LYD)', value: 'LYD' },
        { label: 'Swiss Franc (CHF)', value: 'CHF' },
        { label: 'Pataca (MOP)', value: 'MOP' },
        { label: 'Denar (MKD)', value: 'MKD' },
        { label: 'Malagasy Ariary (MGA)', value: 'MGA' },
        { label: 'Malawi Kwacha (MWK)', value: 'MWK' },
        { label: 'Malaysian Ringgit (MYR)', value: 'MYR' },
        { label: 'Rufiyaa (MVR)', value: 'MVR' },
        { label: 'Ouguiya (MRU)', value: 'MRU' },
        { label: 'Mauritius Rupee (MUR)', value: 'MUR' },
        { label: 'ADB Unit of Account (XUA)', value: 'XUA' },
        { label: 'Mexican Peso (MXN)', value: 'MXN' },
        { label: 'Mexican Unidad de Inversion (UDI) (MXV)', value: 'MXV' },
        { label: 'Moldovan Leu (MDL)', value: 'MDL' },
        { label: 'Tugrik (MNT)', value: 'MNT' },
        { label: 'Moroccan Dirham (MAD)', value: 'MAD' },
        { label: 'Mozambique Metical (MZN)', value: 'MZN' },
        { label: 'Kyat (MMK)', value: 'MMK' },
        { label: 'Namibia Dollar (NAD)', value: 'NAD' },
        { label: 'Nepalese Rupee (NPR)', value: 'NPR' },
        { label: 'Cordoba Oro (NIO)', value: 'NIO' },
        { label: 'Naira (NGN)', value: 'NGN' },
        { label: 'Rial Omani (OMR)', value: 'OMR' },
        { label: 'Pakistan Rupee (PKR)', value: 'PKR' },
        { label: 'Balboa (PAB)', value: 'PAB' },
        { label: 'Kina (PGK)', value: 'PGK' },
        { label: 'Guarani (PYG)', value: 'PYG' },
        { label: 'Sol (PEN)', value: 'PEN' },
        { label: 'Philippine Peso (PHP)', value: 'PHP' },
        { label: 'Zloty (PLN)', value: 'PLN' },
        { label: 'Qatari Rial (QAR)', value: 'QAR' },
        { label: 'Romanian Leu (RON)', value: 'RON' },
        { label: 'Russian Ruble (RUB)', value: 'RUB' },
        { label: 'Rwanda Franc (RWF)', value: 'RWF' },
        { label: 'Saint Helena Pound (SHP)', value: 'SHP' },
        { label: 'Tala (WST)', value: 'WST' },
        { label: 'Dobra (STN)', value: 'STN' },
        { label: 'Saudi Riyal (SAR)', value: 'SAR' },
        { label: 'Serbian Dinar (RSD)', value: 'RSD' },
        { label: 'Seychelles Rupee (SCR)', value: 'SCR' },
        { label: 'Leone (SLL)', value: 'SLL' },
        { label: 'Singapore Dollar (SGD)', value: 'SGD' },
        { label: 'Sucre (XSU)', value: 'XSU' },
        { label: 'Solomon Islands Dollar (SBD)', value: 'SBD' },
        { label: 'Somali Shilling (SOS)', value: 'SOS' },
        { label: 'South Sudanese Pound (SSP)', value: 'SSP' },
        { label: 'Sri Lanka Rupee (LKR)', value: 'LKR' },
        { label: 'Sudanese Pound (SDG)', value: 'SDG' },
        { label: 'Surinam Dollar (SRD)', value: 'SRD' },
        { label: 'Lilangeni (SZL)', value: 'SZL' },
        { label: 'Swedish Krona (SEK)', value: 'SEK' },
        { label: 'WIR Euro (CHE)', value: 'CHE' },
        { label: 'WIR Franc (CHW)', value: 'CHW' },
        { label: 'Syrian Pound (SYP)', value: 'SYP' },
        { label: 'New Taiwan Dollar (TWD)', value: 'TWD' },
        { label: 'Somoni (TJS)', value: 'TJS' },
        { label: 'Tanzanian Shilling (TZS)', value: 'TZS' },
        { label: 'Baht (THB)', value: 'THB' },
        { label: 'Pa’anga (TOP)', value: 'TOP' },
        { label: 'Trinidad and Tobago Dollar (TTD)', value: 'TTD' },
        { label: 'Tunisian Dinar (TND)', value: 'TND' },
        { label: 'Turkish Lira (TRY)', value: 'TRY' },
        { label: 'Turkmenistan New Manat (TMT)', value: 'TMT' },
        { label: 'Uganda Shilling (UGX)', value: 'UGX' },
        { label: 'Hryvnia (UAH)', value: 'UAH' },
        { label: 'UAE Dirham (AED)', value: 'AED' },
        { label: 'US Dollar (Next day) (USN)', value: 'USN' },
        { label: 'Peso Uruguayo (UYU)', value: 'UYU' },
        { label: 'Uruguay Peso en Unidades Indexadas (UYI)', value: 'UYI' },
        { label: 'Unidad Previsional (UYW)', value: 'UYW' },
        { label: 'Uzbekistan Sum (UZS)', value: 'UZS' },
        { label: 'Vatu (VUV)', value: 'VUV' },
        { label: 'Bolívar Soberano (VES)', value: 'VES' },
        { label: 'Dong (VND)', value: 'VND' },
        { label: 'Yemeni Rial (YER)', value: 'YER' },
        { label: 'Zambian Kwacha (ZMW)', value: 'ZMW' },
        { label: 'Zimbabwe Dollar (ZWL),', value:  'ZWL' }
      ]
    }
  }
];
<|endoftext|>


<commit_before>process.env.NODE_ENV = 'test';
const mongoose = require('mongoose');

let chai = require('chai');
let chaiHttp = require('chai-http');
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
const PassThrough = require('stream').PassThrough;
const server = require('../index');
let should = chai.should();
const nconf = require('../config/nconf.js');
const spotifyWebApi = require('spotify-web-api-node');

const loginController = require('../controllers/loginController');
const Stub = require('./stub');

chai.use(chaiHttp);
chai.use(sinonChai);

let stubAuth, stubGetMe, stubGetUserPlaylists, stubGetPlaylistTracks;

describe('Login:', () => {
  let request, response;
  beforeEach(() => {
    request = {
      spotifyApi: new spotifyWebApi({
        clientId : 'SPOTIFY_CLIENT_ID',
        clientSecret : 'SPOTIFY_CLIENT_SECRET',
        redirectUri : 'SPOTIFY_REDIRECT_URI'
      })
    };

    stubAuth = Stub.createStub(request.spotifyApi, 'authorizationCodeGrant',
      {
        statusCode: 200,
        body: { access_token: 'token' }
      });

    stubGetMe = Stub.createStub(request.spotifyApi, 'getMe',
      {
        body: {
          country: 'ES',
          display_name: 'Ro Rey',
          email: 'someone@gmail.com',
          external_urls: { spotify: 'https://open.spotify.com/user/djdjdjdj' },
          followers: { href: null, total: 0 },
          href: 'https://api.spotify.com/v1/users/djdjdjdj',
          id: 'ou2o3iu453245',
          images: [ [Object] ],
          product: 'open',
          type: 'user',
          uri: 'spotify:user:djdjdjdj'
        }
      });

    stubGetUserPlaylists = Stub.createStub(request.spotifyApi, 'getUserPlaylists', { body: { items: [{id: 3838383}, {id: 393939}] }});

    stubGetPlaylistTracks = Stub.createStub(request.spotifyApi, 'getPlaylistTracks', { body: { items: [{track: {id: 2423}}, {track: {id: 7474}}, {track: {id: 92929}}, {track: {id: 94949}}]}});

    response = {};
  });

  afterEach(() => {
    Stub.removeStub(stubAuth);
    Stub.removeStub(stubGetMe);
    Stub.removeStub(stubGetUserPlaylists);
    Stub.removeStub(stubGetPlaylistTracks);

    response = {};
  });

  it('login should succeed given proper user credentials', (done) => {
    request.body = {
      code: '83838383k3i'
    };

    response.send = (obj) => {
      try {
        response.status.should.be.eq(200);
        obj.should.be.a('object');
        obj.should.have.property('userToken');
        obj.should.have.property('name');
        done();
      } catch (err) {
        done(err);
      }

    };

    loginController.login(request, response);

  });

  it('login should fail without an authorization code', (done) => {
    request.body = {};

    response.sendStatus = (status) => {
      try {
        status.should.be.eq(400);
        done();
      } catch (err) {
        done(err);
      }
    };

    loginController.login(request, response);

  });

});
<commit_msg>refactor: add test to check login failure without proper Spotifiy credentials<commit_after>process.env.NODE_ENV = 'test';
const mongoose = require('mongoose');

let chai = require('chai');
let chaiHttp = require('chai-http');
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
const PassThrough = require('stream').PassThrough;
const server = require('../index');
let should = chai.should();
const nconf = require('../config/nconf.js');
const spotifyWebApi = require('spotify-web-api-node');

const loginController = require('../controllers/loginController');
const Stub = require('./stub');

chai.use(chaiHttp);
chai.use(sinonChai);

let stubAuth, stubGetMe, stubGetUserPlaylists, stubGetPlaylistTracks;

describe('Login:', () => {
  let request, response;
  beforeEach(() => {
    request = {
      spotifyApi: new spotifyWebApi({
        clientId : 'SPOTIFY_CLIENT_ID',
        clientSecret : 'SPOTIFY_CLIENT_SECRET',
        redirectUri : 'SPOTIFY_REDIRECT_URI'
      })
    };

    stubAuth = Stub.createStub(request.spotifyApi, 'authorizationCodeGrant',
      {
        statusCode: 200,
        body: { access_token: 'token' }
      });

    stubGetMe = Stub.createStub(request.spotifyApi, 'getMe',
      {
        body: {
          country: 'ES',
          display_name: 'Ro Rey',
          email: 'someone@gmail.com',
          external_urls: { spotify: 'https://open.spotify.com/user/djdjdjdj' },
          followers: { href: null, total: 0 },
          href: 'https://api.spotify.com/v1/users/djdjdjdj',
          id: 'ou2o3iu453245',
          images: [ [Object] ],
          product: 'open',
          type: 'user',
          uri: 'spotify:user:djdjdjdj'
        }
      });

    stubGetUserPlaylists = Stub.createStub(request.spotifyApi, 'getUserPlaylists', { body: { items: [{id: 3838383}, {id: 393939}] }});

    stubGetPlaylistTracks = Stub.createStub(request.spotifyApi, 'getPlaylistTracks', { body: { items: [{track: {id: 2423}}, {track: {id: 7474}}, {track: {id: 92929}}, {track: {id: 94949}}]}});

    response = {};
  });

  afterEach(() => {
    Stub.removeStub(stubAuth);
    Stub.removeStub(stubGetMe);
    Stub.removeStub(stubGetUserPlaylists);
    Stub.removeStub(stubGetPlaylistTracks);

    response = {};
  });

  it('login should succeed given proper user credentials', (done) => {
    request.body = {
      code: '83838383k3i'
    };

    response.send = (obj) => {
      try {
        response.status.should.be.eq(200);
        obj.should.be.a('object');
        obj.should.have.property('userToken');
        obj.should.have.property('name');
        done();
      } catch (err) {
        done(err);
      }

    };

    loginController.login(request, response);

  });

  it('login should fail without an authorization code', (done) => {
    request.body = {};

    response.sendStatus = (status) => {
      try {
        status.should.be.eq(400);
        done();
      } catch (err) {
        done(err);
      }
    };

    loginController.login(request, response);

  });

  it('login should fail without proper Spotify API credentials', (done) => {
    request = {
      body: {
        code: '83838383k3i'
      },
      spotifyApi: new spotifyWebApi({
        clientId : null,
        clientSecret : null,
        redirectUri : 'SPOTIFY_REDIRECT_URI'
      })
    };

    stubAuth.restore();

    stubAuth = Stub.createStub(request.spotifyApi, 'authorizationCodeGrant',
      {
        statusCode: 400,
        body: {}
      });

    response.sendStatus = (status) => {
      try {
        status.should.be.eq(400);
        done();
      } catch (err) {
        done(err);
      }
    };

    loginController.login(request, response);

  });

});
<|endoftext|>


<commit_before>// This file contains the scripts that are called when the buttons on the interface are pressed.

var NSSimulationObject;
var NSSimData;

function RunNotificationSim(){

var NumberOfSimsToRun=10;//this will later be set by the preferences in the interface

//

ScriptToRun='model/runnotificationsimulation.js';

//Creating the data to be used in the simualtions
NSSimData=[];
for (i=0; i<NumberOfSimsToRun; i++){
	NSSimData[i]={};
	NSSimData[i].NoPeople=30000;
}

NSSimulationObject=new MulticoreSim(ScriptToRun, 22, NSSimData, NoCores);
NSSimulationObject.UseSimProgressBar=true;
NSSimulationObject.SimProgressBarID="MainProgress";
NSSimulationObject.Start();

return 0;
}<commit_msg>Adding load notification function<commit_after>// This file contains the scripts that are called when the buttons on the interface are pressed.

var NSSimulationObject;
var NSSimData;

function RunNotificationSim(){

var NumberOfSimsToRun=10;//this will later be set by the preferences in the interface

//

ScriptToRun='model/runnotificationsimulation.js';

//Creating the data to be used in the simualtions
NSSimData=[];
for (i=0; i<NumberOfSimsToRun; i++){
	NSSimData[i]={};
	NSSimData[i].NoPeople=30000;
}

NSSimulationObject=new MulticoreSim(ScriptToRun, 22, NSSimData, NoCores);
NSSimulationObject.UseSimProgressBar=true;
NSSimulationObject.SimProgressBarID="MainProgress";
NSSimulationObject.Start();

return 0;
}

function LoadNotificationData(){
	SummaryNotificationsCSV=new CSVFile('data/summarynotifications.csv');
	SummaryNotificationsTable=SummaryNotificationsCSV.GetValues(1, 2, 5, 10);
}<|endoftext|>