<commit_before>Array.prototype.allValuesSame = function() {

    for(var i = 1; i < this.length; i++)
    {
        if(this[i] !== this[0])
            return false;
    }

    return true;
}
var table;
var meta_table;
var settings_table;
formatResultTables();
formatMetaTable();
formatSettingsTable();
$(".bs-tooltip").tooltip();
$("a.bs-popover").popover();

// if compare is in query string, then we are in the compare view
if (window.location.search.indexOf("compare") >= 0) {
  /* red = new Color(245, 50, 50);
  green = new Color(50, 245, 50); */
  dark_gray = new Color(160, 160, 160);
  gray = new Color(200, 200, 200);
  white = new Color(255, 255, 255);
  red = new Color(240, 40, 150);
  green = new Color(130, 200, 30);
  colorateCells();
}

function formatMetaTable() {
    meta_table = $('.meta-table').DataTable({
        scrollY: '80vh',
        scrollX: true,
        scroller: true,
        scrollCollapse: true,
        paging: false,
    });
}

function formatSettingsTable() {
    settings_table = $('.settings-table').DataTable({
        scrollY: '80vh',
        scrollX: true,
        scroller: true,
        scrollCollapse: true,
        paging: false,
    });
}

function formatResultTables() {
    table = $('.results-table').DataTable({
        scrollY: '80vh',
        scrollX: true,
        scroller: true,
        scrollCollapse: true,
        paging: false,
        columnDefs: [
            { type: 'any-number', targets: 'number' },
        ]
    });

    $('.nav-tabs').stickyTabs();

    $('#resultNavTabs a').click(function (e) {
          e.preventDefault()
          $(this).tab('show')
    });

    $('button#delete-result').click(function (e) {
        e.preventDefault()
        $.ajax({
           type: "DELETE",
           url: "/result/" + end[2],
           success: function (data){ window.location.href = "/search";},
           error:function(){
               alert("Something went wrong.");
           }
        });
    });

    $('button#reimport-result').click(function (e) {
        e.preventDefault()
        button = document.getElementById("reimport-result")
        button.disabled = true;
        currurl = window.location.href;
        $.ajax({
           type: "PUT",
           url: "/result/" + end[2],
           success: function (data){
              window.location.href = currurl;
           },
           error:function(){
               alert("Something went wrong.");
           }
        });
    });

    $('a[href="#settings-filtered"]').click(function (e) {
      e.preventDefault();
      $("tr.default-value").remove();
    });
}

/*
 * Colorate the result table cells for the compare view
 */
function colorateCells() {
    table.cells().every( function () {
      // determine if tooltip is string or number
      var element = $(this.node())[0];
      if (element.attributes["title"] !== undefined) {
          var other_values_str = element.attributes["title"].value;
          var values = Array(element.textContent);
          Array.prototype.push.apply(values, other_values_str.split("\n"));
          var rgb;
          if (element.attributes["invert"] !== undefined) {
            rgb = getRGB(values, true);
          } else {
            rgb = getRGB(values, false);
          }
          if (rgb) {
            element.style.backgroundColor = "rgb(" + rgb.getColorString() + ")";
          }
      }
  })
}

/*
 * Get an array of values, and translate that to into an RGB array.
 */
function getRGB(arr_values, invert) {
  var contains_floats = false;
  var floatValues = Array();
  for (var i = 0; i < arr_values.length; i++) {
    var floatVal = parseFloat(arr_values[i]);
    if (!isNaN(floatVal)) {
      contains_floats = true;
      floatValues.push(floatVal);
    }
  }
  // if array is all floats
  if (floatValues.length === arr_values.length) {
    if (floatValues.allValuesSame()) {
      // all values the same, no color needed
      return null;
    } else {
      // compute the appropriate color
      return computeRGB(floatValues, invert);
    }
  } else if (arr_values.allValuesSame()) {
      return null;
  } else {
    // mix of floats and strings, or different strings
    return gray;
  }
}

function computeRGB(arr_values, invert) {
  // The first value of arr_values is the principle value for compare view

  // compute mean of the compare values
  var sum = 0.0;
  var arr_length = arr_values.length;
  for( var i = 0; i < arr_length; i++ ){
    sum += arr_values[i];
  }
  var mean = sum/(arr_length);

  var sum_of_squares = 0.0;
  for( var i = 0; i < arr_length; i++ ){
    sum_of_squares += (arr_values[i]-mean) * (arr_values[i]-mean);
  }
  var variance = Math.sqrt(sum_of_squares/(arr_length));
  var percentage = variance/mean;

  var largest = Math.max(...arr_values.slice(1));
  var smallest = Math.min(...arr_values.slice(1));
  var value = arr_values[0];

  if ( (smallest < 0 && largest > 0) || smallest == 0 || largest == 0) {
    return Interpolate(dark_gray, percentage);
  }

  if (invert) {
    var tmp = smallest;
    smallest = - largest;
    largest = - tmp;
    value = - value;
  }

  if (value < smallest) {
      percentage = (smallest - value)/smallest;
  } else if (value > largest) {
      percentage = (value - smallest)/smallest;
  }
  if ((largest < value && !invert) || (smallest > value && invert)) {
    return Interpolate(red, percentage);
  } else if ((largest < value && invert) || (smallest > value && !invert)) {
    return Interpolate(green, percentage);
  } else {
    return Interpolate(dark_gray, percentage);
  }
}

function Interpolate(colorBase, percentage) {
  if (percentage >= 1) {
    return colorBase;
  }
  else {
    percentage = percentage * 100;
    if (percentage < 7) {
        percentage = 7;
    }
    var end_color = colorBase.getColors();
    var r = interpolate(255, end_color.r, 100, percentage);
    var g = interpolate(255, end_color.g, 100, percentage);
    var b = interpolate(255, end_color.b, 100, percentage);
    return new Color(r, g, b);
  }
}

// does math
function interpolate(start, end, steps, count) {
  var s = start,
      e = end,
      final = s + (((e - s) / steps) * count);
  return Math.floor(final);
}

// Class to manage an rgb color
function Color(_r, _g, _b) {
    var r, g, b;
    var setColors = function(_r, _g, _b) {
        r = _r;
        g = _g;
        b = _b;
    };

    setColors(_r, _g, _b);
    this.getColors = function() {
        var colors = {
            r: r,
            g: g,
            b: b
        };
        return colors;
    };

    this.getColorString = function() {
        return r + "," + g + "," + b;
    };
}
<commit_msg>reenable correct coloring of bounds in max prob<commit_after>Array.prototype.allValuesSame = function() {

    for(var i = 1; i < this.length; i++)
    {
        if(this[i] !== this[0])
            return false;
    }

    return true;
}
var table;
var meta_table;
var settings_table;
formatResultTables();
formatMetaTable();
formatSettingsTable();
$(".bs-tooltip").tooltip();
$("a.bs-popover").popover();

// if compare is in query string, then we are in the compare view
if (window.location.search.indexOf("compare") >= 0) {
  /* red = new Color(245, 50, 50);
  green = new Color(50, 245, 50); */
  dark_gray = new Color(160, 160, 160);
  gray = new Color(200, 200, 200);
  white = new Color(255, 255, 255);
  red = new Color(240, 40, 150);
  green = new Color(130, 200, 30);
  colorateCells();
}

function formatMetaTable() {
    meta_table = $('.meta-table').DataTable({
        scrollY: '80vh',
        scrollX: true,
        scroller: true,
        scrollCollapse: true,
        paging: false,
    });
}

function formatSettingsTable() {
    settings_table = $('.settings-table').DataTable({
        scrollY: '80vh',
        scrollX: true,
        scroller: true,
        scrollCollapse: true,
        paging: false,
    });
}

function formatResultTables() {
    table = $('.results-table').DataTable({
        scrollY: '80vh',
        scrollX: true,
        scroller: true,
        scrollCollapse: true,
        paging: false,
        columnDefs: [
            { type: 'any-number', targets: 'number' },
        ]
    });

    $('.nav-tabs').stickyTabs();

    $('#resultNavTabs a').click(function (e) {
          e.preventDefault()
          $(this).tab('show')
    });

    $('button#delete-result').click(function (e) {
        e.preventDefault()
        $.ajax({
           type: "DELETE",
           url: "/result/" + end[2],
           success: function (data){ window.location.href = "/search";},
           error:function(){
               alert("Something went wrong.");
           }
        });
    });

    $('button#reimport-result').click(function (e) {
        e.preventDefault()
        button = document.getElementById("reimport-result")
        button.disabled = true;
        currurl = window.location.href;
        $.ajax({
           type: "PUT",
           url: "/result/" + end[2],
           success: function (data){
              window.location.href = currurl;
           },
           error:function(){
               alert("Something went wrong.");
           }
        });
    });

    $('a[href="#settings-filtered"]').click(function (e) {
      e.preventDefault();
      $("tr.default-value").remove();
    });
}

/*
 * Colorate the result table cells for the compare view
 */
function colorateCells() {
    table.cells().every( function () {
      // determine if tooltip is string or number
      var element = $(this.node())[0];
      if (element.attributes["title"] !== undefined) {
          var other_values_str = element.attributes["title"].value;
          var values = Array(element.textContent);
          Array.prototype.push.apply(values, other_values_str.split("\n"));
          var rgb;
          if (element.attributes["invert"] !== undefined) {
            rgb = getRGB(values, true);
          } else {
            rgb = getRGB(values, false);
          }
          if (rgb) {
            element.style.backgroundColor = "rgb(" + rgb.getColorString() + ")";
          }
      }
  })
}

/*
 * Get an array of values, and translate that to into an RGB array.
 */
function getRGB(arr_values, invert) {
  var contains_floats = false;
  var floatValues = Array();
  for (var i = 0; i < arr_values.length; i++) {
    var floatVal = parseFloat(arr_values[i]);
    if (!isNaN(floatVal)) {
      contains_floats = true;
      floatValues.push(floatVal);
    }
  }
  // if array is all floats
  if (floatValues.length === arr_values.length) {
    if (floatValues.allValuesSame()) {
      // all values the same, no color needed
      return null;
    } else {
      // compute the appropriate color
      return computeRGB(floatValues, invert);
    }
  } else if (arr_values.allValuesSame()) {
      return null;
  } else {
    // mix of floats and strings, or different strings
    return gray;
  }
}

function computeRGB(arr_values, invert) {
  // The first value of arr_values is the principle value for compare view

  // compute mean of the compare values
  var sum = 0.0;
  var arr_length = arr_values.length;
  for( var i = 0; i < arr_length; i++ ){
    sum += arr_values[i];
  }
  var mean = sum/(arr_length);

  var sum_of_squares = 0.0;
  for( var i = 0; i < arr_length; i++ ){
    sum_of_squares += (arr_values[i]-mean) * (arr_values[i]-mean);
  }
  var variance = Math.sqrt(sum_of_squares/(arr_length));
  var percentage = variance/mean;

  var largest = Math.max(...arr_values.slice(1));
  var smallest = Math.min(...arr_values.slice(1));
  var value = arr_values[0];

  if ( (smallest < 0 && largest > 0) || smallest == 0 || largest == 0) {
    return Interpolate(dark_gray, percentage);
  }

  if (invert) {
    var tmp = smallest;
    smallest = - largest;
    largest = - tmp;
    value = - value;
  }

  if (value < smallest) {
      percentage = (smallest - value)/smallest;
  } else if (value > largest) {
      percentage = (value - smallest)/smallest;
  }
  if (largest < value) {
    return Interpolate(red, percentage);
  } else if (smallest > value) {
    return Interpolate(green, percentage);
  } else {
    return Interpolate(dark_gray, percentage);
  }
}

