<commit_before>// Load modules

var Chai = require('chai');
var Request = require('request');
var Fs = require('fs');
var Path = require('path');
var Hapi = require('../helpers');

// Declare internals

var internals = {};

// Test shortcuts

var expect = Chai.expect;

describe('Payload', function () {

    describe('raw mode', function () {

        it('returns an error on req socket error', function (done) {

            var handler = function (request) {

                expect(request).to.not.exist;       // Must not be called
            };

            var server = new Hapi.Server();
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler } });

            server.inject({ method: 'POST', url: '/', payload: 'test', simulate: { error: true } }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.code).to.equal(500);
                done();
            });
        });

        it('returns an error on req socket close', function (done) {

            var handler = function (request) {

                expect(request).to.not.exist;       // Must not be called
            };

            var server = new Hapi.Server();
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler } });

            server.inject({ method: 'POST', url: '/', payload: 'test', simulate: { close: true } }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.code).to.equal(500);
                done();
            });
        });

        it('returns a raw body', function (done) {

            var multipartPayload = '{"x":"1","y":"2","z":"3"}';

            var handler = function (request) {

                expect(request.payload).to.not.exist;
                expect(request.rawBody).to.equal(multipartPayload);
                request.reply(request.rawBody);
            };

            var server = new Hapi.Server();
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler, payload: 'raw' } });

            server.inject({ method: 'POST', url: '/', payload: multipartPayload }, function (res) {

                expect(res.result).to.exist;
                expect(res.result).to.equal(multipartPayload);
                done();
            });
        });

        it('returns a parsed body and sets a raw body', function (done) {

            var multipartPayload = '{"x":"1","y":"2","z":"3"}';

            var handler = function (request) {

                expect(request.payload).to.exist;
                expect(request.payload.z).to.equal('3');
                expect(request.rawBody).to.equal(multipartPayload);
                request.reply(request.payload);
            };

            var server = new Hapi.Server();
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler } });

            server.inject({ method: 'POST', url: '/', payload: multipartPayload }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.x).to.equal('1');
                done();
            });
        });
    });

    describe('unzip', function () {

        it('returns an error on malformed payload', function (done) {

            var multipartPayload = '7d8d78347h8347d58w347hd58w374d58w37h5d8w37hd4';

            var handler = function (request) {

                expect(request).to.not.exist;       // Must not be called
            };

            var server = new Hapi.Server();
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler } });

            server.inject({ method: 'POST', url: '/', payload: multipartPayload, headers: { 'content-encoding': 'gzip' } }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.code).to.equal(400);
                done();
            });
        });
    });

    describe('multi-part', function () {

        var invalidHandler = function (request) {

            expect(request).to.not.exist;       // Must not be called
        };

        var echo = function (request) {

            request.reply(request.payload);
        };

        var _server = new Hapi.Server('0.0.0.0', 0);
        _server.addRoute({ method: 'POST', path: '/invalid', handler: invalidHandler });
        _server.addRoute({ method: 'POST', path: '/echo', handler: echo });

        var multipartPayload =
                '--AaB03x\r\n' +
                'content-disposition: form-data; name="field1"\r\n' +
                '\r\n' +
                'Joe Blow\r\nalmost tricked you!\r\n' +
                '--AaB03x\r\n' +
                'content-disposition: form-data; name="field1"\r\n' +
                '\r\n' +
                'Repeated name segment\r\n' +
                '--AaB03x\r\n' +
                'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n' +
                'Content-Type: text/plain\r\n' +
                '\r\n' +
                '... contents of file1.txt ...\r\r\n' +
                '--AaB03x--\r\n';

        it('returns an error on missing boundary in content-type header', function (done) {

            _server.inject({ method: 'POST', url: '/invalid', payload: multipartPayload, headers: { 'content-type': 'multipart/form-data' } }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.code).to.equal(400);
                done();
            });
        });

        it('returns an error on empty separator in content-type header', function (done) {

            _server.inject({ method: 'POST', url: '/invalid', payload: multipartPayload, headers: { 'content-type': 'multipart/form-data; boundary=' } }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.code).to.equal(400);
                done();
            });
        });

        it('returns parsed multipart data', function (done) {

            _server.inject({ method: 'POST', url: '/echo', payload: multipartPayload, headers: { 'content-type': 'multipart/form-data; boundary=AaB03x' } }, function (res) {

                expect(Object.keys(res.result).length).to.equal(2);
                expect(res.result.field1).to.exist;
                expect(res.result.field1.length).to.equal(2);
                expect(res.result.field1[1]).to.equal('Repeated name segment');
                expect(res.result.pics).to.exist;
                done();
            });
        });

        it('parses a file correctly', function (done) {

            var file = Fs.readFileSync(Path.join(__dirname, '../../images/hapi.png'));
            var fileHandler = function (request) {

                expect(request.raw.req.headers['content-type']).to.contain('multipart/form-data');
                expect(request.payload['my_file']).to.contain('Photoshop');
                done();
            };

            var server = new Hapi.Server('0.0.0.0', 0);
            server.addRoute({ method: 'POST', path: '/file', config: { handler: fileHandler } });
            server.start(function () {

                var r = Request.post(server.settings.uri + '/file');
                var form = r.form();
                form.append('my_file', file);
            });
        });
    });
});
<commit_msg>Adding payload interruption tests<commit_after>// Load modules

var Chai = require('chai');
var Request = require('request');
var Fs = require('fs');
var Http = require('http');
var Path = require('path');
var Stream = require('stream');
var Hapi = require('../helpers');

// Declare internals

var internals = {};

// Test shortcuts

var expect = Chai.expect;

describe('Payload', function () {

    describe('raw mode', function () {

        it('returns an error on req socket error', function (done) {

            var handler = function (request) {

                expect(request).to.not.exist;       // Must not be called
            };

            var server = new Hapi.Server();
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler } });

            server.inject({ method: 'POST', url: '/', payload: 'test', simulate: { error: true } }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.code).to.equal(500);
                done();
            });
        });

        it('returns an error on req socket close', function (done) {

            var handler = function (request) {

                expect(request).to.not.exist;       // Must not be called
            };

            var server = new Hapi.Server();
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler } });

            server.inject({ method: 'POST', url: '/', payload: 'test', simulate: { close: true } }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.code).to.equal(500);
                done();
            });
        });

        it('returns a raw body', function (done) {

            var multipartPayload = '{"x":"1","y":"2","z":"3"}';

            var handler = function (request) {

                expect(request.payload).to.not.exist;
                expect(request.rawBody).to.equal(multipartPayload);
                request.reply(request.rawBody);
            };

            var server = new Hapi.Server();
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler, payload: 'raw' } });

            server.inject({ method: 'POST', url: '/', payload: multipartPayload }, function (res) {

                expect(res.result).to.exist;
                expect(res.result).to.equal(multipartPayload);
                done();
            });
        });

        it('returns a parsed body and sets a raw body', function (done) {

            var multipartPayload = '{"x":"1","y":"2","z":"3"}';

            var handler = function (request) {

                expect(request.payload).to.exist;
                expect(request.payload.z).to.equal('3');
                expect(request.rawBody).to.equal(multipartPayload);
                request.reply(request.payload);
            };

            var server = new Hapi.Server();
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler } });

            server.inject({ method: 'POST', url: '/', payload: multipartPayload }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.x).to.equal('1');
                done();
            });
        });

        it('doesn\'t set the request payload when the request is interrupted and its streaming', function (done) {

            var handler = function (request) {

                expect(request.payload).to.not.exist;
                request.reply('Success');
            };

            var server = new Hapi.Server('0.0.0.0', 0);
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler, payload: 'raw' } });

            var s = new Stream();
            s.readable = true;

            server.start(function () {

                var options = {
                    hostname: '127.0.0.1',
                    port: server.settings.port,
                    path: '/',
                    method: 'POST'
                };

                var iv = setInterval(function () {

                    s.emit('data', 'Hello');
                }, 5);

                var req = Http.request(options, function (res) {

                });

                req.on('error', function (err) {

                    expect(err.code).to.equal('ECONNRESET');
                    done();
                });

                s.pipe(req);

                setTimeout(function () {

                    req.abort();
                    clearInterval(iv);
                }, 15);
            });
        });

        it('doesn\'t set the request payload when the request is interrupted', function (done) {

            var handler = function (request) {

                expect(request.payload).to.not.exist;
                request.reply('Success');
            };

            var server = new Hapi.Server('0.0.0.0', 0);
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler, payload: 'raw' } });

            server.start(function () {

                var options = {
                    hostname: '127.0.0.1',
                    port: server.settings.port,
                    path: '/',
                    method: 'POST',
                    headers: {
                        'Content-Length': '10'
                    }
                };

                var req = Http.request(options, function (res) {

                });

                req.write('Hello\n');

                req.on('error', function (err) {

                    expect(err.code).to.equal('ECONNRESET');
                    done();
                });

                setTimeout(function () {

                    req.abort();
                }, 15);
            });
        });
    });

    describe('stream mode', function () {

        var handler = function (request) {

            expect(request.payload).to.not.exist;
            request.reply('Success');
        };

        var server = new Hapi.Server('127.0.0.1', 0);
        server.addRoute({ method: 'POST', path: '/', config: { handler: handler, payload: 'stream' } });

        before(function (done) {

            server.start(done);
        });

        it('doesn\'t set the request payload when streaming data in and the connection is interrupted', function (done) {

            var options = {
                hostname: '127.0.0.1',
                port: server.settings.port,
                path: '/',
                method: 'POST'
            };

            var s = new Stream();
            s.readable = true;

            var iv = setInterval(function () {

                s.emit('data', 'Hello');
            }, 5);

            var req = Http.request(options, function (res) {

                expect(res.statusCode).to.equal(200);
                done();
            });

            s.pipe(req);

            setTimeout(function () {

                req.abort();
                clearInterval(iv);
            }, 15);
        });
    });

    describe('unzip', function () {

        it('returns an error on malformed payload', function (done) {

            var multipartPayload = '7d8d78347h8347d58w347hd58w374d58w37h5d8w37hd4';

            var handler = function (request) {

                expect(request).to.not.exist;       // Must not be called
            };

            var server = new Hapi.Server();
            server.addRoute({ method: 'POST', path: '/', config: { handler: handler } });

            server.inject({ method: 'POST', url: '/', payload: multipartPayload, headers: { 'content-encoding': 'gzip' } }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.code).to.equal(400);
                done();
            });
        });
    });

    describe('multi-part', function () {

        var invalidHandler = function (request) {

            expect(request).to.not.exist;       // Must not be called
        };

        var echo = function (request) {

            request.reply(request.payload);
        };

        var _server = new Hapi.Server('0.0.0.0', 0);
        _server.addRoute({ method: 'POST', path: '/invalid', handler: invalidHandler });
        _server.addRoute({ method: 'POST', path: '/echo', handler: echo });

        var multipartPayload =
                '--AaB03x\r\n' +
                'content-disposition: form-data; name="field1"\r\n' +
                '\r\n' +
                'Joe Blow\r\nalmost tricked you!\r\n' +
                '--AaB03x\r\n' +
                'content-disposition: form-data; name="field1"\r\n' +
                '\r\n' +
                'Repeated name segment\r\n' +
                '--AaB03x\r\n' +
                'content-disposition: form-data; name="pics"; filename="file1.txt"\r\n' +
                'Content-Type: text/plain\r\n' +
                '\r\n' +
                '... contents of file1.txt ...\r\r\n' +
                '--AaB03x--\r\n';

        it('returns an error on missing boundary in content-type header', function (done) {

            _server.inject({ method: 'POST', url: '/invalid', payload: multipartPayload, headers: { 'content-type': 'multipart/form-data' } }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.code).to.equal(400);
                done();
            });
        });

        it('returns an error on empty separator in content-type header', function (done) {

            _server.inject({ method: 'POST', url: '/invalid', payload: multipartPayload, headers: { 'content-type': 'multipart/form-data; boundary=' } }, function (res) {

                expect(res.result).to.exist;
                expect(res.result.code).to.equal(400);
                done();
            });
        });

        it('returns parsed multipart data', function (done) {

            _server.inject({ method: 'POST', url: '/echo', payload: multipartPayload, headers: { 'content-type': 'multipart/form-data; boundary=AaB03x' } }, function (res) {

                expect(Object.keys(res.result).length).to.equal(2);
                expect(res.result.field1).to.exist;
                expect(res.result.field1.length).to.equal(2);
                expect(res.result.field1[1]).to.equal('Repeated name segment');
                expect(res.result.pics).to.exist;
                done();
            });
        });

        it('parses a file correctly', function (done) {

            var file = Fs.readFileSync(Path.join(__dirname, '../../images/hapi.png'));
            var fileHandler = function (request) {

                expect(request.raw.req.headers['content-type']).to.contain('multipart/form-data');
                expect(request.payload['my_file']).to.contain('Photoshop');
                done();
            };

            var server = new Hapi.Server('0.0.0.0', 0);
            server.addRoute({ method: 'POST', path: '/file', config: { handler: fileHandler } });
            server.start(function () {

                var r = Request.post(server.settings.uri + '/file');
                var form = r.form();
                form.append('my_file', file);
            });
        });
    });
});
<|endoftext|>


