diff --git a/bin/_mocha b/bin/_mocha index b355e28352..1d088bbe94 100755 --- a/bin/_mocha +++ b/bin/_mocha @@ -105,7 +105,9 @@ program .option('--trace-deprecation', 'show stack traces on deprecations') .option('--use_strict', 'enforce strict mode') .option('--watch-extensions ,...', 'additional extensions to monitor with --watch', list, []) - .option('--delay', 'wait for async suite definition'); + .option('--delay', 'wait for async suite definition') + .option('--generate-seed', 'generate a random seed and exit') + .option('--random ', 'randomize order of tests (with required random seed)'); program._name = 'mocha'; @@ -186,6 +188,11 @@ if (!process.env.LOADED_MOCHA_OPTS) { program.parse(process.argv); +if (program.generateSeed) { + console.log(Mocha.seed()); + process.exit(0); +} + // infinite stack traces Error.stackTraceLimit = Infinity; // TODO: config @@ -275,6 +282,13 @@ if (program.fgrep) { mocha.fgrep(program.fgrep); } +// --randomize + +if (program.randomize) { + var matches = program.randomize.split(':'); + mocha.randomize(matches[0], matches[1]); +} + // --invert if (program.invert) { diff --git a/browser-entry.js b/browser-entry.js index 789e686ae6..dfeb424d2d 100644 --- a/browser-entry.js +++ b/browser-entry.js @@ -171,6 +171,11 @@ mocha.run = function(fn) { Mocha.process = process; +/** + * Expose Mocha.seed() for browser seed generation. + */ +mocha.seed = Mocha.seed; + /** * Expose mocha. */ diff --git a/lib/interfaces/bdd.js b/lib/interfaces/bdd.js index 830a5fe67a..1f33d6f793 100644 --- a/lib/interfaces/bdd.js +++ b/lib/interfaces/bdd.js @@ -59,9 +59,20 @@ module.exports = function(suite) { }; /** - * Exclusive suite. + * Run tests "in order"; do not randomize. */ + context.describe.inOrder = function func(title, fn) { + var suite = context.describe(title, fn); + suite.randomized(false); + return suite; + }; + // these three are disabled anyway, so don't actually implement inOrder + context.describe.inOrder.skip = context.describe.skip.inOrder + = context.xdescribe.inOrder = context.describe.skip; + /** + * Exclusive suite. + */ context.describe.only = function(title, fn) { return common.suite.only({ title: title, @@ -69,6 +80,12 @@ module.exports = function(suite) { fn: fn }); }; + context.describe.only.inOrder = context.describe.inOrder.only + = function(title, fn) { + var suite = context.describe.inOrder(title, fn); + mocha.grep(suite.fullTitle()); + return suite; + }; /** * Describe a specification or test-case diff --git a/lib/interfaces/qunit.js b/lib/interfaces/qunit.js index a2d67ef90f..a636de4846 100644 --- a/lib/interfaces/qunit.js +++ b/lib/interfaces/qunit.js @@ -57,7 +57,6 @@ module.exports = function(suite) { /** * Exclusive Suite. */ - context.suite.only = function(title) { if (suites.length > 1) { suites.shift(); @@ -68,6 +67,30 @@ module.exports = function(suite) { }); }; + /** + * Do not randomize. + */ + context.suite.inOrder = function(title) { + var suite = common.suite.create({ + title: title, + file: file + }); + suite.enableRandomize(false); + return suite; + }; + + /** + * Do not randomize + exclusive + */ + context.suite.only.inOrder = context.suite.inOrder.only = function(title) { + var suite = common.suite.only({ + title: title, + file: file + }); + suite.enableRandomize(false); + return suite; + }; + /** * Describe a specification or test-case * with the given `title` and callback `fn` diff --git a/lib/interfaces/tdd.js b/lib/interfaces/tdd.js index 445e992213..e7f03aa897 100644 --- a/lib/interfaces/tdd.js +++ b/lib/interfaces/tdd.js @@ -64,6 +64,16 @@ module.exports = function(suite) { }); }; + /** + * Do not randomize. + */ + context.suite.inOrder = function(title, fn) { + var suite = context.suite(title, fn); + suite.randomized(false); + return suite; + }; + context.suite.inOrder.skip = context.suite.skip; + /** * Exclusive test-case. */ @@ -74,6 +84,11 @@ module.exports = function(suite) { fn: fn }); }; + context.suite.only.inOrder = context.suite.inOrder.only + = function(title, fn) { + var suite = context.suite.inOrder(title, fn); + mocha.grep(suite.fullTitle()); + }; /** * Describe a specification or test-case with the given `title` and diff --git a/lib/mocha.js b/lib/mocha.js index a649715191..f00b83ecab 100644 --- a/lib/mocha.js +++ b/lib/mocha.js @@ -12,6 +12,7 @@ var escapeRe = require('escape-string-regexp'); var path = require('path'); var reporters = require('./reporters'); var utils = require('./utils'); +var Random = require('random-js'); /** * Expose `Mocha`. @@ -68,6 +69,7 @@ function image(name) { * - `ignoreLeaks` ignore global leaks * - `fullTrace` display the full stack-trace on failing * - `grep` string or regexp to filter tests with + * - `random` for randomization of tests w/ optional seed * * @param {Object} options * @api public @@ -99,6 +101,9 @@ function Mocha(options) { if (options.slow) { this.slow(options.slow); } + if (options.random) { + this.randomize(options.random); + } } /** @@ -301,6 +306,53 @@ Mocha.prototype.ignoreLeaks = function(ignore) { return this; }; +/** + * Enable or disable randomization of test execution order within suites. + * + * @param {(boolean|number|string)} seed Random seed. `seed` must be + * a 32-bit unsigned integer, or a string which can convert to one. + * If `false`, randomization will be globally disabled (if it was enabled + * previously). + * @return {Mocha} + * @api public + */ +Mocha.prototype.randomize = function randomize(seed) { + if (!arguments.length) { + throw new Error('Generate a random seed using --generate-seed on the ' + + 'command line, or Mocha.seed() in the browser.'); + } + if (seed !== false) { + var validSeed = utils.toSafeUnsignedInteger(seed); + if (isNaN(validSeed)) { + throw new Error('Invalid random seed. Expected unsigned 32-bit ' + + 'integer or value which can convert.'); + } + + var engine = Random.engines.mt19937().seed(validSeed); + this.options.randomConfig = { + shuffleTests: function shuffleTests(tests) { + Random.shuffle(engine, tests); + return tests; + }, + seed: validSeed, + hex: '0x' + Number(validSeed).toString(16).toUpperCase() // for display + }; + } else { + delete this.options.randomConfig; + } + return this; +}; + +/** + * Generate a random seed. + * @returns {string} Hexadecimal string + */ +Mocha.seed = function seed() { + var engine = Random.engines.mt19937() + .autoSeed(); + return utils.toHex(Random.integer(0, utils.MAX_SAFE_INTEGER)(engine)); +}; + /** * Enable global leak checking. * @@ -506,6 +558,10 @@ Mocha.prototype.run = function(fn) { if (options.useColors !== undefined) { exports.reporters.Base.useColors = options.useColors; } + if (options.randomConfig) { + runner.randomConfig = options.randomConfig; + } + exports.reporters.Base.inlineDiffs = options.useInlineDiffs; function done(failures) { diff --git a/lib/runner.js b/lib/runner.js index 22907f570f..60636ca6e4 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -79,6 +79,7 @@ function Runner(suite, delay) { this._defaultGrep = /.*/; this.grep(this._defaultGrep); this.globals(this.globalProps().concat(extraGlobals())); + this.random = false; } /** @@ -212,6 +213,19 @@ Runner.prototype.checkGlobals = function(test) { } }; +/** + * Get an array of a Suite's Tests, potentially in random order. + * @returns {Array.} Array of tests (a copy) + * @api private + */ +Runner.prototype.suiteTests = function suiteTests(suite) { + var tests = suite.tests.slice(); + if (this.randomConfig && suite.randomized()) { + return this.randomConfig.shuffleTests(tests); + } + return tests; +}; + /** * Fail the given `test`. * @@ -447,7 +461,7 @@ Runner.prototype.runTest = function(fn) { */ Runner.prototype.runTests = function(suite, fn) { var self = this; - var tests = suite.tests.slice(); + var tests = self.suiteTests(suite); var test; function hookErr(_, errSuite, after) { diff --git a/lib/suite.js b/lib/suite.js index bf3e4e9fef..d8ed09a5d6 100644 --- a/lib/suite.js +++ b/lib/suite.js @@ -61,6 +61,9 @@ function Suite(title, parentContext) { this._slow = 75; this._bail = false; this._retries = -1; + // this will cause randomization to occur by default if enabled + // globally. + this._randomized = true; this._onlyTests = []; this._onlySuites = []; this.delayed = false; @@ -86,6 +89,7 @@ Suite.prototype.clone = function() { suite.enableTimeouts(this.enableTimeouts()); suite.slow(this.slow()); suite.bail(this.bail()); + suite.randomized(this.randomized()); return suite; }; @@ -187,6 +191,25 @@ Suite.prototype.isPending = function() { return this.pending || (this.parent && this.parent.isPending()); }; +/** + * If randomization is enabled, calling this with a falsy value + * will cause the Suite's tests to NOT be randomized. + * + * This cannot be used in the context of a test, since it will already be + * randomized (or not) by then. + * + * @param {boolean} enabled + * @return {Suite|Boolean} self or enabled + * @api private + */ +Suite.prototype.randomized = function randomized(enabled) { + if (!arguments.length) { + return this._randomized; + } + this._randomized = Boolean(enabled); + return this; +}; + /** * Run `fn(test[, done])` before running tests. * diff --git a/lib/utils.js b/lib/utils.js index 1cfbbae781..edb03a35ad 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -282,7 +282,9 @@ exports.slug = function(str) { exports.clean = function(str) { str = str .replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '') - // (traditional)-> space/name parameters body (lambda)-> parameters body multi-statement/single keep body content + // (traditional)-> space/name parameters body (lambda)-> + // parameters body multi-statement/single keep body + // content .replace(/^function(?:\s*|\s+[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\s*\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\s*\}|((?:.|\n)*))$/, '$1$2$3'); var spaces = str.match(/^\n?( *)/)[1].length; @@ -420,12 +422,15 @@ exports.type = function type(value) { /** * Stringify `value`. Different behavior depending on type of value: * - * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively. - * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes. - * - If `value` is an *empty* object, function, or array, return result of function + * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, + * respectively. + * - If `value` is not an object, function or array, return result of + * `value.toString()` wrapped in double-quotes. + * - If `value` is an *empty* object, function, or array, return result of + * function * {@link emptyRepresentation}. - * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of - * JSON.stringify(). + * - If `value` has properties, call {@link exports.canonicalize} on it, then + * return result of JSON.stringify(). * * @api private * @see exports.type @@ -555,9 +560,12 @@ exports.isBuffer = function(value) { * - is `undefined`, return string `'[undefined]'` * - is `null`, return value `null` * - is some other primitive, return the value - * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method - * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again. - * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()` + * - is not a primitive or an `Array`, `Object`, or `Function`, return the + * value of the Thing's `toString()` method + * - is a non-empty `Array`, `Object`, or `Function`, return the result of + * calling this function again. + * - is an empty `Array`, `Object`, or `Function`, return the result of calling + * `emptyRepresentation()` * * @api private * @see {@link exports.stringify} @@ -711,10 +719,11 @@ exports.getError = function(err) { /** * @summary - * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`) + * This Filter based on `mocha-clean` module.(see: + * `github.com/rstacruz/mocha-clean`) * @description - * When invoking this function you get a filter function that get the Error.stack as an input, - * and return a prettify output. + * When invoking this function you get a filter function that get the + * Error.stack as an input, and return a prettify output. * (i.e: strip Mocha and internal node functions from stack trace). * @returns {Function} */ @@ -767,6 +776,36 @@ exports.stackTraceFilter = function() { }; }; +// +/** + * Number.MAX_SAFE_INTEGER only available in ES2015. + * @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER + * @type {number} + */ +exports.MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 0x1fffffffffffff; + +/** + * Attempt to convert `value` an integer, if it's a representation + * of a "safe" unsigned integer. + * @param {*} [value] Value to convert + * @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/parseInt + * @returns {(number|NaN)} result + */ +exports.toSafeUnsignedInteger = function toSafeUnsignedInteger(value) { + var intVal; + if (/^0[xX]/.test(value)) { + intVal = parseInt(value, 16); + } else if (/^0[^.]/.test(value)) { + intVal = parseInt(value, 8); + } else { + intVal = parseInt(value, 10); + } + return !isNaN(intVal) && parseFloat(intVal) === intVal + && exports.isSafeUnsignedInteger(intVal) + ? intVal + : NaN; +}; + /** * Crude, but effective. * @api @@ -776,3 +815,22 @@ exports.stackTraceFilter = function() { exports.isPromise = function isPromise(value) { return typeof value === 'object' && typeof value.then === 'function'; }; + +/** + * Given integer `int`, try to convert it to a hex string. + * @param {number} int Integer + * @returns {string} Hexadecimal representation thereof + */ +exports.toHex = function toHex(int) { + return '0x' + int.toString(16).toUpperCase(); +}; + +/** + * Returns `true` if `value` is a "safe" 32-bit unsigned int. + * @param {*} [value] Value to test + * @returns {boolean} result + */ +exports.isSafeUnsignedInteger = function isUnsignedInteger(value) { + return typeof value === 'number' && value > 0 + && value <= exports.MAX_SAFE_INTEGER && value % 1 === 0; +}; diff --git a/mocha.js b/mocha.js index 3ca0ae9e67..ee7d989091 100644 --- a/mocha.js +++ b/mocha.js @@ -1,7 +1,5 @@ (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);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1) { suites.shift(); } - return common.suite.create({ - title: title, - file: file - }); + var suite = Suite.create(suites[0], title); + suite.file = file; + suites.unshift(suite); + return suite; }; /** - * Exclusive Suite. + * Do not randomize. */ + context.suite.inOrder = function(title, fn) { + var suite = context.suite(title, fn); + suite.randomized(false); + return suite; + }; - context.suite.only = function(title) { - if (suites.length > 1) { - suites.shift(); - } - return common.suite.only({ - title: title, - file: file - }); + /** + * Exclusive test-case. + */ + + context.suite.only = function(title, fn) { + var suite = context.suite(title, fn); + mocha.grep(suite.fullTitle()); }; + context.suite.only.inOrder = context.suite.inOrder.only + = function(title, fn) { + var suite = context.suite.inOrder(title, fn); + mocha.grep(suite.fullTitle()); + }; /** * Describe a specification or test-case @@ -1112,7 +1049,9 @@ module.exports = function(suite) { */ context.test.only = function(title, fn) { - return common.test.only(mocha, context.test(title, fn)); + var test = context.test(title, fn); + var reString = '^' + escapeRe(test.fullTitle()) + '$'; + mocha.grep(new RegExp(reString)); }; context.test.skip = common.test.skip; @@ -1120,12 +1059,14 @@ module.exports = function(suite) { }); }; -},{"../test":36,"./common":9}],13:[function(require,module,exports){ +},{"../suite":37,"../test":38,"./common":9,"escape-string-regexp":50}],13:[function(require,module,exports){ /** * Module dependencies. */ +var Suite = require('../suite'); var Test = require('../test'); +var escapeRe = require('escape-string-regexp'); /** * TDD-style interface: @@ -1156,7 +1097,7 @@ module.exports = function(suite) { var suites = [suite]; suite.on('pre-require', function(context, file, mocha) { - var common = require('./common')(suites, context, mocha); + var common = require('./common')(suites, context); context.setup = common.beforeEach; context.teardown = common.afterEach; @@ -1169,34 +1110,47 @@ module.exports = function(suite) { * nested suites and/or tests. */ context.suite = function(title, fn) { - return common.suite.create({ - title: title, - file: file, - fn: fn - }); + var suite = Suite.create(suites[0], title); + suite.file = file; + suites.unshift(suite); + fn.call(suite); + suites.shift(); + return suite; }; /** * Pending suite. */ context.suite.skip = function(title, fn) { - return common.suite.skip({ - title: title, - file: file, - fn: fn - }); + var suite = Suite.create(suites[0], title); + suite.pending = true; + suites.unshift(suite); + fn.call(suite); + suites.shift(); + }; + + /** + * Do not randomize. + */ + context.suite.inOrder = function(title, fn) { + var suite = context.suite(title, fn); + suite.randomized(false); + return suite; }; + context.suite.inOrder.skip = context.suite.skip; /** * Exclusive test-case. */ context.suite.only = function(title, fn) { - return common.suite.only({ - title: title, - file: file, - fn: fn - }); + var suite = context.suite(title, fn); + mocha.grep(suite.fullTitle()); }; + context.suite.only.inOrder = context.suite.inOrder.only + = function(title, fn) { + var suite = context.suite.inOrder(title, fn); + mocha.grep(suite.fullTitle()); + }; /** * Describe a specification or test-case with the given `title` and @@ -1218,7 +1172,9 @@ module.exports = function(suite) { */ context.test.only = function(title, fn) { - return common.test.only(mocha, context.test(title, fn)); + var test = context.test(title, fn); + var reString = '^' + escapeRe(test.fullTitle()) + '$'; + mocha.grep(new RegExp(reString)); }; context.test.skip = common.test.skip; @@ -1226,7 +1182,7 @@ module.exports = function(suite) { }); }; -},{"../test":36,"./common":9}],14:[function(require,module,exports){ +},{"../suite":37,"../test":38,"./common":9,"escape-string-regexp":50}],14:[function(require,module,exports){ (function (process,global,__dirname){ /*! * mocha @@ -1242,6 +1198,7 @@ var escapeRe = require('escape-string-regexp'); var path = require('path'); var reporters = require('./reporters'); var utils = require('./utils'); +var Random = require('random-js'); /** * Expose `Mocha`. @@ -1298,6 +1255,7 @@ function image(name) { * - `ignoreLeaks` ignore global leaks * - `fullTrace` display the full stack-trace on failing * - `grep` string or regexp to filter tests with + * - `random` for randomization of tests w/ optional seed * * @param {Object} options * @api public @@ -1310,7 +1268,7 @@ function Mocha(options) { this.grep(new RegExp(options.grep)); } if (options.fgrep) { - this.fgrep(options.fgrep); + this.grep(options.fgrep); } this.suite = new exports.Suite('', new exports.Context()); this.ui(options.ui); @@ -1329,6 +1287,9 @@ function Mocha(options) { if (options.slow) { this.slow(options.slow); } + if (options.random) { + this.randomize(options.random); + } } /** @@ -1476,17 +1437,6 @@ Mocha.prototype._growl = function(runner, reporter) { }); }; -/** - * Escape string and add it to grep as a regexp. - * - * @api public - * @param str - * @returns {Mocha} - */ -Mocha.prototype.fgrep = function(str) { - return this.grep(new RegExp(escapeRe(str))); -}; - /** * Add regexp to grep, if `re` is a string it is escaped. * @@ -1497,15 +1447,10 @@ Mocha.prototype.fgrep = function(str) { * @return {Mocha} */ Mocha.prototype.grep = function(re) { - if (utils.isString(re)) { - // extract args if it's regex-like, i.e: [string, pattern, flag] - var arg = re.match(/^\/(.*)\/(g|i|)$|.*/); - this.options.grep = new RegExp(arg[1] || arg[0], arg[2]); - } else { - this.options.grep = re; - } + this.options.grep = typeof re === 'string' ? new RegExp(escapeRe(re)) : re; return this; }; + /** * Invert `.grep()` matches. * @@ -1531,6 +1476,52 @@ Mocha.prototype.ignoreLeaks = function(ignore) { return this; }; +/** + * Enable or disable randomization of test execution order within suites. + * + * @param {(boolean|number|string)} seed Random seed. `seed` must be + * a 32-bit unsigned integer, or a string which can convert to one. + * If `false`, randomization will be globally disabled (if it was enabled + * previously). + * @return {Mocha} + * @api public + */ +Mocha.prototype.randomize = function randomize(seed) { + if (!arguments.length) { + throw new Error('Generate a random seed using --generate-seed on the ' + + 'command line, or Mocha.seed() in the browser.'); + } + if (seed !== false) { + var validSeed = utils.toSafeUnsignedInteger(seed); + if (isNaN(validSeed)) { + throw new Error('Invalid random seed. Expected unsigned 32-bit ' + + 'integer or value which can convert.'); + } + + var engine = Random.engines.mt19937().seed(validSeed); + this.options.randomConfig = { + shuffleTests: function shuffleTests(tests) { + Random.shuffle(tests, engine); + return tests; + }, + seed: validSeed, + hex: '0x' + Number(validSeed).toString(16).toUpperCase() // for display + }; + } else { + delete this.options.randomConfig; + } + return this; +}; + +/** + * Generate a random seed. + * @returns {number} Unsigned 32-bit integer + */ +Mocha.seed = function seed() { + return Random.integer(0, utils.MAX_SAFE_INTEGER)(Random.engines.mt19937() + .autoSeed()); +}; + /** * Enable global leak checking. * @@ -1721,7 +1712,6 @@ Mocha.prototype.run = function(fn) { var reporter = new this._reporter(runner, options); runner.ignoreLeaks = options.ignoreLeaks !== false; runner.fullStackTrace = options.fullStackTrace; - runner.hasOnly = options.hasOnly; runner.asyncOnly = options.asyncOnly; runner.allowUncaught = options.allowUncaught; if (options.grep) { @@ -1736,6 +1726,10 @@ Mocha.prototype.run = function(fn) { if (options.useColors !== undefined) { exports.reporters.Base.useColors = options.useColors; } + if (options.randomConfig) { + runner.randomConfig = options.randomConfig; + } + exports.reporters.Base.inlineDiffs = options.useInlineDiffs; function done(failures) { @@ -1750,7 +1744,7 @@ Mocha.prototype.run = function(fn) { }; }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},"/lib") -},{"./context":6,"./hook":7,"./interfaces":11,"./reporters":21,"./runnable":33,"./runner":34,"./suite":35,"./test":36,"./utils":38,"_process":67,"escape-string-regexp":47,"growl":49,"path":42}],15:[function(require,module,exports){ +},{"./context":6,"./hook":7,"./interfaces":11,"./reporters":22,"./runnable":35,"./runner":36,"./suite":37,"./test":38,"./utils":39,"_process":59,"escape-string-regexp":50,"growl":51,"path":42,"random-js":60}],15:[function(require,module,exports){ /** * Helpers. */ @@ -1979,9 +1973,7 @@ exports.colors = { exports.symbols = { ok: '✓', err: '✖', - dot: '․', - comma: ',', - bang: '!' + dot: '․' }; // With node.js on Windows: use symbols available in terminal default fonts @@ -2081,7 +2073,7 @@ exports.list = function(failures) { message = ''; } var stack = err.stack || message; - var index = message ? stack.indexOf(message) : -1; + var index = stack.indexOf(message); var actual = err.actual; var expected = err.expected; var escape = true; @@ -2390,7 +2382,7 @@ function sameType(a, b) { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../ms":15,"../utils":38,"_process":67,"diff":46,"supports-color":42,"tty":5}],18:[function(require,module,exports){ +},{"../ms":15,"../utils":39,"_process":59,"diff":49,"supports-color":42,"tty":5}],18:[function(require,module,exports){ /** * Module dependencies. */ @@ -2454,7 +2446,7 @@ function Doc(runner) { }); } -},{"../utils":38,"./base":17}],19:[function(require,module,exports){ +},{"../utils":39,"./base":17}],19:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -2491,7 +2483,7 @@ function Dot(runner) { if (++n % width === 0) { process.stdout.write('\n '); } - process.stdout.write(color('pending', Base.symbols.comma)); + process.stdout.write(color('pending', Base.symbols.dot)); }); runner.on('pass', function(test) { @@ -2509,7 +2501,7 @@ function Dot(runner) { if (++n % width === 0) { process.stdout.write('\n '); } - process.stdout.write(color('fail', Base.symbols.bang)); + process.stdout.write(color('fail', Base.symbols.dot)); }); runner.on('end', function() { @@ -2524,7 +2516,67 @@ function Dot(runner) { inherits(Dot, Base); }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":67}],20:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":59}],20:[function(require,module,exports){ +(function (process,__dirname){ +/** + * Module dependencies. + */ + +var JSONCov = require('./json-cov'); +var readFileSync = require('fs').readFileSync; +var join = require('path').join; + +/** + * Expose `HTMLCov`. + */ + +exports = module.exports = HTMLCov; + +/** + * Initialize a new `JsCoverage` reporter. + * + * @api public + * @param {Runner} runner + */ +function HTMLCov(runner) { + var jade = require('jade'); + var file = join(__dirname, '/templates/coverage.jade'); + var str = readFileSync(file, 'utf8'); + var fn = jade.compile(str, { filename: file }); + var self = this; + + JSONCov.call(this, runner, false); + + runner.on('end', function() { + process.stdout.write(fn({ + cov: self.cov, + coverageClass: coverageClass + })); + }); +} + +/** + * Return coverage class for a given coverage percentage. + * + * @api private + * @param {number} coveragePctg + * @return {string} + */ +function coverageClass(coveragePctg) { + if (coveragePctg >= 75) { + return 'high'; + } + if (coveragePctg >= 50) { + return 'medium'; + } + if (coveragePctg >= 25) { + return 'low'; + } + return 'terrible'; +} + +}).call(this,require('_process'),"/lib/reporters") +},{"./json-cov":23,"_process":59,"fs":42,"jade":42,"path":42}],21:[function(require,module,exports){ (function (global){ /* eslint-env browser */ @@ -2872,7 +2924,7 @@ function on(el, event, fn) { } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../browser/progress":4,"../utils":38,"./base":17,"escape-string-regexp":47}],21:[function(require,module,exports){ +},{"../browser/progress":4,"../utils":39,"./base":17,"escape-string-regexp":50}],22:[function(require,module,exports){ // Alias exports to a their normalized format Mocha#reporter to prevent a need // for dynamic (try/catch) requires, which Browserify doesn't handle. exports.Base = exports.base = require('./base'); @@ -2889,16 +2941,172 @@ exports.XUnit = exports.xunit = require('./xunit'); exports.Markdown = exports.markdown = require('./markdown'); exports.Progress = exports.progress = require('./progress'); exports.Landing = exports.landing = require('./landing'); +exports.JSONCov = exports['json-cov'] = require('./json-cov'); +exports.HTMLCov = exports['html-cov'] = require('./html-cov'); exports.JSONStream = exports['json-stream'] = require('./json-stream'); -},{"./base":17,"./doc":18,"./dot":19,"./html":20,"./json":23,"./json-stream":22,"./landing":24,"./list":25,"./markdown":26,"./min":27,"./nyan":28,"./progress":29,"./spec":30,"./tap":31,"./xunit":32}],22:[function(require,module,exports){ +},{"./base":17,"./doc":18,"./dot":19,"./html":21,"./html-cov":20,"./json":25,"./json-cov":23,"./json-stream":24,"./landing":26,"./list":27,"./markdown":28,"./min":29,"./nyan":30,"./progress":31,"./spec":32,"./tap":33,"./xunit":34}],23:[function(require,module,exports){ +(function (process,global){ +/** + * Module dependencies. + */ + +var Base = require('./base'); + +/** + * Expose `JSONCov`. + */ + +exports = module.exports = JSONCov; + +/** + * Initialize a new `JsCoverage` reporter. + * + * @api public + * @param {Runner} runner + * @param {boolean} output + */ +function JSONCov(runner, output) { + Base.call(this, runner); + + output = arguments.length === 1 || output; + var self = this; + var tests = []; + var failures = []; + var passes = []; + + runner.on('test end', function(test) { + tests.push(test); + }); + + runner.on('pass', function(test) { + passes.push(test); + }); + + runner.on('fail', function(test) { + failures.push(test); + }); + + runner.on('end', function() { + var cov = global._$jscoverage || {}; + var result = self.cov = map(cov); + result.stats = self.stats; + result.tests = tests.map(clean); + result.failures = failures.map(clean); + result.passes = passes.map(clean); + if (!output) { + return; + } + process.stdout.write(JSON.stringify(result, null, 2)); + }); +} + +/** + * Map jscoverage data to a JSON structure + * suitable for reporting. + * + * @api private + * @param {Object} cov + * @return {Object} + */ + +function map(cov) { + var ret = { + instrumentation: 'node-jscoverage', + sloc: 0, + hits: 0, + misses: 0, + coverage: 0, + files: [] + }; + + for (var filename in cov) { + if (Object.prototype.hasOwnProperty.call(cov, filename)) { + var data = coverage(filename, cov[filename]); + ret.files.push(data); + ret.hits += data.hits; + ret.misses += data.misses; + ret.sloc += data.sloc; + } + } + + ret.files.sort(function(a, b) { + return a.filename.localeCompare(b.filename); + }); + + if (ret.sloc > 0) { + ret.coverage = (ret.hits / ret.sloc) * 100; + } + + return ret; +} + +/** + * Map jscoverage data for a single source file + * to a JSON structure suitable for reporting. + * + * @api private + * @param {string} filename name of the source file + * @param {Object} data jscoverage coverage data + * @return {Object} + */ +function coverage(filename, data) { + var ret = { + filename: filename, + coverage: 0, + hits: 0, + misses: 0, + sloc: 0, + source: {} + }; + + data.source.forEach(function(line, num) { + num++; + + if (data[num] === 0) { + ret.misses++; + ret.sloc++; + } else if (data[num] !== undefined) { + ret.hits++; + ret.sloc++; + } + + ret.source[num] = { + source: line, + coverage: data[num] === undefined ? '' : data[num] + }; + }); + + ret.coverage = ret.hits / ret.sloc * 100; + + return ret; +} + +/** + * Return a plain-object representation of `test` + * free of cyclic properties etc. + * + * @api private + * @param {Object} test + * @return {Object} + */ +function clean(test) { + return { + duration: test.duration, + currentRetry: test.currentRetry(), + fullTitle: test.fullTitle(), + title: test.title + }; +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./base":17,"_process":59}],24:[function(require,module,exports){ (function (process){ /** * Module dependencies. */ var Base = require('./base'); -var JSON = require('json3'); /** * Expose `List`. @@ -2956,7 +3164,7 @@ function clean(test) { } }).call(this,require('_process')) -},{"./base":17,"_process":67,"json3":54}],23:[function(require,module,exports){ +},{"./base":17,"_process":59}],25:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3050,7 +3258,7 @@ function errorJSON(err) { } }).call(this,require('_process')) -},{"./base":17,"_process":67}],24:[function(require,module,exports){ +},{"./base":17,"_process":59}],26:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3146,7 +3354,7 @@ function Landing(runner) { inherits(Landing, Base); }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":67}],25:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":59}],27:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3211,7 +3419,7 @@ function List(runner) { inherits(List, Base); }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":67}],26:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":59}],28:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3312,7 +3520,7 @@ function Markdown(runner) { } }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":67}],27:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":59}],29:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3352,7 +3560,7 @@ function Min(runner) { inherits(Min, Base); }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":67}],28:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":59}],30:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3617,7 +3825,7 @@ function write(string) { } }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":67}],29:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":59}],31:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3710,7 +3918,7 @@ function Progress(runner, options) { inherits(Progress, Base); }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":67}],30:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":59}],32:[function(require,module,exports){ /** * Module dependencies. */ @@ -3718,6 +3926,7 @@ inherits(Progress, Base); var Base = require('./base'); var inherits = require('../utils').inherits; var color = Base.color; +var cursor = Base.cursor; /** * Expose `Spec`. @@ -3769,17 +3978,20 @@ function Spec(runner) { fmt = indent() + color('checkmark', ' ' + Base.symbols.ok) + color('pass', ' %s'); + cursor.CR(); console.log(fmt, test.title); } else { fmt = indent() + color('checkmark', ' ' + Base.symbols.ok) + color('pass', ' %s') + color(test.speed, ' (%dms)'); + cursor.CR(); console.log(fmt, test.title, test.duration); } }); runner.on('fail', function(test) { + cursor.CR(); console.log(indent() + color('fail', ' %d) %s'), ++n, test.title); }); @@ -3791,7 +4003,7 @@ function Spec(runner) { */ inherits(Spec, Base); -},{"../utils":38,"./base":17}],31:[function(require,module,exports){ +},{"../utils":39,"./base":17}],33:[function(require,module,exports){ /** * Module dependencies. */ @@ -3861,7 +4073,7 @@ function title(test) { return test.fullTitle().replace(/#/g, ''); } -},{"./base":17}],32:[function(require,module,exports){ +},{"./base":17}],34:[function(require,module,exports){ (function (process,global){ /** * Module dependencies. @@ -4031,19 +4243,18 @@ function tag(name, attrs, close, content) { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../utils":38,"./base":17,"_process":67,"fs":42,"mkdirp":64,"path":42}],33:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":59,"fs":42,"mkdirp":56,"path":42}],35:[function(require,module,exports){ (function (global){ /** * Module dependencies. */ var EventEmitter = require('events').EventEmitter; -var JSON = require('json3'); var Pending = require('./pending'); var debug = require('debug')('mocha:runnable'); var milliseconds = require('./ms'); var utils = require('./utils'); -var create = require('lodash.create'); +var inherits = utils.inherits; /** * Save timer references to avoid Sinon interfering (see GH-237). @@ -4097,9 +4308,7 @@ function Runnable(title, fn) { /** * Inherit from `EventEmitter.prototype`. */ -Runnable.prototype = create(EventEmitter.prototype, { - constructor: Runnable -}); +inherits(Runnable, EventEmitter); /** * Set & get timeout `ms`. @@ -4112,8 +4321,7 @@ Runnable.prototype.timeout = function(ms) { if (!arguments.length) { return this._timeout; } - // see #1652 for reasoning - if (ms === 0 || ms > Math.pow(2, 31)) { + if (ms === 0) { this._enableTimeouts = false; } if (typeof ms === 'string') { @@ -4135,7 +4343,7 @@ Runnable.prototype.timeout = function(ms) { * @return {Runnable|number} ms or Runnable instance. */ Runnable.prototype.slow = function(ms) { - if (typeof ms === 'undefined') { + if (!arguments.length) { return this._slow; } if (typeof ms === 'string') { @@ -4337,10 +4545,6 @@ Runnable.prototype.run = function(fn) { return callFnAsync(this.fn); } try { - // allows skip() to be used in an explicit async context - this.skip = function() { - done(new Pending()); - }; callFnAsync(this.fn); } catch (err) { done(utils.getError(err)); @@ -4389,7 +4593,7 @@ Runnable.prototype.run = function(fn) { } function callFnAsync(fn) { - var result = fn.call(ctx, function(err) { + fn.call(ctx, function(err) { if (err instanceof Error || toString.call(err) === '[object Error]') { return done(err); } @@ -4400,17 +4604,13 @@ Runnable.prototype.run = function(fn) { } return done(new Error('done() invoked with non-Error: ' + err)); } - if (result && utils.isPromise(result)) { - return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.')); - } - done(); }); } }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./ms":15,"./pending":16,"./utils":38,"debug":2,"events":3,"json3":54,"lodash.create":60}],34:[function(require,module,exports){ +},{"./ms":15,"./pending":16,"./utils":39,"debug":2,"events":3}],36:[function(require,module,exports){ (function (process,global){ /** * Module dependencies. @@ -4424,7 +4624,6 @@ var debug = require('debug')('mocha:runner'); var Runnable = require('./runnable'); var filter = utils.filter; var indexOf = utils.indexOf; -var some = utils.some; var keys = utils.keys; var stackFilter = utils.stackTraceFilter(); var stringify = utils.stringify; @@ -4493,6 +4692,7 @@ function Runner(suite, delay) { this._defaultGrep = /.*/; this.grep(this._defaultGrep); this.globals(this.globalProps().concat(extraGlobals())); + this.random = false; } /** @@ -4626,6 +4826,19 @@ Runner.prototype.checkGlobals = function(test) { } }; +/** + * Get an array of a Suite's Tests, potentially in random order. + * @returns {Array.} Array of tests (a copy) + * @api private + */ +Runner.prototype.suiteTests = function suiteTests(suite) { + var tests = suite.tests.slice(); + if (this.randomConfig && suite.randomized()) { + return this.randomConfig.shuffleTests(tests); + } + return tests; +}; + /** * Fail the given `test`. * @@ -4855,7 +5068,7 @@ Runner.prototype.runTest = function(fn) { */ Runner.prototype.runTests = function(suite, fn) { var self = this; - var tests = suite.tests.slice(); + var tests = self.suiteTests(suite); var test; function hookErr(_, errSuite, after) { @@ -5193,11 +5406,6 @@ Runner.prototype.run = function(fn) { var self = this; var rootSuite = this.suite; - // If there is an `only` filter - if (this.hasOnly) { - filterOnly(rootSuite); - } - fn = fn || function() {}; function uncaught(err) { @@ -5254,49 +5462,7 @@ Runner.prototype.abort = function() { }; /** - * Filter suites based on `isOnly` logic. - * - * @param {Array} suite - * @returns {Boolean} - * @api private - */ -function filterOnly(suite) { - if (suite._onlyTests.length) { - // If the suite contains `only` tests, run those and ignore any nested suites. - suite.tests = suite._onlyTests; - suite.suites = []; - } else { - // Otherwise, do not run any of the tests in this suite. - suite.tests = []; - suite._onlySuites.forEach(function(onlySuite) { - // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite. - // Otherwise, all of the tests on this `only` suite should be run, so don't filter it. - if (hasOnly(onlySuite)) { - filterOnly(onlySuite); - } - }); - // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants. - suite.suites = filter(suite.suites, function(childSuite) { - return indexOf(suite._onlySuites, childSuite) !== -1 || filterOnly(childSuite); - }); - } - // Keep the suite only if there is something to run - return suite.tests.length || suite.suites.length; -} - -/** - * Determines whether a suite has an `only` test or suite as a descendant. - * - * @param {Array} suite - * @returns {Boolean} - * @api private - */ -function hasOnly(suite) { - return suite._onlyTests.length || suite._onlySuites.length || some(suite.suites, hasOnly); -} - -/** - * Filter leaks with the given globals flagged as `ok`. + * Filter leaks with the given globals flagged as `ok`. * * @api private * @param {Array} ok @@ -5362,7 +5528,7 @@ function extraGlobals() { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./pending":16,"./runnable":33,"./utils":38,"_process":67,"debug":2,"events":3}],35:[function(require,module,exports){ +},{"./pending":16,"./runnable":35,"./utils":39,"_process":59,"debug":2,"events":3}],37:[function(require,module,exports){ /** * Module dependencies. */ @@ -5406,9 +5572,6 @@ exports.create = function(parent, title) { * @param {Context} parentContext */ function Suite(title, parentContext) { - if (!utils.isString(title)) { - throw new Error('Suite `title` should be a "string" but "' + typeof title + '" was given instead.'); - } this.title = title; function Context() {} Context.prototype = parentContext; @@ -5426,8 +5589,7 @@ function Suite(title, parentContext) { this._slow = 75; this._bail = false; this._retries = -1; - this._onlyTests = []; - this._onlySuites = []; + this._deterministic = false; this.delayed = false; } @@ -5451,6 +5613,7 @@ Suite.prototype.clone = function() { suite.enableTimeouts(this.enableTimeouts()); suite.slow(this.slow()); suite.bail(this.bail()); + suite.randomized(this.randomized()); return suite; }; @@ -5552,6 +5715,25 @@ Suite.prototype.isPending = function() { return this.pending || (this.parent && this.parent.isPending()); }; +/** + * If randomization is enabled, calling this with a falsy value + * will cause the Suite's tests to NOT be randomized. + * + * This cannot be used in the context of a test, since it will already be + * randomized (or not) by then. + * + * @param {boolean} enabled + * @return {Suite|Boolean} self or enabled + * @api private + */ +Suite.prototype.randomized = function randomized(enabled) { + if (!arguments.length) { + return this._randomized; + } + this._randomized = Boolean(enabled); + return this; +}; + /** * Run `fn(test[, done])` before running tests. * @@ -5764,14 +5946,13 @@ Suite.prototype.run = function run() { } }; -},{"./hook":7,"./ms":15,"./utils":38,"debug":2,"events":3}],36:[function(require,module,exports){ +},{"./hook":7,"./ms":15,"./utils":39,"debug":2,"events":3}],38:[function(require,module,exports){ /** * Module dependencies. */ var Runnable = require('./runnable'); -var create = require('lodash.create'); -var isString = require('./utils').isString; +var inherits = require('./utils').inherits; /** * Expose `Test`. @@ -5787,9 +5968,6 @@ module.exports = Test; * @param {Function} fn */ function Test(title, fn) { - if (!isString(title)) { - throw new Error('Test `title` should be a "string" but "' + typeof title + '" was given instead.'); - } Runnable.call(this, title, fn); this.pending = !fn; this.type = 'test'; @@ -5798,9 +5976,7 @@ function Test(title, fn) { /** * Inherit from `Runnable.prototype`. */ -Test.prototype = create(Runnable.prototype, { - constructor: Test -}); +inherits(Test, Runnable); Test.prototype.clone = function() { var test = new Test(this.title, this.fn); @@ -5816,46 +5992,7 @@ Test.prototype.clone = function() { return test; }; -},{"./runnable":33,"./utils":38,"lodash.create":60}],37:[function(require,module,exports){ -'use strict'; - -/** - * Pad a `number` with a ten's place zero. - * - * @param {number} number - * @return {string} - */ -function pad(number) { - var n = number.toString(); - return n.length === 1 ? '0' + n : n; -} - -/** - * Turn a `date` into an ISO string. - * - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString - * - * @param {Date} date - * @return {string} - */ -function toISOString(date) { - return date.getUTCFullYear() - + '-' + pad(date.getUTCMonth() + 1) - + '-' + pad(date.getUTCDate()) - + 'T' + pad(date.getUTCHours()) - + ':' + pad(date.getUTCMinutes()) - + ':' + pad(date.getUTCSeconds()) - + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5) - + 'Z'; -} - -/* - * Exports. - */ - -module.exports = toISOString; - -},{}],38:[function(require,module,exports){ +},{"./runnable":35,"./utils":39}],39:[function(require,module,exports){ (function (process,Buffer){ /* eslint-env browser */ @@ -5863,7 +6000,6 @@ module.exports = toISOString; * Module dependencies. */ -var JSON = require('json3'); var basename = require('path').basename; var debug = require('debug')('mocha:watch'); var exists = require('fs').existsSync || require('path').existsSync; @@ -5872,7 +6008,7 @@ var join = require('path').join; var readdirSync = require('fs').readdirSync; var statSync = require('fs').statSync; var watchFile = require('fs').watchFile; -var toISOString = require('./to-iso-string'); +var toISOString = require('to-iso-string'); /** * Ignored directories. @@ -5997,23 +6133,6 @@ exports.filter = function(arr, fn) { return ret; }; -/** - * Array#some (<=IE8) - * - * @api private - * @param {Array} arr - * @param {Function} fn - * @return {Array} - */ -exports.some = function(arr, fn) { - for (var i = 0, l = arr.length; i < l; i++) { - if (fn(arr[i])) { - return true; - } - } - return false; -}; - /** * Object.keys (<=IE8) * @@ -6141,7 +6260,9 @@ exports.slug = function(str) { exports.clean = function(str) { str = str .replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '') - // (traditional)-> space/name parameters body (lambda)-> parameters body multi-statement/single keep body content + // (traditional)-> space/name parameters body (lambda)-> + // parameters body multi-statement/single keep body + // content .replace(/^function(?:\s*|\s+[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\s*\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\s*\}|((?:.|\n)*))$/, '$1$2$3'); var spaces = str.match(/^\n?( *)/)[1].length; @@ -6279,12 +6400,15 @@ exports.type = function type(value) { /** * Stringify `value`. Different behavior depending on type of value: * - * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively. - * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes. - * - If `value` is an *empty* object, function, or array, return result of function + * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, + * respectively. + * - If `value` is not an object, function or array, return result of + * `value.toString()` wrapped in double-quotes. + * - If `value` is an *empty* object, function, or array, return result of + * function * {@link emptyRepresentation}. - * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of - * JSON.stringify(). + * - If `value` has properties, call {@link exports.canonicalize} on it, then + * return result of JSON.stringify(). * * @api private * @see exports.type @@ -6414,9 +6538,12 @@ exports.isBuffer = function(value) { * - is `undefined`, return string `'[undefined]'` * - is `null`, return value `null` * - is some other primitive, return the value - * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method - * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again. - * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()` + * - is not a primitive or an `Array`, `Object`, or `Function`, return the + * value of the Thing's `toString()` method + * - is a non-empty `Array`, `Object`, or `Function`, return the result of + * calling this function again. + * - is an empty `Array`, `Object`, or `Function`, return the result of calling + * `emptyRepresentation()` * * @api private * @see {@link exports.stringify} @@ -6570,10 +6697,11 @@ exports.getError = function(err) { /** * @summary - * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`) + * This Filter based on `mocha-clean` module.(see: + * `github.com/rstacruz/mocha-clean`) * @description - * When invoking this function you get a filter function that get the Error.stack as an input, - * and return a prettify output. + * When invoking this function you get a filter function that get the + * Error.stack as an input, and return a prettify output. * (i.e: strip Mocha and internal node functions from stack trace). * @returns {Function} */ @@ -6626,129 +6754,48 @@ exports.stackTraceFilter = function() { }; }; +// /** - * Crude, but effective. - * @api - * @param {*} value - * @returns {boolean} Whether or not `value` is a Promise + * Number.MAX_SAFE_INTEGER only available in ES2015. + * @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER + * @type {number} */ -exports.isPromise = function isPromise(value) { - return typeof value === 'object' && typeof value.then === 'function'; -}; - -}).call(this,require('_process'),require("buffer").Buffer) -},{"./to-iso-string":37,"_process":67,"buffer":44,"debug":2,"fs":42,"glob":42,"json3":54,"path":42,"util":82}],39:[function(require,module,exports){ -'use strict' - -exports.toByteArray = toByteArray -exports.fromByteArray = fromByteArray - -var lookup = [] -var revLookup = [] -var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array - -function init () { - var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - for (var i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i] - revLookup[code.charCodeAt(i)] = i - } - - revLookup['-'.charCodeAt(0)] = 62 - revLookup['_'.charCodeAt(0)] = 63 -} - -init() - -function toByteArray (b64) { - var i, j, l, tmp, placeHolders, arr - var len = b64.length - - if (len % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 - - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(len * 3 / 4 - placeHolders) - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? len - 4 : len - - var L = 0 +exports.MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 0x1fffffffffffff; - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] - arr[L++] = (tmp >> 16) & 0xFF - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - if (placeHolders === 2) { - tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) - arr[L++] = tmp & 0xFF - } else if (placeHolders === 1) { - tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - return arr -} - -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] -} - -function encodeChunk (uint8, start, end) { - var tmp - var output = [] - for (var i = start; i < end; i += 3) { - tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output.push(tripletToBase64(tmp)) - } - return output.join('') -} - -function fromByteArray (uint8) { - var tmp - var len = uint8.length - var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes - var output = '' - var parts = [] - var maxChunkLength = 16383 // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1] - output += lookup[tmp >> 2] - output += lookup[(tmp << 4) & 0x3F] - output += '==' - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) - output += lookup[tmp >> 10] - output += lookup[(tmp >> 4) & 0x3F] - output += lookup[(tmp << 2) & 0x3F] - output += '=' +/** + * Attempt to convert `value` an integer, if it's a representation + * of a "safe" unsigned integer. + * @param {*} [value] Value to convert + * @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/parseInt + * @returns {(number|NaN)} result + */ +exports.toSafeUnsignedInteger = function toSafeUnsignedInteger(value) { + var intVal; + if (/^0[xX]/.test(value)) { + intVal = parseInt(value, 16); + } else if (/^0[^.]/.test(value)) { + intVal = parseInt(value, 8); + } else { + intVal = parseInt(value, 10); } + return !isNaN(intVal) && parseFloat(intVal) === intVal + && exports.isSafeUnsignedInteger(intVal) + ? intVal + : NaN; +}; - parts.push(output) - - return parts.join('') -} +/** + * Returns `true` if `value` is a "safe" 32-bit unsigned int. + * @param {*} [value] Value to test + * @returns {boolean} result + */ +exports.isSafeUnsignedInteger = function isUnsignedInteger(value) { + return typeof value === 'number' && value > 0 + && value <= exports.MAX_SAFE_INTEGER && value % 1 === 0; +}; -},{}],40:[function(require,module,exports){ +}).call(this,require('_process'),require("buffer").Buffer) +},{"_process":59,"buffer":43,"debug":2,"fs":42,"glob":42,"path":42,"to-iso-string":72,"util":75}],40:[function(require,module,exports){ },{}],41:[function(require,module,exports){ (function (process){ @@ -6779,129 +6826,17 @@ BrowserStdout.prototype._write = function(chunks, encoding, cb) { } }).call(this,require('_process')) -},{"_process":67,"stream":78,"util":82}],42:[function(require,module,exports){ +},{"_process":59,"stream":46,"util":75}],42:[function(require,module,exports){ arguments[4][40][0].apply(exports,arguments) },{"dup":40}],43:[function(require,module,exports){ (function (global){ -'use strict'; - -var buffer = require('buffer'); -var Buffer = buffer.Buffer; -var SlowBuffer = buffer.SlowBuffer; -var MAX_LEN = buffer.kMaxLength || 2147483647; -exports.alloc = function alloc(size, fill, encoding) { - if (typeof Buffer.alloc === 'function') { - return Buffer.alloc(size, fill, encoding); - } - if (typeof encoding === 'number') { - throw new TypeError('encoding must not be number'); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - var enc = encoding; - var _fill = fill; - if (_fill === undefined) { - enc = undefined; - _fill = 0; - } - var buf = new Buffer(size); - if (typeof _fill === 'string') { - var fillBuf = new Buffer(_fill, enc); - var flen = fillBuf.length; - var i = -1; - while (++i < size) { - buf[i] = fillBuf[i % flen]; - } - } else { - buf.fill(_fill); - } - return buf; -} -exports.allocUnsafe = function allocUnsafe(size) { - if (typeof Buffer.allocUnsafe === 'function') { - return Buffer.allocUnsafe(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - return new Buffer(size); -} -exports.from = function from(value, encodingOrOffset, length) { - if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { - return Buffer.from(value, encodingOrOffset, length); - } - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number'); - } - if (typeof value === 'string') { - return new Buffer(value, encodingOrOffset); - } - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - var offset = encodingOrOffset; - if (arguments.length === 1) { - return new Buffer(value); - } - if (typeof offset === 'undefined') { - offset = 0; - } - var len = length; - if (typeof len === 'undefined') { - len = value.byteLength - offset; - } - if (offset >= value.byteLength) { - throw new RangeError('\'offset\' is out of bounds'); - } - if (len > value.byteLength - offset) { - throw new RangeError('\'length\' is out of bounds'); - } - return new Buffer(value.slice(offset, offset + len)); - } - if (Buffer.isBuffer(value)) { - var out = new Buffer(value.length); - value.copy(out, 0, 0, value.length); - return out; - } - if (value) { - if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { - return new Buffer(value); - } - if (value.type === 'Buffer' && Array.isArray(value.data)) { - return new Buffer(value.data); - } - } - - throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); -} -exports.allocUnsafeSlow = function allocUnsafeSlow(size) { - if (typeof Buffer.allocUnsafeSlow === 'function') { - return Buffer.allocUnsafeSlow(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size >= MAX_LEN) { - throw new RangeError('size is too large'); - } - return new SlowBuffer(size); -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"buffer":44}],44:[function(require,module,exports){ -(function (global){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -/* eslint-disable no-proto */ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +/* eslint-disable no-proto */ 'use strict' @@ -6949,7 +6884,7 @@ exports.kMaxLength = kMaxLength() function typedArraySupport () { try { var arr = new Uint8Array(1) - arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} + arr.foo = function () { return 42 } return arr.foo() === 42 && // typed array instances can be augmented typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` @@ -7093,7 +7028,7 @@ function allocUnsafe (that, size) { assertSize(size) that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) if (!Buffer.TYPED_ARRAY_SUPPORT) { - for (var i = 0; i < size; ++i) { + for (var i = 0; i < size; i++) { that[i] = 0 } } @@ -7271,14 +7206,14 @@ Buffer.concat = function concat (list, length) { var i if (length === undefined) { length = 0 - for (i = 0; i < list.length; ++i) { + for (i = 0; i < list.length; i++) { length += list[i].length } } var buffer = Buffer.allocUnsafe(length) var pos = 0 - for (i = 0; i < list.length; ++i) { + for (i = 0; i < list.length; i++) { var buf = list[i] if (!Buffer.isBuffer(buf)) { throw new TypeError('"list" argument must be an Array of Buffers') @@ -7310,6 +7245,7 @@ function byteLength (string, encoding) { switch (encoding) { case 'ascii': case 'binary': + // Deprecated case 'raw': case 'raws': return len @@ -7547,16 +7483,15 @@ function arrayIndexOf (arr, val, byteOffset, encoding) { } var foundIndex = -1 - for (var i = byteOffset; i < arrLength; ++i) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + for (var i = 0; byteOffset + i < arrLength; i++) { + if (read(arr, byteOffset + i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === valLength) return foundIndex * indexSize + if (i - foundIndex + 1 === valLength) return (byteOffset + foundIndex) * indexSize } else { if (foundIndex !== -1) i -= i - foundIndex foundIndex = -1 } } - return -1 } @@ -7621,7 +7556,7 @@ function hexWrite (buf, string, offset, length) { if (length > strLen / 2) { length = strLen / 2 } - for (var i = 0; i < length; ++i) { + for (var i = 0; i < length; i++) { var parsed = parseInt(string.substr(i * 2, 2), 16) if (isNaN(parsed)) return i buf[offset + i] = parsed @@ -7835,7 +7770,7 @@ function asciiSlice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) - for (var i = start; i < end; ++i) { + for (var i = start; i < end; i++) { ret += String.fromCharCode(buf[i] & 0x7F) } return ret @@ -7845,7 +7780,7 @@ function binarySlice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) - for (var i = start; i < end; ++i) { + for (var i = start; i < end; i++) { ret += String.fromCharCode(buf[i]) } return ret @@ -7858,7 +7793,7 @@ function hexSlice (buf, start, end) { if (!end || end < 0 || end > len) end = len var out = '' - for (var i = start; i < end; ++i) { + for (var i = start; i < end; i++) { out += toHex(buf[i]) } return out @@ -7901,7 +7836,7 @@ Buffer.prototype.slice = function slice (start, end) { } else { var sliceLen = end - start newBuf = new Buffer(sliceLen, undefined) - for (var i = 0; i < sliceLen; ++i) { + for (var i = 0; i < sliceLen; i++) { newBuf[i] = this[i + start] } } @@ -8128,7 +8063,7 @@ Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { function objectWriteUInt16 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> (littleEndian ? i : 1 - i) * 8 } @@ -8162,7 +8097,7 @@ Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert function objectWriteUInt32 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffffffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff } } @@ -8377,12 +8312,12 @@ Buffer.prototype.copy = function copy (target, targetStart, start, end) { if (this === target && start < targetStart && targetStart < end) { // descending copy from end - for (i = len - 1; i >= 0; --i) { + for (i = len - 1; i >= 0; i--) { target[i + targetStart] = this[i + start] } } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { // ascending copy from start - for (i = 0; i < len; ++i) { + for (i = 0; i < len; i++) { target[i + targetStart] = this[i + start] } } else { @@ -8443,7 +8378,7 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) { var i if (typeof val === 'number') { - for (i = start; i < end; ++i) { + for (i = start; i < end; i++) { this[i] = val } } else { @@ -8451,7 +8386,7 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) { ? val : utf8ToBytes(new Buffer(val, encoding).toString()) var len = bytes.length - for (i = 0; i < end - start; ++i) { + for (i = 0; i < end - start; i++) { this[i + start] = bytes[i % len] } } @@ -8493,7 +8428,7 @@ function utf8ToBytes (string, units) { var leadSurrogate = null var bytes = [] - for (var i = 0; i < length; ++i) { + for (var i = 0; i < length; i++) { codePoint = string.charCodeAt(i) // is surrogate component @@ -8568,7 +8503,7 @@ function utf8ToBytes (string, units) { function asciiToBytes (str) { var byteArray = [] - for (var i = 0; i < str.length; ++i) { + for (var i = 0; i < str.length; i++) { // Node's code seems to be doing this and not & 0x7F.. byteArray.push(str.charCodeAt(i) & 0xFF) } @@ -8578,7 +8513,7 @@ function asciiToBytes (str) { function utf16leToBytes (str, units) { var c, hi, lo var byteArray = [] - for (var i = 0; i < str.length; ++i) { + for (var i = 0; i < str.length; i++) { if ((units -= 2) < 0) break c = str.charCodeAt(i) @@ -8596,7 +8531,7 @@ function base64ToBytes (str) { } function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { + for (var i = 0; i < length; i++) { if ((i + offset >= dst.length) || (i >= src.length)) break dst[i + offset] = src[i] } @@ -8608,8 +8543,118 @@ function isnan (val) { } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"base64-js":39,"ieee754":50,"isarray":53}],45:[function(require,module,exports){ -(function (Buffer){ +},{"base64-js":44,"ieee754":52,"isarray":55}],44:[function(require,module,exports){ +'use strict' + +exports.toByteArray = toByteArray +exports.fromByteArray = fromByteArray + +var lookup = [] +var revLookup = [] +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array + +function init () { + var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i + } + + revLookup['-'.charCodeAt(0)] = 62 + revLookup['_'.charCodeAt(0)] = 63 +} + +init() + +function toByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + var len = b64.length + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(len * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? len - 4 : len + + var L = 0 + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] + arr[L++] = (tmp >> 16) & 0xFF + arr[L++] = (tmp >> 8) & 0xFF + arr[L++] = tmp & 0xFF + } + + if (placeHolders === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[L++] = tmp & 0xFF + } else if (placeHolders === 1) { + tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[L++] = (tmp >> 8) & 0xFF + arr[L++] = tmp & 0xFF + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp + var output = [] + for (var i = start; i < end; i += 3) { + tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output.push(tripletToBase64(tmp)) + } + return output.join('') +} + +function fromByteArray (uint8) { + var tmp + var len = uint8.length + var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + var output = '' + var parts = [] + var maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + output += lookup[tmp >> 2] + output += lookup[(tmp << 4) & 0x3F] + output += '==' + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) + output += lookup[tmp >> 10] + output += lookup[(tmp >> 4) & 0x3F] + output += lookup[(tmp << 2) & 0x3F] + output += '=' + } + + parts.push(output) + + return parts.join('') +} + +},{}],45:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -8631,729 +8676,527 @@ function isnan (val) { // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. - -function isArray(arg) { - if (Array.isArray) { - return Array.isArray(arg); - } - return objectToString(arg) === '[object Array]'; +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; } -exports.isArray = isArray; +module.exports = EventEmitter; -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; +// 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; -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; +// 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; +}; -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; + if (!this._events) + this._events = {}; -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; + // 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.'); + } + } -function isRegExp(re) { - return objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; + handler = this._events[type]; -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; + if (isUndefined(handler)) + return false; -function isError(e) { - return (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; + 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: + args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + } else if (isObject(handler)) { + args = Array.prototype.slice.call(arguments, 1); + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; + return true; +}; -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; +EventEmitter.prototype.addListener = function(type, listener) { + var m; -exports.isBuffer = Buffer.isBuffer; + if (!isFunction(listener)) + throw TypeError('listener must be a function'); -function objectToString(o) { - return Object.prototype.toString.call(o); -} + if (!this._events) + this._events = {}; -}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) -},{"../../is-buffer/index.js":52}],46:[function(require,module,exports){ -/* See LICENSE file for terms of use */ + // 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); -/* - * Text diff implementation. - * - * This library supports the following APIS: - * JsDiff.diffChars: Character by character diff - * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace - * JsDiff.diffLines: Line based diff - * - * JsDiff.diffCss: Diff targeted at CSS content - * - * These methods are based on the implementation proposed in - * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986). - * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 - */ -(function(global, undefined) { - var objectPrototypeToString = Object.prototype.toString; + 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]; - /*istanbul ignore next*/ - function map(arr, mapper, that) { - if (Array.prototype.map) { - return Array.prototype.map.call(arr, mapper, that); + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; } - var other = new Array(arr.length); - - for (var i = 0, n = arr.length; i < n; i++) { - other[i] = mapper.call(that, arr[i], i, arr); - } - return other; - } - function clonePath(path) { - return { newPos: path.newPos, components: path.components.slice(0) }; - } - function removeEmpty(array) { - var ret = []; - for (var i = 0; i < array.length; i++) { - if (array[i]) { - ret.push(array[i]); + 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 ret; } - function escapeHTML(s) { - var n = s; - n = n.replace(/&/g, '&'); - n = n.replace(//g, '>'); - n = n.replace(/"/g, '"'); - return n; - } + return this; +}; - // This function handles the presence of circular references by bailing out when encountering an - // object that is already on the "stack" of items being processed. - function canonicalize(obj, stack, replacementStack) { - stack = stack || []; - replacementStack = replacementStack || []; +EventEmitter.prototype.on = EventEmitter.prototype.addListener; - var i; +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - for (i = 0; i < stack.length; i += 1) { - if (stack[i] === obj) { - return replacementStack[i]; - } - } + var fired = false; - var canonicalizedObj; + function g() { + this.removeListener(type, g); - if ('[object Array]' === objectPrototypeToString.call(obj)) { - stack.push(obj); - canonicalizedObj = new Array(obj.length); - replacementStack.push(canonicalizedObj); - for (i = 0; i < obj.length; i += 1) { - canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack); - } - stack.pop(); - replacementStack.pop(); - } else if (typeof obj === 'object' && obj !== null) { - stack.push(obj); - canonicalizedObj = {}; - replacementStack.push(canonicalizedObj); - var sortedKeys = [], - key; - for (key in obj) { - sortedKeys.push(key); - } - sortedKeys.sort(); - for (i = 0; i < sortedKeys.length; i += 1) { - key = sortedKeys[i]; - canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack); - } - stack.pop(); - replacementStack.pop(); - } else { - canonicalizedObj = obj; + if (!fired) { + fired = true; + listener.apply(this, arguments); } - return canonicalizedObj; } - function buildValues(components, newString, oldString, useLongestToken) { - var componentPos = 0, - componentLen = components.length, - newPos = 0, - oldPos = 0; + g.listener = listener; + this.on(type, g); - for (; componentPos < componentLen; componentPos++) { - var component = components[componentPos]; - if (!component.removed) { - if (!component.added && useLongestToken) { - var value = newString.slice(newPos, newPos + component.count); - value = map(value, function(value, i) { - var oldValue = oldString[oldPos + i]; - return oldValue.length > value.length ? oldValue : value; - }); + return this; +}; - component.value = value.join(''); - } else { - component.value = newString.slice(newPos, newPos + component.count).join(''); - } - newPos += component.count; +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; - // Common case - if (!component.added) { - oldPos += component.count; - } - } else { - component.value = oldString.slice(oldPos, oldPos + component.count).join(''); - oldPos += component.count; + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - // Reverse add and remove so removes are output first to match common convention - // The diffing algorithm is tied to add then remove output and this is the simplest - // route to get the desired output with minimal overhead. - if (componentPos && components[componentPos - 1].added) { - var tmp = components[componentPos - 1]; - components[componentPos - 1] = components[componentPos]; - components[componentPos] = tmp; - } + 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; } } - return components; - } + if (position < 0) + return this; - function Diff(ignoreWhitespace) { - this.ignoreWhitespace = ignoreWhitespace; + 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); } - Diff.prototype = { - diff: function(oldString, newString, callback) { - var self = this; - function done(value) { - if (callback) { - setTimeout(function() { callback(undefined, value); }, 0); - return true; - } else { - return value; - } - } + return this; +}; - // Handle the identity case (this is due to unrolling editLength == 0 - if (newString === oldString) { - return done([{ value: newString }]); - } - if (!newString) { - return done([{ value: oldString, removed: true }]); - } - if (!oldString) { - return done([{ value: newString, added: true }]); - } +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; - newString = this.tokenize(newString); - oldString = this.tokenize(oldString); + if (!this._events) + return this; - var newLen = newString.length, oldLen = oldString.length; - var editLength = 1; - var maxEditLength = newLen + oldLen; - var bestPath = [{ newPos: -1, components: [] }]; + // 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; + } - // Seed editLength = 0, i.e. the content starts with the same values - var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); - if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { - // Identity per the equality and tokenizer - return done([{value: newString.join('')}]); - } + // 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; + } - // Main worker method. checks all permutations of a given edit length for acceptance. - function execEditLength() { - for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { - var basePath; - var addPath = bestPath[diagonalPath - 1], - removePath = bestPath[diagonalPath + 1], - oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; - if (addPath) { - // No one else is going to attempt to use this value, clear it - bestPath[diagonalPath - 1] = undefined; - } + listeners = this._events[type]; - var canAdd = addPath && addPath.newPos + 1 < newLen, - canRemove = removePath && 0 <= oldPos && oldPos < oldLen; - if (!canAdd && !canRemove) { - // If this path is a terminal then prune - bestPath[diagonalPath] = undefined; - continue; - } + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; - // Select the diagonal that we want to branch from. We select the prior - // path whose position in the new string is the farthest from the origin - // and does not pass the bounds of the diff graph - if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) { - basePath = clonePath(removePath); - self.pushComponent(basePath.components, undefined, true); - } else { - basePath = addPath; // No need to clone, we've pulled it from the list - basePath.newPos++; - self.pushComponent(basePath.components, true, undefined); - } + return this; +}; - oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); +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; +}; - // If we have hit the end of both strings, then we are done - if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) { - return done(buildValues(basePath.components, newString, oldString, self.useLongestToken)); - } else { - // Otherwise track this path as a potential candidate and continue. - bestPath[diagonalPath] = basePath; - } - } +EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; - editLength++; - } + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; +}; - // Performs the length of edit iteration. Is a bit fugly as this has to support the - // sync and async mode which is never fun. Loops over execEditLength until a value - // is produced. - if (callback) { - (function exec() { - setTimeout(function() { - // This should not happen, but we want to be safe. - /*istanbul ignore next */ - if (editLength > maxEditLength) { - return callback(); - } +EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); +}; - if (!execEditLength()) { - exec(); - } - }, 0); - }()); - } else { - while (editLength <= maxEditLength) { - var ret = execEditLength(); - if (ret) { - return ret; - } - } - } - }, +function isFunction(arg) { + return typeof arg === 'function'; +} - pushComponent: function(components, added, removed) { - var last = components[components.length - 1]; - if (last && last.added === added && last.removed === removed) { - // We need to clone here as the component clone operation is just - // as shallow array clone - components[components.length - 1] = {count: last.count + 1, added: added, removed: removed }; - } else { - components.push({count: 1, added: added, removed: removed }); - } - }, - extractCommon: function(basePath, newString, oldString, diagonalPath) { - var newLen = newString.length, - oldLen = oldString.length, - newPos = basePath.newPos, - oldPos = newPos - diagonalPath, +function isNumber(arg) { + return typeof arg === 'number'; +} - commonCount = 0; - while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { - newPos++; - oldPos++; - commonCount++; - } +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} - if (commonCount) { - basePath.components.push({count: commonCount}); - } +function isUndefined(arg) { + return arg === void 0; +} - basePath.newPos = newPos; - return oldPos; - }, +},{}],46:[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. - equals: function(left, right) { - var reWhitespace = /\S/; - return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)); - }, - tokenize: function(value) { - return value.split(''); - } - }; +module.exports = Stream; - var CharDiff = new Diff(); +var EE = require('events').EventEmitter; +var inherits = require('inherits'); - var WordDiff = new Diff(true); - var WordWithSpaceDiff = new Diff(); - WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) { - return removeEmpty(value.split(/(\s+|\b)/)); - }; +inherits(Stream, EE); +Stream.Readable = require('readable-stream/readable.js'); +Stream.Writable = require('readable-stream/writable.js'); +Stream.Duplex = require('readable-stream/duplex.js'); +Stream.Transform = require('readable-stream/transform.js'); +Stream.PassThrough = require('readable-stream/passthrough.js'); - var CssDiff = new Diff(true); - CssDiff.tokenize = function(value) { - return removeEmpty(value.split(/([{}:;,]|\s+)/)); - }; +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; - var LineDiff = new Diff(); - var TrimmedLineDiff = new Diff(); - TrimmedLineDiff.ignoreTrim = true; - - LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) { - var retLines = [], - lines = value.split(/^/m); - for (var i = 0; i < lines.length; i++) { - var line = lines[i], - lastLine = lines[i - 1], - lastLineLastChar = lastLine && lastLine[lastLine.length - 1]; - - // Merge lines that may contain windows new lines - if (line === '\n' && lastLineLastChar === '\r') { - retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\r\n'; - } else { - if (this.ignoreTrim) { - line = line.trim(); - // add a newline unless this is the last line. - if (i < lines.length - 1) { - line += '\n'; - } - } - retLines.push(line); - } - } - - return retLines; - }; - var PatchDiff = new Diff(); - PatchDiff.tokenize = function(value) { - var ret = [], - linesAndNewlines = value.split(/(\n|\r\n)/); +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. - // Ignore the final empty token that occurs if the string ends with a new line - if (!linesAndNewlines[linesAndNewlines.length - 1]) { - linesAndNewlines.pop(); - } +function Stream() { + EE.call(this); +} - // Merge the content and line separators into single tokens - for (var i = 0; i < linesAndNewlines.length; i++) { - var line = linesAndNewlines[i]; +Stream.prototype.pipe = function(dest, options) { + var source = this; - if (i % 2) { - ret[ret.length - 1] += line; - } else { - ret.push(line); + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); } } - return ret; - }; - - var SentenceDiff = new Diff(); - SentenceDiff.tokenize = function(value) { - return removeEmpty(value.split(/(\S.+?[.!?])(?=\s+|$)/)); - }; + } - var JsonDiff = new Diff(); - // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a - // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: - JsonDiff.useLongestToken = true; - JsonDiff.tokenize = LineDiff.tokenize; - JsonDiff.equals = function(left, right) { - return LineDiff.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')); - }; + source.on('data', ondata); - var JsDiff = { - Diff: Diff, + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } - diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); }, - diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); }, - diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); }, - diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); }, - diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); }, + dest.on('drain', ondrain); - diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); }, + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); + } - diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); }, - diffJson: function(oldObj, newObj, callback) { - return JsonDiff.diff( - typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, ' '), - typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, ' '), - callback - ); - }, + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; - createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) { - var ret = []; + dest.end(); + } - if (oldFileName == newFileName) { - ret.push('Index: ' + oldFileName); - } - ret.push('==================================================================='); - ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader)); - ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader)); - var diff = PatchDiff.diff(oldStr, newStr); - diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier + function onclose() { + if (didOnEnd) return; + didOnEnd = true; - // Formats a given set of lines for printing as context lines in a patch - function contextLines(lines) { - return map(lines, function(entry) { return ' ' + entry; }); - } + if (typeof dest.destroy === 'function') dest.destroy(); + } - // Outputs the no newline at end of file warning if needed - function eofNL(curRange, i, current) { - var last = diff[diff.length - 2], - isLast = i === diff.length - 2, - isLastOfType = i === diff.length - 3 && current.added !== last.added; + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. + } + } - // Figure out if this is the last line for the given file and missing NL - if (!(/\n$/.test(current.value)) && (isLast || isLastOfType)) { - curRange.push('\\ No newline at end of file'); - } - } + source.on('error', onerror); + dest.on('error', onerror); - var oldRangeStart = 0, newRangeStart = 0, curRange = [], - oldLine = 1, newLine = 1; - for (var i = 0; i < diff.length; i++) { - var current = diff[i], - lines = current.lines || current.value.replace(/\n$/, '').split('\n'); - current.lines = lines; + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); - if (current.added || current.removed) { - // If we have previous context, start with that - if (!oldRangeStart) { - var prev = diff[i - 1]; - oldRangeStart = oldLine; - newRangeStart = newLine; + source.removeListener('end', onend); + source.removeListener('close', onclose); - if (prev) { - curRange = contextLines(prev.lines.slice(-4)); - oldRangeStart -= curRange.length; - newRangeStart -= curRange.length; - } - } + source.removeListener('error', onerror); + dest.removeListener('error', onerror); - // Output our changes - curRange.push.apply(curRange, map(lines, function(entry) { - return (current.added ? '+' : '-') + entry; - })); - eofNL(curRange, i, current); + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); - // Track the updated file position - if (current.added) { - newLine += lines.length; - } else { - oldLine += lines.length; - } - } else { - // Identical context lines. Track line changes - if (oldRangeStart) { - // Close out any changes that have been output (or join overlapping) - if (lines.length <= 8 && i < diff.length - 2) { - // Overlapping - curRange.push.apply(curRange, contextLines(lines)); - } else { - // end the range and output - var contextSize = Math.min(lines.length, 4); - ret.push( - '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize) - + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize) - + ' @@'); - ret.push.apply(ret, curRange); - ret.push.apply(ret, contextLines(lines.slice(0, contextSize))); - if (lines.length <= 4) { - eofNL(ret, i, current); - } + dest.removeListener('close', cleanup); + } - oldRangeStart = 0; - newRangeStart = 0; - curRange = []; - } - } - oldLine += lines.length; - newLine += lines.length; - } - } + source.on('end', cleanup); + source.on('close', cleanup); - return ret.join('\n') + '\n'; - }, + dest.on('close', cleanup); - createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) { - return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader); - }, + dest.emit('pipe', source); - applyPatch: function(oldStr, uniDiff) { - var diffstr = uniDiff.split('\n'), - hunks = [], - i = 0, - remEOFNL = false, - addEOFNL = false; + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; - // Skip to the first change hunk - while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) { - i++; - } +},{"events":45,"inherits":53,"readable-stream/duplex.js":61,"readable-stream/passthrough.js":67,"readable-stream/readable.js":68,"readable-stream/transform.js":69,"readable-stream/writable.js":70}],47:[function(require,module,exports){ +(function (global){ +'use strict'; - // Parse the unified diff - for (; i < diffstr.length; i++) { - if (diffstr[i][0] === '@') { - var chnukHeader = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/); - hunks.unshift({ - start: chnukHeader[3], - oldlength: +chnukHeader[2], - removed: [], - newlength: chnukHeader[4], - added: [] - }); - } else if (diffstr[i][0] === '+') { - hunks[0].added.push(diffstr[i].substr(1)); - } else if (diffstr[i][0] === '-') { - hunks[0].removed.push(diffstr[i].substr(1)); - } else if (diffstr[i][0] === ' ') { - hunks[0].added.push(diffstr[i].substr(1)); - hunks[0].removed.push(diffstr[i].substr(1)); - } else if (diffstr[i][0] === '\\') { - if (diffstr[i - 1][0] === '+') { - remEOFNL = true; - } else if (diffstr[i - 1][0] === '-') { - addEOFNL = true; - } - } - } - - // Apply the diff to the input - var lines = oldStr.split('\n'); - for (i = hunks.length - 1; i >= 0; i--) { - var hunk = hunks[i]; - // Sanity check the input string. Bail if we don't match. - for (var j = 0; j < hunk.oldlength; j++) { - if (lines[hunk.start - 1 + j] !== hunk.removed[j]) { - return false; - } - } - Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added)); - } - - // Handle EOFNL insertion/removal - if (remEOFNL) { - while (!lines[lines.length - 1]) { - lines.pop(); - } - } else if (addEOFNL) { - lines.push(''); - } - return lines.join('\n'); - }, - - convertChangesToXML: function(changes) { - var ret = []; - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - if (change.added) { - ret.push(''); - } else if (change.removed) { - ret.push(''); - } - - ret.push(escapeHTML(change.value)); - - if (change.added) { - ret.push(''); - } else if (change.removed) { - ret.push(''); - } - } - return ret.join(''); - }, - - // See: http://code.google.com/p/google-diff-match-patch/wiki/API - convertChangesToDMP: function(changes) { - var ret = [], - change, - operation; - for (var i = 0; i < changes.length; i++) { - change = changes[i]; - if (change.added) { - operation = 1; - } else if (change.removed) { - operation = -1; - } else { - operation = 0; - } - - ret.push([operation, change.value]); - } - return ret; - }, - - canonicalize: canonicalize - }; - - /*istanbul ignore next */ - /*global module */ - if (typeof module !== 'undefined' && module.exports) { - module.exports = JsDiff; - } else if (false) { - /*global define */ - define([], function() { return JsDiff; }); - } else if (typeof global.JsDiff === 'undefined') { - global.JsDiff = JsDiff; +var buffer = require('buffer'); +var Buffer = buffer.Buffer; +var SlowBuffer = buffer.SlowBuffer; +var MAX_LEN = buffer.kMaxLength || 2147483647; +exports.alloc = function alloc(size, fill, encoding) { + if (typeof Buffer.alloc === 'function') { + return Buffer.alloc(size, fill, encoding); + } + if (typeof encoding === 'number') { + throw new TypeError('encoding must not be number'); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size > MAX_LEN) { + throw new RangeError('size is too large'); + } + var enc = encoding; + var _fill = fill; + if (_fill === undefined) { + enc = undefined; + _fill = 0; + } + var buf = new Buffer(size); + if (typeof _fill === 'string') { + var fillBuf = new Buffer(_fill, enc); + var flen = fillBuf.length; + var i = -1; + while (++i < size) { + buf[i] = fillBuf[i % flen]; + } + } else { + buf.fill(_fill); + } + return buf; +} +exports.allocUnsafe = function allocUnsafe(size) { + if (typeof Buffer.allocUnsafe === 'function') { + return Buffer.allocUnsafe(size); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size > MAX_LEN) { + throw new RangeError('size is too large'); + } + return new Buffer(size); +} +exports.from = function from(value, encodingOrOffset, length) { + if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { + return Buffer.from(value, encodingOrOffset, length); + } + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number'); + } + if (typeof value === 'string') { + return new Buffer(value, encodingOrOffset); + } + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + var offset = encodingOrOffset; + if (arguments.length === 1) { + return new Buffer(value); + } + if (typeof offset === 'undefined') { + offset = 0; + } + var len = length; + if (typeof len === 'undefined') { + len = value.byteLength - offset; + } + if (offset >= value.byteLength) { + throw new RangeError('\'offset\' is out of bounds'); + } + if (len > value.byteLength - offset) { + throw new RangeError('\'length\' is out of bounds'); + } + return new Buffer(value.slice(offset, offset + len)); + } + if (Buffer.isBuffer(value)) { + var out = new Buffer(value.length); + value.copy(out, 0, 0, value.length); + return out; + } + if (value) { + if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { + return new Buffer(value); + } + if (value.type === 'Buffer' && Array.isArray(value.data)) { + return new Buffer(value.data); + } } -}(this)); - -},{}],47:[function(require,module,exports){ -'use strict'; - -var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; - -module.exports = function (str) { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } - return str.replace(matchOperatorsRe, '\\$&'); -}; + throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); +} +exports.allocUnsafeSlow = function allocUnsafeSlow(size) { + if (typeof Buffer.allocUnsafeSlow === 'function') { + return Buffer.allocUnsafeSlow(size); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size >= MAX_LEN) { + throw new RangeError('size is too large'); + } + return new SlowBuffer(size); +} -},{}],48:[function(require,module,exports){ +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"buffer":43}],48:[function(require,module,exports){ +(function (Buffer){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -9375,2743 +9218,1160 @@ module.exports = function (str) { // 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; +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. + +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; } -module.exports = EventEmitter; +exports.isArray = isArray; -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; -// 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; +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; -// 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; -}; +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; - if (!this._events) - this._events = {}; +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; - // 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 - } else { - // At least give some kind of context to the user - var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); - err.context = er; - throw err; - } - } - } +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; - handler = this._events[type]; +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; - if (isUndefined(handler)) - return false; +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; - 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: - args = Array.prototype.slice.call(arguments, 1); - handler.apply(this, args); - } - } else if (isObject(handler)) { - args = Array.prototype.slice.call(arguments, 1); - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; - return true; -}; +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; -EventEmitter.prototype.addListener = function(type, listener) { - var m; +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; - if (!isFunction(listener)) - throw TypeError('listener must be a function'); +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; - if (!this._events) - this._events = {}; +exports.isBuffer = Buffer.isBuffer; - // 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); +function objectToString(o) { + return Object.prototype.toString.call(o); +} - 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]; +}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) +},{"../../is-buffer/index.js":54}],49:[function(require,module,exports){ +/* See LICENSE file for terms of use */ - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; - } +/* + * Text diff implementation. + * + * This library supports the following APIS: + * JsDiff.diffChars: Character by character diff + * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace + * JsDiff.diffLines: Line based diff + * + * JsDiff.diffCss: Diff targeted at CSS content + * + * These methods are based on the implementation proposed in + * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986). + * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 + */ +(function(global, undefined) { + var objectPrototypeToString = Object.prototype.toString; - 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(); - } + /*istanbul ignore next*/ + function map(arr, mapper, that) { + if (Array.prototype.map) { + return Array.prototype.map.call(arr, mapper, that); } - } - - 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); + var other = new Array(arr.length); - if (!fired) { - fired = true; - listener.apply(this, arguments); + for (var i = 0, n = arr.length; i < n; i++) { + other[i] = mapper.call(that, arr[i], i, arr); } + return other; } + function clonePath(path) { + return { newPos: path.newPos, components: path.components.slice(0) }; + } + function removeEmpty(array) { + var ret = []; + for (var i = 0; i < array.length; i++) { + if (array[i]) { + ret.push(array[i]); + } + } + return ret; + } + function escapeHTML(s) { + var n = s; + n = n.replace(/&/g, '&'); + n = n.replace(//g, '>'); + n = n.replace(/"/g, '"'); - 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; + return n; + } - list = this._events[type]; - length = list.length; - position = -1; + // This function handles the presence of circular references by bailing out when encountering an + // object that is already on the "stack" of items being processed. + function canonicalize(obj, stack, replacementStack) { + stack = stack || []; + replacementStack = replacementStack || []; - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); + var i; - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; + for (i = 0; i < stack.length; i += 1) { + if (stack[i] === obj) { + return replacementStack[i]; } } - if (position < 0) - return this; + var canonicalizedObj; - if (list.length === 1) { - list.length = 0; - delete this._events[type]; + if ('[object Array]' === objectPrototypeToString.call(obj)) { + stack.push(obj); + canonicalizedObj = new Array(obj.length); + replacementStack.push(canonicalizedObj); + for (i = 0; i < obj.length; i += 1) { + canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack); + } + stack.pop(); + replacementStack.pop(); + } else if (typeof obj === 'object' && obj !== null) { + stack.push(obj); + canonicalizedObj = {}; + replacementStack.push(canonicalizedObj); + var sortedKeys = [], + key; + for (key in obj) { + sortedKeys.push(key); + } + sortedKeys.sort(); + for (i = 0; i < sortedKeys.length; i += 1) { + key = sortedKeys[i]; + canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack); + } + stack.pop(); + replacementStack.pop(); } else { - list.splice(position, 1); + canonicalizedObj = obj; } - - if (this._events.removeListener) - this.emit('removeListener', type, listener); + return canonicalizedObj; } - 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 if (listeners) { - // 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.prototype.listenerCount = function(type) { - if (this._events) { - var evlistener = this._events[type]; - - if (isFunction(evlistener)) - return 1; - else if (evlistener) - return evlistener.length; - } - return 0; -}; - -EventEmitter.listenerCount = function(emitter, type) { - return emitter.listenerCount(type); -}; - -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; -} - -},{}],49:[function(require,module,exports){ -(function (process){ -// Growl - Copyright TJ Holowaychuk (MIT Licensed) - -/** - * Module dependencies. - */ - -var exec = require('child_process').exec - , fs = require('fs') - , path = require('path') - , exists = fs.existsSync || path.existsSync - , os = require('os') - , quote = JSON.stringify - , cmd; - -function which(name) { - var paths = process.env.PATH.split(':'); - var loc; - - for (var i = 0, len = paths.length; i < len; ++i) { - loc = path.join(paths[i], name); - if (exists(loc)) return loc; - } -} - -switch(os.type()) { - case 'Darwin': - if (which('terminal-notifier')) { - cmd = { - type: "Darwin-NotificationCenter" - , pkg: "terminal-notifier" - , msg: '-message' - , title: '-title' - , subtitle: '-subtitle' - , icon: '-appIcon' - , sound: '-sound' - , url: '-open' - , priority: { - cmd: '-execute' - , range: [] - } - }; - } else { - cmd = { - type: "Darwin-Growl" - , pkg: "growlnotify" - , msg: '-m' - , sticky: '--sticky' - , priority: { - cmd: '--priority' - , range: [ - -2 - , -1 - , 0 - , 1 - , 2 - , "Very Low" - , "Moderate" - , "Normal" - , "High" - , "Emergency" - ] - } - }; - } - break; - case 'Linux': - if (which('growl')) { - cmd = { - type: "Linux-Growl" - , pkg: "growl" - , msg: '-m' - , title: '-title' - , subtitle: '-subtitle' - , host: { - cmd: '-H' - , hostname: '192.168.33.1' - } - }; - } else { - cmd = { - type: "Linux" - , pkg: "notify-send" - , msg: '' - , sticky: '-t 0' - , icon: '-i' - , priority: { - cmd: '-u' - , range: [ - "low" - , "normal" - , "critical" - ] - } - }; - } - break; - case 'Windows_NT': - cmd = { - type: "Windows" - , pkg: "growlnotify" - , msg: '' - , sticky: '/s:true' - , title: '/t:' - , icon: '/i:' - , url: '/cu:' - , priority: { - cmd: '/p:' - , range: [ - -2 - , -1 - , 0 - , 1 - , 2 - ] - } - }; - break; -} - -/** - * Expose `growl`. - */ - -exports = module.exports = growl; - -/** - * Node-growl version. - */ - -exports.version = '1.4.1' - -/** - * Send growl notification _msg_ with _options_. - * - * Options: - * - * - title Notification title - * - sticky Make the notification stick (defaults to false) - * - priority Specify an int or named key (default is 0) - * - name Application name (defaults to growlnotify) - * - sound Sound efect ( in OSx defined in preferences -> sound -> effects) * works only in OSX > 10.8x - * - image - * - path to an icon sets --iconpath - * - path to an image sets --image - * - capitalized word sets --appIcon - * - filename uses extname as --icon - * - otherwise treated as --icon - * - * Examples: - * - * growl('New email') - * growl('5 new emails', { title: 'Thunderbird' }) - * growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' }) - * growl('Email sent', function(){ - * // ... notification sent - * }) - * - * @param {string} msg - * @param {object} options - * @param {function} fn - * @api public - */ - -function growl(msg, options, fn) { - var image - , args - , options = options || {} - , fn = fn || function(){}; - - if (options.exec) { - cmd = { - type: "Custom" - , pkg: options.exec - , range: [] - }; - } - - // noop - if (!cmd) return fn(new Error('growl not supported on this platform')); - args = [cmd.pkg]; - - // image - if (image = options.image) { - switch(cmd.type) { - case 'Darwin-Growl': - var flag, ext = path.extname(image).substr(1) - flag = flag || ext == 'icns' && 'iconpath' - flag = flag || /^[A-Z]/.test(image) && 'appIcon' - flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image' - flag = flag || ext && (image = ext) && 'icon' - flag = flag || 'icon' - args.push('--' + flag, quote(image)) - break; - case 'Darwin-NotificationCenter': - args.push(cmd.icon, quote(image)); - break; - case 'Linux': - args.push(cmd.icon, quote(image)); - // libnotify defaults to sticky, set a hint for transient notifications - if (!options.sticky) args.push('--hint=int:transient:1'); - break; - case 'Windows': - args.push(cmd.icon + quote(image)); - break; - } - } - - // sticky - if (options.sticky) args.push(cmd.sticky); - - // priority - if (options.priority) { - var priority = options.priority + ''; - var checkindexOf = cmd.priority.range.indexOf(priority); - if (~cmd.priority.range.indexOf(priority)) { - args.push(cmd.priority, options.priority); - } - } - - //sound - if(options.sound && cmd.type === 'Darwin-NotificationCenter'){ - args.push(cmd.sound, options.sound) - } - - // name - if (options.name && cmd.type === "Darwin-Growl") { - args.push('--name', options.name); - } - - switch(cmd.type) { - case 'Darwin-Growl': - args.push(cmd.msg); - args.push(quote(msg).replace(/\\n/g, '\n')); - if (options.title) args.push(quote(options.title)); - break; - case 'Darwin-NotificationCenter': - args.push(cmd.msg); - var stringifiedMsg = quote(msg); - var escapedMsg = stringifiedMsg.replace(/\\n/g, '\n'); - args.push(escapedMsg); - if (options.title) { - args.push(cmd.title); - args.push(quote(options.title)); - } - if (options.subtitle) { - args.push(cmd.subtitle); - args.push(quote(options.subtitle)); - } - if (options.url) { - args.push(cmd.url); - args.push(quote(options.url)); - } - break; - case 'Linux-Growl': - args.push(cmd.msg); - args.push(quote(msg).replace(/\\n/g, '\n')); - if (options.title) args.push(quote(options.title)); - if (cmd.host) { - args.push(cmd.host.cmd, cmd.host.hostname) - } - break; - case 'Linux': - if (options.title) { - args.push(quote(options.title)); - args.push(cmd.msg); - args.push(quote(msg).replace(/\\n/g, '\n')); - } else { - args.push(quote(msg).replace(/\\n/g, '\n')); - } - break; - case 'Windows': - args.push(quote(msg).replace(/\\n/g, '\n')); - if (options.title) args.push(cmd.title + quote(options.title)); - if (options.url) args.push(cmd.url + quote(options.url)); - break; - case 'Custom': - args[0] = (function(origCommand) { - var message = options.title - ? options.title + ': ' + msg - : msg; - var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message)); - if (command === origCommand) args.push(quote(message)); - return command; - })(args[0]); - break; - } - - // execute - exec(args.join(' '), fn); -}; - -}).call(this,require('_process')) -},{"_process":67,"child_process":42,"fs":42,"os":65,"path":42}],50:[function(require,module,exports){ -exports.read = function (buffer, offset, isLE, mLen, nBytes) { - var e, m - var eLen = nBytes * 8 - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var nBits = -7 - var i = isLE ? (nBytes - 1) : 0 - var d = isLE ? -1 : 1 - var s = buffer[offset + i] - - i += d - - e = s & ((1 << (-nBits)) - 1) - s >>= (-nBits) - nBits += eLen - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - m = e & ((1 << (-nBits)) - 1) - e >>= (-nBits) - nBits += mLen - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + function buildValues(components, newString, oldString, useLongestToken) { + var componentPos = 0, + componentLen = components.length, + newPos = 0, + oldPos = 0; - if (e === 0) { - e = 1 - eBias - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity) - } else { - m = m + Math.pow(2, mLen) - e = e - eBias - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen) -} + for (; componentPos < componentLen; componentPos++) { + var component = components[componentPos]; + if (!component.removed) { + if (!component.added && useLongestToken) { + var value = newString.slice(newPos, newPos + component.count); + value = map(value, function(value, i) { + var oldValue = oldString[oldPos + i]; + return oldValue.length > value.length ? oldValue : value; + }); -exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c - var eLen = nBytes * 8 - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) - var i = isLE ? 0 : (nBytes - 1) - var d = isLE ? 1 : -1 - var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + component.value = value.join(''); + } else { + component.value = newString.slice(newPos, newPos + component.count).join(''); + } + newPos += component.count; - value = Math.abs(value) + // Common case + if (!component.added) { + oldPos += component.count; + } + } else { + component.value = oldString.slice(oldPos, oldPos + component.count).join(''); + oldPos += component.count; - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0 - e = eMax - } else { - e = Math.floor(Math.log(value) / Math.LN2) - if (value * (c = Math.pow(2, -e)) < 1) { - e-- - c *= 2 - } - if (e + eBias >= 1) { - value += rt / c - } else { - value += rt * Math.pow(2, 1 - eBias) - } - if (value * c >= 2) { - e++ - c /= 2 + // Reverse add and remove so removes are output first to match common convention + // The diffing algorithm is tied to add then remove output and this is the simplest + // route to get the desired output with minimal overhead. + if (componentPos && components[componentPos - 1].added) { + var tmp = components[componentPos - 1]; + components[componentPos - 1] = components[componentPos]; + components[componentPos] = tmp; + } + } } - if (e + eBias >= eMax) { - m = 0 - e = eMax - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen) - e = e + eBias - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) - e = 0 - } + return components; } - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m - eLen += mLen - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128 -} - -},{}],51:[function(require,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor + function Diff(ignoreWhitespace) { + this.ignoreWhitespace = ignoreWhitespace; } -} - -},{}],52:[function(require,module,exports){ -/** - * Determine if an object is Buffer - * - * Author: Feross Aboukhadijeh - * License: MIT - * - * `npm install is-buffer` - */ - -module.exports = function (obj) { - return !!(obj != null && - (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) - (obj.constructor && - typeof obj.constructor.isBuffer === 'function' && - obj.constructor.isBuffer(obj)) - )) -} - -},{}],53:[function(require,module,exports){ -var toString = {}.toString; - -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; - -},{}],54:[function(require,module,exports){ -(function (global){ -/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */ -;(function () { - // Detect the `define` function exposed by asynchronous module loaders. The - // strict `define` check is necessary for compatibility with `r.js`. - var isLoader = false; - - // A set of types used to distinguish objects from primitives. - var objectTypes = { - "function": true, - "object": true - }; + Diff.prototype = { + diff: function(oldString, newString, callback) { + var self = this; - // Detect the `exports` object exposed by CommonJS implementations. - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - // Use the `global` object exposed by Node (including Browserify via - // `insert-module-globals`), Narwhal, and Ringo as the default context, - // and the `window` object in browsers. Rhino exports a `global` function - // instead. - var root = objectTypes[typeof window] && window || this, - freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == "object" && global; - - if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal || freeGlobal["self"] === freeGlobal)) { - root = freeGlobal; - } - - // Public: Initializes JSON 3 using the given `context` object, attaching the - // `stringify` and `parse` functions to the specified `exports` object. - function runInContext(context, exports) { - context || (context = root["Object"]()); - exports || (exports = root["Object"]()); - - // Native constructor aliases. - var Number = context["Number"] || root["Number"], - String = context["String"] || root["String"], - Object = context["Object"] || root["Object"], - Date = context["Date"] || root["Date"], - SyntaxError = context["SyntaxError"] || root["SyntaxError"], - TypeError = context["TypeError"] || root["TypeError"], - Math = context["Math"] || root["Math"], - nativeJSON = context["JSON"] || root["JSON"]; - - // Delegate to the native `stringify` and `parse` implementations. - if (typeof nativeJSON == "object" && nativeJSON) { - exports.stringify = nativeJSON.stringify; - exports.parse = nativeJSON.parse; - } - - // Convenience aliases. - var objectProto = Object.prototype, - getClass = objectProto.toString, - isProperty, forEach, undef; - - // Test the `Date#getUTC*` methods. Based on work by @Yaffle. - var isExtended = new Date(-3509827334573292); - try { - // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical - // results for certain dates in Opera >= 10.53. - isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 && - // Safari < 2.0.2 stores the internal millisecond time value correctly, - // but clips the values returned by the date methods to the range of - // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]). - isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708; - } catch (exception) {} - - // Internal: Determines whether the native `JSON.stringify` and `parse` - // implementations are spec-compliant. Based on work by Ken Snyder. - function has(name) { - if (has[name] !== undef) { - // Return cached feature test result. - return has[name]; - } - var isSupported; - if (name == "bug-string-char-index") { - // IE <= 7 doesn't support accessing string characters using square - // bracket notation. IE 8 only supports this for primitives. - isSupported = "a"[0] != "a"; - } else if (name == "json") { - // Indicates whether both `JSON.stringify` and `JSON.parse` are - // supported. - isSupported = has("json-stringify") && has("json-parse"); - } else { - var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'; - // Test `JSON.stringify`. - if (name == "json-stringify") { - var stringify = exports.stringify, stringifySupported = typeof stringify == "function" && isExtended; - if (stringifySupported) { - // A test function object with a custom `toJSON` method. - (value = function () { - return 1; - }).toJSON = value; - try { - stringifySupported = - // Firefox 3.1b1 and b2 serialize string, number, and boolean - // primitives as object literals. - stringify(0) === "0" && - // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object - // literals. - stringify(new Number()) === "0" && - stringify(new String()) == '""' && - // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or - // does not define a canonical JSON representation (this applies to - // objects with `toJSON` properties as well, *unless* they are nested - // within an object or array). - stringify(getClass) === undef && - // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and - // FF 3.1b3 pass this test. - stringify(undef) === undef && - // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, - // respectively, if the value is omitted entirely. - stringify() === undef && - // FF 3.1b1, 2 throw an error if the given value is not a number, - // string, array, object, Boolean, or `null` literal. This applies to - // objects with custom `toJSON` methods as well, unless they are nested - // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` - // methods entirely. - stringify(value) === "1" && - stringify([value]) == "[1]" && - // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of - // `"[null]"`. - stringify([undef]) == "[null]" && - // YUI 3.0.0b1 fails to serialize `null` literals. - stringify(null) == "null" && - // FF 3.1b1, 2 halts serialization if an array contains a function: - // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3 - // elides non-JSON values from objects and arrays, unless they - // define custom `toJSON` methods. - stringify([undef, getClass, null]) == "[null,null,null]" && - // Simple serialization test. FF 3.1b1 uses Unicode escape sequences - // where character escape codes are expected (e.g., `\b` => `\u0008`). - stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized && - // FF 3.1b1 and b2 ignore the `filter` and `width` arguments. - stringify(null, value) === "1" && - stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" && - // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly - // serialize extended years. - stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' && - // The milliseconds are optional in ES 5, but required in 5.1. - stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' && - // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative - // four-digit years instead of six-digit years. Credits: @Yaffle. - stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' && - // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond - // values less than 1000. Credits: @Yaffle. - stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"'; - } catch (exception) { - stringifySupported = false; - } - } - isSupported = stringifySupported; - } - // Test `JSON.parse`. - if (name == "json-parse") { - var parse = exports.parse; - if (typeof parse == "function") { - try { - // FF 3.1b1, b2 will throw an exception if a bare literal is provided. - // Conforming implementations should also coerce the initial argument to - // a string prior to parsing. - if (parse("0") === 0 && !parse(false)) { - // Simple parsing test. - value = parse(serialized); - var parseSupported = value["a"].length == 5 && value["a"][0] === 1; - if (parseSupported) { - try { - // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings. - parseSupported = !parse('"\t"'); - } catch (exception) {} - if (parseSupported) { - try { - // FF 4.0 and 4.0.1 allow leading `+` signs and leading - // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow - // certain octal literals. - parseSupported = parse("01") !== 1; - } catch (exception) {} - } - if (parseSupported) { - try { - // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal - // points. These environments, along with FF 3.1b1 and 2, - // also allow trailing commas in JSON objects and arrays. - parseSupported = parse("1.") !== 1; - } catch (exception) {} - } - } - } - } catch (exception) { - parseSupported = false; - } - } - isSupported = parseSupported; + function done(value) { + if (callback) { + setTimeout(function() { callback(undefined, value); }, 0); + return true; + } else { + return value; } } - return has[name] = !!isSupported; - } - - if (!has("json")) { - // Common `[[Class]]` name aliases. - var functionClass = "[object Function]", - dateClass = "[object Date]", - numberClass = "[object Number]", - stringClass = "[object String]", - arrayClass = "[object Array]", - booleanClass = "[object Boolean]"; - - // Detect incomplete support for accessing string characters by index. - var charIndexBuggy = has("bug-string-char-index"); - - // Define additional utility methods if the `Date` methods are buggy. - if (!isExtended) { - var floor = Math.floor; - // A mapping between the months of the year and the number of days between - // January 1st and the first of the respective month. - var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; - // Internal: Calculates the number of days between the Unix epoch and the - // first day of the given month. - var getDay = function (year, month) { - return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400); - }; - } - // Internal: Determines if a property is a direct property of the given - // object. Delegates to the native `Object#hasOwnProperty` method. - if (!(isProperty = objectProto.hasOwnProperty)) { - isProperty = function (property) { - var members = {}, constructor; - if ((members.__proto__ = null, members.__proto__ = { - // The *proto* property cannot be set multiple times in recent - // versions of Firefox and SeaMonkey. - "toString": 1 - }, members).toString != getClass) { - // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but - // supports the mutable *proto* property. - isProperty = function (property) { - // Capture and break the object's prototype chain (see section 8.6.2 - // of the ES 5.1 spec). The parenthesized expression prevents an - // unsafe transformation by the Closure Compiler. - var original = this.__proto__, result = property in (this.__proto__ = null, this); - // Restore the original prototype chain. - this.__proto__ = original; - return result; - }; - } else { - // Capture a reference to the top-level `Object` constructor. - constructor = members.constructor; - // Use the `constructor` property to simulate `Object#hasOwnProperty` in - // other environments. - isProperty = function (property) { - var parent = (this.constructor || constructor).prototype; - return property in this && !(property in parent && this[property] === parent[property]); - }; - } - members = null; - return isProperty.call(this, property); - }; + // Handle the identity case (this is due to unrolling editLength == 0 + if (newString === oldString) { + return done([{ value: newString }]); } - - // Internal: Normalizes the `for...in` iteration algorithm across - // environments. Each enumerated key is yielded to a `callback` function. - forEach = function (object, callback) { - var size = 0, Properties, members, property; - - // Tests for bugs in the current environment's `for...in` algorithm. The - // `valueOf` property inherits the non-enumerable flag from - // `Object.prototype` in older versions of IE, Netscape, and Mozilla. - (Properties = function () { - this.valueOf = 0; - }).prototype.valueOf = 0; - - // Iterate over a new instance of the `Properties` class. - members = new Properties(); - for (property in members) { - // Ignore all properties inherited from `Object.prototype`. - if (isProperty.call(members, property)) { - size++; - } - } - Properties = members = null; - - // Normalize the iteration algorithm. - if (!size) { - // A list of non-enumerable properties inherited from `Object.prototype`. - members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"]; - // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable - // properties. - forEach = function (object, callback) { - var isFunction = getClass.call(object) == functionClass, property, length; - var hasProperty = !isFunction && typeof object.constructor != "function" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty; - for (property in object) { - // Gecko <= 1.0 enumerates the `prototype` property of functions under - // certain conditions; IE does not. - if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) { - callback(property); - } - } - // Manually invoke the callback for each non-enumerable property. - for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property)); - }; - } else if (size == 2) { - // Safari <= 2.0.4 enumerates shadowed properties twice. - forEach = function (object, callback) { - // Create a set of iterated properties. - var members = {}, isFunction = getClass.call(object) == functionClass, property; - for (property in object) { - // Store each property name to prevent double enumeration. The - // `prototype` property of functions is not enumerated due to cross- - // environment inconsistencies. - if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) { - callback(property); - } - } - }; - } else { - // No bugs detected; use the standard `for...in` algorithm. - forEach = function (object, callback) { - var isFunction = getClass.call(object) == functionClass, property, isConstructor; - for (property in object) { - if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) { - callback(property); - } - } - // Manually invoke the callback for the `constructor` property due to - // cross-environment inconsistencies. - if (isConstructor || isProperty.call(object, (property = "constructor"))) { - callback(property); - } - }; - } - return forEach(object, callback); - }; - - // Public: Serializes a JavaScript `value` as a JSON string. The optional - // `filter` argument may specify either a function that alters how object and - // array members are serialized, or an array of strings and numbers that - // indicates which properties should be serialized. The optional `width` - // argument may be either a string or number that specifies the indentation - // level of the output. - if (!has("json-stringify")) { - // Internal: A map of control characters and their escaped equivalents. - var Escapes = { - 92: "\\\\", - 34: '\\"', - 8: "\\b", - 12: "\\f", - 10: "\\n", - 13: "\\r", - 9: "\\t" - }; - - // Internal: Converts `value` into a zero-padded string such that its - // length is at least equal to `width`. The `width` must be <= 6. - var leadingZeroes = "000000"; - var toPaddedString = function (width, value) { - // The `|| 0` expression is necessary to work around a bug in - // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`. - return (leadingZeroes + (value || 0)).slice(-width); - }; - - // Internal: Double-quotes a string `value`, replacing all ASCII control - // characters (characters with code unit values between 0 and 31) with - // their escaped equivalents. This is an implementation of the - // `Quote(value)` operation defined in ES 5.1 section 15.12.3. - var unicodePrefix = "\\u00"; - var quote = function (value) { - var result = '"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10; - var symbols = useCharIndex && (charIndexBuggy ? value.split("") : value); - for (; index < length; index++) { - var charCode = value.charCodeAt(index); - // If the character is a control character, append its Unicode or - // shorthand escape sequence; otherwise, append the character as-is. - switch (charCode) { - case 8: case 9: case 10: case 12: case 13: case 34: case 92: - result += Escapes[charCode]; - break; - default: - if (charCode < 32) { - result += unicodePrefix + toPaddedString(2, charCode.toString(16)); - break; - } - result += useCharIndex ? symbols[index] : value.charAt(index); - } - } - return result + '"'; - }; - - // Internal: Recursively serializes an object. Implements the - // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations. - var serialize = function (property, object, callback, properties, whitespace, indentation, stack) { - var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result; - try { - // Necessary for host object support. - value = object[property]; - } catch (exception) {} - if (typeof value == "object" && value) { - className = getClass.call(value); - if (className == dateClass && !isProperty.call(value, "toJSON")) { - if (value > -1 / 0 && value < 1 / 0) { - // Dates are serialized according to the `Date#toJSON` method - // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15 - // for the ISO 8601 date time string format. - if (getDay) { - // Manually compute the year, month, date, hours, minutes, - // seconds, and milliseconds if the `getUTC*` methods are - // buggy. Adapted from @Yaffle's `date-shim` project. - date = floor(value / 864e5); - for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++); - for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++); - date = 1 + date - getDay(year, month); - // The `time` value specifies the time within the day (see ES - // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used - // to compute `A modulo B`, as the `%` operator does not - // correspond to the `modulo` operation for negative numbers. - time = (value % 864e5 + 864e5) % 864e5; - // The hours, minutes, seconds, and milliseconds are obtained by - // decomposing the time within the day. See section 15.9.1.10. - hours = floor(time / 36e5) % 24; - minutes = floor(time / 6e4) % 60; - seconds = floor(time / 1e3) % 60; - milliseconds = time % 1e3; - } else { - year = value.getUTCFullYear(); - month = value.getUTCMonth(); - date = value.getUTCDate(); - hours = value.getUTCHours(); - minutes = value.getUTCMinutes(); - seconds = value.getUTCSeconds(); - milliseconds = value.getUTCMilliseconds(); - } - // Serialize extended years correctly. - value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) + - "-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) + - // Months, dates, hours, minutes, and seconds should have two - // digits; milliseconds should have three. - "T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) + - // Milliseconds are optional in ES 5.0, but required in 5.1. - "." + toPaddedString(3, milliseconds) + "Z"; - } else { - value = null; - } - } else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) { - // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the - // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3 - // ignores all `toJSON` methods on these objects unless they are - // defined directly on an instance. - value = value.toJSON(property); - } - } - if (callback) { - // If a replacement function was provided, call it to obtain the value - // for serialization. - value = callback.call(object, property, value); - } - if (value === null) { - return "null"; - } - className = getClass.call(value); - if (className == booleanClass) { - // Booleans are represented literally. - return "" + value; - } else if (className == numberClass) { - // JSON numbers must be finite. `Infinity` and `NaN` are serialized as - // `"null"`. - return value > -1 / 0 && value < 1 / 0 ? "" + value : "null"; - } else if (className == stringClass) { - // Strings are double-quoted and escaped. - return quote("" + value); - } - // Recursively serialize objects and arrays. - if (typeof value == "object") { - // Check for cyclic structures. This is a linear search; performance - // is inversely proportional to the number of unique nested objects. - for (length = stack.length; length--;) { - if (stack[length] === value) { - // Cyclic structures cannot be serialized by `JSON.stringify`. - throw TypeError(); - } - } - // Add the object to the stack of traversed objects. - stack.push(value); - results = []; - // Save the current indentation level and indent one additional level. - prefix = indentation; - indentation += whitespace; - if (className == arrayClass) { - // Recursively serialize array elements. - for (index = 0, length = value.length; index < length; index++) { - element = serialize(index, value, callback, properties, whitespace, indentation, stack); - results.push(element === undef ? "null" : element); - } - result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]"; - } else { - // Recursively serialize object members. Members are selected from - // either a user-specified list of property names, or the object - // itself. - forEach(properties || value, function (property) { - var element = serialize(property, value, callback, properties, whitespace, indentation, stack); - if (element !== undef) { - // According to ES 5.1 section 15.12.3: "If `gap` {whitespace} - // is not the empty string, let `member` {quote(property) + ":"} - // be the concatenation of `member` and the `space` character." - // The "`space` character" refers to the literal space - // character, not the `space` {width} argument provided to - // `JSON.stringify`. - results.push(quote(property) + ":" + (whitespace ? " " : "") + element); - } - }); - result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}"; - } - // Remove the object from the traversed object stack. - stack.pop(); - return result; - } - }; - - // Public: `JSON.stringify`. See ES 5.1 section 15.12.3. - exports.stringify = function (source, filter, width) { - var whitespace, callback, properties, className; - if (objectTypes[typeof filter] && filter) { - if ((className = getClass.call(filter)) == functionClass) { - callback = filter; - } else if (className == arrayClass) { - // Convert the property names array into a makeshift set. - properties = {}; - for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1)); - } - } - if (width) { - if ((className = getClass.call(width)) == numberClass) { - // Convert the `width` to an integer and create a string containing - // `width` number of space characters. - if ((width -= width % 1) > 0) { - for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " "); - } - } else if (className == stringClass) { - whitespace = width.length <= 10 ? width : width.slice(0, 10); - } - } - // Opera <= 7.54u2 discards the values associated with empty string keys - // (`""`) only if they are used directly within an object member list - // (e.g., `!("" in { "": 1})`). - return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []); - }; + if (!newString) { + return done([{ value: oldString, removed: true }]); + } + if (!oldString) { + return done([{ value: newString, added: true }]); } - // Public: Parses a JSON source string. - if (!has("json-parse")) { - var fromCharCode = String.fromCharCode; - - // Internal: A map of escaped control characters and their unescaped - // equivalents. - var Unescapes = { - 92: "\\", - 34: '"', - 47: "/", - 98: "\b", - 116: "\t", - 110: "\n", - 102: "\f", - 114: "\r" - }; + newString = this.tokenize(newString); + oldString = this.tokenize(oldString); - // Internal: Stores the parser state. - var Index, Source; + var newLen = newString.length, oldLen = oldString.length; + var editLength = 1; + var maxEditLength = newLen + oldLen; + var bestPath = [{ newPos: -1, components: [] }]; - // Internal: Resets the parser state and throws a `SyntaxError`. - var abort = function () { - Index = Source = null; - throw SyntaxError(); - }; + // Seed editLength = 0, i.e. the content starts with the same values + var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); + if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + // Identity per the equality and tokenizer + return done([{value: newString.join('')}]); + } - // Internal: Returns the next token, or `"$"` if the parser has reached - // the end of the source string. A token may be a string, number, `null` - // literal, or Boolean literal. - var lex = function () { - var source = Source, length = source.length, value, begin, position, isSigned, charCode; - while (Index < length) { - charCode = source.charCodeAt(Index); - switch (charCode) { - case 9: case 10: case 13: case 32: - // Skip whitespace tokens, including tabs, carriage returns, line - // feeds, and space characters. - Index++; - break; - case 123: case 125: case 91: case 93: case 58: case 44: - // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at - // the current position. - value = charIndexBuggy ? source.charAt(Index) : source[Index]; - Index++; - return value; - case 34: - // `"` delimits a JSON string; advance to the next character and - // begin parsing the string. String tokens are prefixed with the - // sentinel `@` character to distinguish them from punctuators and - // end-of-string tokens. - for (value = "@", Index++; Index < length;) { - charCode = source.charCodeAt(Index); - if (charCode < 32) { - // Unescaped ASCII control characters (those with a code unit - // less than the space character) are not permitted. - abort(); - } else if (charCode == 92) { - // A reverse solidus (`\`) marks the beginning of an escaped - // control character (including `"`, `\`, and `/`) or Unicode - // escape sequence. - charCode = source.charCodeAt(++Index); - switch (charCode) { - case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114: - // Revive escaped control characters. - value += Unescapes[charCode]; - Index++; - break; - case 117: - // `\u` marks the beginning of a Unicode escape sequence. - // Advance to the first character and validate the - // four-digit code point. - begin = ++Index; - for (position = Index + 4; Index < position; Index++) { - charCode = source.charCodeAt(Index); - // A valid sequence comprises four hexdigits (case- - // insensitive) that form a single hexadecimal value. - if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) { - // Invalid Unicode escape sequence. - abort(); - } - } - // Revive the escaped character. - value += fromCharCode("0x" + source.slice(begin, Index)); - break; - default: - // Invalid escape sequence. - abort(); - } - } else { - if (charCode == 34) { - // An unescaped double-quote character marks the end of the - // string. - break; - } - charCode = source.charCodeAt(Index); - begin = Index; - // Optimize for the common case where a string is valid. - while (charCode >= 32 && charCode != 92 && charCode != 34) { - charCode = source.charCodeAt(++Index); - } - // Append the string as-is. - value += source.slice(begin, Index); - } - } - if (source.charCodeAt(Index) == 34) { - // Advance to the next character and return the revived string. - Index++; - return value; - } - // Unterminated string. - abort(); - default: - // Parse numbers and literals. - begin = Index; - // Advance past the negative sign, if one is specified. - if (charCode == 45) { - isSigned = true; - charCode = source.charCodeAt(++Index); - } - // Parse an integer or floating-point value. - if (charCode >= 48 && charCode <= 57) { - // Leading zeroes are interpreted as octal literals. - if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) { - // Illegal octal literal. - abort(); - } - isSigned = false; - // Parse the integer component. - for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++); - // Floats cannot contain a leading decimal point; however, this - // case is already accounted for by the parser. - if (source.charCodeAt(Index) == 46) { - position = ++Index; - // Parse the decimal component. - for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); - if (position == Index) { - // Illegal trailing decimal. - abort(); - } - Index = position; - } - // Parse exponents. The `e` denoting the exponent is - // case-insensitive. - charCode = source.charCodeAt(Index); - if (charCode == 101 || charCode == 69) { - charCode = source.charCodeAt(++Index); - // Skip past the sign following the exponent, if one is - // specified. - if (charCode == 43 || charCode == 45) { - Index++; - } - // Parse the exponential component. - for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); - if (position == Index) { - // Illegal empty exponent. - abort(); - } - Index = position; - } - // Coerce the parsed value to a JavaScript number. - return +source.slice(begin, Index); - } - // A negative sign may only precede numbers. - if (isSigned) { - abort(); - } - // `true`, `false`, and `null` literals. - if (source.slice(Index, Index + 4) == "true") { - Index += 4; - return true; - } else if (source.slice(Index, Index + 5) == "false") { - Index += 5; - return false; - } else if (source.slice(Index, Index + 4) == "null") { - Index += 4; - return null; - } - // Unrecognized token. - abort(); - } + // Main worker method. checks all permutations of a given edit length for acceptance. + function execEditLength() { + for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { + var basePath; + var addPath = bestPath[diagonalPath - 1], + removePath = bestPath[diagonalPath + 1], + oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; + if (addPath) { + // No one else is going to attempt to use this value, clear it + bestPath[diagonalPath - 1] = undefined; } - // Return the sentinel `$` character if the parser has reached the end - // of the source string. - return "$"; - }; - // Internal: Parses a JSON `value` token. - var get = function (value) { - var results, hasMembers; - if (value == "$") { - // Unexpected end of input. - abort(); - } - if (typeof value == "string") { - if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") { - // Remove the sentinel `@` character. - return value.slice(1); - } - // Parse object and array literals. - if (value == "[") { - // Parses a JSON array, returning a new JavaScript array. - results = []; - for (;; hasMembers || (hasMembers = true)) { - value = lex(); - // A closing square bracket marks the end of the array literal. - if (value == "]") { - break; - } - // If the array literal contains elements, the current token - // should be a comma separating the previous element from the - // next. - if (hasMembers) { - if (value == ",") { - value = lex(); - if (value == "]") { - // Unexpected trailing `,` in array literal. - abort(); - } - } else { - // A `,` must separate each array element. - abort(); - } - } - // Elisions and leading commas are not permitted. - if (value == ",") { - abort(); - } - results.push(get(value)); - } - return results; - } else if (value == "{") { - // Parses a JSON object, returning a new JavaScript object. - results = {}; - for (;; hasMembers || (hasMembers = true)) { - value = lex(); - // A closing curly brace marks the end of the object literal. - if (value == "}") { - break; - } - // If the object literal contains members, the current token - // should be a comma separator. - if (hasMembers) { - if (value == ",") { - value = lex(); - if (value == "}") { - // Unexpected trailing `,` in object literal. - abort(); - } - } else { - // A `,` must separate each object member. - abort(); - } - } - // Leading commas are not permitted, object property names must be - // double-quoted strings, and a `:` must separate each property - // name and value. - if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") { - abort(); - } - results[value.slice(1)] = get(lex()); - } - return results; - } - // Unexpected token encountered. - abort(); + var canAdd = addPath && addPath.newPos + 1 < newLen, + canRemove = removePath && 0 <= oldPos && oldPos < oldLen; + if (!canAdd && !canRemove) { + // If this path is a terminal then prune + bestPath[diagonalPath] = undefined; + continue; } - return value; - }; - // Internal: Updates a traversed object member. - var update = function (source, property, callback) { - var element = walk(source, property, callback); - if (element === undef) { - delete source[property]; + // Select the diagonal that we want to branch from. We select the prior + // path whose position in the new string is the farthest from the origin + // and does not pass the bounds of the diff graph + if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) { + basePath = clonePath(removePath); + self.pushComponent(basePath.components, undefined, true); } else { - source[property] = element; + basePath = addPath; // No need to clone, we've pulled it from the list + basePath.newPos++; + self.pushComponent(basePath.components, true, undefined); } - }; - // Internal: Recursively traverses a parsed JSON object, invoking the - // `callback` function for each value. This is an implementation of the - // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2. - var walk = function (source, property, callback) { - var value = source[property], length; - if (typeof value == "object" && value) { - // `forEach` can't be used to traverse an array in Opera <= 8.54 - // because its `Object#hasOwnProperty` implementation returns `false` - // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`). - if (getClass.call(value) == arrayClass) { - for (length = value.length; length--;) { - update(value, length, callback); - } - } else { - forEach(value, function (property) { - update(value, property, callback); - }); - } - } - return callback.call(source, property, value); - }; + oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); - // Public: `JSON.parse`. See ES 5.1 section 15.12.2. - exports.parse = function (source, callback) { - var result, value; - Index = 0; - Source = "" + source; - result = get(lex()); - // If a JSON string contains multiple tokens, it is invalid. - if (lex() != "$") { - abort(); + // If we have hit the end of both strings, then we are done + if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + return done(buildValues(basePath.components, newString, oldString, self.useLongestToken)); + } else { + // Otherwise track this path as a potential candidate and continue. + bestPath[diagonalPath] = basePath; } - // Reset the parser state. - Index = Source = null; - return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result; - }; + } + + editLength++; } - } - exports["runInContext"] = runInContext; - return exports; - } + // Performs the length of edit iteration. Is a bit fugly as this has to support the + // sync and async mode which is never fun. Loops over execEditLength until a value + // is produced. + if (callback) { + (function exec() { + setTimeout(function() { + // This should not happen, but we want to be safe. + /*istanbul ignore next */ + if (editLength > maxEditLength) { + return callback(); + } - if (freeExports && !isLoader) { - // Export for CommonJS environments. - runInContext(root, freeExports); - } else { - // Export for web browsers and JavaScript engines. - var nativeJSON = root.JSON, - previousJSON = root["JSON3"], - isRestored = false; - - var JSON3 = runInContext(root, (root["JSON3"] = { - // Public: Restores the original value of the global `JSON` object and - // returns a reference to the `JSON3` object. - "noConflict": function () { - if (!isRestored) { - isRestored = true; - root.JSON = nativeJSON; - root["JSON3"] = previousJSON; - nativeJSON = previousJSON = null; + if (!execEditLength()) { + exec(); + } + }, 0); + }()); + } else { + while (editLength <= maxEditLength) { + var ret = execEditLength(); + if (ret) { + return ret; + } } - return JSON3; } - })); - - root.JSON = { - "parse": JSON3.parse, - "stringify": JSON3.stringify - }; - } - - // Export for asynchronous module loaders. - if (isLoader) { - define(function () { - return JSON3; - }); - } -}).call(this); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],55:[function(require,module,exports){ -/** - * lodash 3.2.0 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var baseCopy = require('lodash._basecopy'), - keys = require('lodash.keys'); - -/** - * The base implementation of `_.assign` without support for argument juggling, - * multiple sources, and `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ -function baseAssign(object, source) { - return source == null - ? object - : baseCopy(source, keys(source), object); -} - -module.exports = baseAssign; - -},{"lodash._basecopy":56,"lodash.keys":63}],56:[function(require,module,exports){ -/** - * lodash 3.0.1 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ - -/** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property names to copy. - * @param {Object} [object={}] The object to copy properties to. - * @returns {Object} Returns `object`. - */ -function baseCopy(source, props, object) { - object || (object = {}); + }, - var index = -1, - length = props.length; + pushComponent: function(components, added, removed) { + var last = components[components.length - 1]; + if (last && last.added === added && last.removed === removed) { + // We need to clone here as the component clone operation is just + // as shallow array clone + components[components.length - 1] = {count: last.count + 1, added: added, removed: removed }; + } else { + components.push({count: 1, added: added, removed: removed }); + } + }, + extractCommon: function(basePath, newString, oldString, diagonalPath) { + var newLen = newString.length, + oldLen = oldString.length, + newPos = basePath.newPos, + oldPos = newPos - diagonalPath, - while (++index < length) { - var key = props[index]; - object[key] = source[key]; - } - return object; -} + commonCount = 0; + while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { + newPos++; + oldPos++; + commonCount++; + } -module.exports = baseCopy; + if (commonCount) { + basePath.components.push({count: commonCount}); + } -},{}],57:[function(require,module,exports){ -/** - * lodash 3.0.3 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ + basePath.newPos = newPos; + return oldPos; + }, -/** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ -var baseCreate = (function() { - function object() {} - return function(prototype) { - if (isObject(prototype)) { - object.prototype = prototype; - var result = new object; - object.prototype = undefined; + equals: function(left, right) { + var reWhitespace = /\S/; + return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)); + }, + tokenize: function(value) { + return value.split(''); } - return result || {}; }; -}()); - -/** - * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ -function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); -} - -module.exports = baseCreate; -},{}],58:[function(require,module,exports){ -/** - * lodash 3.9.1 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ - -/** `Object#toString` result references. */ -var funcTag = '[object Function]'; - -/** Used to detect host constructors (Safari > 5). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; + var CharDiff = new Diff(); -/** - * Checks if `value` is object-like. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - */ -function isObjectLike(value) { - return !!value && typeof value == 'object'; -} + var WordDiff = new Diff(true); + var WordWithSpaceDiff = new Diff(); + WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) { + return removeEmpty(value.split(/(\s+|\b)/)); + }; -/** Used for native method references. */ -var objectProto = Object.prototype; + var CssDiff = new Diff(true); + CssDiff.tokenize = function(value) { + return removeEmpty(value.split(/([{}:;,]|\s+)/)); + }; -/** Used to resolve the decompiled source of functions. */ -var fnToString = Function.prototype.toString; + var LineDiff = new Diff(); -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + var TrimmedLineDiff = new Diff(); + TrimmedLineDiff.ignoreTrim = true; -/** - * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) - * of values. - */ -var objToString = objectProto.toString; + LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) { + var retLines = [], + lines = value.split(/^/m); + for (var i = 0; i < lines.length; i++) { + var line = lines[i], + lastLine = lines[i - 1], + lastLineLastChar = lastLine && lastLine[lastLine.length - 1]; -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + // Merge lines that may contain windows new lines + if (line === '\n' && lastLineLastChar === '\r') { + retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\r\n'; + } else { + if (this.ignoreTrim) { + line = line.trim(); + // add a newline unless this is the last line. + if (i < lines.length - 1) { + line += '\n'; + } + } + retLines.push(line); + } + } -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = object == null ? undefined : object[key]; - return isNative(value) ? value : undefined; -} + return retLines; + }; -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in older versions of Chrome and Safari which return 'function' for regexes - // and Safari 8 equivalents which return 'object' for typed array constructors. - return isObject(value) && objToString.call(value) == funcTag; -} + var PatchDiff = new Diff(); + PatchDiff.tokenize = function(value) { + var ret = [], + linesAndNewlines = value.split(/(\n|\r\n)/); -/** - * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ -function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); -} + // Ignore the final empty token that occurs if the string ends with a new line + if (!linesAndNewlines[linesAndNewlines.length - 1]) { + linesAndNewlines.pop(); + } -/** - * Checks if `value` is a native function. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, else `false`. - * @example - * - * _.isNative(Array.prototype.push); - * // => true - * - * _.isNative(_); - * // => false - */ -function isNative(value) { - if (value == null) { - return false; - } - if (isFunction(value)) { - return reIsNative.test(fnToString.call(value)); - } - return isObjectLike(value) && reIsHostCtor.test(value); -} + // Merge the content and line separators into single tokens + for (var i = 0; i < linesAndNewlines.length; i++) { + var line = linesAndNewlines[i]; -module.exports = getNative; + if (i % 2) { + ret[ret.length - 1] += line; + } else { + ret.push(line); + } + } + return ret; + }; -},{}],59:[function(require,module,exports){ -/** - * lodash 3.0.9 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ + var SentenceDiff = new Diff(); + SentenceDiff.tokenize = function(value) { + return removeEmpty(value.split(/(\S.+?[.!?])(?=\s+|$)/)); + }; -/** Used to detect unsigned integer values. */ -var reIsUint = /^\d+$/; + var JsonDiff = new Diff(); + // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a + // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: + JsonDiff.useLongestToken = true; + JsonDiff.tokenize = LineDiff.tokenize; + JsonDiff.equals = function(left, right) { + return LineDiff.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')); + }; -/** - * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) - * of an array-like value. - */ -var MAX_SAFE_INTEGER = 9007199254740991; + var JsDiff = { + Diff: Diff, -/** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new function. - */ -function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; -} + diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); }, + diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); }, + diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); }, + diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); }, + diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); }, -/** - * Gets the "length" property value of `object`. - * - * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) - * that affects Safari on at least iOS 8.1-8.3 ARM64. - * - * @private - * @param {Object} object The object to query. - * @returns {*} Returns the "length" value. - */ -var getLength = baseProperty('length'); + diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); }, -/** - * Checks if `value` is array-like. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - */ -function isArrayLike(value) { - return value != null && isLength(getLength(value)); -} + diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); }, + diffJson: function(oldObj, newObj, callback) { + return JsonDiff.diff( + typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, ' '), + typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, ' '), + callback + ); + }, -/** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ -function isIndex(value, length) { - value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; - length = length == null ? MAX_SAFE_INTEGER : length; - return value > -1 && value % 1 == 0 && value < length; -} + createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) { + var ret = []; -/** - * Checks if the provided arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. - */ -function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object)) { - var other = object[index]; - return value === value ? (value === other) : (other !== other); - } - return false; -} + if (oldFileName == newFileName) { + ret.push('Index: ' + oldFileName); + } + ret.push('==================================================================='); + ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader)); + ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader)); -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - */ -function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} + var diff = PatchDiff.diff(oldStr, newStr); + diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier -/** - * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ -function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); -} + // Formats a given set of lines for printing as context lines in a patch + function contextLines(lines) { + return map(lines, function(entry) { return ' ' + entry; }); + } -module.exports = isIterateeCall; + // Outputs the no newline at end of file warning if needed + function eofNL(curRange, i, current) { + var last = diff[diff.length - 2], + isLast = i === diff.length - 2, + isLastOfType = i === diff.length - 3 && current.added !== last.added; -},{}],60:[function(require,module,exports){ -/** - * lodash 3.1.1 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var baseAssign = require('lodash._baseassign'), - baseCreate = require('lodash._basecreate'), - isIterateeCall = require('lodash._isiterateecall'); - -/** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { - * 'constructor': Circle - * }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ -function create(prototype, properties, guard) { - var result = baseCreate(prototype); - if (guard && isIterateeCall(prototype, properties, guard)) { - properties = undefined; - } - return properties ? baseAssign(result, properties) : result; -} + // Figure out if this is the last line for the given file and missing NL + if (!(/\n$/.test(current.value)) && (isLast || isLastOfType)) { + curRange.push('\\ No newline at end of file'); + } + } -module.exports = create; + var oldRangeStart = 0, newRangeStart = 0, curRange = [], + oldLine = 1, newLine = 1; + for (var i = 0; i < diff.length; i++) { + var current = diff[i], + lines = current.lines || current.value.replace(/\n$/, '').split('\n'); + current.lines = lines; -},{"lodash._baseassign":55,"lodash._basecreate":57,"lodash._isiterateecall":59}],61:[function(require,module,exports){ -/** - * lodash 3.0.8 (Custom Build) - * Build: `lodash modularize exports="npm" -o ./` - * Copyright 2012-2016 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ + if (current.added || current.removed) { + // If we have previous context, start with that + if (!oldRangeStart) { + var prev = diff[i - 1]; + oldRangeStart = oldLine; + newRangeStart = newLine; -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; + if (prev) { + curRange = contextLines(prev.lines.slice(-4)); + oldRangeStart -= curRange.length; + newRangeStart -= curRange.length; + } + } -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]'; + // Output our changes + curRange.push.apply(curRange, map(lines, function(entry) { + return (current.added ? '+' : '-') + entry; + })); + eofNL(curRange, i, current); -/** Used for built-in method references. */ -var objectProto = Object.prototype; + // Track the updated file position + if (current.added) { + newLine += lines.length; + } else { + oldLine += lines.length; + } + } else { + // Identical context lines. Track line changes + if (oldRangeStart) { + // Close out any changes that have been output (or join overlapping) + if (lines.length <= 8 && i < diff.length - 2) { + // Overlapping + curRange.push.apply(curRange, contextLines(lines)); + } else { + // end the range and output + var contextSize = Math.min(lines.length, 4); + ret.push( + '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize) + + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize) + + ' @@'); + ret.push.apply(ret, curRange); + ret.push.apply(ret, contextLines(lines.slice(0, contextSize))); + if (lines.length <= 4) { + eofNL(ret, i, current); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + oldRangeStart = 0; + newRangeStart = 0; + curRange = []; + } + } + oldLine += lines.length; + newLine += lines.length; + } + } -/** - * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) - * of values. - */ -var objectToString = objectProto.toString; + return ret.join('\n') + '\n'; + }, -/** Built-in value references. */ -var propertyIsEnumerable = objectProto.propertyIsEnumerable; + createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) { + return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader); + }, -/** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new function. - */ -function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; -} + applyPatch: function(oldStr, uniDiff) { + var diffstr = uniDiff.split('\n'), + hunks = [], + i = 0, + remEOFNL = false, + addEOFNL = false; -/** - * Gets the "length" property value of `object`. - * - * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) - * that affects Safari on at least iOS 8.1-8.3 ARM64. - * - * @private - * @param {Object} object The object to query. - * @returns {*} Returns the "length" value. - */ -var getLength = baseProperty('length'); + // Skip to the first change hunk + while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) { + i++; + } -/** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ -function isArguments(value) { - // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. - return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && - (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); -} + // Parse the unified diff + for (; i < diffstr.length; i++) { + if (diffstr[i][0] === '@') { + var chnukHeader = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/); + hunks.unshift({ + start: chnukHeader[3], + oldlength: +chnukHeader[2], + removed: [], + newlength: chnukHeader[4], + added: [] + }); + } else if (diffstr[i][0] === '+') { + hunks[0].added.push(diffstr[i].substr(1)); + } else if (diffstr[i][0] === '-') { + hunks[0].removed.push(diffstr[i].substr(1)); + } else if (diffstr[i][0] === ' ') { + hunks[0].added.push(diffstr[i].substr(1)); + hunks[0].removed.push(diffstr[i].substr(1)); + } else if (diffstr[i][0] === '\\') { + if (diffstr[i - 1][0] === '+') { + remEOFNL = true; + } else if (diffstr[i - 1][0] === '-') { + addEOFNL = true; + } + } + } -/** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ -function isArrayLike(value) { - return value != null && isLength(getLength(value)) && !isFunction(value); -} + // Apply the diff to the input + var lines = oldStr.split('\n'); + for (i = hunks.length - 1; i >= 0; i--) { + var hunk = hunks[i]; + // Sanity check the input string. Bail if we don't match. + for (var j = 0; j < hunk.oldlength; j++) { + if (lines[hunk.start - 1 + j] !== hunk.removed[j]) { + return false; + } + } + Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added)); + } -/** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ -function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); -} + // Handle EOFNL insertion/removal + if (remEOFNL) { + while (!lines[lines.length - 1]) { + lines.pop(); + } + } else if (addEOFNL) { + lines.push(''); + } + return lines.join('\n'); + }, -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 8 which returns 'object' for typed array and weak map constructors, - // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. - var tag = isObject(value) ? objectToString.call(value) : ''; - return tag == funcTag || tag == genTag; -} + convertChangesToXML: function(changes) { + var ret = []; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + if (change.added) { + ret.push(''); + } else if (change.removed) { + ret.push(''); + } -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ -function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} + ret.push(escapeHTML(change.value)); -/** - * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); -} + if (change.added) { + ret.push(''); + } else if (change.removed) { + ret.push(''); + } + } + return ret.join(''); + }, -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return !!value && typeof value == 'object'; -} + // See: http://code.google.com/p/google-diff-match-patch/wiki/API + convertChangesToDMP: function(changes) { + var ret = [], + change, + operation; + for (var i = 0; i < changes.length; i++) { + change = changes[i]; + if (change.added) { + operation = 1; + } else if (change.removed) { + operation = -1; + } else { + operation = 0; + } -module.exports = isArguments; + ret.push([operation, change.value]); + } + return ret; + }, -},{}],62:[function(require,module,exports){ -/** - * lodash 3.0.4 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ + canonicalize: canonicalize + }; -/** `Object#toString` result references. */ -var arrayTag = '[object Array]', - funcTag = '[object Function]'; + /*istanbul ignore next */ + /*global module */ + if (typeof module !== 'undefined' && module.exports) { + module.exports = JsDiff; + } else if (typeof define === 'function' && define.amd) { + /*global define */ + define([], function() { return JsDiff; }); + } else if (typeof global.JsDiff === 'undefined') { + global.JsDiff = JsDiff; + } +}(this)); -/** Used to detect host constructors (Safari > 5). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; +},{}],50:[function(require,module,exports){ +'use strict'; -/** - * Checks if `value` is object-like. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - */ -function isObjectLike(value) { - return !!value && typeof value == 'object'; -} +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; -/** Used for native method references. */ -var objectProto = Object.prototype; +module.exports = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } -/** Used to resolve the decompiled source of functions. */ -var fnToString = Function.prototype.toString; + return str.replace(matchOperatorsRe, '\\$&'); +}; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +},{}],51:[function(require,module,exports){ +(function (process){ +// Growl - Copyright TJ Holowaychuk (MIT Licensed) /** - * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) - * of values. + * Module dependencies. */ -var objToString = objectProto.toString; -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); - -/* Native method references for those with the same name as other `lodash` methods. */ -var nativeIsArray = getNative(Array, 'isArray'); +var exec = require('child_process').exec + , fs = require('fs') + , path = require('path') + , exists = fs.existsSync || path.existsSync + , os = require('os') + , quote = JSON.stringify + , cmd; -/** - * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) - * of an array-like value. - */ -var MAX_SAFE_INTEGER = 9007199254740991; +function which(name) { + var paths = process.env.PATH.split(':'); + var loc; -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = object == null ? undefined : object[key]; - return isNative(value) ? value : undefined; + for (var i = 0, len = paths.length; i < len; ++i) { + loc = path.join(paths[i], name); + if (exists(loc)) return loc; + } } -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - */ -function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +switch(os.type()) { + case 'Darwin': + if (which('terminal-notifier')) { + cmd = { + type: "Darwin-NotificationCenter" + , pkg: "terminal-notifier" + , msg: '-message' + , title: '-title' + , subtitle: '-subtitle' + , icon: '-appIcon' + , sound: '-sound' + , url: '-open' + , priority: { + cmd: '-execute' + , range: [] + } + }; + } else { + cmd = { + type: "Darwin-Growl" + , pkg: "growlnotify" + , msg: '-m' + , sticky: '--sticky' + , priority: { + cmd: '--priority' + , range: [ + -2 + , -1 + , 0 + , 1 + , 2 + , "Very Low" + , "Moderate" + , "Normal" + , "High" + , "Emergency" + ] + } + }; + } + break; + case 'Linux': + if (which('growl')) { + cmd = { + type: "Linux-Growl" + , pkg: "growl" + , msg: '-m' + , title: '-title' + , subtitle: '-subtitle' + , host: { + cmd: '-H' + , hostname: '192.168.33.1' + } + }; + } else { + cmd = { + type: "Linux" + , pkg: "notify-send" + , msg: '' + , sticky: '-t 0' + , icon: '-i' + , priority: { + cmd: '-u' + , range: [ + "low" + , "normal" + , "critical" + ] + } + }; + } + break; + case 'Windows_NT': + cmd = { + type: "Windows" + , pkg: "growlnotify" + , msg: '' + , sticky: '/s:true' + , title: '/t:' + , icon: '/i:' + , url: '/cu:' + , priority: { + cmd: '/p:' + , range: [ + -2 + , -1 + , 0 + , 1 + , 2 + ] + } + }; + break; } /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(function() { return arguments; }()); - * // => false + * Expose `growl`. */ -var isArray = nativeIsArray || function(value) { - return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; -}; + +exports = module.exports = growl; /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false + * Node-growl version. */ -function isFunction(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in older versions of Chrome and Safari which return 'function' for regexes - // and Safari 8 equivalents which return 'object' for typed array constructors. - return isObject(value) && objToString.call(value) == funcTag; -} + +exports.version = '1.4.1' /** - * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true + * Send growl notification _msg_ with _options_. * - * _.isObject([1, 2, 3]); - * // => true + * Options: * - * _.isObject(1); - * // => false - */ -function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); -} - -/** - * Checks if `value` is a native function. + * - title Notification title + * - sticky Make the notification stick (defaults to false) + * - priority Specify an int or named key (default is 0) + * - name Application name (defaults to growlnotify) + * - sound Sound efect ( in OSx defined in preferences -> sound -> effects) * works only in OSX > 10.8x + * - image + * - path to an icon sets --iconpath + * - path to an image sets --image + * - capitalized word sets --appIcon + * - filename uses extname as --icon + * - otherwise treated as --icon * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, else `false`. - * @example + * Examples: * - * _.isNative(Array.prototype.push); - * // => true + * growl('New email') + * growl('5 new emails', { title: 'Thunderbird' }) + * growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' }) + * growl('Email sent', function(){ + * // ... notification sent + * }) * - * _.isNative(_); - * // => false + * @param {string} msg + * @param {object} options + * @param {function} fn + * @api public */ -function isNative(value) { - if (value == null) { - return false; - } - if (isFunction(value)) { - return reIsNative.test(fnToString.call(value)); + +function growl(msg, options, fn) { + var image + , args + , options = options || {} + , fn = fn || function(){}; + + if (options.exec) { + cmd = { + type: "Custom" + , pkg: options.exec + , range: [] + }; } - return isObjectLike(value) && reIsHostCtor.test(value); -} -module.exports = isArray; + // noop + if (!cmd) return fn(new Error('growl not supported on this platform')); + args = [cmd.pkg]; -},{}],63:[function(require,module,exports){ -/** - * lodash 3.1.2 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var getNative = require('lodash._getnative'), - isArguments = require('lodash.isarguments'), - isArray = require('lodash.isarray'); + // image + if (image = options.image) { + switch(cmd.type) { + case 'Darwin-Growl': + var flag, ext = path.extname(image).substr(1) + flag = flag || ext == 'icns' && 'iconpath' + flag = flag || /^[A-Z]/.test(image) && 'appIcon' + flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image' + flag = flag || ext && (image = ext) && 'icon' + flag = flag || 'icon' + args.push('--' + flag, quote(image)) + break; + case 'Darwin-NotificationCenter': + args.push(cmd.icon, quote(image)); + break; + case 'Linux': + args.push(cmd.icon, quote(image)); + // libnotify defaults to sticky, set a hint for transient notifications + if (!options.sticky) args.push('--hint=int:transient:1'); + break; + case 'Windows': + args.push(cmd.icon + quote(image)); + break; + } + } -/** Used to detect unsigned integer values. */ -var reIsUint = /^\d+$/; + // sticky + if (options.sticky) args.push(cmd.sticky); -/** Used for native method references. */ -var objectProto = Object.prototype; + // priority + if (options.priority) { + var priority = options.priority + ''; + var checkindexOf = cmd.priority.range.indexOf(priority); + if (~cmd.priority.range.indexOf(priority)) { + args.push(cmd.priority, options.priority); + } + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + //sound + if(options.sound && cmd.type === 'Darwin-NotificationCenter'){ + args.push(cmd.sound, options.sound) + } -/* Native method references for those with the same name as other `lodash` methods. */ -var nativeKeys = getNative(Object, 'keys'); + // name + if (options.name && cmd.type === "Darwin-Growl") { + args.push('--name', options.name); + } -/** - * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) - * of an array-like value. - */ -var MAX_SAFE_INTEGER = 9007199254740991; + switch(cmd.type) { + case 'Darwin-Growl': + args.push(cmd.msg); + args.push(quote(msg).replace(/\\n/g, '\n')); + if (options.title) args.push(quote(options.title)); + break; + case 'Darwin-NotificationCenter': + args.push(cmd.msg); + var stringifiedMsg = quote(msg); + var escapedMsg = stringifiedMsg.replace(/\\n/g, '\n'); + args.push(escapedMsg); + if (options.title) { + args.push(cmd.title); + args.push(quote(options.title)); + } + if (options.subtitle) { + args.push(cmd.subtitle); + args.push(quote(options.subtitle)); + } + if (options.url) { + args.push(cmd.url); + args.push(quote(options.url)); + } + break; + case 'Linux-Growl': + args.push(cmd.msg); + args.push(quote(msg).replace(/\\n/g, '\n')); + if (options.title) args.push(quote(options.title)); + if (cmd.host) { + args.push(cmd.host.cmd, cmd.host.hostname) + } + break; + case 'Linux': + if (options.title) { + args.push(quote(options.title)); + args.push(cmd.msg); + args.push(quote(msg).replace(/\\n/g, '\n')); + } else { + args.push(quote(msg).replace(/\\n/g, '\n')); + } + break; + case 'Windows': + args.push(quote(msg).replace(/\\n/g, '\n')); + if (options.title) args.push(cmd.title + quote(options.title)); + if (options.url) args.push(cmd.url + quote(options.url)); + break; + case 'Custom': + args[0] = (function(origCommand) { + var message = options.title + ? options.title + ': ' + msg + : msg; + var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message)); + if (command === origCommand) args.push(quote(message)); + return command; + })(args[0]); + break; + } -/** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new function. - */ -function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; -} + // execute + exec(args.join(' '), fn); +}; -/** - * Gets the "length" property value of `object`. - * - * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) - * that affects Safari on at least iOS 8.1-8.3 ARM64. - * - * @private - * @param {Object} object The object to query. - * @returns {*} Returns the "length" value. - */ -var getLength = baseProperty('length'); +}).call(this,require('_process')) +},{"_process":59,"child_process":42,"fs":42,"os":57,"path":42}],52:[function(require,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] -/** - * Checks if `value` is array-like. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - */ -function isArrayLike(value) { - return value != null && isLength(getLength(value)); -} + i += d -/** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ -function isIndex(value, length) { - value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; - length = length == null ? MAX_SAFE_INTEGER : length; - return value > -1 && value % 1 == 0 && value < length; -} + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - */ -function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) } -/** - * A fallback implementation of `Object.keys` which creates an array of the - * own enumerable property names of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function shimKeys(object) { - var props = keysIn(object), - propsLength = props.length, - length = propsLength && object.length; +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 - var allowIndexes = !!length && isLength(length) && - (isArray(object) || isArguments(object)); + value = Math.abs(value) - var index = -1, - result = []; + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } - while (++index < propsLength) { - var key = props[index]; - if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { - result.push(key); + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 } } - return result; -} -/** - * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ -function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 } -/** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) - * for more details. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ -var keys = !nativeKeys ? shimKeys : function(object) { - var Ctor = object == null ? undefined : object.constructor; - if ((typeof Ctor == 'function' && Ctor.prototype === object) || - (typeof object != 'function' && isArrayLike(object))) { - return shimKeys(object); +},{}],53:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor } - return isObject(object) ? nativeKeys(object) : []; -}; +} +},{}],54:[function(require,module,exports){ /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } + * Determine if an object is Buffer * - * Foo.prototype.c = 3; + * Author: Feross Aboukhadijeh + * License: MIT * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + * `npm install is-buffer` */ -function keysIn(object) { - if (object == null) { - return []; - } - if (!isObject(object)) { - object = Object(object); - } - var length = object.length; - length = (length && isLength(length) && - (isArray(object) || isArguments(object)) && length) || 0; - var Ctor = object.constructor, - index = -1, - isProto = typeof Ctor == 'function' && Ctor.prototype === object, - result = Array(length), - skipIndexes = length > 0; - - while (++index < length) { - result[index] = (index + ''); - } - for (var key in object) { - if (!(skipIndexes && isIndex(key, length)) && - !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; +module.exports = function (obj) { + return !!(obj != null && + (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) + (obj.constructor && + typeof obj.constructor.isBuffer === 'function' && + obj.constructor.isBuffer(obj)) + )) } -module.exports = keys; +},{}],55:[function(require,module,exports){ +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; -},{"lodash._getnative":58,"lodash.isarguments":61,"lodash.isarray":62}],64:[function(require,module,exports){ +},{}],56:[function(require,module,exports){ (function (process){ var path = require('path'); var fs = require('fs'); @@ -12127,18 +10387,18 @@ function mkdirP (p, opts, f, made) { else if (!opts || typeof opts !== 'object') { opts = { mode: opts }; } - + var mode = opts.mode; var xfs = opts.fs || fs; - + if (mode === undefined) { mode = _0777 & (~process.umask()); } if (!made) made = null; - + var cb = f || function () {}; p = path.resolve(p); - + xfs.mkdir(p, mode, function (er) { if (!er) { made = made || p; @@ -12171,10 +10431,10 @@ mkdirP.sync = function sync (p, opts, made) { if (!opts || typeof opts !== 'object') { opts = { mode: opts }; } - + var mode = opts.mode; var xfs = opts.fs || fs; - + if (mode === undefined) { mode = _0777 & (~process.umask()); } @@ -12213,7 +10473,7 @@ mkdirP.sync = function sync (p, opts, made) { }; }).call(this,require('_process')) -},{"_process":67,"fs":42,"path":42}],65:[function(require,module,exports){ +},{"_process":59,"fs":42,"path":42}],57:[function(require,module,exports){ exports.endianness = function () { return 'LE' }; exports.hostname = function () { @@ -12260,7 +10520,7 @@ exports.tmpdir = exports.tmpDir = function () { exports.EOL = '\n'; -},{}],66:[function(require,module,exports){ +},{}],58:[function(require,module,exports){ (function (process){ 'use strict'; @@ -12307,35 +10567,15 @@ function nextTick(fn, arg1, arg2, arg3) { } }).call(this,require('_process')) -},{"_process":67}],67:[function(require,module,exports){ +},{"_process":59}],59:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; +// cached from whatever global is present so that test runners that stub it don't break things. +var cachedSetTimeout = setTimeout; +var cachedClearTimeout = clearTimeout; -(function () { - try { - cachedSetTimeout = setTimeout; - } catch (e) { - cachedSetTimeout = function () { - throw new Error('setTimeout is not defined'); - } - } - try { - cachedClearTimeout = clearTimeout; - } catch (e) { - cachedClearTimeout = function () { - throw new Error('clearTimeout is not defined'); - } - } -} ()) var queue = []; var draining = false; var currentQueue; @@ -12375,63 +10615,780 @@ function drainQueue() { queueIndex = -1; len = queue.length; } - currentQueue = null; - draining = false; - cachedClearTimeout(timeout); -} + currentQueue = null; + draining = false; + cachedClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + cachedSetTimeout(drainQueue, 0); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +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'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],60:[function(require,module,exports){ +/*jshint eqnull:true*/ +(function (root) { + "use strict"; + + var GLOBAL_KEY = "Random"; + + var imul = (typeof Math.imul !== "function" || Math.imul(0xffffffff, 5) !== -5 ? + function (a, b) { + var ah = (a >>> 16) & 0xffff; + var al = a & 0xffff; + var bh = (b >>> 16) & 0xffff; + var bl = b & 0xffff; + // the shift by 0 fixes the sign on the high part + // the final |0 converts the unsigned value into a signed value + return (al * bl) + (((ah * bl + al * bh) << 16) >>> 0) | 0; + } : + Math.imul); + + var stringRepeat = (typeof String.prototype.repeat === "function" && "x".repeat(3) === "xxx" ? + function (x, y) { + return x.repeat(y); + } : function (pattern, count) { + var result = ""; + while (count > 0) { + if (count & 1) { + result += pattern; + } + count >>= 1; + pattern += pattern; + } + return result; + }); + + function Random(engine) { + if (!(this instanceof Random)) { + return new Random(engine); + } + + if (engine == null) { + engine = Random.engines.nativeMath; + } else if (typeof engine !== "function") { + throw new TypeError("Expected engine to be a function, got " + typeof engine); + } + this.engine = engine; + } + var proto = Random.prototype; + + Random.engines = { + nativeMath: function () { + return (Math.random() * 0x100000000) | 0; + }, + mt19937: (function (Int32Array) { + // http://en.wikipedia.org/wiki/Mersenne_twister + function refreshData(data) { + var k = 0; + var tmp = 0; + for (; + (k | 0) < 227; k = (k + 1) | 0) { + tmp = (data[k] & 0x80000000) | (data[(k + 1) | 0] & 0x7fffffff); + data[k] = data[(k + 397) | 0] ^ (tmp >>> 1) ^ ((tmp & 0x1) ? 0x9908b0df : 0); + } + + for (; + (k | 0) < 623; k = (k + 1) | 0) { + tmp = (data[k] & 0x80000000) | (data[(k + 1) | 0] & 0x7fffffff); + data[k] = data[(k - 227) | 0] ^ (tmp >>> 1) ^ ((tmp & 0x1) ? 0x9908b0df : 0); + } + + tmp = (data[623] & 0x80000000) | (data[0] & 0x7fffffff); + data[623] = data[396] ^ (tmp >>> 1) ^ ((tmp & 0x1) ? 0x9908b0df : 0); + } + + function temper(value) { + value ^= value >>> 11; + value ^= (value << 7) & 0x9d2c5680; + value ^= (value << 15) & 0xefc60000; + return value ^ (value >>> 18); + } + + function seedWithArray(data, source) { + var i = 1; + var j = 0; + var sourceLength = source.length; + var k = Math.max(sourceLength, 624) | 0; + var previous = data[0] | 0; + for (; + (k | 0) > 0; --k) { + data[i] = previous = ((data[i] ^ imul((previous ^ (previous >>> 30)), 0x0019660d)) + (source[j] | 0) + (j | 0)) | 0; + i = (i + 1) | 0; + ++j; + if ((i | 0) > 623) { + data[0] = data[623]; + i = 1; + } + if (j >= sourceLength) { + j = 0; + } + } + for (k = 623; + (k | 0) > 0; --k) { + data[i] = previous = ((data[i] ^ imul((previous ^ (previous >>> 30)), 0x5d588b65)) - i) | 0; + i = (i + 1) | 0; + if ((i | 0) > 623) { + data[0] = data[623]; + i = 1; + } + } + data[0] = 0x80000000; + } + + function mt19937() { + var data = new Int32Array(624); + var index = 0; + var uses = 0; + + function next() { + if ((index | 0) >= 624) { + refreshData(data); + index = 0; + } + + var value = data[index]; + index = (index + 1) | 0; + uses += 1; + return temper(value) | 0; + } + next.getUseCount = function() { + return uses; + }; + next.discard = function (count) { + uses += count; + if ((index | 0) >= 624) { + refreshData(data); + index = 0; + } + while ((count - index) > 624) { + count -= 624 - index; + refreshData(data); + index = 0; + } + index = (index + count) | 0; + return next; + }; + next.seed = function (initial) { + var previous = 0; + data[0] = previous = initial | 0; + + for (var i = 1; i < 624; i = (i + 1) | 0) { + data[i] = previous = (imul((previous ^ (previous >>> 30)), 0x6c078965) + i) | 0; + } + index = 624; + uses = 0; + return next; + }; + next.seedWithArray = function (source) { + next.seed(0x012bd6aa); + seedWithArray(data, source); + return next; + }; + next.autoSeed = function () { + return next.seedWithArray(Random.generateEntropyArray()); + }; + return next; + } + + return mt19937; + }(typeof Int32Array === "function" ? Int32Array : Array)), + browserCrypto: (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function" && typeof Int32Array === "function") ? (function () { + var data = null; + var index = 128; + + return function () { + if (index >= 128) { + if (data === null) { + data = new Int32Array(128); + } + crypto.getRandomValues(data); + index = 0; + } + + return data[index++] | 0; + }; + }()) : null + }; + + Random.generateEntropyArray = function () { + var array = []; + var engine = Random.engines.nativeMath; + for (var i = 0; i < 16; ++i) { + array[i] = engine() | 0; + } + array.push(new Date().getTime() | 0); + return array; + }; + + function returnValue(value) { + return function () { + return value; + }; + } + + // [-0x80000000, 0x7fffffff] + Random.int32 = function (engine) { + return engine() | 0; + }; + proto.int32 = function () { + return Random.int32(this.engine); + }; + + // [0, 0xffffffff] + Random.uint32 = function (engine) { + return engine() >>> 0; + }; + proto.uint32 = function () { + return Random.uint32(this.engine); + }; + + // [0, 0x1fffffffffffff] + Random.uint53 = function (engine) { + var high = engine() & 0x1fffff; + var low = engine() >>> 0; + return (high * 0x100000000) + low; + }; + proto.uint53 = function () { + return Random.uint53(this.engine); + }; + + // [0, 0x20000000000000] + Random.uint53Full = function (engine) { + while (true) { + var high = engine() | 0; + if (high & 0x200000) { + if ((high & 0x3fffff) === 0x200000 && (engine() | 0) === 0) { + return 0x20000000000000; + } + } else { + var low = engine() >>> 0; + return ((high & 0x1fffff) * 0x100000000) + low; + } + } + }; + proto.uint53Full = function () { + return Random.uint53Full(this.engine); + }; + + // [-0x20000000000000, 0x1fffffffffffff] + Random.int53 = function (engine) { + var high = engine() | 0; + var low = engine() >>> 0; + return ((high & 0x1fffff) * 0x100000000) + low + (high & 0x200000 ? -0x20000000000000 : 0); + }; + proto.int53 = function () { + return Random.int53(this.engine); + }; + + // [-0x20000000000000, 0x20000000000000] + Random.int53Full = function (engine) { + while (true) { + var high = engine() | 0; + if (high & 0x400000) { + if ((high & 0x7fffff) === 0x400000 && (engine() | 0) === 0) { + return 0x20000000000000; + } + } else { + var low = engine() >>> 0; + return ((high & 0x1fffff) * 0x100000000) + low + (high & 0x200000 ? -0x20000000000000 : 0); + } + } + }; + proto.int53Full = function () { + return Random.int53Full(this.engine); + }; + + function add(generate, addend) { + if (addend === 0) { + return generate; + } else { + return function (engine) { + return generate(engine) + addend; + }; + } + } + + Random.integer = (function () { + function isPowerOfTwoMinusOne(value) { + return ((value + 1) & value) === 0; + } + + function bitmask(masking) { + return function (engine) { + return engine() & masking; + }; + } + + function downscaleToLoopCheckedRange(range) { + var extendedRange = range + 1; + var maximum = extendedRange * Math.floor(0x100000000 / extendedRange); + return function (engine) { + var value = 0; + do { + value = engine() >>> 0; + } while (value >= maximum); + return value % extendedRange; + }; + } + + function downscaleToRange(range) { + if (isPowerOfTwoMinusOne(range)) { + return bitmask(range); + } else { + return downscaleToLoopCheckedRange(range); + } + } + + function isEvenlyDivisibleByMaxInt32(value) { + return (value | 0) === 0; + } + + function upscaleWithHighMasking(masking) { + return function (engine) { + var high = engine() & masking; + var low = engine() >>> 0; + return (high * 0x100000000) + low; + }; + } + + function upscaleToLoopCheckedRange(extendedRange) { + var maximum = extendedRange * Math.floor(0x20000000000000 / extendedRange); + return function (engine) { + var ret = 0; + do { + var high = engine() & 0x1fffff; + var low = engine() >>> 0; + ret = (high * 0x100000000) + low; + } while (ret >= maximum); + return ret % extendedRange; + }; + } + + function upscaleWithinU53(range) { + var extendedRange = range + 1; + if (isEvenlyDivisibleByMaxInt32(extendedRange)) { + var highRange = ((extendedRange / 0x100000000) | 0) - 1; + if (isPowerOfTwoMinusOne(highRange)) { + return upscaleWithHighMasking(highRange); + } + } + return upscaleToLoopCheckedRange(extendedRange); + } + + function upscaleWithinI53AndLoopCheck(min, max) { + return function (engine) { + var ret = 0; + do { + var high = engine() | 0; + var low = engine() >>> 0; + ret = ((high & 0x1fffff) * 0x100000000) + low + (high & 0x200000 ? -0x20000000000000 : 0); + } while (ret < min || ret > max); + return ret; + }; + } + + return function (min, max) { + min = Math.floor(min); + max = Math.floor(max); + if (min < -0x20000000000000 || !isFinite(min)) { + throw new RangeError("Expected min to be at least " + (-0x20000000000000)); + } else if (max > 0x20000000000000 || !isFinite(max)) { + throw new RangeError("Expected max to be at most " + 0x20000000000000); + } + + var range = max - min; + if (range <= 0 || !isFinite(range)) { + return returnValue(min); + } else if (range === 0xffffffff) { + if (min === 0) { + return Random.uint32; + } else { + return add(Random.int32, min + 0x80000000); + } + } else if (range < 0xffffffff) { + return add(downscaleToRange(range), min); + } else if (range === 0x1fffffffffffff) { + return add(Random.uint53, min); + } else if (range < 0x1fffffffffffff) { + return add(upscaleWithinU53(range), min); + } else if (max - 1 - min === 0x1fffffffffffff) { + return add(Random.uint53Full, min); + } else if (min === -0x20000000000000 && max === 0x20000000000000) { + return Random.int53Full; + } else if (min === -0x20000000000000 && max === 0x1fffffffffffff) { + return Random.int53; + } else if (min === -0x1fffffffffffff && max === 0x20000000000000) { + return add(Random.int53, 1); + } else if (max === 0x20000000000000) { + return add(upscaleWithinI53AndLoopCheck(min - 1, max - 1), 1); + } else { + return upscaleWithinI53AndLoopCheck(min, max); + } + }; + }()); + proto.integer = function (min, max) { + return Random.integer(min, max)(this.engine); + }; + + // [0, 1] (floating point) + Random.realZeroToOneInclusive = function (engine) { + return Random.uint53Full(engine) / 0x20000000000000; + }; + proto.realZeroToOneInclusive = function () { + return Random.realZeroToOneInclusive(this.engine); + }; + + // [0, 1) (floating point) + Random.realZeroToOneExclusive = function (engine) { + return Random.uint53(engine) / 0x20000000000000; + }; + proto.realZeroToOneExclusive = function () { + return Random.realZeroToOneExclusive(this.engine); + }; + + Random.real = (function () { + function multiply(generate, multiplier) { + if (multiplier === 1) { + return generate; + } else if (multiplier === 0) { + return function () { + return 0; + }; + } else { + return function (engine) { + return generate(engine) * multiplier; + }; + } + } + + return function (left, right, inclusive) { + if (!isFinite(left)) { + throw new RangeError("Expected left to be a finite number"); + } else if (!isFinite(right)) { + throw new RangeError("Expected right to be a finite number"); + } + return add( + multiply( + inclusive ? Random.realZeroToOneInclusive : Random.realZeroToOneExclusive, + right - left), + left); + }; + }()); + proto.real = function (min, max, inclusive) { + return Random.real(min, max, inclusive)(this.engine); + }; + + Random.bool = (function () { + function isLeastBitTrue(engine) { + return (engine() & 1) === 1; + } + + function lessThan(generate, value) { + return function (engine) { + return generate(engine) < value; + }; + } + + function probability(percentage) { + if (percentage <= 0) { + return returnValue(false); + } else if (percentage >= 1) { + return returnValue(true); + } else { + var scaled = percentage * 0x100000000; + if (scaled % 1 === 0) { + return lessThan(Random.int32, (scaled - 0x80000000) | 0); + } else { + return lessThan(Random.uint53, Math.round(percentage * 0x20000000000000)); + } + } + } + + return function (numerator, denominator) { + if (denominator == null) { + if (numerator == null) { + return isLeastBitTrue; + } + return probability(numerator); + } else { + if (numerator <= 0) { + return returnValue(false); + } else if (numerator >= denominator) { + return returnValue(true); + } + return lessThan(Random.integer(0, denominator - 1), numerator); + } + }; + }()); + proto.bool = function (numerator, denominator) { + return Random.bool(numerator, denominator)(this.engine); + }; + + function toInteger(value) { + var number = +value; + if (number < 0) { + return Math.ceil(number); + } else { + return Math.floor(number); + } + } + + function convertSliceArgument(value, length) { + if (value < 0) { + return Math.max(value + length, 0); + } else { + return Math.min(value, length); + } + } + Random.pick = function (engine, array, begin, end) { + var length = array.length; + var start = begin == null ? 0 : convertSliceArgument(toInteger(begin), length); + var finish = end === void 0 ? length : convertSliceArgument(toInteger(end), length); + if (start >= finish) { + return void 0; + } + var distribution = Random.integer(start, finish - 1); + return array[distribution(engine)]; + }; + proto.pick = function (array, begin, end) { + return Random.pick(this.engine, array, begin, end); + }; + + function returnUndefined() { + return void 0; + } + var slice = Array.prototype.slice; + Random.picker = function (array, begin, end) { + var clone = slice.call(array, begin, end); + if (!clone.length) { + return returnUndefined; + } + var distribution = Random.integer(0, clone.length - 1); + return function (engine) { + return clone[distribution(engine)]; + }; + }; -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; + Random.shuffle = function (engine, array, downTo) { + var length = array.length; + if (length) { + if (downTo == null) { + downTo = 0; + } + for (var i = (length - 1) >>> 0; i > downTo; --i) { + var distribution = Random.integer(0, i); + var j = distribution(engine); + if (i !== j) { + var tmp = array[i]; + array[i] = array[j]; + array[j] = tmp; } + } } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - cachedSetTimeout(drainQueue, 0); + return array; + }; + proto.shuffle = function (array) { + return Random.shuffle(this.engine, array); + }; + + Random.sample = function (engine, population, sampleSize) { + if (sampleSize < 0 || sampleSize > population.length || !isFinite(sampleSize)) { + throw new RangeError("Expected sampleSize to be within 0 and the length of the population"); } -}; -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; + if (sampleSize === 0) { + return []; + } -function noop() {} + var clone = slice.call(population); + var length = clone.length; + if (length === sampleSize) { + return Random.shuffle(engine, clone, 0); + } + var tailLength = length - sampleSize; + return Random.shuffle(engine, clone, tailLength - 1).slice(tailLength); + }; + proto.sample = function (population, sampleSize) { + return Random.sample(this.engine, population, sampleSize); + }; -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; + Random.die = function (sideCount) { + return Random.integer(1, sideCount); + }; + proto.die = function (sideCount) { + return Random.die(sideCount)(this.engine); + }; -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; + Random.dice = function (sideCount, dieCount) { + var distribution = Random.die(sideCount); + return function (engine) { + var result = []; + result.length = dieCount; + for (var i = 0; i < dieCount; ++i) { + result[i] = distribution(engine); + } + return result; + }; + }; + proto.dice = function (sideCount, dieCount) { + return Random.dice(sideCount, dieCount)(this.engine); + }; -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; + // http://en.wikipedia.org/wiki/Universally_unique_identifier + Random.uuid4 = (function () { + function zeroPad(string, zeroCount) { + return stringRepeat("0", zeroCount - string.length) + string; + } + + return function (engine) { + var a = engine() >>> 0; + var b = engine() | 0; + var c = engine() | 0; + var d = engine() >>> 0; + + return ( + zeroPad(a.toString(16), 8) + + "-" + + zeroPad((b & 0xffff).toString(16), 4) + + "-" + + zeroPad((((b >> 4) & 0x0fff) | 0x4000).toString(16), 4) + + "-" + + zeroPad(((c & 0x3fff) | 0x8000).toString(16), 4) + + "-" + + zeroPad(((c >> 4) & 0xffff).toString(16), 4) + + zeroPad(d.toString(16), 8)); + }; + }()); + proto.uuid4 = function () { + return Random.uuid4(this.engine); + }; + + Random.string = (function () { + // has 2**x chars, for faster uniform distribution + var DEFAULT_STRING_POOL = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"; + + return function (pool) { + if (pool == null) { + pool = DEFAULT_STRING_POOL; + } + + var length = pool.length; + if (!length) { + throw new Error("Expected pool not to be an empty string"); + } + + var distribution = Random.integer(0, length - 1); + return function (engine, length) { + var result = ""; + for (var i = 0; i < length; ++i) { + var j = distribution(engine); + result += pool.charAt(j); + } + return result; + }; + }; + }()); + proto.string = function (length, pool) { + return Random.string(pool)(this.engine, length); + }; + + Random.hex = (function () { + var LOWER_HEX_POOL = "0123456789abcdef"; + var lowerHex = Random.string(LOWER_HEX_POOL); + var upperHex = Random.string(LOWER_HEX_POOL.toUpperCase()); + + return function (upper) { + if (upper) { + return upperHex; + } else { + return lowerHex; + } + }; + }()); + proto.hex = function (length, upper) { + return Random.hex(upper)(this.engine, length); + }; + + Random.date = function (start, end) { + if (!(start instanceof Date)) { + throw new TypeError("Expected start to be a Date, got " + typeof start); + } else if (!(end instanceof Date)) { + throw new TypeError("Expected end to be a Date, got " + typeof end); + } + var distribution = Random.integer(start.getTime(), end.getTime()); + return function (engine) { + return new Date(distribution(engine)); + }; + }; + proto.date = function (start, end) { + return Random.date(start, end)(this.engine); + }; -},{}],68:[function(require,module,exports){ + if (typeof define === "function" && define.amd) { + define(function () { + return Random; + }); + } else if (typeof module !== "undefined" && typeof require === "function") { + module.exports = Random; + } else { + (function () { + var oldGlobal = root[GLOBAL_KEY]; + Random.noConflict = function () { + root[GLOBAL_KEY] = oldGlobal; + return this; + }; + }()); + root[GLOBAL_KEY] = Random; + } +}(this)); +},{}],61:[function(require,module,exports){ module.exports = require("./lib/_stream_duplex.js") -},{"./lib/_stream_duplex.js":69}],69:[function(require,module,exports){ +},{"./lib/_stream_duplex.js":62}],62:[function(require,module,exports){ // a duplex stream is just a stream that is both readable and writable. // Since JS doesn't have multiple prototypal inheritance, this class // prototypally inherits from Readable, and then parasitically from @@ -12507,7 +11464,7 @@ function forEach(xs, f) { f(xs[i], i); } } -},{"./_stream_readable":71,"./_stream_writable":73,"core-util-is":45,"inherits":51,"process-nextick-args":66}],70:[function(require,module,exports){ +},{"./_stream_readable":64,"./_stream_writable":66,"core-util-is":48,"inherits":53,"process-nextick-args":58}],63:[function(require,module,exports){ // a passthrough stream. // basically just the most minimal sort of Transform stream. // Every written chunk gets output as-is. @@ -12534,7 +11491,7 @@ function PassThrough(options) { PassThrough.prototype._transform = function (chunk, encoding, cb) { cb(null, chunk); }; -},{"./_stream_transform":72,"core-util-is":45,"inherits":51}],71:[function(require,module,exports){ +},{"./_stream_transform":65,"core-util-is":48,"inherits":53}],64:[function(require,module,exports){ (function (process){ 'use strict'; @@ -13430,7 +12387,7 @@ function indexOf(xs, x) { return -1; } }).call(this,require('_process')) -},{"./_stream_duplex":69,"_process":67,"buffer":44,"buffer-shims":43,"core-util-is":45,"events":48,"inherits":51,"isarray":53,"process-nextick-args":66,"string_decoder/":79,"util":40}],72:[function(require,module,exports){ +},{"./_stream_duplex":62,"_process":59,"buffer":43,"buffer-shims":47,"core-util-is":48,"events":45,"inherits":53,"isarray":55,"process-nextick-args":58,"string_decoder/":71,"util":40}],65:[function(require,module,exports){ // a transform stream is a readable/writable stream where you do // something with the data. Sometimes it's called a "filter", // but that's not a great name for it, since that implies a thing where @@ -13611,7 +12568,7 @@ function done(stream, er) { return stream.push(null); } -},{"./_stream_duplex":69,"core-util-is":45,"inherits":51}],73:[function(require,module,exports){ +},{"./_stream_duplex":62,"core-util-is":48,"inherits":53}],66:[function(require,module,exports){ (function (process){ // A bit simpler than readable streams. // Implement an async ._write(chunk, encoding, cb), and it'll handle all @@ -14140,10 +13097,10 @@ function CorkedRequest(state) { }; } }).call(this,require('_process')) -},{"./_stream_duplex":69,"_process":67,"buffer":44,"buffer-shims":43,"core-util-is":45,"events":48,"inherits":51,"process-nextick-args":66,"util-deprecate":80}],74:[function(require,module,exports){ +},{"./_stream_duplex":62,"_process":59,"buffer":43,"buffer-shims":47,"core-util-is":48,"events":45,"inherits":53,"process-nextick-args":58,"util-deprecate":73}],67:[function(require,module,exports){ module.exports = require("./lib/_stream_passthrough.js") -},{"./lib/_stream_passthrough.js":70}],75:[function(require,module,exports){ +},{"./lib/_stream_passthrough.js":63}],68:[function(require,module,exports){ (function (process){ var Stream = (function (){ try { @@ -14163,142 +13120,13 @@ if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) { } }).call(this,require('_process')) -},{"./lib/_stream_duplex.js":69,"./lib/_stream_passthrough.js":70,"./lib/_stream_readable.js":71,"./lib/_stream_transform.js":72,"./lib/_stream_writable.js":73,"_process":67}],76:[function(require,module,exports){ +},{"./lib/_stream_duplex.js":62,"./lib/_stream_passthrough.js":63,"./lib/_stream_readable.js":64,"./lib/_stream_transform.js":65,"./lib/_stream_writable.js":66,"_process":59}],69:[function(require,module,exports){ module.exports = require("./lib/_stream_transform.js") -},{"./lib/_stream_transform.js":72}],77:[function(require,module,exports){ +},{"./lib/_stream_transform.js":65}],70:[function(require,module,exports){ module.exports = require("./lib/_stream_writable.js") -},{"./lib/_stream_writable.js":73}],78:[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. - -module.exports = Stream; - -var EE = require('events').EventEmitter; -var inherits = require('inherits'); - -inherits(Stream, EE); -Stream.Readable = require('readable-stream/readable.js'); -Stream.Writable = require('readable-stream/writable.js'); -Stream.Duplex = require('readable-stream/duplex.js'); -Stream.Transform = require('readable-stream/transform.js'); -Stream.PassThrough = require('readable-stream/passthrough.js'); - -// Backwards-compat with node 0.4.x -Stream.Stream = Stream; - - - -// old-style streams. Note that the pipe method (the only relevant -// part of this class) is overridden in the Readable class. - -function Stream() { - EE.call(this); -} - -Stream.prototype.pipe = function(dest, options) { - var source = this; - - function ondata(chunk) { - if (dest.writable) { - if (false === dest.write(chunk) && source.pause) { - source.pause(); - } - } - } - - source.on('data', ondata); - - function ondrain() { - if (source.readable && source.resume) { - source.resume(); - } - } - - dest.on('drain', ondrain); - - // If the 'end' option is not supplied, dest.end() will be called when - // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { - source.on('end', onend); - source.on('close', onclose); - } - - var didOnEnd = false; - function onend() { - if (didOnEnd) return; - didOnEnd = true; - - dest.end(); - } - - - function onclose() { - if (didOnEnd) return; - didOnEnd = true; - - if (typeof dest.destroy === 'function') dest.destroy(); - } - - // don't leave dangling pipes when there are errors. - function onerror(er) { - cleanup(); - if (EE.listenerCount(this, 'error') === 0) { - throw er; // Unhandled stream error in pipe. - } - } - - source.on('error', onerror); - dest.on('error', onerror); - - // remove all the event listeners that were added. - function cleanup() { - source.removeListener('data', ondata); - dest.removeListener('drain', ondrain); - - source.removeListener('end', onend); - source.removeListener('close', onclose); - - source.removeListener('error', onerror); - dest.removeListener('error', onerror); - - source.removeListener('end', cleanup); - source.removeListener('close', cleanup); - - dest.removeListener('close', cleanup); - } - - source.on('end', cleanup); - source.on('close', cleanup); - - dest.on('close', cleanup); - - dest.emit('pipe', source); - - // Allow for unix-like usage: A.pipe(B).pipe(C) - return dest; -}; - -},{"events":48,"inherits":51,"readable-stream/duplex.js":68,"readable-stream/passthrough.js":74,"readable-stream/readable.js":75,"readable-stream/transform.js":76,"readable-stream/writable.js":77}],79:[function(require,module,exports){ +},{"./lib/_stream_writable.js":66}],71:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -14521,7 +13349,48 @@ function base64DetectIncompleteChar(buffer) { this.charLength = this.charReceived ? 3 : 0; } -},{"buffer":44}],80:[function(require,module,exports){ +},{"buffer":43}],72:[function(require,module,exports){ + +/** + * Expose `toIsoString`. + */ + +module.exports = toIsoString; + + +/** + * Turn a `date` into an ISO string. + * + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString + * + * @param {Date} date + * @return {String} + */ + +function toIsoString (date) { + return date.getUTCFullYear() + + '-' + pad(date.getUTCMonth() + 1) + + '-' + pad(date.getUTCDate()) + + 'T' + pad(date.getUTCHours()) + + ':' + pad(date.getUTCMinutes()) + + ':' + pad(date.getUTCSeconds()) + + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5) + + 'Z'; +} + + +/** + * Pad a `number` with a ten's place zero. + * + * @param {Number} number + * @return {String} + */ + +function pad (number) { + var n = number.toString(); + return n.length === 1 ? '0' + n : n; +} +},{}],73:[function(require,module,exports){ (function (global){ /** @@ -14592,14 +13461,14 @@ function config (name) { } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],81:[function(require,module,exports){ +},{}],74:[function(require,module,exports){ module.exports = function isBuffer(arg) { return arg && typeof arg === 'object' && typeof arg.copy === 'function' && typeof arg.fill === 'function' && typeof arg.readUInt8 === 'function'; } -},{}],82:[function(require,module,exports){ +},{}],75:[function(require,module,exports){ (function (process,global){ // Copyright Joyent, Inc. and other Node contributors. // @@ -15189,4 +14058,4 @@ function hasOwnProperty(obj, prop) { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":81,"_process":67,"inherits":51}]},{},[1]); +},{"./support/isBuffer":74,"_process":59,"inherits":53}]},{},[1]); diff --git a/package.json b/package.json index 5a069ba02d..31bda41a92 100644 --- a/package.json +++ b/package.json @@ -311,6 +311,7 @@ "json3": "3.3.2", "lodash.create": "3.1.1", "mkdirp": "0.5.1", + "random-js": "1.0.8", "supports-color": "3.1.2" }, "devDependencies": { diff --git a/test/acceptance/random.spec.js b/test/acceptance/random.spec.js new file mode 100644 index 0000000000..4d22f76731 --- /dev/null +++ b/test/acceptance/random.spec.js @@ -0,0 +1,85 @@ +'use strict'; + +var mocha = require('../..'); +// yuk +var Mocha = mocha.Mocha || mocha; +var utils = require('../../lib/utils'); + +describe('random option', function() { + describe('seed', function() { + it('should return a hex string', function() { + expect(Mocha.seed()) + .to + .match(/^0x[0-9A-F]+/); + }); + + it('should be a valid seed', function() { + expect(utils.toSafeUnsignedInteger(Mocha.seed())).to.be.a('number'); + }); + + it('should return a finite number', function() { + expect(Mocha.seed()) + .not + .to + .equal(Infinity); + }); + }); + + describe('when Mocha is instantiated with "random" option', function() { + var mocha; + + describe('and that option is "false"', function() { + beforeEach(function() { + mocha = new Mocha({ random: false }); + }); + + it('should not populate the "randomConfig" option', function() { + expect(mocha.options.randomConfig).to.be(undefined); + }); + }); + + describe('and that option is undefined', function() { + it('should not populate the "randomConfig" option', function() { + expect(mocha.options.randomConfig).to.be(undefined); + }); + }); + + describe('and that option is not an integer or convertable string', function() { + it('should throw', function() { + expect(function() { + new Mocha({random: true}); + }) + .to + .throwException(Error); + }); + }); + + describe('and that option is a valid seed', function() { + var seed; + + beforeEach(function() { + seed = '0xDEADBEEF'; + mocha = new Mocha({ random: seed }); + }); + + describe('randomConfig', function() { + it('should be defined', function() { + expect(mocha.options.randomConfig).not.to.be(undefined); + }); + + it('should define a "seed" prop', function() { + expect(mocha.options.randomConfig.seed).to.equal(0xDEADBEEF); + }); + + it('should define a hexadecimal representation in the "hex" prop', function() { + expect(mocha.options.randomConfig.hex).to.equal(seed); + }); + + it('should define a function to shuffle tests in the "shuffleTests" prop', function() { + expect(mocha.options.randomConfig.shuffleTests).to.be.a('function'); + }); + }); + + }); + }); +}); diff --git a/test/hook-async.spec.js b/test/hook-async.spec.js index ae6e642d24..0e2a615c1a 100644 --- a/test/hook-async.spec.js +++ b/test/hook-async.spec.js @@ -1,4 +1,4 @@ -describe('async', function(){ +describe.inOrder('async', function(){ var calls = []; before(function(){ @@ -43,7 +43,7 @@ describe('async', function(){ calls.push('parent after' ); }) - describe('hooks', function(){ + describe.inOrder('hooks', function(){ before(function(){ calls.push('before all'); }); diff --git a/test/hook-sync-nested.spec.js b/test/hook-sync-nested.spec.js index b87c22298f..c4c69d8d51 100644 --- a/test/hook-sync-nested.spec.js +++ b/test/hook-sync-nested.spec.js @@ -1,5 +1,5 @@ -describe('serial', function(){ - describe('nested', function(){ +describe.inOrder('serial', function(){ + describe.inOrder('nested', function(){ var calls = []; beforeEach(function(){ @@ -34,7 +34,7 @@ describe('serial', function(){ , 'parent before test bar']); }) - describe('hooks', function(){ + describe.inOrder('hooks', function(){ beforeEach(function(){ calls.push('before'); if (this.currentTest) { diff --git a/test/hook-sync.spec.js b/test/hook-sync.spec.js index 1d40f5d0c0..d4def641da 100644 --- a/test/hook-sync.spec.js +++ b/test/hook-sync.spec.js @@ -1,4 +1,4 @@ -describe('serial', function(){ +describe.inOrder('serial', function(){ var calls = []; beforeEach(function(){ @@ -9,7 +9,7 @@ describe('serial', function(){ calls.push('parent after'); }) - describe('hooks', function(){ + describe.inOrder('hooks', function(){ beforeEach(function(){ calls.push('before'); if (this.currentTest) { diff --git a/test/utils.spec.js b/test/utils.spec.js index 501ea7abe8..d37fab0714 100644 --- a/test/utils.spec.js +++ b/test/utils.spec.js @@ -184,6 +184,56 @@ describe('utils', function() { }); }); + describe('.isSafeUnsignedInteger', function() { + it('should return `false` if the value is not a number', function() { + utils.isSafeUnsignedInteger('boo-boo butt').should.be.false; + }); + + it('should return `false` if the value is negative', function() { + utils.isSafeUnsignedInteger(-1).should.be.false; + }); + + it('should return `false` if the value is greater than Number.MAX_SAFE_INTEGER', function() { + utils.isSafeUnsignedInteger(utils.MAX_SAFE_INTEGER + 1).should.be.false; + }); + + it('should return `false` if the value is not an integer', function() { + utils.isSafeUnsignedInteger(1.5).should.be.false; + }); + + it('should return `true` if the value is a positive integer lteq MAX_SAFE_INTEGER', function() { + utils.isSafeUnsignedInteger(10).should.be.true; + }); + }); + + describe('.toSafeUnsignedInteger()', function() { + it('should return NaN if isSafeUnsignedInteger() would return false', function() { + utils.toSafeUnsignedInteger(Infinity).should.be.NaN; + }); + + it('should return NaN if a string representation of a float value', function() { + utils.toSafeUnsignedInteger('10.5').should.be.NaN; + }); + + it('should return an integer if a safe hex string value', function() { + utils.toSafeUnsignedInteger('0xDEADBEEF').should.equal(0xDEADBEEF); + }); + + it('should return an integer if a safe integer string value', function() { + utils.toSafeUnsignedInteger('10').should.equal(10); + }); + + it('should return an integer if a safe octal string value', function() { + utils.toSafeUnsignedInteger('01234').should.equal(01234); + }); + }); + + describe('.toHex', function() { + it('should convert an integer to hex', function() { + utils.toHex(0xDEADBEEF).should.equal('0xDEADBEEF'); + }); + }); + describe('.isPromise', function() { it('should return true if the value is Promise-ish', function() { utils.isPromise({then: function() {}}).should.be.true; @@ -197,4 +247,5 @@ describe('utils', function() { utils.isPromise({}).should.be.false; }); }); + });