function Interpolate(colorBase, percentage) {
  if (percentage >= 1) {
    return colorBase;
  }
  else {
    percentage = percentage * 100;
    if (percentage < 7) {
        percentage = 7;
    }
    var end_color = colorBase.getColors();
    var r = interpolate(255, end_color.r, 100, percentage);
    var g = interpolate(255, end_color.g, 100, percentage);
    var b = interpolate(255, end_color.b, 100, percentage);
    return new Color(r, g, b);
  }
}

// does math
function interpolate(start, end, steps, count) {
  var s = start,
      e = end,
      final = s + (((e - s) / steps) * count);
  return Math.floor(final);
}

// Class to manage an rgb color
function Color(_r, _g, _b) {
    var r, g, b;
    var setColors = function(_r, _g, _b) {
        r = _r;
        g = _g;
        b = _b;
    };

    setColors(_r, _g, _b);
    this.getColors = function() {
        var colors = {
            r: r,
            g: g,
            b: b
        };
        return colors;
    };

    this.getColorString = function() {
        return r + "," + g + "," + b;
    };
}
<|endoftext|>


<commit_before>// Unit tests for the Model module.
// Curran Kelleher 4/15/2014
describe('model', function() {

  var Model;

  // Use require.js to fetch the module
  it("should load the AMD module", function(done) {
    require(['model'], function (loadedModule) {
      Model = loadedModule;
      done();
    });
  });

  it('should create a model and listen for changes to a single property', function(done) {

    // Create a new model.
    var model = Model();

    // Listen for changes on x.
    model.when('x', function (x) {
      expect(x).toBe(30);
      done();
    });

    // Set x.
    model.set('x', 30);
  });

  it('should call fn only once for multiple updates', function(done) {
    var model = Model();
    model.when('x', function (x) {
      expect(x).toBe(30);
      done();
    });
    model.set('x', 10);
    model.set('x', 20);
    model.set('x', 30);
  });

  it('should call fn with multiple dependency properties', function(done) {
    var model = Model();
    model.when(['x', 'y', 'z'], function (x, y, z) {
      expect(x).toBe(5);
      expect(y).toBe(6);
      expect(z).toBe(7);
      done();
    });
    model.set('x', 5);
    model.set('y', 6);
    model.set('z', 7);
  });

  it('should call fn with multiple dependency properties in the order specified', function(done) {
    var model = Model();

    // Test changing the order
    model.when(['y', 'x', 'z'], function (y, x, z) {
      expect(x).toBe(5);
      expect(y).toBe(6);
      expect(z).toBe(7);
      done();
    });
    model.set('x', 5);
    model.set('y', 6);
    model.set('z', 7);
  });
  it('should call fn with multiple dependency properties only once after several updates', function(done) {
    var model = Model();
    model.when(['x', 'y', 'z'], function (x, y, z) {
      expect(x).toBe(5);
      expect(y).toBe(6);
      expect(z).toBe(7);
      done();
    });
    model.set('x', 5);
    model.set('y', 6);
    model.set('z', 5);
    model.set('z', 6);
    model.set('z', 7);
  });

  it('should call fn once to initialize', function(done) {
    var model = Model();
    model.set('x', 55);
    model.when(['x'], function (x) {
      expect(x).toBe(55);
      done();
    });
  });

  it('should use thisArg', function(done) {
    var model = Model(),
        theThing = { foo: "bar" };
    model.when('x', function (x) {
      expect(x).toBe(5);
      expect(this).toBe(theThing);
      expect(this.foo).toBe("bar");
      done();
    }, theThing);
    model.set('x', 5);
  });

  it('should propagate changes two hops through a data dependency graph', function(done) {
    var model = Model();
    model.when(['x'], function (x) {
      model.set('y', x + 1);
    });
    model.when(['y'], function (y) {
      expect(y).toBe(11);
      model.set('z', y * 2);
    });
    model.when(['z'], function (z) {
      expect(z).toBe(22);
      done();
    });
    model.set('x', 10);
  });

  it('should propagate changes three hops through a data dependency graph', function(done) {
    var model = Model();
    model.when(['w'], function (w) {
      expect(w).toBe(5);
      model.set('x', w * 2);
    });
    model.when(['x'], function (x) {
      expect(x).toBe(10);
      model.set('y', x + 1);
    });
    model.when(['y'], function (y) {
      expect(y).toBe(11);
      model.set('z', y * 2);
    });
    model.when(['z'], function (z) {
      expect(z).toBe(22);
      done();
    });
    model.set('w', 5);
  });
});
<commit_msg>Added TODO<commit_after>// Unit tests for the Model module.
// Curran Kelleher 4/15/2014
describe('model', function() {

  var Model;

  // Use require.js to fetch the module
  it("should load the AMD module", function(done) {
    require(['model'], function (loadedModule) {
      Model = loadedModule;
      done();
    });
  });

  it('should create a model and listen for changes to a single property', function(done) {

    // Create a new model.
    var model = Model();

    // Listen for changes on x.
    model.when('x', function (x) {
      expect(x).toBe(30);
      done();
    });

    // Set x.
    model.set('x', 30);
  });

  it('should call fn only once for multiple updates', function(done) {
    var model = Model();
    model.when('x', function (x) {
      expect(x).toBe(30);
      done();
    });
    model.set('x', 10);
    model.set('x', 20);
    model.set('x', 30);
  });

  it('should call fn with multiple dependency properties', function(done) {
    var model = Model();
    model.when(['x', 'y', 'z'], function (x, y, z) {
      expect(x).toBe(5);
      expect(y).toBe(6);
      expect(z).toBe(7);
      done();
    });
    model.set('x', 5);
    model.set('y', 6);
    model.set('z', 7);
  });

  it('should call fn with multiple dependency properties in the order specified', function(done) {
    var model = Model();

    // Test changing the order
    model.when(['y', 'x', 'z'], function (y, x, z) {
      expect(x).toBe(5);
      expect(y).toBe(6);
      expect(z).toBe(7);
      done();
    });
    model.set('x', 5);
    model.set('y', 6);
    model.set('z', 7);
  });
  it('should call fn with multiple dependency properties only once after several updates', function(done) {
    var model = Model();
    model.when(['x', 'y', 'z'], function (x, y, z) {
      expect(x).toBe(5);
      expect(y).toBe(6);
      expect(z).toBe(7);
      done();
    });
    model.set('x', 5);
    model.set('y', 6);
    model.set('z', 5);
    model.set('z', 6);
    model.set('z', 7);
  });

  it('should call fn once to initialize', function(done) {
    var model = Model();
    model.set('x', 55);
    model.when(['x'], function (x) {
      expect(x).toBe(55);
      done();
    });
  });

  it('should use thisArg', function(done) {
    var model = Model(),
        theThing = { foo: "bar" };
    model.when('x', function (x) {
      expect(x).toBe(5);
      expect(this).toBe(theThing);
      expect(this.foo).toBe("bar");
      done();
    }, theThing);
    model.set('x', 5);
  });

  it('should propagate changes two hops through a data dependency graph', function(done) {
    var model = Model();
    model.when(['x'], function (x) {
      model.set('y', x + 1);
    });
    model.when(['y'], function (y) {
      expect(y).toBe(11);
      model.set('z', y * 2);
    });
    model.when(['z'], function (z) {
      expect(z).toBe(22);
      done();
    });
    model.set('x', 10);
  });

  it('should propagate changes three hops through a data dependency graph', function(done) {
    var model = Model();
    model.when(['w'], function (w) {
      expect(w).toBe(5);
      model.set('x', w * 2);
    });
    model.when(['x'], function (x) {
      expect(x).toBe(10);
      model.set('y', x + 1);
    });
    model.when(['y'], function (y) {
      expect(y).toBe(11);
      model.set('z', y * 2);
    });
    model.when(['z'], function (z) {
      expect(z).toBe(22);
      done();
    });
    model.set('w', 5);
  });
  // TODO add more starting from Ohm's Law
});
<|endoftext|>


<commit_before>var fs = require('fs');
var browserify = require('browserify');
var through = require('through2');
var globRequireTransform = require('./../index');
var transformTools = require('browserify-transform-tools');

describe('basic glob replacement', function() {
	it('should have both test tokens when bundled', function(done) {

		var data = '';
		browserify({
			entries: require.resolve('./hash/main.js')
		}).transform(globRequireTransform).bundle().pipe(through(function(buf, enc, cb) {
			data += buf;
			cb();
		}, function(cb) {
			var err;
			if (!(data.indexOf('test token1') !== -1 && data.indexOf('test token1') !== -1)) {
				err = new Error('expected the bundle to include both test tokens');
			}
			if (!(data.indexOf('test token3') === -1 && data.indexOf('test token4') === -1)) {
				err = new Error('expected the bundle to NOT include commented out files');
			}

			cb();
			done(err);
		}));
	});

	it('should not include itself when glob expression includes itself', function(done) {
		var data = '';
		browserify({
			entries: require.resolve('./hash/self-exclusion/module.js')
		}).transform(globRequireTransform).bundle().pipe(through(function(buf, enc, cb) {
			data += buf;
			cb();
		}, function(cb) {
			var err;
			if (data.indexOf('module.js') !== -1) {
				err = new Error('expected this require call to be skipped');
			}

			cb();
			done(err);
		}));
	});

	it('should include the extensions of files if the configuration is set so', function(done) {
		var data = '';
		browserify({
			entries: require.resolve('./hash/include-exts/module.js')
		}).transform(globRequireTransform).bundle().pipe(through(function(buf, enc, cb) {
			data += buf;
			cb();
		}, function(cb) {
			var err;
			if (data.indexOf('"1.js":') === -1) {
				err = new Error('expected extension to be included in "1.js":');
			} else if (data.indexOf('require("./1.js")') === -1) {
				err = new Error('expected extension to be included in require("./1.js")');
			} else if (data.indexOf('"2.js":') === -1) {
				err = new Error('expected extension to be included in "2.js":');
			} else if (data.indexOf('require("./2.js")') === -1) {
				err = new Error('expected extension to be included in require("./2.js")');
			}

			cb();
			done(err);
		}));
	});

	it('should not include the extensions of files if the configuration is set so', function(done) {
		var data = '';
		browserify({
			entries: require.resolve('./hash/dont-include-exts/module.js')
		}).transform(globRequireTransform).bundle().pipe(through(function(buf, enc, cb) {
			data += buf;
			cb();
		}, function(cb) {
			var err;
			if (data.indexOf('"1":') === -1) {
				err = new Error('expected no extension in "1":');
			} else if (data.indexOf('require("./1")') === -1) {
				err = new Error('expected no extension in require("./1")');
			} else if (data.indexOf('"2":') === -1) {
				err = new Error('expected no extension in "2":');
			} else if (data.indexOf('require("./2")') === -1) {
				err = new Error('expected no extension in require("./2")');
			}
			if (data.indexOf('"1.js":') !== -1) {
				err = new Error('unexpected extension in "1.js":');
			} else if (data.indexOf('require("./1.js")') !== -1) {
				err = new Error('unexpected extension in require("./1.js")');
			} else if (data.indexOf('"2.js":') !== -1) {
				err = new Error('unexpected extension in "2.js":');
			} else if (data.indexOf('require("./2.js")') !== -1) {
				err = new Error('unexpected extension in require("./2.js")');
			}

			cb();
			done(err);
		}));
	});

	it('should not include the extensions of files by default', function(done) {
		var data = '';
		browserify({
			entries: require.resolve('./hash/self-exclusion/module.js')
		}).transform(globRequireTransform).bundle().pipe(through(function(buf, enc, cb) {
			data += buf;
			cb();
		}, function(cb) {
			var err;
			if (data.indexOf('"1":') === -1) {
				err = new Error('expected no extension in "1":');
			} else if (data.indexOf('require("./1")') === -1) {
				err = new Error('expected no extension in require("./1")');
			} else if (data.indexOf('"2":') === -1) {
				err = new Error('expected no extension in "2":');
			} else if (data.indexOf('require("./2")') === -1) {
				err = new Error('expected no extension in require("./2")');
			}
			if (data.indexOf('"1.js":') !== -1) {
				err = new Error('unexpected extension in "1.js":');
			} else if (data.indexOf('require("./1.js")') !== -1) {
				err = new Error('unexpected extension in require("./1.js")');
			} else if (data.indexOf('"2.js":') !== -1) {
				err = new Error('unexpected extension in "2.js":');
			} else if (data.indexOf('require("./2.js")') !== -1) {
				err = new Error('unexpected extension in require("./2.js")');
			}

			cb();
			done(err);
		}));
	});

});