<commit_before><?php
require_once("ui.inc");
require_once("utils.inc");
require_once("dbapi.inc");

// Return an array of frame times for each page.
$gNumUrls = getParam('n');
$gLabel = getParam('l');
if ( ! $gNumUrls || ! $gLabel ) {
	exit();
}

// Ask for twice as many as needed so we can filter out adult sites.
$limitgoogle = "(url = 'http://www.google.com/' OR url not like '%://www.google.%')";
$query = "select pageid, url, wptid, wptrun from $gPagesTable where label='$gLabel' and rank > 0 and rank <= " . (2*$gNumUrls) . " and $limitgoogle order by rank asc;";
$result = doQuery($query);
if ( 0 == mysql_num_rows($result) ) {
	mysql_free_result($result);
	// Older crawls do NOT have values for "rank". Use today's rank.
	$query = "select u.rank, pageid, url, wptid, wptrun from $gPagesTable, $gUrlsTable as u where label='$gLabel' and u.rank > 0 and u.rank <= " . (2*$gNumUrls) . " and urlOrig=url and $limitgoogle order by u.rank asc;";
	$result = doQuery($query);
}
$wptServer = wptServer();
$i = 0;
$msMax = 0;
while ($row = mysql_fetch_assoc($result)) {
	$url = $row['url'];
	if ( ! isAdultContent($url) ) {
		$pageid = $row['pageid'];
		$wptid = $row['wptid'];
		$wptrun = $row['wptrun'];

		$xmlurl = "{$wptServer}xmlResult.php?test=$wptid";
		$xmlstr = fetchUrl($xmlurl);
		$xml = new SimpleXMLElement($xmlstr);
		$frames = $xml->data->run[($wptrun - 1)]->firstView->videoFrames;
		if ( $frames->frame ) {
			$sJS = "";
			foreach($frames->frame as $frame) {
				$ms = floatval($frame->time) * 1000;
				$msMax = max($msMax, $ms);
				$sJS .= ( $sJS ? ", " : "" ) . "$ms: 1"; // must NOT end with a comma - poop
			}
			echo "hPages[$pageid] = {" . $sJS . "};\n";
		}

		$i++;
		if ( $i >= $gNumUrls ) {
			break;
		}
	}
}
mysql_free_result($result);
echo "\nmsMax = Math.max(msMax, $msMax);\n";
?>
<commit_msg>update to match patchwork.php where we get the same 100 URLs from both crawls<commit_after><?php
require_once("ui.inc");
require_once("utils.inc");
require_once("dbapi.inc");

// Return an array of frame times for each page.
$gNumUrls = getParam('n');
$gLabel1 = getParam('l1');
if ( ! $gNumUrls || ! $gLabel1 ) {
	exit();
}
$gLabel2 = getParam('l2');
$wptServer = wptServer();
$msMax = 0;

// Find the topmost URLs in both crawls:
$limitgoogle = "(url = 'http://www.google.com/' OR url not like '%://www.google.%')"; // There are 10+ sites that all look the same from Google intl sites
$maxRank = 5 * $gNumUrls; // we get back MORE results than needed so we can filter out adult content
$query = "select url, count(*) as num from $gPagesTable, $gUrlsTable as u where (label = '$gLabel1' or label = '$gLabel2') and url=urlOrig and u.rank > 0 and u.rank < $maxRank and $limitgoogle group by url having num=2 order by u.rank asc;";
$result = doQuery($query);
$i = 0;
$sUrls = "";
while ($row = mysql_fetch_assoc($result)) {
	$url = $row['url'];
	if ( ! isAdultContent($url) ) {
		$sUrls .= ", '$url'";
		$i++;
		if ( $i >= $gNumUrls ) {
			break;
		}
	}
}
$sUrls = substr($sUrls, 1); // remove leading ","
mysql_free_result($result);

// Display a thumbnail of the Top N websites at a certain time in the loading process.
$query = "select pageid, url, wptid, wptrun from $gPagesTable, $gUrlsTable as u where label='$gLabel1' and urlOrig=url and u.rank > 0 and u.rank <= $maxRank and url in ($sUrls) order by u.rank asc;";
$result = doQuery($query);
while ($row = mysql_fetch_assoc($result)) {
	$url = $row['url'];
	$pageid = $row['pageid'];
	$wptid = $row['wptid'];
	$wptrun = $row['wptrun'];

	$xmlurl = "{$wptServer}xmlResult.php?test=$wptid";
	$xmlstr = fetchUrl($xmlurl);
	$xml = new SimpleXMLElement($xmlstr);
	$frames = $xml->data->run[($wptrun - 1)]->firstView->videoFrames;
	if ( $frames->frame ) {
		$sJS = "";
		foreach($frames->frame as $frame) {
			$ms = floatval($frame->time) * 1000;
			$msMax = max($msMax, $ms);
			$sJS .= ( $sJS ? ", " : "" ) . "$ms: 1"; // must NOT end with a comma - poop
		}
		echo "hPages[$pageid] = {" . $sJS . "};\n";
	}
}
mysql_free_result($result);

// Display a thumbnail of the Top N websites at a certain time in the loading process.
$query = "select pageid, url, wptid, wptrun from $gPagesTable, $gUrlsTable as u where label='$gLabel2' and urlOrig=url and u.rank > 0 and u.rank <= $maxRank and url in ($sUrls) order by u.rank asc;";
$result = doQuery($query);
while ($row = mysql_fetch_assoc($result)) {
	$url = $row['url'];
	$pageid = $row['pageid'];
	$wptid = $row['wptid'];
	$wptrun = $row['wptrun'];

	$xmlurl = "{$wptServer}xmlResult.php?test=$wptid";
	$xmlstr = fetchUrl($xmlurl);
	$xml = new SimpleXMLElement($xmlstr);
	$frames = $xml->data->run[($wptrun - 1)]->firstView->videoFrames;
	if ( $frames->frame ) {
		$sJS = "";
		foreach($frames->frame as $frame) {
			$ms = floatval($frame->time) * 1000;
			$msMax = max($msMax, $ms);
			$sJS .= ( $sJS ? ", " : "" ) . "$ms: 1"; // must NOT end with a comma - poop
		}
		echo "hPages[$pageid] = {" . $sJS . "};\n";
	}
}
mysql_free_result($result);

echo "\nmsMax = Math.max(msMax, $msMax);\n";
?>
<|endoftext|>


<commit_before>import add from '../support/task';
import calf from '../support/calf';
import {getElementById} from '../common/getElement';
import {now} from '../support/dataObj';
import {pCC} from '../support/layout';
import retryAjax from '../ajax/retryAjax';
import {
  createDocument,
  getRandomInt,
  getValue,
  imageServer,
  rnd,
  setValue
} from '../support/system';

var composeMsg =
  '

' +
  'Composing to do

';

function displayComposeMsg() {
  getElementById('notifications')
    .insertAdjacentHTML('afterbegin', composeMsg);
}

function getDoc(data) {
  if (calf.cmd !== 'composing') {
    return createDocument(data);
  }
  return document;
}

function parseComposing(data) {
  var doc = getDoc(data);
  var timeRE = /ETA:\s*(\d+)h\s*(\d+)m\s*(\d+)s/;
  var times = [];
  var openSlots = doc.getElementsByClassName('composing-potion-time');
  Array.prototype.forEach.call(openSlots, function(el) {
    if (el.textContent === 'ETA: Ready to Collect!' ||
        el.textContent === 'ETA: n/a') {
      times.push(0);
    } else {
      var timeArr = timeRE.exec(el.textContent);
      var milli = (timeArr[1] * 3600 + timeArr[2] * 60 + Number(timeArr[3])) *
        1000 + now;
      times.push(milli);
    }
  });
  var eta = Math.min.apply(null, times);
  if (eta === 0) {
    if (calf.cmd !== 'composing') {displayComposeMsg();}
    setValue('needToCompose', true);
  } else {
    setValue('needToCompose', false);
    setValue('lastComposeCheck', eta);
  }
}

function createSuccess(temp, textStatus) {
  var potName = temp[temp.selectedIndex].text;
  var myParent = temp.parentNode;
  var infoDiv = myParent.previousElementSibling.previousElementSibling;
  infoDiv.children[0].innerHTML = '';
  infoDiv.children[0].classList.add('fshPot');
  infoDiv.children[0].style.backgroundImage = 'url(' + imageServer +
    '/composing/potions/' + getRandomInt(1, 11) + '_' +
    getRandomInt(1, 51) + '.gif)';
  infoDiv.children[2].innerHTML = 'Creating \'' +
    potName + '\' Potion';
  infoDiv.children[3].innerHTML = '';
  myParent.innerHTML = '
' + textStatus + '
';
}

