UNPKG

karma-benchpress

Version:

Karma plugin to run angular-benchpress benchmarks.

1,677 lines (1,495 loc) 569 kB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ var di = require('di'); var Measure = require('./Measure'); var RunState = require('./RunState'); var Statistics = require('./Statistics'); var Steps = require('./Steps'); function Aggregator (measure, runState, statistics, steps) { this._measure = measure; this._runState = runState; this._statistics = statistics; this._steps = steps.all(); this.timesPerAction = {}; } Aggregator.prototype.trimSamples = function(times) { var delta = times.length - this._runState.numSamples; if (delta > 0) { return times.slice(delta); } return times; }; Aggregator.prototype.getTimesPerAction = function(name) { if (this.timesPerAction[name]) return this.timesPerAction[name]; var tpa = this.timesPerAction[name] = { name: name, nextEntry: 0 }; _.each(this._measure.characteristics, function(c) { tpa[c] = { recent: undefined, history: [], avg: {}, min: Number.MAX_VALUE, max: Number.MIN_VALUE }; }); return tpa; }; Aggregator.prototype.updateTimes = function(tpa, index, reference, recentTime) { var curTpa = tpa[reference]; curTpa.recent = recentTime; curTpa.history[index] = recentTime; curTpa.history = this.trimSamples(curTpa.history); curTpa.min = Math.min(curTpa.min, recentTime); curTpa.max = Math.max(curTpa.max, recentTime); }; Aggregator.prototype.calcStats = function() { var stats = {}; var self = this; this._steps.forEach(function(bs) { var recentResult = self._runState.recentResult[bs.name], tpa = self.getTimesPerAction(bs.name); tpa.description = bs.description; _.each(self._measure.characteristics, function(c) { self.updateTimes(tpa, tpa.nextEntry, c, recentResult[c]); var mean = self._statistics.getMean(tpa[c].history); var stdDev = self._statistics.calculateStandardDeviation(tpa[c].history, mean); tpa[c].avg = { mean: mean, stdDev: stdDev, coefficientOfVariation: self._statistics.calculateCoefficientOfVariation(stdDev, mean) }; }); // Start over samples when hits the max set by numSamples tpa.nextEntry++; tpa.nextEntry %= self._runState.numSamples; stats[bs.name] = tpa; }); return stats; }; di.annotate(Aggregator, new di.Inject(Measure, RunState, Statistics, Steps)); module.exports = Aggregator; },{"./Measure":8,"./RunState":9,"./Statistics":11,"./Steps":12,"di":24}],2:[function(require,module,exports){ var di = require('di'); var Aggregator = require('./Aggregator'); var Globals = require('./Globals'); var Logger = require('./Logger'); var Runner = require('./Runner'); var RunState = require('./RunState'); var Rx = require('rx'); var Steps = require('./Steps'); var Utils = require('./Utils'); function AutoRunner(aggregator,globals,logger,runner,runState,steps,utils){ this._aggregator = aggregator; this._globals = globals; this._logger = logger; this._runner = runner; this._runState = runState; this._utils = utils; this._steps = steps; } AutoRunner.prototype.bootstrap = function() { var parsed = this._utils.parseSearch(this._globals._window.location.search) this._runState.setDefault(parsed); if (parsed['__bpAutoClose__'] === 'true') { this._runState.headless = true; } }; AutoRunner.prototype.ready = function () { this._globals._window.setTimeout(function() { this.runBenchmark(this._runState); }.bind(this)); }; AutoRunner.prototype.runBenchmark = function(config) { this.runAllTests().subscribe(function(update) { this._logger.write(update); }.bind(this), null, function() { if (this._runState.headless === true) { var benchpressComplete = new Event('benchpressComplete'); benchpressComplete.result = this.stats; this._globals._window.dispatchEvent(benchpressComplete); this._globals._window.close(); } }.bind(this)); }; AutoRunner.prototype.runAllTests = function (iterations) { this.subject = this.subject || new Rx.Subject(); iterations = typeof iterations === 'number' ? iterations : this._runState.iterations; if (iterations--) { this._steps.all().forEach(function(bs) { var testResults = this._runner.runTimedTest(bs); this._runState.recentResult[bs.name] = testResults; this.subject.onNext({step: bs.name, results: testResults}) }.bind(this)); this.stats = this._aggregator.calcStats(); window.requestAnimationFrame(function() { this.runAllTests(iterations); }.bind(this)); } else { this.stats = this._aggregator.calcStats(); this.subject.onCompleted(); this.subject.dispose(); delete this.subject; } return this.subject; }; di.annotate(AutoRunner, new di.Inject(Aggregator,Globals,Logger,Runner,RunState,Steps,Utils)); module.exports = AutoRunner; },{"./Aggregator":1,"./Globals":5,"./Logger":7,"./RunState":9,"./Runner":10,"./Steps":12,"./Utils":13,"di":24,"rx":29}],3:[function(require,module,exports){ function ClientScripts () { this._scripts = []; } ClientScripts.prototype.all = function() { return this._scripts; } ClientScripts.prototype.shiftOne = function() { return this._scripts.shift(); }; ClientScripts.prototype.add = function(script) { this._scripts.push(script); }; ClientScripts.prototype.addMany = function(scripts) { this._scripts.push.apply(this._scripts, scripts); } module.exports = ClientScripts; },{}],4:[function(require,module,exports){ var di = require('di'); var ClientScripts = require('./ClientScripts'); var Globals = require('./Globals'); var RunState = require('./RunState'); var Rx = require('rx'); var Utils = require('./Utils'); function Document(globals, runState, scripts, utils) { this._utils = utils; this._scripts = scripts; this._globals = globals; this._runState = runState; this.loadNextScript = this.loadNextScript.bind(this); } Document.prototype.setAutoRun = function(val) { this.autoRunner = val; }; Document.prototype.addSampleRange = function() { this.sampleRange = this.container().querySelector('#sampleRange'); if (this.sampleRange) { this.sampleRange.value = Math.max(this._runState.numSamples, 1); this.sampleRange.addEventListener('input', this.onSampleInputChanged.bind(this)); } }; Document.prototype.onSampleInputChanged = function (evt) { var value = evt.target.value; this._runState.numSamples = parseInt(value, 10); }; Document.prototype.container = function() { if (!this._container) { this._container = document.querySelector('#benchmarkContainer'); } return this._container; }; Document.prototype.addInfo = function() { this.infoDiv = this.container().querySelector('div.info'); if (this.infoDiv) { this.infoTemplate = _.template(this.container().querySelector('#infoTemplate').innerHTML); } }; Document.prototype.loadNextScript = function() { var params = this._utils.parseSearch(this._globals._window.location.search); var config = this._scripts.shiftOne(); if (!config) return; if (config.id) { if (params[config.id]) { config.src = params[config.id]; } this.addScriptToUI(config); } var tag = document.createElement('script'); tag.setAttribute('src', config.src); tag.onload = this.loadNextScript; document.body.appendChild(tag); }; Document.prototype.openTab = function (id) { var divs = this._container.querySelectorAll('.tab-pane'); for (var i=0;i<divs.length;i++) { divs[i].style.display = 'none'; } this._container.querySelector('.nav-tabs li.active').classList.remove('active'); this._container.querySelector(id).style.display = 'block'; this._container.querySelector('[href="' + id + '"]').parentElement.classList.add('active'); } Document.prototype.addScriptToUI = function(config) { if (!this._scriptsContainer) return; var compiled = this._scriptTemplate(config); this._scriptsContainer.innerHTML += compiled; }; //Deprecated Document.prototype.getParams = function() { return this._utils.parseSearch(this._globals._window.location.search); }; Document.prototype.addScriptsContainer = function() { if (!this.container()) return; this._scriptsContainer = this.container().querySelector('table.scripts tbody'); this._scriptTemplate = _.template(this.container().querySelector('#scriptTemplate').innerHTML); }; Document.prototype.onDOMContentLoaded = function() { if (!this.container() || this.autoRunner) return; this.addSampleRange(); this.addInfo(); this.addScriptsContainer(); this.loopBtn = document.querySelector('.loopBtn'); this.onceBtn = document.querySelector('.onceBtn'); this.twentyFiveBtn = document.querySelector('.twentyFiveBtn'); }; Document.prototype.observeBtns = function () { if (!this.btnObserver) this.btnObserver = Rx.Observable. fromEvent(document.querySelectorAll('.bp-btn'), 'click'); return this.btnObserver; } Document.prototype.writeReport = function(reportContent) { this.infoDiv.innerHTML = reportContent; }; di.annotate(Document, new di.Inject(Globals, RunState, ClientScripts, Utils)); module.exports = Document; },{"./ClientScripts":3,"./Globals":5,"./RunState":9,"./Utils":13,"di":24,"rx":29}],5:[function(require,module,exports){ function Globals() { this._window = window; } module.exports = Globals; },{}],6:[function(require,module,exports){ var di = require('di'); var Aggregator = require('./Aggregator'); var Document = require('./Document'); var Measure = require('./Measure'); var RunState = require('./RunState'); var Statistics = require('./Statistics'); var Steps = require('./Steps'); var _ = require('underscore'); function Report(aggregator, doc, measure, runState, statistics, steps) { this._aggregator = aggregator; this._doc = doc; this._measure = measure; this._runState = runState; this._statistics = statistics; this._steps = steps.all(); } Report.prototype.generatePartial = function(model) { return this._doc.infoTemplate(model); }; Report.prototype.getMarkup = function(stats) { var report = ''; Object.keys(stats).forEach(function(key) { report += this.generatePartial(stats[key]); }.bind(this)); return report; }; di.annotate(Report, new di.Inject(Aggregator, Document, Measure, RunState, Statistics, Steps)); module.exports = Report; },{"./Aggregator":1,"./Document":4,"./Measure":8,"./RunState":9,"./Statistics":11,"./Steps":12,"di":24,"underscore":30}],7:[function(require,module,exports){ function Logger() { } Logger.prototype.write = function(ln) { console.log(ln); }; module.exports = Logger; },{}],8:[function(require,module,exports){ function Measure(){ this.characteristics = ['gcTime','testTime','garbageCount','retainedCount']; }; Measure.prototype.numMilliseconds = function() { if (window.performance != null && typeof window.performance.now == 'function') { return window.performance.now(); } else if (window.performance != null && typeof window.performance.webkitNow == 'function') { return window.performance.webkitNow(); } else { console.log('using Date.now'); return Date.now(); } }; module.exports = Measure; },{}],9:[function(require,module,exports){ function RunState() { this.defaults = { iterations: 25, numSamples: 20 }; this.iterations = 25; this.numSamples = 20; this.recentResult = {}; }; RunState.prototype.setIterations = function(i) { this.iterations = i; }; RunState.prototype.resetIterations = function() { this.iterations = this.defaults.iterations; }; RunState.prototype.setDefault = function(defaults) { ['iterations','numSamples'].forEach(function(prop) { var propVal = parseInt(defaults[prop],10); if (typeof propVal === 'number' && !isNaN(propVal)) { this[prop] = propVal; this.defaults[prop] = propVal; } else if (typeof defaults[prop] !== 'undefined') { throw new Error(prop + ' must be of type number, got: ' + typeof defaults[prop]); } }.bind(this)); }; module.exports = RunState; },{}],10:[function(require,module,exports){ var di = require('di'); var Aggregator = require('./Aggregator'); var Document = require('./Document'); var Globals = require('./Globals'); var Measure = require('./Measure'); var Report = require('./HtmlReport'); var RunState = require('./RunState'); var Steps = require('./Steps'); var Rx = require('rx'); function Runner (aggregator, doc, globals, measure, report, runState, steps) { this._aggregator = aggregator; this._doc = doc; this._globals = globals; this._measure = measure; this._steps = steps; this._runState = runState; this._report = report; this.reportMarkup = ''; } Runner.prototype.bootstrap = function() { this._btnSubscription = this._doc.observeBtns().subscribe(this.onBtnClick.bind(this)); }; Runner.prototype.ready = function () { //No-op. API symmetry to AutoRunner }; Runner.prototype.onBtnClick = function(e) { switch (e && e.target && e.target.textContent) { case 'Loop': this.loopBenchmark(); break; case 'Once': this.onceBenchmark(); break; case 'Loop 25x': this.twentyFiveBenchmark(); break; case 'Profile': this.profile(); break; case 'Pause': this._runState.setIterations(0); this._doc.loopBtn.innerText = 'Loop'; break; default: throw new Error('Could not find handler'); } }; Runner.prototype.loopBenchmark = function (notify) { this._runState.setIterations(-1); notify && notify({status: 'done', runType: 'loop'}) this._doc.loopBtn.innerText = 'Pause'; this.runAllTests(); }; Runner.prototype.onceBenchmark = function() { this._runState.setIterations(1); this._doc.onceBtn.innerText = '...'; this.runAllTests(function() { this._doc.onceBtn.innerText = 'Once'; }.bind(this)); }; Runner.prototype.twentyFiveBenchmark = function() { var twentyFiveBtn = this._doc.twentyFiveBtn; this._runState.setIterations(25); twentyFiveBtn.innerText = 'Looping...'; this.runAllTests(function() { twentyFiveBtn.innerText = 'Loop 25x'; }, 5); }; Runner.prototype.runAllTests = function (done) { var self = this; if (this._runState.iterations--) { this._steps.all().forEach(function(bs) { var testResults = self.runTimedTest(bs); self._runState.recentResult[bs.name] = testResults; }); var stats = this._aggregator.calcStats(); this.reportMarkup = this._report.getMarkup(stats); this._doc.writeReport(this.reportMarkup); window.requestAnimationFrame(function() { self.runAllTests(done); }); } else { this._doc.writeReport(this.reportMarkup); this._runState.resetIterations(); done && done(); } }; Runner.prototype.profile = function() { console.profile(); this.onceBenchmark(); console.profileEnd(); }; Runner.prototype.runTimedTest = function (bs) { var startTime, endTime, startGCTime, endGCTime, retainedMemory, garbage, beforeHeap, afterHeap, finalHeap; if (typeof this._globals._window.gc === 'function') { this._globals._window.gc(); } if (window.performance && window.performance.memory) { beforeHeap = performance.memory.usedJSHeapSize; } startTime = this._measure.numMilliseconds(); bs.fn(); endTime = this._measure.numMilliseconds() - startTime; if (window.performance && window.performance.memory) { afterHeap = performance.memory.usedJSHeapSize; } startGCTime = this._measure.numMilliseconds(); if (typeof window.gc === 'function') { window.gc(); } endGCTime = this._measure.numMilliseconds() - startGCTime; if (window.performance && window.performance.memory) { finalHeap = performance.memory.usedJSHeapSize; garbage = Math.abs(finalHeap - afterHeap); retainedMemory = finalHeap - beforeHeap; } return { testTime: endTime, gcTime: endGCTime || 0, beforeHeap: beforeHeap || 0, garbageCount: garbage || 0, retainedCount: retainedMemory || 0 }; }; di.annotate(Runner, new di.Inject(Aggregator, Document, Globals, Measure, Report, RunState, Steps)); module.exports = Runner; },{"./Aggregator":1,"./Document":4,"./Globals":5,"./HtmlReport":6,"./Measure":8,"./RunState":9,"./Steps":12,"di":24,"rx":29}],11:[function(require,module,exports){ var di = require('di'); function Statistics() { //Taken from z-table where confidence is 95% this.criticalValue = 1.96 } Statistics.prototype.getMean = function (sample) { var total = 0; sample.forEach(function(x) { total += x; }); return total / sample.length; }; Statistics.prototype.calculateConfidenceInterval = function(standardDeviation, sampleSize) { var standardError = standardDeviation / Math.sqrt(sampleSize); return this.criticalValue * standardError; }; Statistics.prototype.calculateRelativeMarginOfError = function(marginOfError, mean) { /* * Converts absolute margin of error to a relative margin of error by * converting it to a percentage of the mean. */ return (marginOfError / mean); }; Statistics.prototype.calculateCoefficientOfVariation = function(standardDeviation, mean) { return standardDeviation / mean; }; Statistics.prototype.calculateStandardDeviation = function(sample, mean) { var deviation = 0; sample.forEach(function(x) { deviation += Math.pow(x - mean, 2); }); deviation = deviation / (sample.length -1); deviation = Math.sqrt(deviation); return deviation; }; // di.annotate(Statistics, new di.Inject()) module.exports = Statistics; },{"di":24}],12:[function(require,module,exports){ function Steps() { this._steps = []; }; Steps.prototype.all = function () { return this._steps; }; Steps.prototype.add = function (step) { this._steps.push(step); }; module.exports = Steps; },{}],13:[function(require,module,exports){ function Utils() {} Utils.prototype.parseSearch = function (search) { var parsed = {}; var tuples = search.replace(/^\?/, '').split('&'); tuples.forEach(function(pair) { var keyVal = pair.split('='); parsed[keyVal[0]] = keyVal[1]; }); return parsed; }; module.exports = Utils; },{}],14:[function(require,module,exports){ var di = require('di'); var Utils = require('./Utils'); var Globals = require('./Globals'); function Variables(utils, globals) { this.variables = []; this._utils = utils; this._globals = globals; } Variables.prototype._setPendingFromSearch = function() { if (this._pending === undefined) { this._pending = this._utils. parseSearch(this._globals._window.location.search).variable; } }; Variables.prototype._autoSelectPending = function() { if (this._pending !== null && this._pending !== undefined) { return this.select(this._pending); var reduced = this.variables.reduce(function(prev, curr) { prev[curr.value] = curr; return prev; }, {}); this.selected = reduced[this._pending]; } }; Variables.prototype.add = function (variable) { this._setPendingFromSearch(); this.variables.push(variable); this._autoSelectPending(); }; Variables.prototype.addMany = function (varArr) { this._setPendingFromSearch(); this.variables.push.apply(this.variables, varArr); this._autoSelectPending(); }; Variables.prototype.select = function (val) { this.selected = this.variables.reduce(function(prev, curr) { prev[curr.value] = curr; return prev; }, {})[val]; if (this.selected !== undefined) this._pending = null; }; di.annotate(Variables, new di.Inject(Utils, Globals)) module.exports = Variables; },{"./Globals":5,"./Utils":13,"di":24}],15:[function(require,module,exports){ var di = require('di'); var ClientScripts = require('./ClientScripts'); var Document = require('./Document'); var Globals = require('./Globals'); var Measure = require('./Measure'); var Report = require('./HtmlReport'); var AutoRunner = require('./AutoRunner'); var Statistics = require('./Statistics'); var Steps = require('./Steps'); var Variables = require('./Variables'); //Benchpress Facade function AutoBenchPress (doc, globals, measure, report, runner, scripts, statistics, steps, variables) { doc.setAutoRun(true); // Left benchmarkSteps on global for backwards-compatibility //Deprecated window.benchmarkSteps = this.steps = steps.all(); this._scripts = scripts; this.runner = runner; //Deprecated this.scripts = scripts.all(); this.doc = doc; this.variables = variables; //Legacy Support this.Document = doc; this.Measure = measure; this.Runner = runner; this.Report = report; this.Statistics = statistics; if (globals._window) globals._window.addEventListener('DOMContentLoaded', function(e) { doc.onDOMContentLoaded.call(doc); runner.bootstrap(); }.bind(this)); } di.annotate(AutoBenchPress, new di.Inject(Document, Globals, Measure, Report, AutoRunner, ClientScripts, Statistics, Steps, Variables)) var injector = new di.Injector([]); window.bp = injector.get(AutoBenchPress); module.exports = AutoBenchPress; },{"./AutoRunner":2,"./ClientScripts":3,"./Document":4,"./Globals":5,"./HtmlReport":6,"./Measure":8,"./Statistics":11,"./Steps":12,"./Variables":14,"di":24}],16:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. function EventEmitter() { this._events = this._events || {}; this._maxListeners = this._maxListeners || undefined; } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. EventEmitter.defaultMaxListeners = 10; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function(n) { if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number'); this._maxListeners = n; return this; }; EventEmitter.prototype.emit = function(type) { var er, handler, len, args, i, listeners; if (!this._events) this._events = {}; // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || (isObject(this._events.error) && !this._events.error.length)) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event } throw TypeError('Uncaught, unspecified "error" event.'); } } handler = this._events[type]; if (isUndefined(handler)) return false; if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: handler.call(this); break; case 2: handler.call(this, arguments[1]); break; case 3: handler.call(this, arguments[1], arguments[2]); break; // slower default: len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; handler.apply(this, args); } } else if (isObject(handler)) { len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } return true; }; EventEmitter.prototype.addListener = function(type, listener) { var m; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener); if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; else if (isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener); else // Adding the second element, need to change to array. this._events[type] = [this._events[type], listener]; // Check for listener leak if (isObject(this._events[type]) && !this._events[type].warned) { var m; if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = EventEmitter.defaultMaxListeners; } if (m && m > 0 && this._events[type].length > m) { this._events[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { if (!isFunction(listener)) throw TypeError('listener must be a function'); var fired = false; function g() { this.removeListener(type, g); if (!fired) { fired = true; listener.apply(this, arguments); } } g.listener = listener; this.on(type, g); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { var list, position, length, i; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) return this; list = this._events[type]; length = list.length; position = -1; if (list === listener || (isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); } else if (isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { position = i; break; } } if (position < 0) return this; if (list.length === 1) { list.length = 0; delete this._events[type]; } else { list.splice(position, 1); } if (this._events.removeListener) this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { var key, listeners; if (!this._events) return this; // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) this._events = {}; else if (this._events[type]) delete this._events[type]; return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { for (key in this._events) { if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = {}; return this; } listeners = this._events[type]; if (isFunction(listeners)) { this.removeListener(type, listeners); } else { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } delete this._events[type]; return this; }; EventEmitter.prototype.listeners = function(type) { var ret; if (!this._events || !this._events[type]) ret = []; else if (isFunction(this._events[type])) ret = [this._events[type]]; else ret = this._events[type].slice(); return ret; }; EventEmitter.listenerCount = function(emitter, type) { var ret; if (!emitter._events || !emitter._events[type]) ret = 0; else if (isFunction(emitter._events[type])) ret = 1; else ret = emitter._events[type].length; return ret; }; function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } },{}],17:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; process.nextTick = (function () { var canSetImmediate = typeof window !== 'undefined' && window.setImmediate; var canPost = typeof window !== 'undefined' && window.postMessage && window.addEventListener ; if (canSetImmediate) { return function (f) { return window.setImmediate(f) }; } if (canPost) { var queue = []; window.addEventListener('message', function (ev) { var source = ev.source; if ((source === window || source === null) && ev.data === 'process-tick') { ev.stopPropagation(); if (queue.length > 0) { var fn = queue.shift(); fn(); } } }, true); return function nextTick(fn) { queue.push(fn); window.postMessage('process-tick', '*'); }; } return function nextTick(fn) { setTimeout(fn, 0); }; })(); process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); } // TODO(shtylman) process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; },{}],18:[function(require,module,exports){ "use strict"; var __moduleName = "annotations"; var isFunction = $traceurRuntime.assertObject(require('./util')).isFunction; var SuperConstructor = function SuperConstructor() {}; ($traceurRuntime.createClass)(SuperConstructor, {}, {}); var TransientScope = function TransientScope() {}; ($traceurRuntime.createClass)(TransientScope, {}, {}); var Inject = function Inject() { for (var tokens = [], $__5 = 0; $__5 < arguments.length; $__5++) tokens[$__5] = arguments[$__5]; this.tokens = tokens; this.isPromise = false; this.isLazy = false; }; ($traceurRuntime.createClass)(Inject, {}, {}); var InjectPromise = function InjectPromise() { for (var tokens = [], $__6 = 0; $__6 < arguments.length; $__6++) tokens[$__6] = arguments[$__6]; this.tokens = tokens; this.isPromise = true; this.isLazy = false; }; ($traceurRuntime.createClass)(InjectPromise, {}, {}, Inject); var InjectLazy = function InjectLazy() { for (var tokens = [], $__7 = 0; $__7 < arguments.length; $__7++) tokens[$__7] = arguments[$__7]; this.tokens = tokens; this.isPromise = false; this.isLazy = true; }; ($traceurRuntime.createClass)(InjectLazy, {}, {}, Inject); var Provide = function Provide(token) { this.token = token; this.isPromise = false; }; ($traceurRuntime.createClass)(Provide, {}, {}); var ProvidePromise = function ProvidePromise(token) { this.token = token; this.isPromise = true; }; ($traceurRuntime.createClass)(ProvidePromise, {}, {}, Provide); function annotate(fn, annotation) { fn.annotations = fn.annotations || []; fn.annotations.push(annotation); } function hasAnnotation(fn, annotationClass) { if (!fn.annotations || fn.annotations.length === 0) { return false; } for (var $__1 = fn.annotations[Symbol.iterator](), $__2; !($__2 = $__1.next()).done; ) { var annotation = $__2.value; { if (annotation instanceof annotationClass) { return true; } } } return false; } function readAnnotations(fn) { var collectedAnnotations = { provide: { token: null, isPromise: false }, params: [] }; if (fn.annotations && fn.annotations.length) { for (var $__1 = fn.annotations[Symbol.iterator](), $__2; !($__2 = $__1.next()).done; ) { var annotation = $__2.value; { if (annotation instanceof Inject) { collectedAnnotations.params = annotation.tokens.map((function(token) { return { token: token, isPromise: annotation.isPromise, isLazy: annotation.isLazy }; })); } if (annotation instanceof Provide) { collectedAnnotations.provide.token = annotation.token; collectedAnnotations.provide.isPromise = annotation.isPromise; } } } } if (fn.parameters) { fn.parameters.forEach((function(param, idx) { for (var $__3 = param[Symbol.iterator](), $__4; !($__4 = $__3.next()).done; ) { var paramAnnotation = $__4.value; { if (isFunction(paramAnnotation) && !collectedAnnotations.params[idx]) { collectedAnnotations.params[idx] = { token: paramAnnotation, isPromise: false, isLazy: false }; } else if (paramAnnotation instanceof Inject) { collectedAnnotations.params[idx] = { token: paramAnnotation.tokens[0], isPromise: paramAnnotation.isPromise, isLazy: paramAnnotation.isLazy }; } } } })); } return collectedAnnotations; } ; module.exports = { get annotate() { return annotate; }, get hasAnnotation() { return hasAnnotation; }, get readAnnotations() { return readAnnotations; }, get SuperConstructor() { return SuperConstructor; }, get TransientScope() { return TransientScope; }, get Inject() { return Inject; }, get InjectPromise() { return InjectPromise; }, get InjectLazy() { return InjectLazy; }, get Provide() { return Provide; }, get ProvidePromise() { return ProvidePromise; }, __esModule: true }; },{"./util":23}],19:[function(require,module,exports){ "use strict"; var __moduleName = "index"; var $__injector__ = require('./injector'); var $__annotations__ = require('./annotations'); module.exports = { get Injector() { return $__injector__.Injector; }, get annotate() { return $__annotations__.annotate; }, get Inject() { return $__annotations__.Inject; }, get InjectPromise() { return $__annotations__.InjectPromise; }, get Provide() { return $__annotations__.Provide; }, get ProvidePromise() { return $__annotations__.ProvidePromise; }, get SuperConstructor() { return $__annotations__.SuperConstructor; }, get TransientScope() { return $__annotations__.TransientScope; }, __esModule: true }; },{"./annotations":18,"./injector":20}],20:[function(require,module,exports){ "use strict"; var __moduleName = "injector"; var $__4 = $traceurRuntime.assertObject(require('./annotations')), annotate = $__4.annotate, readAnnotations = $__4.readAnnotations, hasAnnotation = $__4.hasAnnotation, ProvideAnnotation = $__4.Provide, TransientScopeAnnotation = $__4.TransientScope; var $__4 = $traceurRuntime.assertObject(require('./util')), isFunction = $__4.isFunction, toString = $__4.toString; var getUniqueId = $traceurRuntime.assertObject(require('./profiler')).getUniqueId; var createProviderFromFnOrClass = $traceurRuntime.assertObject(require('./providers')).createProviderFromFnOrClass; function constructResolvingMessage(resolving) { var token = arguments[1] !== (void 0) ? arguments[1] : null; if (token) { resolving.push(token); } if (resolving.length > 1) { return (" (" + resolving.map(toString).join(' -> ') + ")"); } return ''; } var Injector = function Injector() { var modules = arguments[0] !== (void 0) ? arguments[0] : []; var parentInjector = arguments[1] !== (void 0) ? arguments[1] : null; var providers = arguments[2] !== (void 0) ? arguments[2] : new Map(); this.cache = new Map(); this.providers = providers; this.parent = parentInjector; this.id = getUniqueId(); this._loadModules(modules); }; var $Injector = Injector; ($traceurRuntime.createClass)(Injector, { _collectProvidersWithAnnotation: function(annotationClass, collectedProviders) { this.providers.forEach((function(provider, token) { if (!collectedProviders.has(token) && hasAnnotation(provider.provider, annotationClass)) { collectedProviders.set(token, provider); } })); if (this.parent) { this.parent._collectProvidersWithAnnotation(annotationClass, collectedProviders); } }, _loadModules: function(modules) { var $__0 = this; for (var $__2 = modules[Symbol.iterator](), $__3; !($__3 = $__2.next()).done; ) { var module = $__3.value; { if (isFunction(module)) { this._loadFnOrClass(module); continue; } Object.keys(module).forEach((function(key) { if (isFunction(module[key])) { $__0._loadFnOrClass(module[key], key); } })); } } }, _loadFnOrClass: function(fnOrClass, key) { var annotations = readAnnotations(fnOrClass); var token = annotations.provide.token || key || fnOrClass; var provider = createProviderFromFnOrClass(fnOrClass, annotations); this.providers.set(token, provider); }, _hasProviderFor: function(token) { if (this.providers.has(token)) { return true; } if (this.parent) { return this.parent._hasProviderFor(token); } return false; }, get: function(token) { var resolving = arguments[1] !== (void 0) ? arguments[1] : []; var wantPromise = arguments[2] !== (void 0) ? arguments[2] : false; var wantLazy = arguments[3] !== (void 0) ? arguments[3] : false; var $__0 = this; var resolvingMsg = ''; var instance; var injector = this; if (token === $Injector) { if (wantPromise) { return Promise.resolve(this); } return this; } if (wantLazy) { return function createLazyInstance() { var lazyInjector = injector; if (arguments.length) { var locals = []; var args = arguments; for (var i = 0; i < args.length; i += 2) { locals.push((function(ii) { var fn = function createLocalInstance() { return args[ii + 1]; }; annotate(fn, new ProvideAnnotation(args[ii])); return fn; })(i)); } lazyInjector = injector.createChild(locals); } return lazyInjector.get(token, resolving, wantPromise, false); }; } if (this.cache.has(token)) { instance = this.cache.get(token); if (this.providers.get(token).isPromise) { if (!wantPromise) { resolvingMsg = constructResolvingMessage(resolving, token); throw new Error(("Cannot instantiate " + toString(token) + " synchronously. It is provided as a promise!" + resolvingMsg)); } } else { if (wantPromise) { return Promise.resolve(instance); } } return instance; } var provider = this.providers.get(token); if (!provider && isFunction(token) && !this._hasProviderFor(token)) { provider = createProviderFromFnOrClass(token, readAnnotations(token)); this.providers.set(token, provider); } if (!provider) { if (!this.parent) { resolvingMsg = constructResolvingMessage(resolving, token); console.log('bad token', token); throw new Error(("No provider for " + token + "!" + resolvingMsg)); } return this.parent.get(token, resolving, wantPromise, wantLazy); } if (resolving.indexOf(token) !== -1) { resolvingMsg = constructResolvingMessage(resolving, token); throw new Error(("Cannot instantiate cyclic dependency!" + resolvingMsg)); } resolving.push(token); var delayingInstantiation = wantPromise && provider.params.some((function(param) { return !param.isPromise; })); var args = provider.params.map((function(param) { if (delayingInstantiation) { return $__0.get(param.token, resolving, true, param.isLazy); } return $__0.get(param.token, resolving, param.isPromise, param.isLazy); })); if (delayingInstantiation) { var delayedResolving = resolving.slice(); resolving.pop(); return Promise.all(args).then(function(args) { try { instance = provider.create(args); } catch (e) { resolvingMsg = constructResolvingMessage(delayedResolving); var originalMsg = 'ORIGINAL ERROR: ' + e.message; e.message = ("Error during instantiation of " + toString(token) + "!" + resolvingMsg + "\n" + originalMsg); throw e; } if (!hasAnnotation(provider.provider, TransientScopeAnnotation)) { injector.cache.set(token, instance); } return instance; }); } try { instance = provider.create(args); } catch (e) { resolvingMsg = constructResolvingMessage(resolving); var originalMsg = 'ORIGINAL ERROR: ' + e.message; e.message = ("Error during instantiation of " + toString(token) + "!" + resolvingMsg + "\n" + originalMsg); throw e; } if (!hasAnnotation(provider.provider, TransientScopeAnnotation)) { this.cache.set(token, instance); } if (!wantPromise && provider.isPromise) { resolvingMsg = constructResolvingMessage(resolving); throw new Error(("Cannot instantiate " + toString(token) + " synchronously. It is provided as a promise!" + resolvingMsg)); } if (wantPromise && !provider.isPromise) { instance = Promise.resolve(instance); } resolving.pop(); return instance; }, getPromise: function(token) { return this.get(token, [], true); }, createChild: function() { var modules = arguments[0] !== (void 0) ? arguments[0] : []; var forceNewInstancesOf = arguments[1] !== (void 0) ? arguments[1] : []; var forcedProviders = new Map(); for (var $__2 = forceNewInstancesOf[Symbol.iterator](), $__3; !($__3 = $__2.next()).done; ) { var annotation = $__3.value; { this._collectProvidersWithAnnotation(annotation, forcedProviders); } } return new $Injector(modules, this, forcedProviders); }, dump: function() { var $__0 = this; var serialized = { id: this.id, parent_id: this.parent ? this.parent.id : null, providers: {} }; Object.keys(this.providers).forEach((function(token) { serialized.providers[token] = { name: token, dependencies: $__0.providers[token].params }; })); return serialized; } }, {}); ; module.exports = { get Injector() { return Injector; }, __esModule: true }; },{"./annotations":18,"./profiler":21,"./providers":22,"./util":23}],21:[function(require,module,exports){ "use strict"; var __moduleName = "profiler"; var globalCounter = 0; function getUniqueId() { return ++globalCounter; } ; module.exports = { get getUniqueId() { return getUniqueId; }, __esModule: true }; },{}],22:[function(require,module,exports){ "use strict"; var __moduleName = "providers"; var $__3 = $traceurRuntime.assertObject(require('./annotations')), SuperConstructorAnnotation = $__3.SuperConstructor, readAnnotations = $__3.readAnnotations; var $__3 = $traceurRuntime.assertObject(require('./util')), isClass = $__3.isClass, isFunction = $__3.isFunction, isObject = $__3.isObject, toString = $__3.toString; var EmptyFunction = Object.getPrototypeOf(Function); var ClassProvider = function ClassProvider(clazz, params, isPromise) { this.provider = clazz; this.isPromise = isPromise; this.params = []; this.constructors = []; this._flattenParams(clazz, params); this.constructors.unshift([clazz, 0, this.params.length - 1]); }; ($traceurRuntime.createClass)(ClassProvider, { _flattenParams: function(constructor, params) { var SuperConstructor; var constructorInfo; for (var $__1 = params[Symbol.iterator](), $__2; !($__2 = $__1.next()).done; ) { var param = $__2.value; { if (param.token === SuperConstructorAnnotation) { SuperConstructor = Object.getPrototypeOf(constructor); if (SuperConstructor === EmptyFunction) { throw new Error((toString(constructor) + " does not have a parent constructor. Only classes with a parent can ask for SuperConstructor!")); } constructorInfo = [SuperConstructor, this.params.length]; this.constructors.push(constructorInfo); this._flattenParams(SuperConstructor, readAnnotations(SuperConstructor).params); constructorInfo.push(this.params.length - 1); } else { this.params.push(param); } } } }, _createConstructor: function(currentConstructorIdx, context, allArguments) { var constructorInfo = this.constructors[currentConstructorIdx]; var nextConstructorInfo = this.constructors[currentConstructorIdx + 1]; var argsForCurrentConstructor; if (nextConstructorInfo) { argsForCurrentConstructor = allArguments.slice(constructorInfo[1], nextConstructorInfo[1]).concat([this._createConstructor(currentConstructorIdx + 1, context, allArguments)]).concat(allArguments.slice(nextConstructorInfo[2] + 1, constructorInfo[2] + 1)); } else { argsForCurrentConstructor = allArguments.slice(constructorInfo[1], constructorInfo[2] + 1); } return function InjectedAndBoundSuperConstructor() { return constructorInfo[0].apply(context, argsForCurrentConstructor); }; }, create: function(args) { var context = Object.create(this.provider.prototype); var constructor = this._createConstructor(0, context, args); var returnedValue = constructor(); if (isFunction(returnedValue) || isObject(returnedValue)) { return returnedValue; } return context; } }, {}); var FactoryProvider = function FactoryProvider(factoryFunction, params, isPromise) { this.provider = factoryFunction; this.params = params; this.isPromise = isPromise; for (var $__1 = params[Symbol.iterator](), $__2; !($__2 = $__1.next()).done; ) { var param = $__2.value; { if (param.token === SuperConstructorAnnotation) { throw new Error((toString(factoryFunction) + " is not a class. Only classes with a parent can ask for SuperConstructor!")); } } } }; ($traceurRuntime.createClass)(FactoryProvider, {create: function(args) { return this.provider.apply(undefined, args); }}, {}); function createProviderFromFnOrClass(fnOrClass, annotations) { if (isClass(fnOrClass)) { return new ClassProvider(fnOrClass, annotations.params, annotations.provide.isPromise); } return new FactoryProvider(fnOrClass, annotations.params, annotations.provide.isPromise); } module.exports = { get createProviderFromFnOrClass() { return createProviderFromFnOrClass; }, __esModule: true }; },{"./annotations":18,"./util":23}],23:[function(require,module,exports){ "use strict"; var __moduleName = "util"; function isUpperCase(char) { return char.toUpperCase() === char; } function isClass(clsOrFunction) { if (clsOrFunction.name) { return isUpperCase(clsOrFunction.name.charAt(0)); } return Object.keys(clsOrFunction.prototype).length > 0; } function isFunction(value) { return typeof value === 'function'; } function isObject(value) { return typeof value === 'object'; } function toString(token) { if (typeof token === 'string') { return token; } if (token.name) { return token.name; } return token.toString(); } ; module.exports = { get isUpperCase() { return isUpperCase; }, get isClass() { return isClass; }, get isFunction() { return isFunction; }, get isObject() { return isObject; }, get toString() { return toString; }, __esModule: true }; },{}],24:[function(require,module,exports){ // This is the file that gets included when you use "di" module in Node.js. // Include Traceur runtime. require('traceur/bin/traceur-runtime'); // Node.js has to be run with --harmony_collections to support ES6 Map. // If not defined, i