<commit_msg>Change name to be different than the basic spec.<commit_after>var fs = require('fs');
var browserify = require('browserify');
var through = require('through2');
var globRequireTransform = require('./../index');
var transformTools = require('browserify-transform-tools');

describe('hash glob replacement', function() {
	it('should have both test tokens when bundled', function(done) {

		var data = '';
		browserify({
			entries: require.resolve('./hash/main.js')
		}).transform(globRequireTransform).bundle().pipe(through(function(buf, enc, cb) {
			data += buf;
			cb();
		}, function(cb) {
			var err;
			if (!(data.indexOf('test token1') !== -1 && data.indexOf('test token1') !== -1)) {
				err = new Error('expected the bundle to include both test tokens');
			}
			if (!(data.indexOf('test token3') === -1 && data.indexOf('test token4') === -1)) {
				err = new Error('expected the bundle to NOT include commented out files');
			}

			cb();
			done(err);
		}));
	});

	it('should not include itself when glob expression includes itself', function(done) {
		var data = '';
		browserify({
			entries: require.resolve('./hash/self-exclusion/module.js')
		}).transform(globRequireTransform).bundle().pipe(through(function(buf, enc, cb) {
			data += buf;
			cb();
		}, function(cb) {
			var err;
			if (data.indexOf('module.js') !== -1) {
				err = new Error('expected this require call to be skipped');
			}

			cb();
			done(err);
		}));
	});

	it('should include the extensions of files if the configuration is set so', function(done) {
		var data = '';
		browserify({
			entries: require.resolve('./hash/include-exts/module.js')
		}).transform(globRequireTransform).bundle().pipe(through(function(buf, enc, cb) {
			data += buf;
			cb();
		}, function(cb) {
			var err;
			if (data.indexOf('"1.js":') === -1) {
				err = new Error('expected extension to be included in "1.js":');
			} else if (data.indexOf('require("./1.js")') === -1) {
				err = new Error('expected extension to be included in require("./1.js")');
			} else if (data.indexOf('"2.js":') === -1) {
				err = new Error('expected extension to be included in "2.js":');
			} else if (data.indexOf('require("./2.js")') === -1) {
				err = new Error('expected extension to be included in require("./2.js")');
			}

			cb();
			done(err);
		}));
	});

	it('should not include the extensions of files if the configuration is set so', function(done) {
		var data = '';
		browserify({
			entries: require.resolve('./hash/dont-include-exts/module.js')
		}).transform(globRequireTransform).bundle().pipe(through(function(buf, enc, cb) {
			data += buf;
			cb();
		}, function(cb) {
			var err;
			if (data.indexOf('"1":') === -1) {
				err = new Error('expected no extension in "1":');
			} else if (data.indexOf('require("./1")') === -1) {
				err = new Error('expected no extension in require("./1")');
			} else if (data.indexOf('"2":') === -1) {
				err = new Error('expected no extension in "2":');
			} else if (data.indexOf('require("./2")') === -1) {
				err = new Error('expected no extension in require("./2")');
			}
			if (data.indexOf('"1.js":') !== -1) {
				err = new Error('unexpected extension in "1.js":');
			} else if (data.indexOf('require("./1.js")') !== -1) {
				err = new Error('unexpected extension in require("./1.js")');
			} else if (data.indexOf('"2.js":') !== -1) {
				err = new Error('unexpected extension in "2.js":');
			} else if (data.indexOf('require("./2.js")') !== -1) {
				err = new Error('unexpected extension in require("./2.js")');
			}

			cb();
			done(err);
		}));
	});

	it('should not include the extensions of files by default', function(done) {
		var data = '';
		browserify({
			entries: require.resolve('./hash/self-exclusion/module.js')
		}).transform(globRequireTransform).bundle().pipe(through(function(buf, enc, cb) {
			data += buf;
			cb();
		}, function(cb) {
			var err;
			if (data.indexOf('"1":') === -1) {
				err = new Error('expected no extension in "1":');
			} else if (data.indexOf('require("./1")') === -1) {
				err = new Error('expected no extension in require("./1")');
			} else if (data.indexOf('"2":') === -1) {
				err = new Error('expected no extension in "2":');
			} else if (data.indexOf('require("./2")') === -1) {
				err = new Error('expected no extension in require("./2")');
			}
			if (data.indexOf('"1.js":') !== -1) {
				err = new Error('unexpected extension in "1.js":');
			} else if (data.indexOf('require("./1.js")') !== -1) {
				err = new Error('unexpected extension in require("./1.js")');
			} else if (data.indexOf('"2.js":') !== -1) {
				err = new Error('unexpected extension in "2.js":');
			} else if (data.indexOf('require("./2.js")') !== -1) {
				err = new Error('unexpected extension in require("./2.js")');
			}

			cb();
			done(err);
		}));
	});

});

<|endoftext|>


<commit_before>const assert = require('assert')
const ChildProcess = require('child_process')
const fs = require('fs')
const path = require('path')
const os = require('os')
const {remote} = require('electron')

const isCI = remote.getGlobal('isCi')

describe('node feature', function () {
  var fixtures = path.join(__dirname, 'fixtures')

  describe('child_process', function () {
    describe('child_process.fork', function () {
      it('works in current process', function (done) {
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'ping.js'))
        child.on('message', function (msg) {
          assert.equal(msg, 'message')
          done()
        })
        child.send('message')
      })

      it('preserves args', function (done) {
        var args = ['--expose_gc', '-test', '1']
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'process_args.js'), args)
        child.on('message', function (msg) {
          assert.deepEqual(args, msg.slice(2))
          done()
        })
        child.send('message')
      })

      it('works in forked process', function (done) {
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'fork_ping.js'))
        child.on('message', function (msg) {
          assert.equal(msg, 'message')
          done()
        })
        child.send('message')
      })

      it('works in forked process when options.env is specifed', function (done) {
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'fork_ping.js'), [], {
          path: process.env['PATH']
        })
        child.on('message', function (msg) {
          assert.equal(msg, 'message')
          done()
        })
        child.send('message')
      })

      it('works in browser process', function (done) {
        var fork = remote.require('child_process').fork
        var child = fork(path.join(fixtures, 'module', 'ping.js'))
        child.on('message', function (msg) {
          assert.equal(msg, 'message')
          done()
        })
        child.send('message')
      })

      it('has String::localeCompare working in script', function (done) {
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'locale-compare.js'))
        child.on('message', function (msg) {
          assert.deepEqual(msg, [0, -1, 1])
          done()
        })
        child.send('message')
      })

      it('has setImmediate working in script', function (done) {
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'set-immediate.js'))
        child.on('message', function (msg) {
          assert.equal(msg, 'ok')
          done()
        })
        child.send('message')
      })

      it('pipes stdio', function (done) {
        let child = ChildProcess.fork(path.join(fixtures, 'module', 'process-stdout.js'), {silent: true})
        let data = ''
        child.stdout.on('data', (chunk) => {
          data += String(chunk)
        })
        child.on('exit', (code) => {
          assert.equal(code, 0)
          assert.equal(data, 'pipes stdio')
          done()
        })
      })
    })
  })

  describe('contexts', function () {
    describe('setTimeout in fs callback', function () {
      if (process.env.TRAVIS === 'true') {
        return
      }

      it('does not crash', function (done) {
        fs.readFile(__filename, function () {
          setTimeout(done, 0)
        })
      })
    })

    describe('throw error in node context', function () {
      it('gets caught', function (done) {
        var error = new Error('boo!')
        var lsts = process.listeners('uncaughtException')
        process.removeAllListeners('uncaughtException')
        process.on('uncaughtException', function () {
          var i, len, lst
          process.removeAllListeners('uncaughtException')
          for (i = 0, len = lsts.length; i < len; i++) {
            lst = lsts[i]
            process.on('uncaughtException', lst)
          }
          done()
        })
        fs.readFile(__filename, function () {
          throw error
        })
      })
    })

    describe('setTimeout called under Chromium event loop in browser process', function () {
      it('can be scheduled in time', function (done) {
        remote.getGlobal('setTimeout')(done, 0)
      })
    })

    describe('setInterval called under Chromium event loop in browser process', function () {
      it('can be scheduled in time', function (done) {
        var clear, interval
        clear = function () {
          remote.getGlobal('clearInterval')(interval)
          done()
        }
        interval = remote.getGlobal('setInterval')(clear, 10)
      })
    })
  })

  describe('message loop', function () {
    describe('process.nextTick', function () {
      it('emits the callback', function (done) {
        process.nextTick(done)
      })

      it('works in nested calls', function (done) {
        process.nextTick(function () {
          process.nextTick(function () {
            process.nextTick(done)
          })
        })
      })
    })

    describe('setImmediate', function () {
      it('emits the callback', function (done) {
        setImmediate(done)
      })

      it('works in nested calls', function (done) {
        setImmediate(function () {
          setImmediate(function () {
            setImmediate(done)
          })
        })
      })
    })
  })

  describe('net.connect', function () {
    if (process.platform !== 'darwin') {
      return
    }

    it('emit error when connect to a socket path without listeners', function (done) {
      var socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock')
      var script = path.join(fixtures, 'module', 'create_socket.js')
      var child = ChildProcess.fork(script, [socketPath])
      child.on('exit', function (code) {
        assert.equal(code, 0)
        var client = require('net').connect(socketPath)
        client.on('error', function (error) {
          assert.equal(error.code, 'ECONNREFUSED')
          done()
        })
      })
    })
  })

  describe('Buffer', function () {
    it('can be created from WebKit external string', function () {
      var p = document.createElement('p')
      p.innerText = '闲云潭影日悠悠，物换星移几度秋'
      var b = new Buffer(p.innerText)
      assert.equal(b.toString(), '闲云潭影日悠悠，物换星移几度秋')
      assert.equal(Buffer.byteLength(p.innerText), 45)
    })

    it('correctly parses external one-byte UTF8 string', function () {
      var p = document.createElement('p')
      p.innerText = 'Jøhänñéß'
      var b = new Buffer(p.innerText)
      assert.equal(b.toString(), 'Jøhänñéß')
      assert.equal(Buffer.byteLength(p.innerText), 13)
    })

    it('does not crash when creating large Buffers', function () {
      var buffer = new Buffer(new Array(4096).join(' '))
      assert.equal(buffer.length, 4095)
      buffer = new Buffer(new Array(4097).join(' '))
      assert.equal(buffer.length, 4096)
    })
  })

  describe('process.stdout', function () {
    it('does not throw an exception when accessed', function () {
      assert.doesNotThrow(function () {
        process.stdout
      })
    })

    it('does not throw an exception when calling write()', function () {
      assert.doesNotThrow(function () {
        process.stdout.write('test')
      })
    })

    it('should have isTTY defined on Mac and Linux', function () {
      if (isCI) return

      if (process.platform === 'win32')
        assert.equal(process.stdout.isTTY, undefined)
      else
        assert.equal(typeof process.stdout.isTTY, 'boolean')
    })
  })

  describe('process.stdin', function () {
    it('does not throw an exception when accessed', function () {
      assert.doesNotThrow(function () {
        process.stdin
      })
    })

    it('returns null when read from', function () {
      assert.equal(process.stdin.read(), null)
    })
  })

  describe('process.version', function () {
    it('should not have -pre', function () {
      assert(!process.version.endsWith('-pre'))
    })
  })

  describe('vm.createContext', function () {
    it('should not crash', function () {
      require('vm').runInNewContext('')
    })
  })
})
<commit_msg>Add missing {}<commit_after>const assert = require('assert')
const ChildProcess = require('child_process')
const fs = require('fs')
const path = require('path')
const os = require('os')
const {remote} = require('electron')