function createPotion(temp) { // jQuery
  retryAjax({
    cache: false,
    dataType: 'json',
    url: 'index.php',
    data: {
      cmd: 'composing',
      subcmd: 'createajax',
      template_id: temp.value,
      _rnd: rnd()
    }
  }).done(function potionDone(data, textStatus) {
    if (data.error !== '') {
      temp.parentNode.innerHTML = '
' +
        data.error + '
';
    } else {
      createSuccess(temp, textStatus);
    }
  });
}

function quickCreateBailOut(target) {
  return target.tagName !== 'SPAN' || target.className !== 'quickCreate';
}

function quickCreate(evt) {
  var self = evt.target.parentNode;
  if (quickCreateBailOut(self)) {return;}
  var temp = self.previousElementSibling.previousElementSibling;
  if (temp && temp.value !== 'none') {
    self.innerHTML = '';
    self.classList.add('fshSpinner', 'fshSpinner12', 'fshComposingSpinner');
    createPotion(temp);
  }
}

function checkLastCompose() { // jQuery
  var lastComposeCheck = getValue('lastComposeCheck');
  if (lastComposeCheck && now < lastComposeCheck) {return;}
  retryAjax('index.php?cmd=composing').done(function(data) {
    add(3, parseComposing, [data]);
  });
}

function composeAlert() {
  var needToCompose = getValue('needToCompose');
  if (needToCompose) {
    displayComposeMsg();
    return;
  }
  checkLastCompose();
}

export function injectComposeAlert() {
  if (calf.cmd !== 'composing') {composeAlert();}
}

function moveButtons() {
  if (getValue('moveComposingButtons')) {
    var buttonDiv = getElementById('composing-error-dialog')
      .previousElementSibling;
    buttonDiv.setAttribute('style', 'text-align: right; padding: 0 38px 0 0');
    var top = pCC.getElementsByClassName('composing-level')[0]
      .parentNode;
    top.insertAdjacentElement('beforebegin', buttonDiv);
  }
}

export function injectComposing() {
  if (!pCC) {return;}
  if (calf.enableComposingAlert) {
    parseComposing();
  }

  var buttons = pCC
    .querySelectorAll('input[id^=create-]:not(#create-multi)');
  Array.prototype.forEach.call(buttons, function(el) {
    el.insertAdjacentHTML('afterend', '' +
      '[Quick Create]');
  });
  pCC.addEventListener('click', quickCreate);
  moveButtons();
}

export function composingCreate() {
  getElementById('composing-add-skill')
    .addEventListener('click', function() {
      getElementById('composing-skill-level-input').value =
        getElementById('composing-skill-level-max').textContent;
    });
  getElementById('composing-skill-select')
    .addEventListener('change', function() {
      getElementById('composing-skill-level-input').value =
        getElementById('composing-skill-level-max').textContent;
    });
}
<commit_msg>reduce complexity (updated eslint rule 4.14.0)<commit_after>import add from '../support/task';
import calf from '../support/calf';
import {getElementById} from '../common/getElement';
import {now} from '../support/dataObj';
import {pCC} from '../support/layout';
import retryAjax from '../ajax/retryAjax';
import {
  createDocument,
  getRandomInt,
  getValue,
  imageServer,
  rnd,
  setValue
} from '../support/system';

var composeMsg =
  '

' +
  'Composing to do

';

function displayComposeMsg() {
  getElementById('notifications')
    .insertAdjacentHTML('afterbegin', composeMsg);
}

function getDoc(data) {
  if (calf.cmd !== 'composing') {
    return createDocument(data);
  }
  return document;
}

function parseComposing(data) {
  var doc = getDoc(data);
  var timeRE = /ETA:\s*(\d+)h\s*(\d+)m\s*(\d+)s/;
  var times = [];
  var openSlots = doc.getElementsByClassName('composing-potion-time');
  Array.prototype.forEach.call(openSlots, function(el) {
    if (el.textContent === 'ETA: Ready to Collect!' ||
        el.textContent === 'ETA: n/a') {
      times.push(0);
    } else {
      var timeArr = timeRE.exec(el.textContent);
      var milli = (timeArr[1] * 3600 + timeArr[2] * 60 + Number(timeArr[3])) *
        1000 + now;
      times.push(milli);
    }
  });
  var eta = Math.min.apply(null, times);
  if (eta === 0) {
    if (calf.cmd !== 'composing') {displayComposeMsg();}
    setValue('needToCompose', true);
  } else {
    setValue('needToCompose', false);
    setValue('lastComposeCheck', eta);
  }
}

function createSuccess(temp, textStatus) {
  var potName = temp[temp.selectedIndex].text;
  var myParent = temp.parentNode;
  var infoDiv = myParent.previousElementSibling.previousElementSibling;
  infoDiv.children[0].innerHTML = '';
  infoDiv.children[0].classList.add('fshPot');
  infoDiv.children[0].style.backgroundImage = 'url(' + imageServer +
    '/composing/potions/' + getRandomInt(1, 11) + '_' +
    getRandomInt(1, 51) + '.gif)';
  infoDiv.children[2].innerHTML = 'Creating \'' +
    potName + '\' Potion';
  infoDiv.children[3].innerHTML = '';
  myParent.innerHTML = '
' + textStatus + '
';
}

function createPotion(temp) { // jQuery
  retryAjax({
    cache: false,
    dataType: 'json',
    url: 'index.php',
    data: {
      cmd: 'composing',
      subcmd: 'createajax',
      template_id: temp.value,
      _rnd: rnd()
    }
  }).done(function potionDone(data, textStatus) {
    if (data.error !== '') {
      temp.parentNode.innerHTML = '
' +
        data.error + '
';
    } else {
      createSuccess(temp, textStatus);
    }
  });
}

function isOurTarget(target) {
  return target.tagName === 'SPAN' && target.className === 'quickCreate';
}

function doQuickCreate(self) {
  var temp = self.previousElementSibling.previousElementSibling;
  if (temp && temp.value !== 'none') {
    self.innerHTML = '';
    self.classList.add('fshSpinner', 'fshSpinner12', 'fshComposingSpinner');
    createPotion(temp);
  }
}

function quickCreate(evt) {
  var self = evt.target.parentNode;
  if (isOurTarget(self)) {doQuickCreate(self);}
}

function checkLastCompose() { // jQuery
  var lastComposeCheck = getValue('lastComposeCheck');
  if (lastComposeCheck && now < lastComposeCheck) {return;}
  retryAjax('index.php?cmd=composing').done(function(data) {
    add(3, parseComposing, [data]);
  });
}

function composeAlert() {
  var needToCompose = getValue('needToCompose');
  if (needToCompose) {
    displayComposeMsg();
    return;
  }
  checkLastCompose();
}

export function injectComposeAlert() {
  if (calf.cmd !== 'composing') {composeAlert();}
}

function moveButtons() {
  if (getValue('moveComposingButtons')) {
    var buttonDiv = getElementById('composing-error-dialog')
      .previousElementSibling;
    buttonDiv.setAttribute('style', 'text-align: right; padding: 0 38px 0 0');
    var top = pCC.getElementsByClassName('composing-level')[0]
      .parentNode;
    top.insertAdjacentElement('beforebegin', buttonDiv);
  }
}

export function injectComposing() {
  if (!pCC) {return;}
  if (calf.enableComposingAlert) {
    parseComposing();
  }

  var buttons = pCC
    .querySelectorAll('input[id^=create-]:not(#create-multi)');
  Array.prototype.forEach.call(buttons, function(el) {
    el.insertAdjacentHTML('afterend', '' +
      '[Quick Create]');
  });
  pCC.addEventListener('click', quickCreate);
  moveButtons();
}

export function composingCreate() {
  getElementById('composing-add-skill')
    .addEventListener('click', function() {
      getElementById('composing-skill-level-input').value =
        getElementById('composing-skill-level-max').textContent;
    });
  getElementById('composing-skill-select')
    .addEventListener('change', function() {
      getElementById('composing-skill-level-input').value =
        getElementById('composing-skill-level-max').textContent;
    });
}
<|endoftext|>


<commit_before>/**
 * @param {Object=} options Configuration options
 * @param {(VowelWorm.instance|VowelWorm.instance[])} options.worms Any
 * VowelWorm instances to begin with
 * @param {number=700} options.width The width of the game board
 * @param {number=500} options.height The height of the game board
 * @param {number=0xFFFFFF} options.background The background color of the game
 * @param {HTMLElement=document.body} options.element What to append the graph to
 * @type VowelWorm.Game
 * @constructor
 */