const isCI = remote.getGlobal('isCi')

describe('node feature', function () {
  var fixtures = path.join(__dirname, 'fixtures')

  describe('child_process', function () {
    describe('child_process.fork', function () {
      it('works in current process', function (done) {
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'ping.js'))
        child.on('message', function (msg) {
          assert.equal(msg, 'message')
          done()
        })
        child.send('message')
      })

      it('preserves args', function (done) {
        var args = ['--expose_gc', '-test', '1']
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'process_args.js'), args)
        child.on('message', function (msg) {
          assert.deepEqual(args, msg.slice(2))
          done()
        })
        child.send('message')
      })

      it('works in forked process', function (done) {
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'fork_ping.js'))
        child.on('message', function (msg) {
          assert.equal(msg, 'message')
          done()
        })
        child.send('message')
      })

      it('works in forked process when options.env is specifed', function (done) {
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'fork_ping.js'), [], {
          path: process.env['PATH']
        })
        child.on('message', function (msg) {
          assert.equal(msg, 'message')
          done()
        })
        child.send('message')
      })

      it('works in browser process', function (done) {
        var fork = remote.require('child_process').fork
        var child = fork(path.join(fixtures, 'module', 'ping.js'))
        child.on('message', function (msg) {
          assert.equal(msg, 'message')
          done()
        })
        child.send('message')
      })

      it('has String::localeCompare working in script', function (done) {
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'locale-compare.js'))
        child.on('message', function (msg) {
          assert.deepEqual(msg, [0, -1, 1])
          done()
        })
        child.send('message')
      })

      it('has setImmediate working in script', function (done) {
        var child = ChildProcess.fork(path.join(fixtures, 'module', 'set-immediate.js'))
        child.on('message', function (msg) {
          assert.equal(msg, 'ok')
          done()
        })
        child.send('message')
      })

      it('pipes stdio', function (done) {
        let child = ChildProcess.fork(path.join(fixtures, 'module', 'process-stdout.js'), {silent: true})
        let data = ''
        child.stdout.on('data', (chunk) => {
          data += String(chunk)
        })
        child.on('exit', (code) => {
          assert.equal(code, 0)
          assert.equal(data, 'pipes stdio')
          done()
        })
      })
    })
  })

  describe('contexts', function () {
    describe('setTimeout in fs callback', function () {
      if (process.env.TRAVIS === 'true') {
        return
      }

      it('does not crash', function (done) {
        fs.readFile(__filename, function () {
          setTimeout(done, 0)
        })
      })
    })

    describe('throw error in node context', function () {
      it('gets caught', function (done) {
        var error = new Error('boo!')
        var lsts = process.listeners('uncaughtException')
        process.removeAllListeners('uncaughtException')
        process.on('uncaughtException', function () {
          var i, len, lst
          process.removeAllListeners('uncaughtException')
          for (i = 0, len = lsts.length; i < len; i++) {
            lst = lsts[i]
            process.on('uncaughtException', lst)
          }
          done()
        })
        fs.readFile(__filename, function () {
          throw error
        })
      })
    })

    describe('setTimeout called under Chromium event loop in browser process', function () {
      it('can be scheduled in time', function (done) {
        remote.getGlobal('setTimeout')(done, 0)
      })
    })

    describe('setInterval called under Chromium event loop in browser process', function () {
      it('can be scheduled in time', function (done) {
        var clear, interval
        clear = function () {
          remote.getGlobal('clearInterval')(interval)
          done()
        }
        interval = remote.getGlobal('setInterval')(clear, 10)
      })
    })
  })

  describe('message loop', function () {
    describe('process.nextTick', function () {
      it('emits the callback', function (done) {
        process.nextTick(done)
      })

      it('works in nested calls', function (done) {
        process.nextTick(function () {
          process.nextTick(function () {
            process.nextTick(done)
          })
        })
      })
    })

    describe('setImmediate', function () {
      it('emits the callback', function (done) {
        setImmediate(done)
      })

      it('works in nested calls', function (done) {
        setImmediate(function () {
          setImmediate(function () {
            setImmediate(done)
          })
        })
      })
    })
  })

  describe('net.connect', function () {
    if (process.platform !== 'darwin') {
      return
    }

    it('emit error when connect to a socket path without listeners', function (done) {
      var socketPath = path.join(os.tmpdir(), 'atom-shell-test.sock')
      var script = path.join(fixtures, 'module', 'create_socket.js')
      var child = ChildProcess.fork(script, [socketPath])
      child.on('exit', function (code) {
        assert.equal(code, 0)
        var client = require('net').connect(socketPath)
        client.on('error', function (error) {
          assert.equal(error.code, 'ECONNREFUSED')
          done()
        })
      })
    })
  })

  describe('Buffer', function () {
    it('can be created from WebKit external string', function () {
      var p = document.createElement('p')
      p.innerText = '闲云潭影日悠悠，物换星移几度秋'
      var b = new Buffer(p.innerText)
      assert.equal(b.toString(), '闲云潭影日悠悠，物换星移几度秋')
      assert.equal(Buffer.byteLength(p.innerText), 45)
    })

    it('correctly parses external one-byte UTF8 string', function () {
      var p = document.createElement('p')
      p.innerText = 'Jøhänñéß'
      var b = new Buffer(p.innerText)
      assert.equal(b.toString(), 'Jøhänñéß')
      assert.equal(Buffer.byteLength(p.innerText), 13)
    })

    it('does not crash when creating large Buffers', function () {
      var buffer = new Buffer(new Array(4096).join(' '))
      assert.equal(buffer.length, 4095)
      buffer = new Buffer(new Array(4097).join(' '))
      assert.equal(buffer.length, 4096)
    })
  })

  describe('process.stdout', function () {
    it('does not throw an exception when accessed', function () {
      assert.doesNotThrow(function () {
        process.stdout
      })
    })

    it('does not throw an exception when calling write()', function () {
      assert.doesNotThrow(function () {
        process.stdout.write('test')
      })
    })

    it('should have isTTY defined on Mac and Linux', function () {
      if (isCI) return

      if (process.platform === 'win32') {
        assert.equal(process.stdout.isTTY, undefined)
      } else {
        assert.equal(typeof process.stdout.isTTY, 'boolean')
      }
    })
  })

  describe('process.stdin', function () {
    it('does not throw an exception when accessed', function () {
      assert.doesNotThrow(function () {
        process.stdin
      })
    })

    it('returns null when read from', function () {
      assert.equal(process.stdin.read(), null)
    })
  })

  describe('process.version', function () {
    it('should not have -pre', function () {
      assert(!process.version.endsWith('-pre'))
    })
  })

  describe('vm.createContext', function () {
    it('should not crash', function () {
      require('vm').runInNewContext('')
    })
  })
})
<|endoftext|>


<commit_before>(function() {
  Benchmark.options.maxTime = 1;

  var jasmineEnv = jasmine.getEnv();
  jasmineEnv.updateInterval = 1000;

  var specReporter = new SpecReporter();
  jasmineEnv.addReporter(specReporter);

  var arrays = {};
  var benchmarksForToArray = {};
  var benchmarksForEach = {};
  var benchmarkResults = {};

  window.lodash = _.noConflict();

  function displayCoordinates(element, pos) {
    element.textContent = "(" + pos.join(", ") + ")";
  }

  function initializeDomExample() {
    var sourceElement = document.getElementById("dom-event-source");
    var leftElement   = document.querySelector("#dom-event-output .left p");
    var rightElement  = document.querySelector("#dom-event-output .right p");

    var mouseEvents = Lazy.events(sourceElement, "mousemove");

    var coordinates = mouseEvents.map(function(e) {
      var elementRect = sourceElement.getBoundingClientRect();
      return [
        Math.floor(e.clientX - elementRect.left),
        Math.floor(e.clientY - elementRect.top)
      ];
    });

    coordinates
      .filter(function(pos) { return pos[0] < sourceElement.clientWidth / 2; })
      .each(function(pos) { displayCoordinates(leftElement, pos); });

    coordinates
      .filter(function(pos) { return pos[0] > sourceElement.clientWidth / 2; })
      .each(function(pos) { displayCoordinates(rightElement, pos); });
  }

  function getOrCreateArray(size) {
    if (!arrays[size]) {
      arrays[size] = Lazy.range(size).toArray();
    }

    return arrays[size];
  }

  function createBenchmarkSuite() {
    var suite = new Benchmark.Suite();

    $(".benchmark-result.selected").each(function() {
      var benchmarkId = $(this).attr("data-benchmark-id");
      var benchmarksToRun = $("#test-to-array").is(":checked") ?
        benchmarksForToArray[benchmarkId] :
        benchmarksForEach[benchmarkId];

      Lazy(benchmarksToRun).each(function(benchmark) {
        suite.add(benchmark);
      });
    });

    return suite;
  }

  function addCommas(number) {
    var parts = number.toString().split(".");
    var pattern = /(\d+)(\d{3})/;
    while (pattern.test(parts[0])) {
        parts[0] = parts[0].replace(pattern, '$1,$2');
    }
    return parts.join(".");
  }

  function finishedLoading() {
    $(".benchmark-results-section").removeClass("loading");
    $(".start-benchmarking").prop("disabled", false);
  }

  function createBenchmarks(description, input, options) {
    var toArrayBenchmarks = [
      options.valueOnly ?
        new Benchmark(description, function() { options.lazy.apply(this, input); }) :
        new Benchmark(description, function() { options.lazy.apply(this, input).toArray(); }),
      new Benchmark(description, function() { options.underscore.apply(this, input); }),
      new Benchmark(description, function() { options.lodash.apply(this, input); })
    ];

    var eachBenchmarks = options.valueOnly ? toArrayBenchmarks : [
      new Benchmark(description, function() {
        options.lazy.apply(this, input).each(function(e) {});
      }),
      new Benchmark(description, function() {
        _.each(options.underscore.apply(this, input), function(e) {});
      }),
      new Benchmark(description, function() {
        lodash.each(options.lodash.apply(this, input), function(e) {});
      })
    ];

    // We'll use the same benchmark to ID all of these as that's how we
    // reference a set of benchmarks from the table.
    var benchmarkSetId = toArrayBenchmarks[0].id;
    benchmarksForToArray[benchmarkSetId] = toArrayBenchmarks;
    benchmarksForEach[benchmarkSetId] = eachBenchmarks;

    // Mark each benchmark with this ID.
    Lazy(toArrayBenchmarks).concat(eachBenchmarks).each(function(bm) {
      bm.benchmarkSetId = benchmarkSetId;
    });

    return benchmarkSetId;
  }

  function addBenchmarkToTable(description, benchmarkId, elementCount) {
    var table = $("#benchmark-results-table-" + elementCount);
    var row   = $("<tr>")
      .addClass("benchmark-result")
      .attr("id", "benchmark-result-" + benchmarkId)
      .attr("data-benchmark-id", benchmarkId)
      .appendTo(table);

    $("<td>").text(description).appendTo(row);
    $("<td>").addClass("underscore-result").appendTo(row);
    $("<td>").addClass("lodash-result").appendTo(row);
    $("<td>").addClass("lazy-result").appendTo(row);
  }

  function addBenchmarkResultToTable(result) {
    var row   = $("#benchmark-result-" + result.benchmarkSetId);
    var style = result.lazy.hz > result.underscore.hz &&
                result.lazy.hz > result.lodash.hz ? "positive" : "negative";

    $(".underscore-result", row).text(addCommas(result.underscore.hz.toFixed(2)));
    $(".lodash-result", row).text(addCommas(result.lodash.hz.toFixed(2)));
    $(".lazy-result", row).text(addCommas(result.lazy.hz.toFixed(2))).addClass(style);
  }

  function updateCharts() {
    $(".column-chart").each(function() {
      HighTables.renderChart(this);
    });
  }

  window.benchmarkChartOptions = function() {
    return {
      plotOptions: {
        series: { animation: false }
      },

      xAxis: {
        labels: {
          align: "right",
          rotation: -45
        }
      }
    };
  };

  window.benchmarkChartRowFilter = function(row) {
    return $(row).find("td.lazy-result").is(":not(:empty)");
  };

  window.compareToUnderscore = function(description, options) {
    var inputs = options.inputs ?
      Lazy(options.inputs) :
      Lazy([10, 100]).map(function(size) { return [getOrCreateArray(size)] });

    var smallInput = inputs.first();

    if (options.shouldMatch !== false) {
      it("returns the same result as underscore.js for '" + description + "'", function() {
        var lazyResult = options.lazy.apply(this, smallInput);
        var underscoreResult = options.underscore.apply(this, smallInput);
        if (typeof underscoreResult.value === "function") {
          underscoreResult = underscoreResult.value();
        }
        expect(lazyResult).toEqual(underscoreResult);
      });

      it("returns the same result as Lo-Dash for '" + description + "'", function() {
        var lazyResult = options.lazy.apply(this, smallInput);
        var lodashResult = options.lodash.apply(this, smallInput);
        if (typeof lodashResult.value === "function") {
          lodashResult = lodashResult.value();
        }
        expect(lazyResult).toEqual(lodashResult);
      });
    }

    inputs.each(function(input) {
      var benchmarkSetId = createBenchmarks(description, input, options);

      // Add a row to the appropriate table for this benchmark
      // once the document's loaded.
      $(document).ready(function() {
        addBenchmarkToTable(description, benchmarkSetId, input[0].length);
      });
    });
  };

  window.onload = function() {
    jasmineEnv.execute();

    $("nav ul li a").on("click", function() {
      var link   = $(this);
      var nav    = link.closest("nav");
      var target = link.attr("href");

      // Show the section
      $(nav.attr("data-sections")).hide();
      $(target).show();

      // Highlight the tab
      $("li.selected", nav).removeClass("selected");
      link.closest("li").addClass("selected");

      // Refresh the chart, if necessary
      var columnChart = $(".column-chart:visible");
      if (columnChart.length > 0) {
        HighTables.renderChart(columnChart[0]);
      }

      return false;
    });

    $("#test-to-array").on("change", function() {
      $("#test-each").prop("checked", false);
    });

    $("#test-each").on("change", function() {
      $("#test-to-array").prop("checked", false);
    });

    $(".select-all").on("click", function() {
      $(this).closest("section").find(".benchmark-result").addClass("selected");
    });

    $(".select-none").on("click", function() {
      $(this).closest("section").find(".benchmark-result").removeClass("selected");
    });

    $(".clear-selected").on("click", function() {
      $(this).closest("section").find(".benchmark-result td:nth-child(n+2)").empty();
    });

    $(".benchmark-result").on("click", function() {
      $(this).toggleClass("selected");
    });

    $(".start-benchmarking").on("click", function() {
      $(".start-benchmarking").prop("disabled", true);
      $(".benchmark-results-section").addClass("loading");

      var benchmarkSuite = createBenchmarkSuite();

      var currentResultSet = [];
      benchmarkSuite.on("cycle", function(e) {
        currentResultSet.push(e.target);
        if (currentResultSet.length === 3) {
          addBenchmarkResultToTable({
            benchmarkSetId: currentResultSet[0].benchmarkSetId,
            lazy: currentResultSet[0],
            underscore: currentResultSet[1],
            lodash: currentResultSet[2]
          });
          updateCharts();
          currentResultSet = [];
        }
      });

      benchmarkSuite.on("complete", function() {
        finishedLoading();
      });

      benchmarkSuite.run({ async: true });
    });

    initializeDomExample();
    updateCharts();
  };
})();
<commit_msg>fixed failing specs checking against underscore<commit_after>(function() {
  Benchmark.options.maxTime = 1;

  var jasmineEnv = jasmine.getEnv();
  jasmineEnv.updateInterval = 1000;

  var specReporter = new SpecReporter();
  jasmineEnv.addReporter(specReporter);

  var arrays = {};
  var benchmarksForToArray = {};
  var benchmarksForEach = {};
  var benchmarkResults = {};

  window.lodash = _.noConflict();

  function displayCoordinates(element, pos) {
    element.textContent = "(" + pos.join(", ") + ")";
  }

  function initializeDomExample() {
    var sourceElement = document.getElementById("dom-event-source");
    var leftElement   = document.querySelector("#dom-event-output .left p");
    var rightElement  = document.querySelector("#dom-event-output .right p");

    var mouseEvents = Lazy.events(sourceElement, "mousemove");

    var coordinates = mouseEvents.map(function(e) {
      var elementRect = sourceElement.getBoundingClientRect();
      return [
        Math.floor(e.clientX - elementRect.left),
        Math.floor(e.clientY - elementRect.top)
      ];
    });

    coordinates
      .filter(function(pos) { return pos[0] < sourceElement.clientWidth / 2; })
      .each(function(pos) { displayCoordinates(leftElement, pos); });

    coordinates
      .filter(function(pos) { return pos[0] > sourceElement.clientWidth / 2; })
      .each(function(pos) { displayCoordinates(rightElement, pos); });
  }

  function getOrCreateArray(size) {
    if (!arrays[size]) {
      arrays[size] = Lazy.range(size).toArray();
    }

    return arrays[size];
  }

  function createBenchmarkSuite() {
    var suite = new Benchmark.Suite();

    $(".benchmark-result.selected").each(function() {
      var benchmarkId = $(this).attr("data-benchmark-id");
      var benchmarksToRun = $("#test-to-array").is(":checked") ?
        benchmarksForToArray[benchmarkId] :
        benchmarksForEach[benchmarkId];

      Lazy(benchmarksToRun).each(function(benchmark) {
        suite.add(benchmark);
      });
    });

    return suite;
  }

  function addCommas(number) {
    var parts = number.toString().split(".");
    var pattern = /(\d+)(\d{3})/;
    while (pattern.test(parts[0])) {
        parts[0] = parts[0].replace(pattern, '$1,$2');
    }
    return parts.join(".");
  }

  function finishedLoading() {
    $(".benchmark-results-section").removeClass("loading");
    $(".start-benchmarking").prop("disabled", false);
  }

  function createBenchmarks(description, input, options) {
    var toArrayBenchmarks = [
      options.valueOnly ?
        new Benchmark(description, function() { options.lazy.apply(this, input); }) :
        new Benchmark(description, function() { options.lazy.apply(this, input).toArray(); }),
      new Benchmark(description, function() { options.underscore.apply(this, input); }),
      new Benchmark(description, function() { options.lodash.apply(this, input); })
    ];

    var eachBenchmarks = options.valueOnly ? toArrayBenchmarks : [
      new Benchmark(description, function() {
        options.lazy.apply(this, input).each(function(e) {});
      }),
      new Benchmark(description, function() {
        _.each(options.underscore.apply(this, input), function(e) {});
      }),
      new Benchmark(description, function() {
        lodash.each(options.lodash.apply(this, input), function(e) {});
      })
    ];

    // We'll use the same benchmark to ID all of these as that's how we
    // reference a set of benchmarks from the table.
    var benchmarkSetId = toArrayBenchmarks[0].id;
    benchmarksForToArray[benchmarkSetId] = toArrayBenchmarks;
    benchmarksForEach[benchmarkSetId] = eachBenchmarks;

    // Mark each benchmark with this ID.
    Lazy(toArrayBenchmarks).concat(eachBenchmarks).each(function(bm) {
      bm.benchmarkSetId = benchmarkSetId;
    });

    return benchmarkSetId;
  }

  function addBenchmarkToTable(description, benchmarkId, elementCount) {
    var table = $("#benchmark-results-table-" + elementCount);
    var row   = $("<tr>")
      .addClass("benchmark-result")
      .attr("id", "benchmark-result-" + benchmarkId)
      .attr("data-benchmark-id", benchmarkId)
      .appendTo(table);

    $("<td>").text(description).appendTo(row);
    $("<td>").addClass("underscore-result").appendTo(row);
    $("<td>").addClass("lodash-result").appendTo(row);
    $("<td>").addClass("lazy-result").appendTo(row);
  }

  function addBenchmarkResultToTable(result) {
    var row   = $("#benchmark-result-" + result.benchmarkSetId);
    var style = result.lazy.hz > result.underscore.hz &&
                result.lazy.hz > result.lodash.hz ? "positive" : "negative";

    $(".underscore-result", row).text(addCommas(result.underscore.hz.toFixed(2)));
    $(".lodash-result", row).text(addCommas(result.lodash.hz.toFixed(2)));
    $(".lazy-result", row).text(addCommas(result.lazy.hz.toFixed(2))).addClass(style);
  }

  function updateCharts() {
    $(".column-chart").each(function() {
      HighTables.renderChart(this);
    });
  }

  window.benchmarkChartOptions = function() {
    return {
      plotOptions: {
        series: { animation: false }
      },

      xAxis: {
        labels: {
          align: "right",
          rotation: -45
        }
      }
    };
  };

  window.benchmarkChartRowFilter = function(row) {
    return $(row).find("td.lazy-result").is(":not(:empty)");
  };

  window.compareToUnderscore = function(description, options) {
    var inputs = options.inputs ?
      Lazy(options.inputs) :
      Lazy([10, 100]).map(function(size) { return [getOrCreateArray(size)] });

    var smallInput = inputs.first();

    if (options.shouldMatch !== false) {
      it("returns the same result as underscore.js for '" + description + "'", function() {
        var lazyResult = options.lazy.apply(this, smallInput);
        var underscoreResult = options.underscore.apply(this, smallInput);
        if (typeof lazyResult.toArray === "function") {
          lazyResult = lazyResult.toArray();
        }
        if (typeof underscoreResult.value === "function") {
          underscoreResult = underscoreResult.value();
        }
        expect(lazyResult).toEqual(underscoreResult);
      });

      it("returns the same result as Lo-Dash for '" + description + "'", function() {
        var lazyResult = options.lazy.apply(this, smallInput);
        var lodashResult = options.lodash.apply(this, smallInput);
        if (typeof lazyResult.toArray === "function") {
          lazyResult = lazyResult.toArray();
        }
        if (typeof lodashResult.value === "function") {
          lodashResult = lodashResult.value();
        }
        expect(lazyResult).toEqual(lodashResult);
      });
    }

    inputs.each(function(input) {
      var benchmarkSetId = createBenchmarks(description, input, options);

      // Add a row to the appropriate table for this benchmark
      // once the document's loaded.
      $(document).ready(function() {
        addBenchmarkToTable(description, benchmarkSetId, input[0].length);
      });
    });
  };

  window.onload = function() {
    jasmineEnv.execute();

    $("nav ul li a").on("click", function() {
      var link   = $(this);
      var nav    = link.closest("nav");
      var target = link.attr("href");

      // Show the section
      $(nav.attr("data-sections")).hide();
      $(target).show();

      // Highlight the tab
      $("li.selected", nav).removeClass("selected");
      link.closest("li").addClass("selected");

      // Refresh the chart, if necessary
      var columnChart = $(".column-chart:visible");
      if (columnChart.length > 0) {
        HighTables.renderChart(columnChart[0]);
      }

      return false;
    });

    $("#test-to-array").on("change", function() {
      $("#test-each").prop("checked", false);
    });

    $("#test-each").on("change", function() {
      $("#test-to-array").prop("checked", false);
    });

    $(".select-all").on("click", function() {
      $(this).closest("section").find(".benchmark-result").addClass("selected");
    });

    $(".select-none").on("click", function() {
      $(this).closest("section").find(".benchmark-result").removeClass("selected");
    });

    $(".clear-selected").on("click", function() {
      $(this).closest("section").find(".benchmark-result td:nth-child(n+2)").empty();
    });

    $(".benchmark-result").on("click", function() {
      $(this).toggleClass("selected");
    });

    $(".start-benchmarking").on("click", function() {
      $(".start-benchmarking").prop("disabled", true);
      $(".benchmark-results-section").addClass("loading");

      var benchmarkSuite = createBenchmarkSuite();

      var currentResultSet = [];
      benchmarkSuite.on("cycle", function(e) {
        currentResultSet.push(e.target);
        if (currentResultSet.length === 3) {
          addBenchmarkResultToTable({
            benchmarkSetId: currentResultSet[0].benchmarkSetId,
            lazy: currentResultSet[0],
            underscore: currentResultSet[1],
            lodash: currentResultSet[2]
          });
          updateCharts();
          currentResultSet = [];
        }
      });

      benchmarkSuite.on("complete", function() {
        finishedLoading();
      });

      benchmarkSuite.run({ async: true });
    });

    initializeDomExample();
    updateCharts();
  };
})();
<|endoftext|>