VowelWorm.Game = function( options ) {
  var game = this;
  game.width = options.width || 700;
  game.height = options.height || 500;
  game.x1 = -1;
  game.x2 = 2;
  game.y1 = -1;
  game.y2 = 3;

  game.minHz = 300;
  game.maxHz = 8000;
  game.fb = 10;

  /**
   * Represents the threshold in dB that VowelWorm's audio should be at in
   * order to to plot anything.
   * @see {@link isSilent}
   */
  game.silence = -70;

  /**
   * Used for storing frequency data.
   * Chrome does not adequately garbage collect typed arrays, so this shouldn't
   * be created in a repeatedly-called function--otherwise we'll run up memory
   * pretty fast.
   *
   * TODO - the VowelWorm core code needs to handle this, not this game module
   */
  var buffer = new Float32Array(1024);

  /**
   * Contains all instances of worms for this game
   * @type Array.Object
   */
  var worms = [];

  game.play = function(){
    game.drawWorm();
    window.requestAnimationFrame(game.play);
  };

  /**
   * Inserts a worm into the ever-increasing frenzy of VowelWorm.
   * @param {VowelWorm.instance} worm
   */
  game.addWorm = function(worm) {
   var container = {};
   container.worm = worm;
   container.circles = [];
   worms.push(container);
  };

  game.drawVowels = function(){
    var letters = [
      ["e",241.28871891963863,272.35519027188354],
      ["i",189.01833799969594,191.97765003235634],
      ["a",337.6219414250667,357.00896411883406],
      ["o",404.5714404194302,304.96641792056766],
      ["u",432.17314090483404,251.94657762575406]
    ];

    for(var i=0; i<letters.length; i++){
      var letter = new PIXI.Text(letters[i][0],{font: "35px sans-serif", fill: "black", align: "center"});
      letter.position.x = letters[i][1];
      letter.position.y = letters[i][2];

      game._stage.addChild(letter);
    }
    game._renderer.render(game._stage);
  };

  game.drawWorm = function(){
    var current_color = 0x00FF00;
    worms.forEach(function(container) {
      var worm = container.worm,
          circles = container.circles;

      var coords = getCoords(worm);

      if(coords!==null){
        doRender = true;

        var x = coords.x;
        var y = coords.y;

        var circle = new PIXI.Sprite.fromImage("src/modules/core/circle.png");
        circle.position.x = x;
        circle.position.y = y;
        circle.tint = current_color;

        circles.push(circle);

        game._stage.addChild(circle);
      }
      current_color = getNextColor(current_color);
    });
    fadeOldCircles();
    game._renderer.render(game._stage);
  };

  var getCoords = function(worm){
    worm._analyzer.getFloatFrequencyData(buffer);

    if(isSilent(buffer)) {
      return null;
    }

    var position = worm.getMFCCs({
      minFreq: game.minHz,
      maxFreq: game.maxHz,
      filterBanks: game.fb
    });

    if(position.length) {
      var x = position[1];
      var y = position[2];

      //Pass in coords flipped 90 degrees
      var coords = adjustXAndY(y,-x);
      return coords;
    }else{
      return null;
    }
  };

  var adjustXAndY = function(x,y){
    var xStart = game.x1;
    var xEnd = game.x2;
    var yStart = game.y1;
    var yEnd = game.y2;

    var xDist = game.width/(xEnd-xStart);
    var yDist = game.height/(yEnd-yStart);

    var adjustedX = (x-xStart)*xDist + 20;
    var adjustedY = game.height-(y-yStart)*yDist+20;

    return {x:adjustedX,y:adjustedY};
  };

  /**
   * Determines whether, for plotting purposes, the audio data is silent or not
   * Compares against the threshold given for {@link game.silence}.
   * @param {Array.<number>} data - An array containing dB values
   * @return {boolean} Whether or not the data is essentially 'silent'
   */
  var isSilent = function(data) {
    for(var i = 0; i<data.length; i++) {
      if(data[i] > game.silence) {
        return false;
      }
    }
    return true;
  };

  var fadeOldCircles = function(){
    worms.forEach(function(container) {
      var circles = container.circles;
      for(var i=0; i<circles.length; i++){
        var obj = circles[i];

        obj.alpha = obj.alpha - .2;

        if(obj.alpha <= 0){
          game._stage.removeChild(obj);
          circles.splice(i, 1);
          i--;
        }
      }
    });
  };

  //Color Functions
  //Converts an integer representing a color to an integer representing a color 45 degrees away
  var getNextColor = function(old_color){
    if(typeof old_color == 'number'){
      old_color = old_color.toString(16);
      //Pad with 0's if necessary
      while(old_color.length<6){
        old_color = "0" + old_color;
      }
    }

    old_color = tinycolor(old_color);
    new_color = old_color.spin(45).toHex();
    new_color = parseInt(new_color,16);
    return new_color;
  };

  // CREATE GAME
  var bgColor = options.background !== undefined ? options.background : 0xFFFFFF;
  game._stage = new PIXI.Stage(bgColor);
  game._renderer = PIXI.autoDetectRenderer(game.width, game.height);
  game._renderer.render(game._stage);
  try{
    options.element.appendChild(game._renderer.view);
  }catch(e){
    document.body.appendChild(game._renderer.view);
  }
  game.drawVowels();

  if(options.worms) {
    if(options.worms instanceof Array) {
      options.worms.forEach(function(worm) {
        game.addWorm(worm);
      });
    }
    else
    {
      game.addWorm(worm);
    }
  }
  game.play();
};
<commit_msg>Toggling IPA chart enabled.<commit_after>/**
 * @param {Object=} options Configuration options
 * @param {(VowelWorm.instance|VowelWorm.instance[])} options.worms Any
 * VowelWorm instances to begin with
 * @param {number=700} options.width The width of the game board
 * @param {number=500} options.height The height of the game board
 * @param {number=0xFFFFFF} options.background The background color of the game
 * @param {HTMLElement=document.body} options.element What to append the graph to
 * @type VowelWorm.Game
 * @constructor
 */
VowelWorm.Game = function( options ) {
  "use strict";

  var game = this;
  game.width = options.width || 700;
  game.height = options.height || 500;
  game.x1 = -1;
  game.x2 = 2;
  game.y1 = -1;
  game.y2 = 3;

  game.minHz = 300;
  game.maxHz = 8000;
  game.fb = 10;

  /**
   * Represents the threshold in dB that VowelWorm's audio should be at in
   * order to to plot anything.
   * @see {@link isSilent}
   */
  game.silence = -70;

  /**
   * Used for storing frequency data.
   * Chrome does not adequately garbage collect typed arrays, so this shouldn't
   * be created in a repeatedly-called function--otherwise we'll run up memory
   * pretty fast.
   *
   * TODO - the VowelWorm core code needs to handle this, not this game module
   */
  var buffer = new Float32Array(1024);

  /**
   * Contains all instances of worms for this game
   * @type Array.Object
   */
  var worms = [];

  /**
   * You can change this with game.ipa = true/false
   * @type boolean
   */
  var ipaEnabled = true;

  var ipaChart = new PIXI.DisplayObjectContainer();

  game.play = function(){
    game.drawWorm();
    window.requestAnimationFrame(game.play);
  };

  /**
   * Inserts a worm into the ever-increasing frenzy of VowelWorm.
   * @param {VowelWorm.instance} worm
   */
  game.addWorm = function(worm) {
   var container = {};
   container.worm = worm;
   container.circles = [];
   worms.push(container);
  };

  game.drawWorm = function(){
    var current_color = 0x00FF00;
    worms.forEach(function(container) {
      var worm = container.worm,
          circles = container.circles;

      var coords = getCoords(worm);

      if(coords!==null){
        var doRender = true;

        var x = coords.x;
        var y = coords.y;

        var circle = new PIXI.Sprite.fromImage("src/modules/core/circle.png");
        circle.position.x = x;
        circle.position.y = y;
        circle.tint = current_color;

        circles.push(circle);

        game._stage.addChild(circle);
      }
      current_color = getNextColor(current_color);
    });
    fadeOldCircles();
    game._renderer.render(game._stage);
  };

  Object.defineProperties(game, {
    ipa: {
      enumerable: true,
      get: function() {
        return ipaEnabled;
      },
      set: function(val) {
        var bool = !!val;
        if(ipaEnabled === bool) {
          return;
        }
        ipaEnabled = bool;

        if(ipaEnabled) {
          game._stage.addChild(ipaChart);
        }
        else
        {
          game._stage.removeChild(ipaChart);
        }
        window.requestAnimationFrame(game._renderer.render);
      }
    }
  });

  var getCoords = function(worm){
    worm._analyzer.getFloatFrequencyData(buffer);

    if(isSilent(buffer)) {
      return null;
    }

    var position = worm.getMFCCs({
      minFreq: game.minHz,
      maxFreq: game.maxHz,
      filterBanks: game.fb
    });

    if(position.length) {
      var x = position[1];
      var y = position[2];

      //Pass in coords flipped 90 degrees
      var coords = adjustXAndY(y,-x);
      return coords;
    }else{
      return null;
    }
  };

  var adjustXAndY = function(x,y){
    var xStart = game.x1;
    var xEnd = game.x2;
    var yStart = game.y1;
    var yEnd = game.y2;

    var xDist = game.width/(xEnd-xStart);
    var yDist = game.height/(yEnd-yStart);

    var adjustedX = (x-xStart)*xDist + 20;
    var adjustedY = game.height-(y-yStart)*yDist+20;

    return {x:adjustedX,y:adjustedY};
  };

  /**
   * Determines whether, for plotting purposes, the audio data is silent or not
   * Compares against the threshold given for {@link game.silence}.
   * @param {Array.<number>} data - An array containing dB values
   * @return {boolean} Whether or not the data is essentially 'silent'
   */
  var isSilent = function(data) {
    for(var i = 0; i<data.length; i++) {
      if(data[i] > game.silence) {
        return false;
      }
    }
    return true;
  };

  var fadeOldCircles = function(){
    worms.forEach(function(container) {
      var circles = container.circles;
      for(var i=0; i<circles.length; i++){
        var obj = circles[i];

        obj.alpha = obj.alpha - .2;

        if(obj.alpha <= 0){
          game._stage.removeChild(obj);
          circles.splice(i, 1);
          i--;
        }
      }
    });
  };

  //Color Functions
  //Converts an integer representing a color to an integer representing a color 45 degrees away
  var getNextColor = function(old_color){
    if(typeof old_color == 'number'){
      old_color = old_color.toString(16);
      //Pad with 0's if necessary
      while(old_color.length<6){
        old_color = "0" + old_color;
      }
    }

    old_color = tinycolor(old_color);
    var new_color = old_color.spin(45).toHex();
    new_color = parseInt(new_color,16);
    return new_color;
  };

  /**
   * Fills the IPA Chart. A constructor helper method.
   */
  var drawVowels = function() {
    if(!ipaChart.children.length) {
      var letters = [
        ["e",241.28871891963863,272.35519027188354],
        ["i",189.01833799969594,191.97765003235634],
        ["a",337.6219414250667,357.00896411883406],
        ["o",404.5714404194302,304.96641792056766],
        ["u",432.17314090483404,251.94657762575406]
      ];
      for(var i=0; i<letters.length; i++){
        var letter = new PIXI.Text(letters[i][0],{font: "35px sans-serif", fill: "black", align: "center"});
        letter.position.x = letters[i][1];
        letter.position.y = letters[i][2];
        ipaChart.addChild(letter);
      }
    }
  };

  // CREATE GAME
  var bgColor = options.background !== undefined ? options.background : 0xFFFFFF;
  game._stage = new PIXI.Stage(bgColor);
  game._renderer = PIXI.autoDetectRenderer(game.width, game.height);
  try{
    options.element.appendChild(game._renderer.view);
  }catch(e){
    document.body.appendChild(game._renderer.view);
  }
  drawVowels();
  if(ipaEnabled) {
    game._stage.addChild(ipaChart);
  }

  if(options.worms) {
    if(options.worms instanceof Array) {
      options.worms.forEach(function(worm) {
        game.addWorm(worm);
      });
    }
    else
    {
      game.addWorm(worm);
    }
  }
  game._renderer.render(game._stage);
  game.play();
};
<|endoftext|>


<commit_before>/* Keeps the URL in sync with the navigator store */
import {
  getters as moreInfoGetters,
  actions as moreInfoActions
} from '../more-info';
import { activePane, activeFilter, activePage } from './getters';
import { navigate } from './actions';
import paneFilterToPage from './pane-filter-to-page';
import pageToPaneFilter from './page-to-pane-filter';

const isSupported = history.pushState && !__DEMO__;
const title = 'Home Assistant';

let ignoreNextDeselectEntity = false;
let unwatchNavigationObserver;
let unwatchMoreInfoObserver;

function initialSync(reactor) {
  let pane, filter, url;
  // store current state in url or set state based on url
  if (location.pathname === '/') {
    pane = reactor.evaluate(activePane);
    filter = reactor.evaluate(activeFilter);
    url = paneFilterToPage(pane, filter);
  } else {
    const paneFilter = pageToPaneFilter(location.pathname.substr(1));
    pane = paneFilter.pane;
    filter = paneFilter.filter;
    url = location.pathname;
    navigate(reactor, pane, filter);
  }
  history.replaceState({pane, filter}, title, url);
}

function popstateChangeListener(reactor, ev) {
  const {pane, filter} = ev.state;

  if (reactor.evaluate(moreInfoGetters.hasCurrentEntityId)) {
    ignoreNextDeselectEntity = true;
    moreInfoActions.deselectEntity();
  } else {
    navigate(reactor, pane, filter);
  }
};