<commit_before>angular.module('qmsk.e2', [
        'qmsk.e2.source',
        'qmsk.e2.web',
        'ngResource',
        'ngRoute',
        'ngWebSocket',
        'luegg.directives',
        'jsonFormatter',
        'ui.bootstrap',
])

.config(function($routeProvider) {
    $routeProvider
        .when('/main', {
            templateUrl: '/static/qmsk.e2/server/main.html',
            controller: 'MainCtrl',
            reloadOnSearch: false,
        })
        .when('/sources', {
            templateUrl: '/static/qmsk.e2/server/sources.html',
            controller: 'SourcesCtrl',
        })
        .when('/screens', {
            templateUrl: '/static/qmsk.e2/server/screens.html',
            controller: 'ScreensCtrl',
        })
        .when('/auxes', {
            templateUrl: '/static/qmsk.e2/server/auxes.html',
            controller: 'AuxesCtrl',
        })
        .when('/presets', {
            templateUrl: '/static/qmsk.e2/server/presets.html',
            controller: 'PresetsCtrl',
            reloadOnSearch: false,
        })
        .when('/system', {
            templateUrl: '/static/qmsk.e2/server/system.html',
            controller: 'SystemCtrl',
        })
        .otherwise({
            redirectTo: '/main',
        });
})

.factory('Status', function($http) {
    var Status = {};

    $http.get('/api/status').then(
        function success(r) {
            Status.server = r.data.server;
            Status.mode = r.data.mode;
        }
    );

    return Status;
})

.factory('State', function($rootScope, Events) {
    var State = {
        System: Events.state.System,
    };

    $rootScope.$on('qmsk.e2.event', function($e, event){
        State.System = Events.state.System;
    });

    return State;
})

.factory('Preset', function($resource) {
    return $resource('/api/presets/:id', { }, {
        get: {
            method: 'GET',
            url: '/api/presets',
        },
        all: {
            method: 'GET',
            isArray: true,
        },
        query: {
            method: 'GET',
            isArray: false,
        },
        activate: {
            method: 'POST',
            url: '/api/presets',
        },
    }, {stripTrailingSlashes: false});
})

.filter('dimensions', function() {
    return function(dimensions) {
        if (dimensions && dimensions.width && dimensions.height) {
            return dimensions.width + "x" + dimensions.height;
        } else {
            return null;
        }
    };
})

.controller('HeaderCtrl', function($scope, $location, Status, httpState) {
    $scope.status = Status;
    $scope.state = httpState;

    $scope.isActive = function(prefix) {
        return $location.path().startsWith(prefix);
    };

})

.controller('StatusCtrl', function($scope, Events) {
    $scope.events = Events;
})

.controller('SystemCtrl', function($scope, State) {
    $scope.state = State;
})

.controller('MainCtrl', function($scope, $location, State) {
    $scope.state = State;
    $scope.sources = [];

    $scope.$watch('state.System', function(system) {
        // compute a merged state mapping sources to their active destinations
        // TODO: aux destinations
        $scope.sources = $.map(system.SrcMgr.SourceCol, function(source, sourceID){
            var item = {
                id: sourceID,
                type: source.SrcType,
                name: source.Name,
                source: source,
                active: false,
                preview: [],
                program: [],
            };

            if (source.SrcType == "input") {
                item.input = system.SrcMgr.InputCfgCol[source.InputCfgIndex];
            }

            $.each(system.DestMgr.ScreenDestCol, function(screenID, screen) {
                var output = {
                    type: "screen",
                    id: screenID,
                    name: screen.Name,
                    active: screen.IsActive > 0,
                };

                $.each(screen.LayerCollection, function(layerID, layer) {
                    if (layer.PgmMode > 0 && layer.LastSrcIdx == sourceID) {
                        output.program = true;
                    }

                    if (layer.PvwMode > 0 && layer.LastSrcIdx == sourceID) {
                        output.preview = true;
                    }
                });

                if (output.program) {
                    item.program.push(output);
                }
                if (output.preview) {
                    item.preview.push(output);
                }
                if (output.active && output.preview) {
                    item.active = true;
                }
            });

            return item;
        });
    });

    $scope.selectOrder = function(order) {
        $scope.order = order;
        $scope.orderBy = function(){
            switch (order) {
            case 'source':
                return ['-type', 'name'];
            case 'preview':
                return ['preview_screens', 'program_screens'];
            case 'program':
                return ['program_screens', 'preview_screens'];
            default:
                return [];
            }
        }();

        $location.search('order', order || null);
    };
    $scope.selectOrder($location.search().order || 'source');
})

.controller('SourcesCtrl', function($scope, State) {
    $scope.state = State;
})

.controller('ScreensCtrl', function($scope, State) {
    $scope.state = State;
})

.controller('AuxesCtrl', function($scope, State) {
    $scope.state = State;
})

.controller('PresetsCtrl', function($scope, State, $location, $log) {
    $scope.state = State;

    // size
    $scope.displaySize = $location.search().size || 'normal';

    $scope.$watch('displaySize', function(displaySize) {
        $location.search('size', displaySize);
    });

    // collapsing
    $scope.showGroup = $location.search().group || null;
    $scope.collapseGroups = {};

    $scope.selectGroup = function(groupID) {
        $scope.collapseGroups = {};

        if (groupID != $scope.showGroup) {
            $scope.showGroup = groupID;

            $location.search('group', groupID);
        }
    }
    $scope.clearGroup = function() {
        $scope.collapseGroups = {};
        $scope.showGroup = null;
        $location.search('group', null);
    };
    $scope.toggleGroup = function(groupID) {
        $scope.collapseGroups[groupID] = !$scope.collapseGroups[groupID];
    };

    // grouping
    $scope.groupBy = $location.search().groupBy || 'sno';

    $scope.$watch('groupBy', function(groupBy) {
        $location.search('groupBy', groupBy);
    });

    function groupBySno(presets) {
        var groups = { };

        $.each(presets, function(id, preset) {
            var groupID = preset.presetSno.Group;
            var groupIndex = preset.presetSno.Index;

            preset = $.extend({groupIndex: groupIndex}, preset);

            // group it
            var group = groups[groupID];

            if (!group) {
                group = groups[groupID] = {
                    id: groupID,
                    name: groupID,
                    presets: []
                };
            }

            group.presets.push(preset);
        });

        return $.map(groups, function(group, id){
            return group;
        });
    };
    function groupByConsole(presets) {
        var groups = { };
        var presetsByID = { };

        $.each(presets, function(presetID, preset){
            presetsByID[preset.id] = preset;
        });

        $.each(State.System.ConsoleLayoutMgr.ConsoleLayout.PresetBusColl, function(buttonID, button) {
            var groupID = Math.floor(button.id / 12); // rows of 12 keys
            var group = groups[groupID];
            var preset = presetsByID[button.ConsoleButtonTypeIndex];

            if (button.ConsoleButtonType != 'preset' || !preset) {
                return;
            }

            // copy with groupIndex, since the same preset can be included multiple times
            preset = $.extend({ groupIndex: button.id }, preset);

            if (!group) {
                group = groups[groupID] = {
                    id: groupID+1,
                    name: "Preset PG" + (groupID+1),
                    presets: []
                };
            }

            group.presets.push(preset);

        });

        return $.map(groups, function(group) {
            return group;
        });
    }

    $scope.groups = [];

    $scope.$watchGroup(['groupBy', 'state.System'], function() {
        var presets = State.System.PresetMgr.Preset;
        var groups;

        if ($scope.groupBy == 'sno') {
            groups = groupBySno(presets);
        } else if ($scope.groupBy == 'console') {
            groups = groupByConsole(presets);
        } else {

            groups = [{
                id: 0,
                name: "",
                presets: $.map(presets, function(preset){
                    return $.extend({groupIndex: preset.id}, preset);
                }),
            }];
        }

        $log.info("Refresh presets: presets=" + presets.length + ", groupBy=" + $scope.groupBy + ", groups=" + groups.length);

        $scope.groups = groups;
    });

    // active preset on server; reset while changing...
    $scope.activePresetID = null;
    $scope.$watch('state.System', function(system) {
        $scope.activePresetID = system.PresetMgr.LastRecall
    });

    // select preset for preview
    $scope.previewPreset = null
    $scope.select = function(preset) {
        $scope.activePresetID = null;
        Preset.activate({id: preset.id},
            function success(r) {
                $scope.previewPreset = preset;
            },
            function error(e) {

            }
        );
    };

    // take preset for program
    $scope.autoTake = $location.search().autotake || false;

    $scope.$watch('autoTake', function(autoTake) {
        $location.search('autotake', autoTake ? true : null);
    });

    $scope.programPreset = null;
    $scope.take = function(preset) {
        if (preset) {

        } else if ($scope.previewPreset) {
            preset = $scope.previewPreset;
        } else {
            return;
        }

        $scope.activePresetID = null;
        Preset.activate({id: preset.id, live: true},
            function success(r) {
                $scope.programPreset = preset;
            },
            function error(e) {

            }
        );
    };

    // preview -> program
    $scope.cut = function() {
        Preset.activate({cut: true});
    };
    $scope.autotrans = function() {
        Preset.activate({autotrans: 0});
    };
})

;
<commit_msg>server web presets: fix Preset.activate actions<commit_after>angular.module('qmsk.e2', [
        'qmsk.e2.source',
        'qmsk.e2.web',
        'ngResource',
        'ngRoute',
        'ngWebSocket',
        'luegg.directives',
        'jsonFormatter',
        'ui.bootstrap',
])

.config(function($routeProvider) {
    $routeProvider
        .when('/main', {
            templateUrl: '/static/qmsk.e2/server/main.html',
            controller: 'MainCtrl',
            reloadOnSearch: false,
        })
        .when('/sources', {
            templateUrl: '/static/qmsk.e2/server/sources.html',
            controller: 'SourcesCtrl',
        })
        .when('/screens', {
            templateUrl: '/static/qmsk.e2/server/screens.html',
            controller: 'ScreensCtrl',
        })
        .when('/auxes', {
            templateUrl: '/static/qmsk.e2/server/auxes.html',
            controller: 'AuxesCtrl',
        })
        .when('/presets', {
            templateUrl: '/static/qmsk.e2/server/presets.html',
            controller: 'PresetsCtrl',
            reloadOnSearch: false,
        })
        .when('/system', {
            templateUrl: '/static/qmsk.e2/server/system.html',
            controller: 'SystemCtrl',
        })
        .otherwise({
            redirectTo: '/main',
        });
})

.factory('Status', function($http) {
    var Status = {};

    $http.get('/api/status').then(
        function success(r) {
            Status.server = r.data.server;
            Status.mode = r.data.mode;
        }
    );

    return Status;
})

.factory('State', function($rootScope, Events) {
    var State = {
        System: Events.state.System,
    };

    $rootScope.$on('qmsk.e2.event', function($e, event){
        State.System = Events.state.System;
    });

    return State;
})

.factory('Preset', function($resource) {
    return $resource('/api/presets/:id', { }, {
        get: {
            method: 'GET',
            url: '/api/presets',
        },
        all: {
            method: 'GET',
            isArray: true,
        },
        query: {
            method: 'GET',
            isArray: false,
        },
        activate: {
            method: 'POST',
            url: '/api/presets',
        },
    }, {stripTrailingSlashes: false});
})

.filter('dimensions', function() {
    return function(dimensions) {
        if (dimensions && dimensions.width && dimensions.height) {
            return dimensions.width + "x" + dimensions.height;
        } else {
            return null;
        }
    };
})

.controller('HeaderCtrl', function($scope, $location, Status, httpState) {
    $scope.status = Status;
    $scope.state = httpState;

    $scope.isActive = function(prefix) {
        return $location.path().startsWith(prefix);
    };

})

.controller('StatusCtrl', function($scope, Events) {
    $scope.events = Events;
})

.controller('SystemCtrl', function($scope, State) {
    $scope.state = State;
})

.controller('MainCtrl', function($scope, $location, State) {
    $scope.state = State;
    $scope.sources = [];

    $scope.$watch('state.System', function(system) {
        // compute a merged state mapping sources to their active destinations
        // TODO: aux destinations
        $scope.sources = $.map(system.SrcMgr.SourceCol, function(source, sourceID){
            var item = {
                id: sourceID,
                type: source.SrcType,
                name: source.Name,
                source: source,
                active: false,
                preview: [],
                program: [],
            };

            if (source.SrcType == "input") {
                item.input = system.SrcMgr.InputCfgCol[source.InputCfgIndex];
            }

            $.each(system.DestMgr.ScreenDestCol, function(screenID, screen) {
                var output = {
                    type: "screen",
                    id: screenID,
                    name: screen.Name,
                    active: screen.IsActive > 0,
                };

                $.each(screen.LayerCollection, function(layerID, layer) {
                    if (layer.PgmMode > 0 && layer.LastSrcIdx == sourceID) {
                        output.program = true;
                    }

                    if (layer.PvwMode > 0 && layer.LastSrcIdx == sourceID) {
                        output.preview = true;
                    }
                });

                if (output.program) {
                    item.program.push(output);
                }
                if (output.preview) {
                    item.preview.push(output);
                }
                if (output.active && output.preview) {
                    item.active = true;
                }
            });

            return item;
        });
    });

    $scope.selectOrder = function(order) {
        $scope.order = order;
        $scope.orderBy = function(){
            switch (order) {
            case 'source':
                return ['-type', 'name'];
            case 'preview':
                return ['preview_screens', 'program_screens'];
            case 'program':
                return ['program_screens', 'preview_screens'];
            default:
                return [];
            }
        }();

        $location.search('order', order || null);
    };
    $scope.selectOrder($location.search().order || 'source');
})

.controller('SourcesCtrl', function($scope, State) {
    $scope.state = State;
})

.controller('ScreensCtrl', function($scope, State) {
    $scope.state = State;
})

.controller('AuxesCtrl', function($scope, State) {
    $scope.state = State;
})

.controller('PresetsCtrl', function($scope, State, Preset, $location, $log) {
    $scope.state = State;

    // size
    $scope.displaySize = $location.search().size || 'normal';

    $scope.$watch('displaySize', function(displaySize) {
        $location.search('size', displaySize);
    });

    // collapsing
    $scope.showGroup = $location.search().group || null;
    $scope.collapseGroups = {};

    $scope.selectGroup = function(groupID) {
        $scope.collapseGroups = {};

        if (groupID != $scope.showGroup) {
            $scope.showGroup = groupID;

            $location.search('group', groupID);
        }
    }
    $scope.clearGroup = function() {
        $scope.collapseGroups = {};
        $scope.showGroup = null;
        $location.search('group', null);
    };
    $scope.toggleGroup = function(groupID) {
        $scope.collapseGroups[groupID] = !$scope.collapseGroups[groupID];
    };

    // grouping
    $scope.groupBy = $location.search().groupBy || 'sno';

    $scope.$watch('groupBy', function(groupBy) {
        $location.search('groupBy', groupBy);
    });

    function groupBySno(presets) {
        var groups = { };

        $.each(presets, function(id, preset) {
            var groupID = preset.presetSno.Group;
            var groupIndex = preset.presetSno.Index;

            preset = $.extend({groupIndex: groupIndex}, preset);

            // group it
            var group = groups[groupID];

            if (!group) {
                group = groups[groupID] = {
                    id: groupID,
                    name: groupID,
                    presets: []
                };
            }

            group.presets.push(preset);
        });

        return $.map(groups, function(group, id){
            return group;
        });
    };
    function groupByConsole(presets) {
        var groups = { };
        var presetsByID = { };

        $.each(presets, function(presetID, preset){
            presetsByID[preset.id] = preset;
        });

        $.each(State.System.ConsoleLayoutMgr.ConsoleLayout.PresetBusColl, function(buttonID, button) {
            var groupID = Math.floor(button.id / 12); // rows of 12 keys
            var group = groups[groupID];
            var preset = presetsByID[button.ConsoleButtonTypeIndex];

            if (button.ConsoleButtonType != 'preset' || !preset) {
                return;
            }

            // copy with groupIndex, since the same preset can be included multiple times
            preset = $.extend({ groupIndex: button.id }, preset);

            if (!group) {
                group = groups[groupID] = {
                    id: groupID+1,
                    name: "Preset PG" + (groupID+1),
                    presets: []
                };
            }

            group.presets.push(preset);

        });

        return $.map(groups, function(group) {
            return group;
        });
    }

    $scope.groups = [];

    $scope.$watchGroup(['groupBy', 'state.System'], function() {
        var presets = State.System.PresetMgr.Preset;
        var groups;

        if ($scope.groupBy == 'sno') {
            groups = groupBySno(presets);
        } else if ($scope.groupBy == 'console') {
            groups = groupByConsole(presets);
        } else {

            groups = [{
                id: 0,
                name: "",
                presets: $.map(presets, function(preset){
                    return $.extend({groupIndex: preset.id}, preset);
                }),
            }];
        }

        $log.info("Refresh presets: presets=" + presets.length + ", groupBy=" + $scope.groupBy + ", groups=" + groups.length);

        $scope.groups = groups;
    });

    // active preset on server; reset while changing...
    $scope.activePresetID = null;
    $scope.$watch('state.System', function(system) {
        $scope.activePresetID = system.PresetMgr.LastRecall
    });

    // select preset for preview
    $scope.previewPreset = null
    $scope.select = function(preset) {
        $scope.activePresetID = null;
        Preset.activate({id: preset.id},
            function success(r) {
                $scope.previewPreset = preset;
            },
            function error(e) {

            }
        );
    };

    // take preset for program
    $scope.autoTake = $location.search().autotake || false;

    $scope.$watch('autoTake', function(autoTake) {
        $location.search('autotake', autoTake ? true : null);
    });

    $scope.programPreset = null;
    $scope.take = function(preset) {
        if (preset) {

        } else if ($scope.previewPreset) {
            preset = $scope.previewPreset;
        } else {
            return;
        }

        $scope.activePresetID = null;
        Preset.activate({id: preset.id, live: true},
            function success(r) {
                $scope.programPreset = preset;
            },
            function error(e) {

            }
        );
    };

    // preview -> program
    $scope.cut = function() {
        Preset.activate({cut: true});
    };
    $scope.autotrans = function() {
        Preset.activate({autotrans: 0});
    };
})

;
<|endoftext|>


<commit_before>/**
 * 配置.
 * @typedef {{ name: string, image: string, style: CSSStyleDeclaration, }[]} Pendants
 * @typedef {{ style: CSSStyleDeclaration, }} Control
 * @typedef {{ title: string, freq: number, size: [[quote, size]] style: CSSStyleDeclaration, }} Lottery
 * @typedef {{ freq: number, size: [[quote, size]], style: CSSStyleDeclaration, }} Roller
 * @typedef {{ name: string, code: string, }[]} Dataset
 * @typedef {{ name: string, quota: number, }[]} Turns
 * @typedef {{ bgi: string, bgm: string}} Body
 * @type {{ pendants: Pendants, control: Control, lottery: Lottery, roller: Roller, dataset: Dataset, turns: Turns, body: Body, }}
 */