export function startSync(reactor) {
  if (!isSupported) {
    return;
  }

  initialSync(reactor);

  // keep url in sync with state
  unwatchNavigationObserver = reactor.observe(activePage, (page) => {
    const state = pageToPaneFilter(page);
    if (!(state.pane === history.state.pane &&
          state.filter == history.state.filter)) {
      history.pushState(state, page, `/${page}`);
    }
  });

  unwatchMoreInfoObserver = reactor.observe(
    moreInfoGetters.hasCurrentEntityId,
    (moreInfoEntitySelected) => {
      if (moreInfoEntitySelected) {
        history.pushState(history.state, title, location.pathname);
      } else if (ignoreNextDeselectEntity) {
        ignoreNextDeselectEntity = false;
      } else {
        history.back();
      }
    }
  );

  // keep state in sync when url changes via forward/back buttons
  window.addEventListener('popstate', popstateChangeListener.bind(null, reactor));
};

export function stopSync(reactor) {
  if (!isSupported) {
    return;
  }

  if (unwatchNavigationObserver) {
    unwatchNavigationObserver();
    unwatchMoreInfoObserver();
  }

  window.removeEventListener('popstate', popstateChangeListener);
}
<commit_msg>Update navigation to support multiple reactors<commit_after>/* Keeps the URL in sync with the navigator store */
import {
  getters as moreInfoGetters,
  actions as moreInfoActions
} from '../more-info';
import { activePane, activeFilter, activePage } from './getters';
import { navigate } from './actions';
import paneFilterToPage from './pane-filter-to-page';
import pageToPaneFilter from './page-to-pane-filter';

const IS_SUPPORTED = history.pushState && !__DEMO__;
const PAGE_TITLE = 'Home Assistant';
const SYNCS = {};

function getSync(reactor) {
  return SYNCS[reactor.hassId];
}

function initialSync(reactor) {
  let pane;
  let filter;
  let url;
  // store current state in url or set state based on url
  if (location.pathname === '/') {
    pane = reactor.evaluate(activePane);
    filter = reactor.evaluate(activeFilter);
    url = paneFilterToPage(pane, filter);
  } else {
    const paneFilter = pageToPaneFilter(location.pathname.substr(1));
    pane = paneFilter.pane;
    filter = paneFilter.filter;
    url = location.pathname;
    navigate(reactor, pane, filter);
  }
  history.replaceState({pane, filter}, PAGE_TITLE, url);
}

function popstateChangeListener(reactor, ev) {
  const {pane, filter} = ev.state;

  if (reactor.evaluate(moreInfoGetters.hasCurrentEntityId)) {
    getSync(reactor).ignoreNextDeselectEntity = true;
    moreInfoActions.deselectEntity(reactor);
  } else {
    navigate(reactor, pane, filter);
  }
}

export function startSync(reactor) {
  if (!IS_SUPPORTED) {
    return;
  }

  initialSync(reactor);

  // keep url in sync with state
  const unwatchNavigationObserver = reactor.observe(activePage, (page) => {
    const state = pageToPaneFilter(page);
    if (!(state.pane === history.state.pane &&
          state.filter === history.state.filter)) {
      history.pushState(state, page, `/${page}`);
    }
  });
  const unwatchMoreInfoObserver = reactor.observe(
    moreInfoGetters.hasCurrentEntityId,
    (moreInfoEntitySelected) => {
      if (moreInfoEntitySelected) {
        history.pushState(history.state, PAGE_TITLE, location.pathname);
      /* eslint-disable no-use-before-define */
      } else if (sync.ignoreNextDeselectEntity) {
        sync.ignoreNextDeselectEntity = false;
      /* eslint-enable no-use-before-define */
      } else {
        history.back();
      }
    }
  );
  const boundPopstateChangeListener = popstateChangeListener.bind(null, reactor);
  const sync = {
    unwatchNavigationObserver,
    unwatchMoreInfoObserver,
    popstateChangeListener: boundPopstateChangeListener,
    ignoreNextDeselectEntity: false,
  };

  SYNCS[reactor.hassId] = sync;

  // keep state in sync when url changes via forward/back buttons
  window.addEventListener('popstate', boundPopstateChangeListener);
}

export function stopSync(reactor) {
  if (!IS_SUPPORTED) {
    return;
  }

  const sync = getSync(reactor);
  if (!sync) {
    return;
  }

  sync.unwatchNavigationObserver();
  sync.unwatchMoreInfoObserver();
  window.removeEventListener('popstate', sync.popstateChangeListener);
  SYNCS[reactor.hassId] = false;
}
<|endoftext|>