const config = { // eslint-disable-line no-unused-vars
    // 挂件
    pendants: [
        // {
        //     name: 'logo',
        //     image: './static/image/pendant/logo.png',
        //     style: {
        //         width: '300px',
        //         left: '20%',
        //         top: '12%',
        //     },
        // },
        // {
        //     name: 'cg',
        //     image: './static/image/pendant/cg.png',
        //     style: {
        //         width: '1200px',
        //         right: '12%',
        //         top: '8%',
        //     },
        // },
        // {
        //     name: '恭喜中奖',
        //     image: './static/image/pendant/恭喜中奖.png',
        //     style: {
        //         right: '3%',
        //         bottom: '3%',
        //     },
        // },
    ],

    // 控制器
    control: {
        style: {
            left: '6%',
            bottom: '12%',
        },
    },

    // 抽奖台
    lottery: {
        title: '未配置 - xxx庆功宴抽奖',
        freq: 50, // 当实在放不下时，自动滚动频率，ms
        size: [
            [3, 2.5],
            [5, 2.0],
            [10, 1.6],
            [15, 1.3],
            [20, 1.2],
            [30, 1.0],
            [50, 0.7],
            [999, 0.7],
        ],
        style: {
            minHeight: '30%',
            maxHeight: '64%',
            maxWidth: '60%',
            left: '10%',
            top: '15%',
        },
    },

    // 滚筒区域
    roller: {
        freq: 100, // ms
        size: [
            [3, 2.5],
            [10, 2.0],
            [20, 1.8],
            [30, 1.5],
            [50, 1.0],
            [999, 1.0],
        ],
        style: {
            height: '80%',
            minWidth: '50%',
            right: '10%',
            bottom: '10%',
        },
    },

    // 抽奖回合
    get turns() {
        return [
            { name: '未配置 - 第一轮抽奖', quota: 3, },
            { name: '未配置 - 第二轮抽奖', quota: 5, },
            { name: '未配置 - 第三轮抽奖', quota: 10, },
            { name: '未配置 - 第四轮抽奖', quota: 15, },
            { name: '未配置 - 第五轮抽奖', quota: 20, },
            { name: '未配置 - 第六轮抽奖', quota: 30, },
            { name: '未配置 - 第七轮抽奖', quota: 50, },
            { name: '未配置 - 第八轮抽奖', quota: 100, },
        ];
    },

    // 数据集
    get dataset() { return new Array(160).fill().map((_, i) => ({ name: `姓名${i}`, code: `xxx${i}xxx`, })); },

    body: {
        bgi: './static/image/bgi.jpg', // 背景图片
        bgm: './static/audio/bgm.mp3', // 背景音乐
    },

    renderUser: (data) => data.name ? `${data.name} [${data.code}]` : data.code,
};
window.config = config;

{
    let _title = config.lottery.title;
    config.lottery.__defineGetter__('title', () => _title);
    // check.lottery.title
    const checkTitle = (title) => {
        const search = decodeURIComponent(location.search);
        if (search.indexOf(`config=${title}`) == -1) {
            throw new Error(`prevent to load a config because of mismatching title, title: "${title}", found: "${search}"`);
        }
        _title = title;
    };
    config.lottery.__defineSetter__('title', checkTitle);
}

{
    // check.turns
    const checkTurns = (turns) => {
        const names = new Set();
        const errs = [];
        turns.forEach((data, index) => names.has(data.name) ? errs.push(`${index}: ${data.name}`) : names.add(data.name));
        if (errs.length > 0) {
            throw new Error(`invalid turns, name conflict: ${JSON.stringify(errs)}`);
        }
    };
    config.__defineSetter__('turns', (turns) => {
        checkTurns(turns);
        config.__defineGetter__('turns', () => turns);
    });
    checkTurns(config.turns);
}

{
    // check.dataset
    const checkDataset = (dataset) => {
        const codes = new Set();
        const errs = [];
        dataset.forEach((data, index) => codes.has(data.code) ? errs.push(`${index}: ${data.code}`) : codes.add(data.code));
        if (errs.length > 0) {
            throw new Error(`invalid dataset, code conflict: ${JSON.stringify(errs)}`);
        }
    };
    config.__defineSetter__('dataset', (dataset) => {
        checkDataset(dataset);
        config.__defineGetter__('dataset', () => dataset);
    });
    checkDataset(config.dataset);
}<commit_msg>添加后台日志用以确认名额<commit_after>/**
 * 配置.
 * @typedef {{ name: string, image: string, style: CSSStyleDeclaration, }[]} Pendants
 * @typedef {{ style: CSSStyleDeclaration, }} Control
 * @typedef {{ title: string, freq: number, size: [[quote, size]] style: CSSStyleDeclaration, }} Lottery
 * @typedef {{ freq: number, size: [[quote, size]], style: CSSStyleDeclaration, }} Roller
 * @typedef {{ name: string, code: string, }[]} Dataset
 * @typedef {{ name: string, quota: number, }[]} Turns
 * @typedef {{ bgi: string, bgm: string}} Body
 * @type {{ pendants: Pendants, control: Control, lottery: Lottery, roller: Roller, dataset: Dataset, turns: Turns, body: Body, }}
 */
const config = { // eslint-disable-line no-unused-vars
    // 挂件
    pendants: [
        // {
        //     name: 'logo',
        //     image: './static/image/pendant/logo.png',
        //     style: {
        //         width: '300px',
        //         left: '20%',
        //         top: '12%',
        //     },
        // },
        // {
        //     name: 'cg',
        //     image: './static/image/pendant/cg.png',
        //     style: {
        //         width: '1200px',
        //         right: '12%',
        //         top: '8%',
        //     },
        // },
        // {
        //     name: '恭喜中奖',
        //     image: './static/image/pendant/恭喜中奖.png',
        //     style: {
        //         right: '3%',
        //         bottom: '3%',
        //     },
        // },
    ],

    // 控制器
    control: {
        style: {
            left: '6%',
            bottom: '12%',
        },
    },

    // 抽奖台
    lottery: {
        title: '未配置 - xxx庆功宴抽奖',
        freq: 50, // 当实在放不下时，自动滚动频率，ms
        size: [
            [3, 2.5],
            [5, 2.0],
            [10, 1.6],
            [15, 1.3],
            [20, 1.2],
            [30, 1.0],
            [50, 0.7],
            [999, 0.7],
        ],
        style: {
            minHeight: '30%',
            maxHeight: '64%',
            maxWidth: '60%',
            left: '10%',
            top: '15%',
        },
    },

    // 滚筒区域
    roller: {
        freq: 100, // ms
        size: [
            [3, 2.5],
            [10, 2.0],
            [20, 1.8],
            [30, 1.5],
            [50, 1.0],
            [999, 1.0],
        ],
        style: {
            height: '80%',
            minWidth: '50%',
            right: '10%',
            bottom: '10%',
        },
    },

    // 抽奖回合
    get turns() {
        return [
            { name: '未配置 - 第一轮抽奖', quota: 3, },
            { name: '未配置 - 第二轮抽奖', quota: 5, },
            { name: '未配置 - 第三轮抽奖', quota: 10, },
            { name: '未配置 - 第四轮抽奖', quota: 15, },
            { name: '未配置 - 第五轮抽奖', quota: 20, },
            { name: '未配置 - 第六轮抽奖', quota: 30, },
            { name: '未配置 - 第七轮抽奖', quota: 50, },
            { name: '未配置 - 第八轮抽奖', quota: 100, },
        ];
    },

    // 数据集
    get dataset() { return new Array(160).fill().map((_, i) => ({ name: `姓名${i}`, code: `xxx${i}xxx`, })); },

    body: {
        bgi: './static/image/bgi.jpg', // 背景图片
        bgm: './static/audio/bgm.mp3', // 背景音乐
    },

    renderUser: (data) => data.name ? `${data.name} [${data.code}]` : data.code,
};
window.config = config;

{
    let _title = config.lottery.title;
    config.lottery.__defineGetter__('title', () => _title);
    // check.lottery.title
    const checkTitle = (title) => {
        const search = decodeURIComponent(location.search);
        if (search.indexOf(`config=${title}`) == -1) {
            throw new Error(`prevent to load a config because of mismatching title, title: "${title}", found: "${search}"`);
        }
        _title = title;
        console.info(title);
    };
    config.lottery.__defineSetter__('title', checkTitle);
}

{
    // check.turns
    const checkTurns = (turns) => {
        const names = new Set();
        const errs = [];
        turns.forEach((data, index) => names.has(data.name) ? errs.push(`${index}: ${data.name}`) : names.add(data.name));
        if (errs.length > 0) {
            throw new Error(`invalid turns, name conflict: ${JSON.stringify(errs)}`);
        }
    };
    config.__defineSetter__('turns', (turns) => {
        checkTurns(turns);
        config.__defineGetter__('turns', () => turns);
        console.info('共计', turns.reduce((l, r) => l + r.quota, 0), '个抽奖名额');
    });
    checkTurns(config.turns);
}

{
    // check.dataset
    const checkDataset = (dataset) => {
        const codes = new Set();
        const errs = [];
        dataset.forEach((data, index) => codes.has(data.code) ? errs.push(`${index}: ${data.code}`) : codes.add(data.code));
        if (errs.length > 0) {
            throw new Error(`invalid dataset, code conflict: ${JSON.stringify(errs)}`);
        }
    };
    config.__defineSetter__('dataset', (dataset) => {
        checkDataset(dataset);
        config.__defineGetter__('dataset', () => dataset);
        console.info('共计', dataset.length, '人参与抽奖');
    });
    checkDataset(config.dataset);
}<|endoftext|>


<commit_before>const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    entry: {
        main: './src/main.js',
        vendor: ['pixijs', 'eventemitter3']
    },
    output: {
        filename: '[name].[chunkhash].js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {presets: ['es2015']}
            },
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    use: 'css-loader'
                })
            },
            {
                test: /\.(jpg|png|svg)$/,
                loader: 'file-loader',
                options: {name: '[name].[hash].[ext]'},
            },
        ]
    },
    resolve: {
        alias: {
            pixijs: path.resolve(__dirname, 'node_modules/pixi.js'),
        }
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'src/index.html'
        }),
        new ExtractTextPlugin('[name].[contenthash].css'),
        new webpack.optimize.CommonsChunkPlugin({
            names: ['vendor', 'manifest']
        })
    ]
};
<commit_msg>Webpack now handles ES6 modules.<commit_after>const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    entry: {
        main: './src/main.js',
        vendor: ['pixijs', 'eventemitter3']
    },
    output: {
        filename: '[name].[chunkhash].js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    presets: [["es2015", {"modules": false}]]
                }
            },
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    use: 'css-loader'
                })
            },
            {
                test: /\.(jpg|png|svg)$/,
                loader: 'file-loader',
                options: {name: '[name].[hash].[ext]'},
            },
        ]
    },
    resolve: {
        alias: {
            pixijs: path.resolve(__dirname, 'node_modules/pixi.js'),
        }
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'src/index.html'
        }),
        new ExtractTextPlugin('[name].[contenthash].css'),
        new webpack.optimize.CommonsChunkPlugin({
            names: ['vendor', 'manifest']
        })
    ]
};
<|endoftext|>