<commit_before>(function(window) {

  /** Use a single load function */
  var load = typeof require == 'function' ? require : window.load;

  /** Load Benchmark.js */
  var Benchmark =
    window.Benchmark || (
      Benchmark = load('../vendor/benchmark.js/benchmark.js') || window.Benchmark,
      Benchmark.Benchmark || Benchmark
    );

  /** Load Lo-Dash */
  var lodash =
    window.lodash || (
      lodash = load('../lodash.js') || window._,
      lodash = lodash._ || lodash,
      lodash.noConflict()
    );

  /** Load Underscore */
  var _ =
    window._ || (
      _ = load('../vendor/underscore/underscore.js') || window._,
      _._ || _
    );

  /** Used to access the Firebug Lite panel */
  var fbPanel = (fbPanel = window.document && document.getElementById('FirebugUI')) &&
    (fbPanel = (fbPanel = fbPanel.contentWindow || fbPanel.contentDocument).document || fbPanel) &&
    fbPanel.getElementById('fbPanel1');

  /** Used to score Lo-Dash and Underscore performance */
  var score = { 'lodash': 0, 'underscore': 0 };

  /** Used to queue benchmark suites */
  var suites = [];

  /** Add `console.log()` support for Narwhal and RingoJS */
  window.console || (window.console = { 'log': window.print });

  /** Expose functions to the global object */
  window._ = _;
  window.Benchmark = Benchmark;
  window.lodash = lodash;

  /*--------------------------------------------------------------------------*/

  /**
   * Logs text to the console.
   *
   * @private
   * @param {String} text The text to log.
   */
  function log(text) {
    console.log(text);
    if (fbPanel) {
      // scroll down the Firebug Lite panel
      fbPanel.scrollTop = fbPanel.scrollHeight;
    }
  }

  /*--------------------------------------------------------------------------*/

  lodash.extend(Benchmark.options, {
    'async': true,
    'setup': function() {
      var window = Function('return this || global')(),
          _ = window._,
          lodash = window.lodash;

      var length = 20,
          numbers = [],
          object = {},
          fourNumbers = [5, 25, 10, 30],
          nestedNumbers = [1, [2], [3, [[4]]]],
          twoNumbers = [12, 21],
          words = [
            'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
            'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen',
            'seventeen', 'eighteen', 'nineteen', 'twenty'
          ];

      var ctor = function() { },
          func = function(greeting) { return greeting + ': ' + this.name; };

      var lodashBoundNormal = lodash.bind(func, { 'name': 'moe' }),
          lodashBoundCtor = lodash.bind(ctor, { 'name': 'moe' }),
          lodashBoundPartial = lodash.bind(func, { 'name': 'moe' }, 'hi');

      var _boundNormal = _.bind(func, { 'name': 'moe' }),
          _boundCtor = _.bind(ctor, { 'name': 'moe' }),
          _boundPartial = _.bind(func, { 'name': 'moe' }, 'hi');

      for (var index = 0; index < length; index++) {
        numbers[index] = index;
        object['key' + index] = index;
      }

      var objects = lodash.map(numbers, function(num) {
        return { 'num': num };
      });
    }
  });

  lodash.extend(Benchmark.Suite.options, {
    'onStart': function() {
      log('\n' + this.name + ':');
    },
    'onCycle': function(event) {
      log(event.target + '');
    },
    'onComplete': function() {
      var formatNumber = Benchmark.formatNumber,
          fastest = this.filter('fastest'),
          slowest = this.filter('slowest'),
          lodashHz = 1 / (this[0].stats.mean + this[0].stats.moe),
          underscoreHz = 1 / (this[1].stats.mean + this[1].stats.moe);

      if (fastest.length > 1) {
        log('It\'s too close to call.');
        lodashHz = underscoreHz = Math.min(lodashHz, underscoreHz);
      }
      else {
        var fastestHz = fastest[0] == this[0] ? lodashHz : underscoreHz,
            slowestHz = slowest[0] == this[0] ? lodashHz : underscoreHz,
            percent = formatNumber(Math.round(((fastestHz / slowestHz) - 1) * 100));

        log(fastest[0].name + ' is ' + percent + '% faster.');
      }
      // add score adjusted for margin of error
      score.lodash += lodashHz;
      score.underscore += underscoreHz;

      // remove current suite from queue
      suites.shift();

      if (suites.length) {
        // run next suite
        suites[0].run();
      }
      else {
        var fastestTotalHz = Math.max(score.lodash, score.underscore),
            slowestTotalHz = Math.min(score.lodash, score.underscore),
            totalPercent = formatNumber(Math.round(((fastestTotalHz  / slowestTotalHz) - 1) * 100)),
            totalX = formatNumber((fastestTotalHz / slowestTotalHz).toFixed(2)),
            message = ' is ' + totalPercent + '% (' + totalX + 'x) faster than ';

        // report results
        if (score.lodash >= score.underscore) {
          log('\nLo-Dash' + message + 'Underscore.');
        } else {
          log('\nUnderscore' + message + 'Lo-Dash.');
        }
      }
    }
  });

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('bind call')
      .add('Lo-Dash', function() {
        lodash.bind(func, { 'name': 'moe' }, 'hi');
      })
      .add('Underscore', function() {
        _.bind(func, { 'name': 'moe' }, 'hi');
      })
  );

  suites.push(
    Benchmark.Suite('bound')
      .add('Lo-Dash', function() {
        lodashBoundNormal();
      })
      .add('Underscore', function() {
        _boundNormal();
      })
  );

  suites.push(
    Benchmark.Suite('bound partial')
      .add('Lo-Dash', function() {
        lodashBoundPartial();
      })
      .add('Underscore', function() {
        _boundPartial();
      })
  );

  suites.push(
    Benchmark.Suite('bound constructor')
      .add('Lo-Dash', function() {
        new lodashBoundCtor();
      })
      .add('Underscore', function() {
        new _boundCtor();
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('each array')
      .add('Lo-Dash', function() {
        var result = [];
        lodash.each(numbers, function(num) { result.push(num * 2); });
      })
      .add('Underscore', function() {
        var result = [];
        _.each(numbers, function(num) { result.push(num * 2); });
      })
  );

  suites.push(
    Benchmark.Suite('each array thisArg')
      .add('Lo-Dash', function() {
        var result = [];
        lodash.each(numbers, function(num, index) {
          result.push(num + this['key' + index]);
        }, object);
      })
      .add('Underscore', function() {
        var result = [];
        _.each(numbers, function(num, index) {
          result.push(num + this['key' + index]);
        }, object);
      })
  );

  suites.push(
    Benchmark.Suite('each object')
      .add('Lo-Dash', function() {
        var result = [];
        lodash.each(object, function(num) {
          result.push(num * 2);
        });
      })
      .add('Underscore', function() {
        var result = [];
        _.each(object, function(num) {
          result.push(num * 2);
        });
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('find')
      .add('Lo-Dash', function() {
        lodash.find(numbers, function(num) {
          return num === 19;
        });
      })
      .add('Underscore', function() {
        _.find(numbers, function(num) {
          return num === 19;
        });
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('flatten deep')
      .add('Lo-Dash', function() {
        lodash.flatten(nestedNumbers);
      })
      .add('Underscore', function() {
        _.flatten(nestedNumbers);
      })
  );

  suites.push(
    Benchmark.Suite('flatten shallow')
      .add('Lo-Dash', function() {
        lodash.flatten(nestedNumbers, true);
      })
      .add('Underscore', function() {
        _.flatten(nestedNumbers, true);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('difference')
      .add('Lo-Dash', function() {
        lodash.difference(numbers, fourNumbers);
      })
      .add('Underscore', function() {
        _.difference(numbers, fourNumbers);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('groupBy callback')
      .add('Lo-Dash', function() {
        lodash.groupBy(numbers, function(num) { return num >> 1; });
      })
      .add('Underscore', function() {
        _.groupBy(numbers, function(num) { return num >> 1; });
      })
  );

  suites.push(
    Benchmark.Suite('groupBy property name')
      .add('Lo-Dash', function() {
        lodash.groupBy(words, 'length');
      })
      .add('Underscore', function() {
        _.groupBy(words, 'length');
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('indexOf')
      .add('Lo-Dash', function() {
        lodash.indexOf(numbers, 9);
      })
      .add('Underscore', function() {
        _.indexOf(numbers, 9);
      })
  );

  suites.push(
    Benchmark.Suite('indexOf isSorted')
      .add('Lo-Dash', function() {
        lodash.indexOf(numbers, 9, true);
      })
      .add('Underscore', function() {
        _.indexOf(numbers, 9, true);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('intersection')
      .add('Lo-Dash', function() {
        lodash.intersection(numbers, fourNumbers, twoNumbers);
      })
      .add('Underscore', function() {
        _.intersection(numbers, fourNumbers, twoNumbers);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('keys')
      .add('Lo-Dash', function() {
        lodash.keys(object);
      })
      .add('Underscore', function() {
        _.keys(object);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('lastIndexOf')
      .add('Lo-Dash', function() {
        lodash.lastIndexOf(numbers, 9);
      })
      .add('Underscore', function() {
        _.lastIndexOf(numbers, 9);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('map')
      .add('Lo-Dash', function() {
        lodash.map(objects, function(value) {
          return value.num;
        });
      })
      .add('Underscore', function() {
        _.map(objects, function(value) {
          return value.num;
        });
      })
  );

  suites.push(
    Benchmark.Suite('map thisArg')
      .add('Lo-Dash', function() {
        lodash.map(objects, function(value, index) {
          return this['key' + index] + value.num;
        }, object);
      })
      .add('Underscore', function() {
        _.map(objects, function(value, index) {
          return this['key' + index] + value.num;
        }, object);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('max')
      .add('Lo-Dash', function() {
        lodash.max(numbers);
      })
      .add('Underscore', function() {
        _.max(numbers);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('min')
      .add('Lo-Dash', function() {
        lodash.min(numbers);
      })
      .add('Underscore', function() {
        _.min(numbers);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('pick')
      .add('Lo-Dash', function() {
        lodash.pick(object, 'key6', 'key13');
      })
      .add('Underscore', function() {
        _.pick(object, 'key6', 'key13');
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('pluck')
      .add('Lo-Dash', function() {
        lodash.pluck(objects, 'num');
      })
      .add('Underscore', function() {
        _.pluck(objects, 'num');
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('sortBy callback')
      .add('Lo-Dash', function() {
        lodash.sortBy(numbers, function(num) { return Math.sin(num); });
      })
      .add('Underscore', function() {
        _.sortBy(numbers, function(num) { return Math.sin(num); });
      })
  );

  suites.push(
    Benchmark.Suite('sortBy callback thisArg')
      .add('Lo-Dash', function() {
        lodash.sortBy(numbers, function(num) { return this.sin(num); }, Math);
      })
      .add('Underscore', function() {
        _.sortBy(numbers, function(num) { return this.sin(num); }, Math);
      })
  );

  suites.push(
    Benchmark.Suite('sortBy property name')
      .add('Lo-Dash', function() {
        lodash.sortBy(words, 'length');
      })
      .add('Underscore', function() {
        _.sortBy(words, 'length');
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('times')
      .add('Lo-Dash', function() {
        var result = [];
        lodash.times(length, function(n) { result.push(n); });
      })
      .add('Underscore', function() {
        var result = [];
        _.times(length, function(n) { result.push(n); });
      })
  );

  suites.push(
    Benchmark.Suite('times thisArg')
      .add('Lo-Dash', function() {
        var result = [];
        lodash.times(length, function(n) { result.push(this.sin(n)); }, Math);
      })
      .add('Underscore', function() {
        var result = [];
        _.times(length, function(n) { result.push(this.sin(n)); }, Math);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('union')
      .add('Lo-Dash', function() {
        lodash.union(numbers, fourNumbers, twoNumbers);
      })
      .add('Underscore', function() {
        _.union(numbers, fourNumbers, twoNumbers);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('values')
      .add('Lo-Dash', function() {
        lodash.values(objects);
      })
      .add('Underscore', function() {
        _.values(objects);
      })
  );

  /*--------------------------------------------------------------------------*/

  if (Benchmark.platform + '') {
    log(Benchmark.platform + '');
  }
  // start suites
  suites[0].run();

}(typeof global == 'object' && global || this));
<commit_msg>Tweak `indexOf isSorted` benchmark.<commit_after>(function(window) {

  /** Use a single load function */
  var load = typeof require == 'function' ? require : window.load;

  /** Load Benchmark.js */
  var Benchmark =
    window.Benchmark || (
      Benchmark = load('../vendor/benchmark.js/benchmark.js') || window.Benchmark,
      Benchmark.Benchmark || Benchmark
    );

  /** Load Lo-Dash */
  var lodash =
    window.lodash || (
      lodash = load('../lodash.js') || window._,
      lodash = lodash._ || lodash,
      lodash.noConflict()
    );

  /** Load Underscore */
  var _ =
    window._ || (
      _ = load('../vendor/underscore/underscore.js') || window._,
      _._ || _
    );

  /** Used to access the Firebug Lite panel */
  var fbPanel = (fbPanel = window.document && document.getElementById('FirebugUI')) &&
    (fbPanel = (fbPanel = fbPanel.contentWindow || fbPanel.contentDocument).document || fbPanel) &&
    fbPanel.getElementById('fbPanel1');

  /** Used to score Lo-Dash and Underscore performance */
  var score = { 'lodash': 0, 'underscore': 0 };

  /** Used to queue benchmark suites */
  var suites = [];

  /** Add `console.log()` support for Narwhal and RingoJS */
  window.console || (window.console = { 'log': window.print });

  /** Expose functions to the global object */
  window._ = _;
  window.Benchmark = Benchmark;
  window.lodash = lodash;

  /*--------------------------------------------------------------------------*/

  /**
   * Logs text to the console.
   *
   * @private
   * @param {String} text The text to log.
   */
  function log(text) {
    console.log(text);
    if (fbPanel) {
      // scroll down the Firebug Lite panel
      fbPanel.scrollTop = fbPanel.scrollHeight;
    }
  }

  /*--------------------------------------------------------------------------*/

  lodash.extend(Benchmark.options, {
    'async': true,
    'setup': function() {
      var window = Function('return this || global')(),
          _ = window._,
          lodash = window.lodash;

      var length = 20,
          numbers = [],
          object = {},
          fourNumbers = [5, 25, 10, 30],
          nestedNumbers = [1, [2], [3, [[4]]]],
          twoNumbers = [12, 21],
          words = [
            'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
            'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen',
            'seventeen', 'eighteen', 'nineteen', 'twenty'
          ];

      var ctor = function() { },
          func = function(greeting) { return greeting + ': ' + this.name; };

      var lodashBoundNormal = lodash.bind(func, { 'name': 'moe' }),
          lodashBoundCtor = lodash.bind(ctor, { 'name': 'moe' }),
          lodashBoundPartial = lodash.bind(func, { 'name': 'moe' }, 'hi');

      var _boundNormal = _.bind(func, { 'name': 'moe' }),
          _boundCtor = _.bind(ctor, { 'name': 'moe' }),
          _boundPartial = _.bind(func, { 'name': 'moe' }, 'hi');

      for (var index = 0; index < length; index++) {
        numbers[index] = index;
        object['key' + index] = index;
      }

      var objects = lodash.map(numbers, function(num) {
        return { 'num': num };
      });
    }
  });

  lodash.extend(Benchmark.Suite.options, {
    'onStart': function() {
      log('\n' + this.name + ':');
    },
    'onCycle': function(event) {
      log(event.target + '');
    },
    'onComplete': function() {
      var formatNumber = Benchmark.formatNumber,
          fastest = this.filter('fastest'),
          slowest = this.filter('slowest'),
          lodashHz = 1 / (this[0].stats.mean + this[0].stats.moe),
          underscoreHz = 1 / (this[1].stats.mean + this[1].stats.moe);

      if (fastest.length > 1) {
        log('It\'s too close to call.');
        lodashHz = underscoreHz = Math.min(lodashHz, underscoreHz);
      }
      else {
        var fastestHz = fastest[0] == this[0] ? lodashHz : underscoreHz,
            slowestHz = slowest[0] == this[0] ? lodashHz : underscoreHz,
            percent = formatNumber(Math.round(((fastestHz / slowestHz) - 1) * 100));

        log(fastest[0].name + ' is ' + percent + '% faster.');
      }
      // add score adjusted for margin of error
      score.lodash += lodashHz;
      score.underscore += underscoreHz;

      // remove current suite from queue
      suites.shift();

      if (suites.length) {
        // run next suite
        suites[0].run();
      }
      else {
        var fastestTotalHz = Math.max(score.lodash, score.underscore),
            slowestTotalHz = Math.min(score.lodash, score.underscore),
            totalPercent = formatNumber(Math.round(((fastestTotalHz  / slowestTotalHz) - 1) * 100)),
            totalX = formatNumber((fastestTotalHz / slowestTotalHz).toFixed(2)),
            message = ' is ' + totalPercent + '% (' + totalX + 'x) faster than ';

        // report results
        if (score.lodash >= score.underscore) {
          log('\nLo-Dash' + message + 'Underscore.');
        } else {
          log('\nUnderscore' + message + 'Lo-Dash.');
        }
      }
    }
  });

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('bind call')
      .add('Lo-Dash', function() {
        lodash.bind(func, { 'name': 'moe' }, 'hi');
      })
      .add('Underscore', function() {
        _.bind(func, { 'name': 'moe' }, 'hi');
      })
  );

  suites.push(
    Benchmark.Suite('bound')
      .add('Lo-Dash', function() {
        lodashBoundNormal();
      })
      .add('Underscore', function() {
        _boundNormal();
      })
  );

  suites.push(
    Benchmark.Suite('bound partial')
      .add('Lo-Dash', function() {
        lodashBoundPartial();
      })
      .add('Underscore', function() {
        _boundPartial();
      })
  );

  suites.push(
    Benchmark.Suite('bound constructor')
      .add('Lo-Dash', function() {
        new lodashBoundCtor();
      })
      .add('Underscore', function() {
        new _boundCtor();
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('each array')
      .add('Lo-Dash', function() {
        var result = [];
        lodash.each(numbers, function(num) { result.push(num * 2); });
      })
      .add('Underscore', function() {
        var result = [];
        _.each(numbers, function(num) { result.push(num * 2); });
      })
  );

  suites.push(
    Benchmark.Suite('each array thisArg')
      .add('Lo-Dash', function() {
        var result = [];
        lodash.each(numbers, function(num, index) {
          result.push(num + this['key' + index]);
        }, object);
      })
      .add('Underscore', function() {
        var result = [];
        _.each(numbers, function(num, index) {
          result.push(num + this['key' + index]);
        }, object);
      })
  );

  suites.push(
    Benchmark.Suite('each object')
      .add('Lo-Dash', function() {
        var result = [];
        lodash.each(object, function(num) {
          result.push(num * 2);
        });
      })
      .add('Underscore', function() {
        var result = [];
        _.each(object, function(num) {
          result.push(num * 2);
        });
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('find')
      .add('Lo-Dash', function() {
        lodash.find(numbers, function(num) {
          return num === 19;
        });
      })
      .add('Underscore', function() {
        _.find(numbers, function(num) {
          return num === 19;
        });
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('flatten deep')
      .add('Lo-Dash', function() {
        lodash.flatten(nestedNumbers);
      })
      .add('Underscore', function() {
        _.flatten(nestedNumbers);
      })
  );

  suites.push(
    Benchmark.Suite('flatten shallow')
      .add('Lo-Dash', function() {
        lodash.flatten(nestedNumbers, true);
      })
      .add('Underscore', function() {
        _.flatten(nestedNumbers, true);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('difference')
      .add('Lo-Dash', function() {
        lodash.difference(numbers, fourNumbers);
      })
      .add('Underscore', function() {
        _.difference(numbers, fourNumbers);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('groupBy callback')
      .add('Lo-Dash', function() {
        lodash.groupBy(numbers, function(num) { return num >> 1; });
      })
      .add('Underscore', function() {
        _.groupBy(numbers, function(num) { return num >> 1; });
      })
  );

  suites.push(
    Benchmark.Suite('groupBy property name')
      .add('Lo-Dash', function() {
        lodash.groupBy(words, 'length');
      })
      .add('Underscore', function() {
        _.groupBy(words, 'length');
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('indexOf')
      .add('Lo-Dash', function() {
        lodash.indexOf(numbers, 9);
      })
      .add('Underscore', function() {
        _.indexOf(numbers, 9);
      })
  );

  suites.push(
    Benchmark.Suite('indexOf isSorted')
      .add('Lo-Dash', function() {
        lodash.indexOf(numbers, 19, true);
      })
      .add('Underscore', function() {
        _.indexOf(numbers, 19, true);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('intersection')
      .add('Lo-Dash', function() {
        lodash.intersection(numbers, fourNumbers, twoNumbers);
      })
      .add('Underscore', function() {
        _.intersection(numbers, fourNumbers, twoNumbers);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('keys')
      .add('Lo-Dash', function() {
        lodash.keys(object);
      })
      .add('Underscore', function() {
        _.keys(object);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('lastIndexOf')
      .add('Lo-Dash', function() {
        lodash.lastIndexOf(numbers, 9);
      })
      .add('Underscore', function() {
        _.lastIndexOf(numbers, 9);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('map')
      .add('Lo-Dash', function() {
        lodash.map(objects, function(value) {
          return value.num;
        });
      })
      .add('Underscore', function() {
        _.map(objects, function(value) {
          return value.num;
        });
      })
  );

  suites.push(
    Benchmark.Suite('map thisArg')
      .add('Lo-Dash', function() {
        lodash.map(objects, function(value, index) {
          return this['key' + index] + value.num;
        }, object);
      })
      .add('Underscore', function() {
        _.map(objects, function(value, index) {
          return this['key' + index] + value.num;
        }, object);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('max')
      .add('Lo-Dash', function() {
        lodash.max(numbers);
      })
      .add('Underscore', function() {
        _.max(numbers);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('min')
      .add('Lo-Dash', function() {
        lodash.min(numbers);
      })
      .add('Underscore', function() {
        _.min(numbers);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('pick')
      .add('Lo-Dash', function() {
        lodash.pick(object, 'key6', 'key13');
      })
      .add('Underscore', function() {
        _.pick(object, 'key6', 'key13');
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('pluck')
      .add('Lo-Dash', function() {
        lodash.pluck(objects, 'num');
      })
      .add('Underscore', function() {
        _.pluck(objects, 'num');
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('sortBy callback')
      .add('Lo-Dash', function() {
        lodash.sortBy(numbers, function(num) { return Math.sin(num); });
      })
      .add('Underscore', function() {
        _.sortBy(numbers, function(num) { return Math.sin(num); });
      })
  );

  suites.push(
    Benchmark.Suite('sortBy callback thisArg')
      .add('Lo-Dash', function() {
        lodash.sortBy(numbers, function(num) { return this.sin(num); }, Math);
      })
      .add('Underscore', function() {
        _.sortBy(numbers, function(num) { return this.sin(num); }, Math);
      })
  );

  suites.push(
    Benchmark.Suite('sortBy property name')
      .add('Lo-Dash', function() {
        lodash.sortBy(words, 'length');
      })
      .add('Underscore', function() {
        _.sortBy(words, 'length');
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('times')
      .add('Lo-Dash', function() {
        var result = [];
        lodash.times(length, function(n) { result.push(n); });
      })
      .add('Underscore', function() {
        var result = [];
        _.times(length, function(n) { result.push(n); });
      })
  );

  suites.push(
    Benchmark.Suite('times thisArg')
      .add('Lo-Dash', function() {
        var result = [];
        lodash.times(length, function(n) { result.push(this.sin(n)); }, Math);
      })
      .add('Underscore', function() {
        var result = [];
        _.times(length, function(n) { result.push(this.sin(n)); }, Math);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('union')
      .add('Lo-Dash', function() {
        lodash.union(numbers, fourNumbers, twoNumbers);
      })
      .add('Underscore', function() {
        _.union(numbers, fourNumbers, twoNumbers);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('values')
      .add('Lo-Dash', function() {
        lodash.values(objects);
      })
      .add('Underscore', function() {
        _.values(objects);
      })
  );

  /*--------------------------------------------------------------------------*/

  if (Benchmark.platform + '') {
    log(Benchmark.platform + '');
  }
  // start suites
  suites[0].run();

}(typeof global == 'object' && global || this));
<|endoftext|>


<commit_before>// Copyright (c) 2015 Alejandro Blanco <alejandro.b.e@gmail.com>
// MIT License

import Ember from 'ember';

export default Ember.Route.extend({
    model: function (params) {
        return this.store.findRecord('password', params.password_id);
    },

    setupController: function (controller, model) {
        this._super(controller, model);
        controller.set('tempPassword', null);
        controller.set('wantsToModifyPassword', false);
    },

    actions: {
        willTransition: function () {
            this.controller.set('tempPassword', null);
            return true;
        }
    }
});
<commit_msg>Discard changes when cancelling the editing form<commit_after>// Copyright (c) 2015 Alejandro Blanco <alejandro.b.e@gmail.com>
// MIT License

import Ember from 'ember';

export default Ember.Route.extend({
    model: function (params) {
        return this.store.findRecord('password', params.password_id);
    },

    setupController: function (controller, model) {
        this._super(controller, model);
        controller.set('tempPassword', null);
        controller.set('wantsToModifyPassword', false);
    },

    actions: {
        willTransition: function () {
            var model = this.controller.get('model');

            this.controller.set('tempPassword', null);
            if (model.get('isDirty')) {
                // Discard unsaved changes
                model.rollback();
            }
            return true;
        }
    }
});
<|endoftext|>


<commit_before>exports.ru = {
    profile: 'Профиль',
    logout: 'Выход',
    search: 'Поиск...',

    buttonsTxt: {
        add: 'Добавить',
        enable: 'Включить',
        disable: 'Отключить',
        cancel: 'Отмена',
        back: 'Назад',
        close: 'Закрыть',
        edit: 'Редактировать',
        'delete': 'Удалить',
        submit: 'Подвердить',
        save: 'Сохранить',
        confirm: 'Подтвердить',
        create: 'Создать',
        subscribe: 'Подписаться',
        send: 'Отправить',
        show: 'Показать',
        change: 'Сменить',
        download: 'Скачать'
    },

    allNotifications: 'Посмотреть все уведомления',
    lastNotifications: 'Список последних операций внутри модуля',

    dateTime: {
        seconds: 'Только что',
        minutes: {
            min: 'минуту',
            middle: 'минуты',
            max: 'минут'
        },
        hours: {
            min: 'час',
            middle: 'часа',
            max: 'часов'
        },

        days: {
            min: 'день',
            middle: 'дня',
            max: 'дней'
        }
    },

    crudText: {
        confirm: {
            title: 'Подтверждение',
            body: 'Пожалуйста, подтвердите операцию'
        },

        table: {
            search: 'Поиск',
            info: 'Показано с _START_ по _END_ из _TOTAL_ записей',
            length: '_MENU_ количество записей',
            empty: 'Таблица пустая',
            emptyTable: 'Нет данных для таблицы',
            zeroRecords: 'Нет совпадений в таблице',
            filtered: '- поиск в _MAX_ записей',
            prev: 'Назад',
            next: 'Вперед',
            processing: 'Обработка...'
        },

        create: 'Создать',
        add: 'Добавить',
        save: 'Сохранить',
        process: 'Обработка задания...',
        cancel: 'Отмена',
        waitForOperation: 'Дождитесь обработки текущего процесса заданий прежде чем начать новый',
        warning: 'Внимание',
        success: 'Успешно',
        empty: 'Выберите задания для отправки',
        done: 'Обработка заданий завершена.',
        operation: 'Операция',

        status: {
            created: 'Создан',
            success: 'Успешно',
            paused: 'Выключен',
            process: 'В обработке',
            error: 'Ошибка',
            deleted: 'Удален',
            warning: 'Ошибка',
            unknown: 'Неизвестно'
        }
    },

    taskModal: {
        title: 'Информация по последней операции для ',
        date: 'Дата',
        user: 'Пользователь',
        cmd: 'Команда',
        status: 'Статус',
        report: 'Отчет',
        errors: 'Ошибки'
    },

    breadcrumb: {
        home: 'Домой',
        users: 'Пользователи',
        groups: 'Группы',
        roles: 'Роли',
        borders: 'Бордеры',
        secureips: 'Защищенные IP',
        tunnels: 'Тоннели',
        interfaces: 'Интерфейсы',
        cc: 'Командный центр',
        domains: 'Домены',
        templates: 'Шаблоны',
        hosting: 'Хостинг',
        voxility: 'Voxility',
        nscrub: 'NSCrub',
        nginxDomains: 'Домены NGINX',
        nginxRequests: 'Активность NGINX',
        listenIP: 'Список IP',
        lb: 'Балансировка нагрузки',
        account: 'Учетная запись',
        charts: 'Графики',
        cisco: 'Cisco',
        devices: 'Устройства',
        tunnelIp: 'Тоннельные IP',
        securePool: 'Группы защищенных IP',
        secureNetwork: 'Защищенные сети'
    },

    home: {
        menu: 'Домашняя',
        index: ''
    },

    management: {
        menu: 'Управление',
        users: 'Пользователи',
        groups: 'Группы',
        roles: 'Роли'
    },

    haproxy: {
        menu: 'HAProxy',
        configs: 'Конф. файлы',
        settings: 'Настройки'
    },

    cc: {
        menu: 'Командный центр'
    },

    ajax: {
        notFound: 'Запрошенный адрес не найден',
        serverError: 'Упс! Произошла ошибка сервера',

        title: {
            success: 'Успешно',
            warning: 'Предупреждение',
            danger: 'Ошибка'
        }
    }
};

exports.us = {
    profile: 'My Profile',
    logout: 'Log Out',
    search: 'Search...',

    buttonsTxt: {
        add: 'Add',
        enable: 'Enable',
        disable: 'Disable',
        cancel: 'Cancel',
        back: 'Back',
        close: 'Close',
        edit: 'Edit',
        'delete': 'Delete',
        submit: 'Submit',
        save: 'Save',
        confirm: 'Confirm',
        create: 'Create',
        subscribe: 'Subscribe',
        send: 'Send',
        show: 'Show',
        change: 'Change',
        download: 'Download'
    },

    allNotifications: 'See all notifications',
    lastNotifications: 'The list of last operations inside',

    dateTime: {
        seconds: 'Just now',
        minutes: {
            min: 'minute',
            middle: 'mins',
            max: 'mins'
        },
        hours: {
            min: 'hour',
            middle: 'hrs',
            max: 'hrs'
        },

        days: {
            min: 'day',
            middle: 'days',
            max: 'days'
        }
    },

    crudText: {
        confirm: {
            title: 'Confirm',
            body: 'Please, confirm the operation'
        },

        create: 'Create',
        add: 'Add',
        save: 'Save',
        process: 'Processing the tasks...',
        cancel: 'Cancel',
        waitForOperation: 'Wait for the current processing of tasks before beginning the new',
        warning: 'Warning',
        success: 'Success',
        empty: 'Select tasks for processing',
        done: 'Processing the tasks is completed.',
        operation: 'Operation',

        status: {
            created: 'Created',
            success: 'Success',
            paused: 'Paused',
            process: 'Processing',
            error: 'Error',
            deleted: 'Deleted',
            warning: 'Error',
            unknown: 'Unknown'
        }
    },

    taskModal: {
        title: 'The information about last task of ',
        date: 'Date',
        user: 'User',
        cmd: 'Command',
        status: 'Status',
        report: 'Report',
        errors: 'Errors'
    },

    breadcrumb: {
        home: 'Home',
        users: 'Users',
        cc: 'Command center',
        account: 'Account'
    },

    home: {
        menu: 'Dashboard',
        index: ''
    },

    management: {
        menu: 'Management',
        users: 'Users',
        groups: 'Groups',
        roles: 'Roles'
    },

    haproxy: {
        menu: 'HAProxy',
        configs: 'Configs',
        settings: 'Settings'
    },

    cc: {
        menu: 'Command center'
    },

    ajax: {
        notFound: 'Request not found',
        serverError: 'Oops! A server error occurred',

        title: {
            success: 'Success',
            warning: 'Warning',
            danger: 'Error'
        }
    }
};<commit_msg>add cc words<commit_after>exports.ru = {
    profile: 'Профиль',
    logout: 'Выход',
    search: 'Поиск...',

    buttonsTxt: {
        add: 'Добавить',
        enable: 'Включить',
        disable: 'Отключить',
        cancel: 'Отмена',
        back: 'Назад',
        close: 'Закрыть',
        edit: 'Редактировать',
        'delete': 'Удалить',
        submit: 'Подвердить',
        save: 'Сохранить',
        confirm: 'Подтвердить',
        create: 'Создать',
        subscribe: 'Подписаться',
        send: 'Отправить',
        show: 'Показать',
        change: 'Сменить',
        download: 'Скачать'
    },

    allNotifications: 'Посмотреть все уведомления',
    lastNotifications: 'Список последних операций внутри модуля',

    dateTime: {
        seconds: 'Только что',
        minutes: {
            min: 'минуту',
            middle: 'минуты',
            max: 'минут'
        },
        hours: {
            min: 'час',
            middle: 'часа',
            max: 'часов'
        },

        days: {
            min: 'день',
            middle: 'дня',
            max: 'дней'
        }
    },

    crudText: {
        confirm: {
            title: 'Подтверждение',
            body: 'Пожалуйста, подтвердите операцию'
        },

        table: {
            search: 'Поиск',
            info: 'Показано с _START_ по _END_ из _TOTAL_ записей',
            length: '_MENU_ количество записей',
            empty: 'Таблица пустая',
            emptyTable: 'Нет данных для таблицы',
            zeroRecords: 'Нет совпадений в таблице',
            filtered: '- поиск в _MAX_ записей',
            prev: 'Назад',
            next: 'Вперед',
            processing: 'Обработка...'
        },

        create: 'Создать',
        add: 'Добавить',
        save: 'Сохранить',
        process: 'Обработка задания...',
        cancel: 'Отмена',
        waitForOperation: 'Дождитесь обработки текущего процесса заданий прежде чем начать новый',
        warning: 'Внимание',
        success: 'Успешно',
        empty: 'Выберите задания для отправки',
        done: 'Обработка заданий завершена.',
        operation: 'Операция',

        status: {
            created: 'Создан',
            success: 'Успешно',
            paused: 'Выключен',
            process: 'В обработке',
            error: 'Ошибка',
            deleted: 'Удален',
            warning: 'Ошибка',
            unknown: 'Неизвестно'
        }
    },

    taskModal: {
        title: 'Информация по последней операции для ',
        date: 'Дата',
        user: 'Пользователь',
        cmd: 'Команда',
        status: 'Статус',
        report: 'Отчет',
        errors: 'Ошибки'
    },

    breadcrumb: {
        home: 'Домой',
        users: 'Пользователи',
        groups: 'Группы',
        roles: 'Роли',
        borders: 'Бордеры',
        secureips: 'Защищенные IP',
        tunnels: 'Тоннели',
        interfaces: 'Интерфейсы',
        cc: 'Командный центр',
        domains: 'Домены',
        templates: 'Шаблоны',
        hosting: 'Хостинг',
        voxility: 'Voxility',
        nscrub: 'NSCrub',
        nginxDomains: 'Домены NGINX',
        nginxRequests: 'Активность NGINX',
        listenIP: 'Список IP',
        lb: 'Балансировка нагрузки',
        account: 'Учетная запись',
        charts: 'Графики',
        cisco: 'Cisco',
        devices: 'Устройства',
        tunnelIp: 'Тоннельные IP',
        securePool: 'Группы защищенных IP',
        secureNetwork: 'Защищенные сети'
    },

    home: {
        menu: 'Домашняя',
        index: ''
    },

    management: {
        menu: 'Управление',
        users: 'Пользователи',
        groups: 'Группы',
        roles: 'Роли'
    },

    haproxy: {
        menu: 'HAProxy',
        configs: 'Конф. файлы',
        settings: 'Настройки'
    },

    cc: {
        menu: 'Командный центр',
        info: 'Информация',
        groups: 'Группы'
    },

    ajax: {
        notFound: 'Запрошенный адрес не найден',
        serverError: 'Упс! Произошла ошибка сервера',

        title: {
            success: 'Успешно',
            warning: 'Предупреждение',
            danger: 'Ошибка'
        }
    }
};

exports.us = {
    profile: 'My Profile',
    logout: 'Log Out',
    search: 'Search...',

    buttonsTxt: {
        add: 'Add',
        enable: 'Enable',
        disable: 'Disable',
        cancel: 'Cancel',
        back: 'Back',
        close: 'Close',
        edit: 'Edit',
        'delete': 'Delete',
        submit: 'Submit',
        save: 'Save',
        confirm: 'Confirm',
        create: 'Create',
        subscribe: 'Subscribe',
        send: 'Send',
        show: 'Show',
        change: 'Change',
        download: 'Download'
    },

    allNotifications: 'See all notifications',
    lastNotifications: 'The list of last operations inside',

    dateTime: {
        seconds: 'Just now',
        minutes: {
            min: 'minute',
            middle: 'mins',
            max: 'mins'
        },
        hours: {
            min: 'hour',
            middle: 'hrs',
            max: 'hrs'
        },

        days: {
            min: 'day',
            middle: 'days',
            max: 'days'
        }
    },

    crudText: {
        confirm: {
            title: 'Confirm',
            body: 'Please, confirm the operation'
        },

        create: 'Create',
        add: 'Add',
        save: 'Save',
        process: 'Processing the tasks...',
        cancel: 'Cancel',
        waitForOperation: 'Wait for the current processing of tasks before beginning the new',
        warning: 'Warning',
        success: 'Success',
        empty: 'Select tasks for processing',
        done: 'Processing the tasks is completed.',
        operation: 'Operation',

        status: {
            created: 'Created',
            success: 'Success',
            paused: 'Paused',
            process: 'Processing',
            error: 'Error',
            deleted: 'Deleted',
            warning: 'Error',
            unknown: 'Unknown'
        }
    },

    taskModal: {
        title: 'The information about last task of ',
        date: 'Date',
        user: 'User',
        cmd: 'Command',
        status: 'Status',
        report: 'Report',
        errors: 'Errors'
    },

    breadcrumb: {
        home: 'Home',
        users: 'Users',
        cc: 'Command center',
        account: 'Account'
    },

    home: {
        menu: 'Dashboard',
        index: ''
    },

    management: {
        menu: 'Management',
        users: 'Users',
        groups: 'Groups',
        roles: 'Roles'
    },

    haproxy: {
        menu: 'HAProxy',
        configs: 'Configs',
        settings: 'Settings'
    },

    cc: {
        menu: 'Command center',
        info: 'Info',
        groups: 'Groups'
    },

    ajax: {
        notFound: 'Request not found',
        serverError: 'Oops! A server error occurred',

        title: {
            success: 'Success',
            warning: 'Warning',
            danger: 'Error'
        }
    }
};<|endoftext|>