From 3ad5be44fed25a6e6f6fc2a80b2a239090ff221f Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Wed, 29 Jul 2015 16:30:49 -0700 Subject: [PATCH] update dependencies --- LICENSE.md | 5 +- lib/jsdoc/src/astbuilder.js | 2 + lib/jsdoc/src/syntax.js | 3 + lib/jsdoc/src/walker.js | 8 + node_modules/async/lib/async.js | 1475 +++++++++-------- node_modules/async/package.json | 98 +- node_modules/bluebird/LICENSE | 2 +- node_modules/bluebird/js/main/async.js | 90 +- node_modules/bluebird/js/main/bind.js | 9 +- node_modules/bluebird/js/main/cancel.js | 1 + .../bluebird/js/main/captured_trace.js | 5 +- node_modules/bluebird/js/main/catch_filter.js | 2 +- .../bluebird/js/main/debuggability.js | 27 +- .../bluebird/js/main/direct_resolve.js | 13 +- node_modules/bluebird/js/main/finally.js | 7 +- node_modules/bluebird/js/main/map.js | 6 +- node_modules/bluebird/js/main/nodeify.js | 8 +- node_modules/bluebird/js/main/promise.js | 96 +- .../bluebird/js/main/promise_array.js | 2 +- node_modules/bluebird/js/main/promisify.js | 23 +- node_modules/bluebird/js/main/reduce.js | 6 +- node_modules/bluebird/js/main/schedule.js | 25 +- node_modules/bluebird/js/main/thenables.js | 7 +- node_modules/bluebird/js/main/util.js | 79 +- node_modules/bluebird/package.json | 30 +- .../escape-string-regexp/package.json | 41 +- node_modules/espree/espree.js | 64 +- node_modules/espree/lib/ast-node-factory.js | 32 + node_modules/espree/lib/ast-node-types.js | 3 + node_modules/espree/lib/comment-attachment.js | 18 +- node_modules/espree/lib/features.js | 8 +- node_modules/espree/lib/syntax.js | 6 +- node_modules/espree/package.json | 21 +- node_modules/js2xmlparser/LICENSE.md | 208 ++- node_modules/js2xmlparser/lib/js2xmlparser.js | 43 +- node_modules/js2xmlparser/package.json | 33 +- node_modules/marked/lib/marked.js | 45 +- node_modules/marked/package.json | 35 +- node_modules/underscore/LICENSE | 2 +- node_modules/underscore/package.json | 42 +- node_modules/underscore/underscore.js | 745 +++++---- package.json | 22 +- 42 files changed, 2127 insertions(+), 1270 deletions(-) mode change 100755 => 100644 node_modules/async/lib/async.js diff --git a/LICENSE.md b/LICENSE.md index 57b6a91d..55a84793 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -226,7 +226,8 @@ https://github.com/mhevery/jasmine-node ## js2xmlparser ## -js2xmlparser is distributed under the MIT license, which is reproduced above. +js2xmlparser is distributed under the Apache License 2.0, which is +included with this package. Copyright (c) 2012 Michael Kourlas. @@ -374,7 +375,7 @@ https://github.com/geraintluff/tv4 Underscore.js is distributed under the MIT license, which is reproduced above. -Copyright (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative +Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors. The source code for Underscore.js is available at: diff --git a/lib/jsdoc/src/astbuilder.js b/lib/jsdoc/src/astbuilder.js index b36e42f6..b5aaf8ef 100644 --- a/lib/jsdoc/src/astbuilder.js +++ b/lib/jsdoc/src/astbuilder.js @@ -82,11 +82,13 @@ var parserOptions = exports.parserOptions = { classes: true, defaultParams: true, destructuring: true, + experimentalObjectRestSpread: true, forOf: true, generators: true, globalReturn: true, jsx: false, modules: true, + newTarget: true, objectLiteralComputedProperties: true, objectLiteralDuplicateProperties: true, objectLiteralShorthandMethods: true, diff --git a/lib/jsdoc/src/syntax.js b/lib/jsdoc/src/syntax.js index 2b466c4f..942f6a18 100644 --- a/lib/jsdoc/src/syntax.js +++ b/lib/jsdoc/src/syntax.js @@ -22,6 +22,8 @@ exports.Syntax = { DebuggerStatement: 'DebuggerStatement', DoWhileStatement: 'DoWhileStatement', EmptyStatement: 'EmptyStatement', + ExperimentalRestProperty: 'ExperimentalRestProperty', + ExperimentalSpreadProperty: 'ExperimentalSpreadProperty', ExportAllDeclaration: 'ExportAllDeclaration', ExportDefaultDeclaration: 'ExportDefaultDeclaration', ExportNamedDeclaration: 'ExportNamedDeclaration', @@ -43,6 +45,7 @@ exports.Syntax = { Literal: 'Literal', LogicalExpression: 'LogicalExpression', MemberExpression: 'MemberExpression', + MetaProperty: 'MetaProperty', MethodDefinition: 'MethodDefinition', NewExpression: 'NewExpression', ObjectExpression: 'ObjectExpression', diff --git a/lib/jsdoc/src/walker.js b/lib/jsdoc/src/walker.js index 030b8098..02c7febd 100644 --- a/lib/jsdoc/src/walker.js +++ b/lib/jsdoc/src/walker.js @@ -163,6 +163,12 @@ walkers[Syntax.DoWhileStatement] = function(node, parent, state, cb) { walkers[Syntax.EmptyStatement] = leafNode; +walkers[Syntax.ExperimentalRestProperty] = function(node, parent, state, cb) { + cb(node.argument); +}; + +walkers[Syntax.ExperimentalSpreadProperty] = walkers[Syntax.ExperimentalRestProperty]; + walkers[Syntax.ExportAllDeclaration] = function(node, parent, state, cb) { if (node.source) { cb(node.source, node, state); @@ -297,6 +303,8 @@ walkers[Syntax.MemberExpression] = function(node, parent, state, cb) { } }; +walkers[Syntax.MetaProperty] = leafNode; + walkers[Syntax.MethodDefinition] = function(node, parent, state, cb) { if (node.key) { cb(node.key, node, state); diff --git a/node_modules/async/lib/async.js b/node_modules/async/lib/async.js old mode 100755 new mode 100644 index 01e8afcc..f3cfb807 --- a/node_modules/async/lib/async.js +++ b/node_modules/async/lib/async.js @@ -5,18 +5,32 @@ * Copyright 2010-2014 Caolan McMahon * Released under the MIT license */ -/*jshint onevar: false, indent:4 */ -/*global setImmediate: false, setTimeout: false, console: false */ (function () { var async = {}; + function noop() {} + function identity(v) { + return v; + } + function toBool(v) { + return !!v; + } + function notId(v) { + return !v; + } // global on the server, window in the browser - var root, previous_async; + var previous_async; + + // Establish the root object, `window` (`self`) in the browser, `global` + // on the server, or `this` in some virtual machines. We use `self` + // instead of `window` for `WebWorker` support. + var root = typeof self === 'object' && self.self === self && self || + typeof global === 'object' && global.global === global && global || + this; - root = this; if (root != null) { - previous_async = root.async; + previous_async = root.async; } async.noConflict = function () { @@ -25,12 +39,19 @@ }; function only_once(fn) { - var called = false; return function() { - if (called) throw new Error("Callback was already called."); - called = true; - fn.apply(root, arguments); - } + if (fn === null) throw new Error("Callback was already called."); + fn.apply(this, arguments); + fn = null; + }; + } + + function _once(fn) { + return function() { + if (fn === null) return; + fn.apply(this, arguments); + fn = null; + }; } //// cross-browser compatiblity functions //// @@ -41,40 +62,66 @@ return _toString.call(obj) === '[object Array]'; }; - var _each = function (arr, iterator) { - if (arr.forEach) { - return arr.forEach(iterator); - } - for (var i = 0; i < arr.length; i += 1) { - iterator(arr[i], i, arr); - } - }; + function _isArrayLike(arr) { + return _isArray(arr) || ( + // has a positive integer length property + typeof arr.length === "number" && + arr.length >= 0 && + arr.length % 1 === 0 + ); + } - var _map = function (arr, iterator) { - if (arr.map) { - return arr.map(iterator); - } - var results = []; - _each(arr, function (x, i, a) { - results.push(iterator(x, i, a)); - }); - return results; - }; + function _each(coll, iterator) { + return _isArrayLike(coll) ? + _arrayEach(coll, iterator) : + _forEachOf(coll, iterator); + } - var _reduce = function (arr, iterator, memo) { - if (arr.reduce) { - return arr.reduce(iterator, memo); + function _arrayEach(arr, iterator) { + var index = -1, + length = arr.length; + + while (++index < length) { + iterator(arr[index], index, arr); } - _each(arr, function (x, i, a) { + } + + function _map(arr, iterator) { + var index = -1, + length = arr.length, + result = Array(length); + + while (++index < length) { + result[index] = iterator(arr[index], index, arr); + } + return result; + } + + function _range(count) { + return _map(Array(count), function (v, i) { return i; }); + } + + function _reduce(arr, iterator, memo) { + _arrayEach(arr, function (x, i, a) { memo = iterator(memo, x, i, a); }); return memo; - }; + } - var _keys = function (obj) { - if (Object.keys) { - return Object.keys(obj); + function _forEachOf(object, iterator) { + _arrayEach(_keys(object), function (key) { + iterator(object[key], key); + }); + } + + function _indexOf(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] === item) return i; } + return -1; + } + + var _keys = Object.keys || function (obj) { var keys = []; for (var k in obj) { if (obj.hasOwnProperty(k)) { @@ -84,311 +131,337 @@ return keys; }; + function _keyIterator(coll) { + var i = -1; + var len; + var keys; + if (_isArrayLike(coll)) { + len = coll.length; + return function next() { + i++; + return i < len ? i : null; + }; + } else { + keys = _keys(coll); + len = keys.length; + return function next() { + i++; + return i < len ? keys[i] : null; + }; + } + } + + // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html) + // This accumulates the arguments passed into an array, after a given index. + // From underscore.js (https://github.com/jashkenas/underscore/pull/2140). + function _restParam(func, startIndex) { + startIndex = startIndex == null ? func.length - 1 : +startIndex; + return function() { + var length = Math.max(arguments.length - startIndex, 0); + var rest = Array(length); + for (var index = 0; index < length; index++) { + rest[index] = arguments[index + startIndex]; + } + switch (startIndex) { + case 0: return func.call(this, rest); + case 1: return func.call(this, arguments[0], rest); + case 2: return func.call(this, arguments[0], arguments[1], rest); + } + // Currently unused but handle cases outside of the switch statement: + // var args = Array(startIndex + 1); + // for (index = 0; index < startIndex; index++) { + // args[index] = arguments[index]; + // } + // args[startIndex] = rest; + // return func.apply(this, args); + }; + } + + function _withoutIndex(iterator) { + return function (value, index, callback) { + return iterator(value, callback); + }; + } + //// exported async module functions //// //// nextTick implementation with browser-compatible fallback //// - if (typeof process === 'undefined' || !(process.nextTick)) { - if (typeof setImmediate === 'function') { - async.nextTick = function (fn) { - // not a direct alias for IE10 compatibility - setImmediate(fn); - }; - async.setImmediate = async.nextTick; - } - else { - async.nextTick = function (fn) { - setTimeout(fn, 0); - }; - async.setImmediate = async.nextTick; - } - } - else { - async.nextTick = process.nextTick; - if (typeof setImmediate !== 'undefined') { - async.setImmediate = function (fn) { - // not a direct alias for IE10 compatibility - setImmediate(fn); - }; - } - else { - async.setImmediate = async.nextTick; - } - } + // capture the global reference to guard against fakeTimer mocks + var _setImmediate = typeof setImmediate === 'function' && setImmediate; + + var _delay = _setImmediate ? function(fn) { + // not a direct alias for IE10 compatibility + _setImmediate(fn); + } : function(fn) { + setTimeout(fn, 0); + }; + + if (typeof process === 'object' && typeof process.nextTick === 'function') { + async.nextTick = process.nextTick; + } else { + async.nextTick = _delay; + } + async.setImmediate = _setImmediate ? _delay : async.nextTick; + + + async.forEach = async.each = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } + return async.eachOf(arr, _withoutIndex(iterator), callback); + }; + + async.forEachSeries = + async.eachSeries = function (arr, iterator, callback) { + return async.eachOfSeries(arr, _withoutIndex(iterator), callback); + }; + + + async.forEachLimit = + async.eachLimit = function (arr, limit, iterator, callback) { + return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback); + }; + + async.forEachOf = + async.eachOf = function (object, iterator, callback) { + callback = _once(callback || noop); + object = object || []; + var size = _isArrayLike(object) ? object.length : _keys(object).length; var completed = 0; - _each(arr, function (x) { - iterator(x, only_once(done) ); + if (!size) { + return callback(null); + } + _each(object, function (value, key) { + iterator(object[key], key, only_once(done)); }); function done(err) { - if (err) { - callback(err); - callback = function () {}; - } - else { - completed += 1; - if (completed >= arr.length) { - callback(); - } - } + if (err) { + callback(err); + } + else { + completed += 1; + if (completed >= size) { + callback(null); + } + } } }; - async.forEach = async.each; - async.eachSeries = function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length) { - return callback(); - } - var completed = 0; - var iterate = function () { - iterator(arr[completed], function (err) { + async.forEachOfSeries = + async.eachOfSeries = function (obj, iterator, callback) { + callback = _once(callback || noop); + obj = obj || []; + var nextKey = _keyIterator(obj); + var key = nextKey(); + function iterate() { + var sync = true; + if (key === null) { + return callback(null); + } + iterator(obj[key], key, only_once(function (err) { if (err) { callback(err); - callback = function () {}; } else { - completed += 1; - if (completed >= arr.length) { - callback(); - } - else { - iterate(); + key = nextKey(); + if (key === null) { + return callback(null); + } else { + if (sync) { + async.nextTick(iterate); + } else { + iterate(); + } } } - }); - }; + })); + sync = false; + } iterate(); }; - async.forEachSeries = async.eachSeries; - async.eachLimit = function (arr, limit, iterator, callback) { - var fn = _eachLimit(limit); - fn.apply(null, [arr, iterator, callback]); + + + async.forEachOfLimit = + async.eachOfLimit = function (obj, limit, iterator, callback) { + _eachOfLimit(limit)(obj, iterator, callback); }; - async.forEachLimit = async.eachLimit; - var _eachLimit = function (limit) { + function _eachOfLimit(limit) { - return function (arr, iterator, callback) { - callback = callback || function () {}; - if (!arr.length || limit <= 0) { - return callback(); + return function (obj, iterator, callback) { + callback = _once(callback || noop); + obj = obj || []; + var nextKey = _keyIterator(obj); + if (limit <= 0) { + return callback(null); } - var completed = 0; - var started = 0; + var done = false; var running = 0; + var errored = false; (function replenish () { - if (completed >= arr.length) { - return callback(); + if (done && running <= 0) { + return callback(null); } - while (running < limit && started < arr.length) { - started += 1; + while (running < limit && !errored) { + var key = nextKey(); + if (key === null) { + done = true; + if (running <= 0) { + callback(null); + } + return; + } running += 1; - iterator(arr[started - 1], function (err) { + iterator(obj[key], key, only_once(function (err) { + running -= 1; if (err) { callback(err); - callback = function () {}; + errored = true; } else { - completed += 1; - running -= 1; - if (completed >= arr.length) { - callback(); - } - else { - replenish(); - } + replenish(); } - }); + })); } })(); }; - }; + } - var doParallel = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.each].concat(args)); + function doParallel(fn) { + return function (obj, iterator, callback) { + return fn(async.eachOf, obj, iterator, callback); }; - }; - var doParallelLimit = function(limit, fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [_eachLimit(limit)].concat(args)); + } + function doParallelLimit(fn) { + return function (obj, limit, iterator, callback) { + return fn(_eachOfLimit(limit), obj, iterator, callback); }; - }; - var doSeries = function (fn) { - return function () { - var args = Array.prototype.slice.call(arguments); - return fn.apply(null, [async.eachSeries].concat(args)); + } + function doSeries(fn) { + return function (obj, iterator, callback) { + return fn(async.eachOfSeries, obj, iterator, callback); }; - }; + } - - var _asyncMap = function (eachfn, arr, iterator, callback) { - arr = _map(arr, function (x, i) { - return {index: i, value: x}; + function _asyncMap(eachfn, arr, iterator, callback) { + callback = _once(callback || noop); + var results = []; + eachfn(arr, function (value, index, callback) { + iterator(value, function (err, v) { + results[index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); }); - if (!callback) { - eachfn(arr, function (x, callback) { - iterator(x.value, function (err) { - callback(err); - }); - }); - } else { - var results = []; - eachfn(arr, function (x, callback) { - iterator(x.value, function (err, v) { - results[x.index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; + } + async.map = doParallel(_asyncMap); async.mapSeries = doSeries(_asyncMap); - async.mapLimit = function (arr, limit, iterator, callback) { - return _mapLimit(limit)(arr, iterator, callback); - }; - - var _mapLimit = function(limit) { - return doParallelLimit(limit, _asyncMap); - }; + async.mapLimit = doParallelLimit(_asyncMap); // reduce only has a series version, as doing reduce in parallel won't // work in many situations. + async.inject = + async.foldl = async.reduce = function (arr, memo, iterator, callback) { - async.eachSeries(arr, function (x, callback) { + async.eachOfSeries(arr, function (x, i, callback) { iterator(memo, x, function (err, v) { memo = v; callback(err); }); }, function (err) { - callback(err, memo); + callback(err || null, memo); }); }; - // inject alias - async.inject = async.reduce; - // foldl alias - async.foldl = async.reduce; + async.foldr = async.reduceRight = function (arr, memo, iterator, callback) { - var reversed = _map(arr, function (x) { - return x; - }).reverse(); + var reversed = _map(arr, identity).reverse(); async.reduce(reversed, memo, iterator, callback); }; - // foldr alias - async.foldr = async.reduceRight; - var _filter = function (eachfn, arr, iterator, callback) { + function _filter(eachfn, arr, iterator, callback) { var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { + eachfn(arr, function (x, index, callback) { + iterator(x, function (v) { if (v) { - results.push(x); + results.push({index: index, value: x}); } callback(); }); - }, function (err) { + }, function () { callback(_map(results.sort(function (a, b) { return a.index - b.index; }), function (x) { return x.value; })); }); - }; - async.filter = doParallel(_filter); - async.filterSeries = doSeries(_filter); - // select alias - async.select = async.filter; - async.selectSeries = async.filterSeries; + } - var _reject = function (eachfn, arr, iterator, callback) { - var results = []; - arr = _map(arr, function (x, i) { - return {index: i, value: x}; - }); - eachfn(arr, function (x, callback) { - iterator(x.value, function (v) { - if (!v) { - results.push(x); - } - callback(); + async.select = + async.filter = doParallel(_filter); + + async.selectLimit = + async.filterLimit = doParallelLimit(_filter); + + async.selectSeries = + async.filterSeries = doSeries(_filter); + + function _reject(eachfn, arr, iterator, callback) { + _filter(eachfn, arr, function(value, cb) { + iterator(value, function(v) { + cb(!v); }); - }, function (err) { - callback(_map(results.sort(function (a, b) { - return a.index - b.index; - }), function (x) { - return x.value; - })); - }); - }; + }, callback); + } async.reject = doParallel(_reject); + async.rejectLimit = doParallelLimit(_reject); async.rejectSeries = doSeries(_reject); - var _detect = function (eachfn, arr, iterator, main_callback) { - eachfn(arr, function (x, callback) { - iterator(x, function (result) { - if (result) { - main_callback(x); - main_callback = function () {}; - } - else { + function _createTester(eachfn, check, getResult) { + return function(arr, limit, iterator, cb) { + function done() { + if (cb) cb(getResult(false, void 0)); + } + function iteratee(x, _, callback) { + if (!cb) return callback(); + iterator(x, function (v) { + if (cb && check(v)) { + cb(getResult(true, x)); + cb = iterator = false; + } callback(); - } - }); - }, function (err) { - main_callback(); - }); - }; - async.detect = doParallel(_detect); - async.detectSeries = doSeries(_detect); + }); + } + if (arguments.length > 3) { + eachfn(arr, limit, iteratee, done); + } else { + cb = iterator; + iterator = limit; + eachfn(arr, iteratee, done); + } + }; + } - async.some = function (arr, iterator, main_callback) { - async.each(arr, function (x, callback) { - iterator(x, function (v) { - if (v) { - main_callback(true); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(false); - }); - }; - // any alias - async.any = async.some; + async.any = + async.some = _createTester(async.eachOf, toBool, identity); - async.every = function (arr, iterator, main_callback) { - async.each(arr, function (x, callback) { - iterator(x, function (v) { - if (!v) { - main_callback(false); - main_callback = function () {}; - } - callback(); - }); - }, function (err) { - main_callback(true); - }); - }; - // all alias - async.all = async.every; + async.someLimit = _createTester(async.eachOfLimit, toBool, identity); + + async.all = + async.every = _createTester(async.eachOf, notId, notId); + + async.everyLimit = _createTester(async.eachOfLimit, notId, notId); + + function _findGetResult(v, x) { + return x; + } + async.detect = _createTester(async.eachOf, identity, _findGetResult); + async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult); async.sortBy = function (arr, iterator, callback) { async.map(arr, function (x, callback) { @@ -405,147 +478,189 @@ return callback(err); } else { - var fn = function (left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }; - callback(null, _map(results.sort(fn), function (x) { + callback(null, _map(results.sort(comparator), function (x) { return x.value; })); } + }); + + function comparator(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + } }; async.auto = function (tasks, callback) { - callback = callback || function () {}; + callback = _once(callback || noop); var keys = _keys(tasks); - var remainingTasks = keys.length + var remainingTasks = keys.length; if (!remainingTasks) { - return callback(); + return callback(null); } var results = {}; var listeners = []; - var addListener = function (fn) { + function addListener(fn) { listeners.unshift(fn); - }; - var removeListener = function (fn) { - for (var i = 0; i < listeners.length; i += 1) { - if (listeners[i] === fn) { - listeners.splice(i, 1); - return; - } - } - }; - var taskComplete = function () { - remainingTasks-- - _each(listeners.slice(0), function (fn) { + } + function removeListener(fn) { + var idx = _indexOf(listeners, fn); + if (idx >= 0) listeners.splice(idx, 1); + } + function taskComplete() { + remainingTasks--; + _arrayEach(listeners.slice(0), function (fn) { fn(); }); - }; + } addListener(function () { if (!remainingTasks) { - var theCallback = callback; - // prevent final callback from calling itself if it errors - callback = function () {}; - - theCallback(null, results); + callback(null, results); } }); - _each(keys, function (k) { + _arrayEach(keys, function (k) { var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; - var taskCallback = function (err) { - var args = Array.prototype.slice.call(arguments, 1); + var taskCallback = _restParam(function(err, args) { if (args.length <= 1) { args = args[0]; } if (err) { var safeResults = {}; - _each(_keys(results), function(rkey) { - safeResults[rkey] = results[rkey]; + _forEachOf(results, function(val, rkey) { + safeResults[rkey] = val; }); safeResults[k] = args; callback(err, safeResults); - // stop subsequent errors hitting callback multiple times - callback = function () {}; } else { results[k] = args; async.setImmediate(taskComplete); } - }; - var requires = task.slice(0, Math.abs(task.length - 1)) || []; - var ready = function () { + }); + var requires = task.slice(0, task.length - 1); + // prevent dead-locks + var len = requires.length; + var dep; + while (len--) { + if (!(dep = tasks[requires[len]])) { + throw new Error('Has inexistant dependency'); + } + if (_isArray(dep) && _indexOf(dep, k) >= 0) { + throw new Error('Has cyclic dependencies'); + } + } + function ready() { return _reduce(requires, function (a, x) { return (a && results.hasOwnProperty(x)); }, true) && !results.hasOwnProperty(k); - }; + } if (ready()) { task[task.length - 1](taskCallback, results); } else { - var listener = function () { - if (ready()) { - removeListener(listener); - task[task.length - 1](taskCallback, results); - } - }; addListener(listener); } + function listener() { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + } }); }; + + async.retry = function(times, task, callback) { var DEFAULT_TIMES = 5; + var DEFAULT_INTERVAL = 0; + var attempts = []; - // Use defaults if times not passed - if (typeof times === 'function') { + + var opts = { + times: DEFAULT_TIMES, + interval: DEFAULT_INTERVAL + }; + + function parseTimes(acc, t){ + if(typeof t === 'number'){ + acc.times = parseInt(t, 10) || DEFAULT_TIMES; + } else if(typeof t === 'object'){ + acc.times = parseInt(t.times, 10) || DEFAULT_TIMES; + acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL; + } else { + throw new Error('Unsupported argument type for \'times\': ' + typeof(t)); + } + } + + var length = arguments.length; + if (length < 1 || length > 3) { + throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)'); + } else if (length <= 2 && typeof times === 'function') { callback = task; task = times; - times = DEFAULT_TIMES; } - // Make sure times is a number - times = parseInt(times, 10) || DEFAULT_TIMES; - var wrappedTask = function(wrappedCallback, wrappedResults) { - var retryAttempt = function(task, finalAttempt) { + if (typeof times !== 'function') { + parseTimes(opts, times); + } + opts.callback = callback; + opts.task = task; + + function wrappedTask(wrappedCallback, wrappedResults) { + function retryAttempt(task, finalAttempt) { return function(seriesCallback) { task(function(err, result){ seriesCallback(!err || finalAttempt, {err: err, result: result}); }, wrappedResults); }; - }; - while (times) { - attempts.push(retryAttempt(task, !(times-=1))); } + + function retryInterval(interval){ + return function(seriesCallback){ + setTimeout(function(){ + seriesCallback(null); + }, interval); + }; + } + + while (opts.times) { + + var finalAttempt = !(opts.times-=1); + attempts.push(retryAttempt(opts.task, finalAttempt)); + if(!finalAttempt && opts.interval > 0){ + attempts.push(retryInterval(opts.interval)); + } + } + async.series(attempts, function(done, data){ data = data[data.length - 1]; - (wrappedCallback || callback)(data.err, data.result); + (wrappedCallback || opts.callback)(data.err, data.result); }); } + // If a callback is passed, run this as a controll flow - return callback ? wrappedTask() : wrappedTask + return opts.callback ? wrappedTask() : wrappedTask; }; async.waterfall = function (tasks, callback) { - callback = callback || function () {}; + callback = _once(callback || noop); if (!_isArray(tasks)) { - var err = new Error('First argument to waterfall must be an array of functions'); - return callback(err); + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); } if (!tasks.length) { return callback(); } - var wrapIterator = function (iterator) { - return function (err) { + function wrapIterator(iterator) { + return _restParam(function (err, args) { if (err) { - callback.apply(null, arguments); - callback = function () {}; + callback.apply(null, [err].concat(args)); } else { - var args = Array.prototype.slice.call(arguments, 1); var next = iterator.next(); if (next) { args.push(wrapIterator(next)); @@ -553,260 +668,244 @@ else { args.push(callback); } - async.setImmediate(function () { - iterator.apply(null, args); - }); + ensureAsync(iterator).apply(null, args); } - }; - }; + }); + } wrapIterator(async.iterator(tasks))(); }; - var _parallel = function(eachfn, tasks, callback) { - callback = callback || function () {}; - if (_isArray(tasks)) { - eachfn.map(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); + function _parallel(eachfn, tasks, callback) { + callback = callback || noop; + var results = _isArrayLike(tasks) ? [] : {}; + + eachfn(tasks, function (task, key, callback) { + task(_restParam(function (err, args) { + if (args.length <= 1) { + args = args[0]; } - }, callback); - } - else { - var results = {}; - eachfn.each(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } - }; + results[key] = args; + callback(err); + })); + }, function (err) { + callback(err, results); + }); + } async.parallel = function (tasks, callback) { - _parallel({ map: async.map, each: async.each }, tasks, callback); + _parallel(async.eachOf, tasks, callback); }; async.parallelLimit = function(tasks, limit, callback) { - _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); + _parallel(_eachOfLimit(limit), tasks, callback); }; - async.series = function (tasks, callback) { - callback = callback || function () {}; - if (_isArray(tasks)) { - async.mapSeries(tasks, function (fn, callback) { - if (fn) { - fn(function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - callback.call(null, err, args); - }); - } - }, callback); - } - else { - var results = {}; - async.eachSeries(_keys(tasks), function (k, callback) { - tasks[k](function (err) { - var args = Array.prototype.slice.call(arguments, 1); - if (args.length <= 1) { - args = args[0]; - } - results[k] = args; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } + async.series = function(tasks, callback) { + _parallel(async.eachOfSeries, tasks, callback); }; async.iterator = function (tasks) { - var makeCallback = function (index) { - var fn = function () { + function makeCallback(index) { + function fn() { if (tasks.length) { tasks[index].apply(null, arguments); } return fn.next(); - }; + } fn.next = function () { return (index < tasks.length - 1) ? makeCallback(index + 1): null; }; return fn; - }; + } return makeCallback(0); }; - async.apply = function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - return function () { + async.apply = _restParam(function (fn, args) { + return _restParam(function (callArgs) { return fn.apply( - null, args.concat(Array.prototype.slice.call(arguments)) + null, args.concat(callArgs) ); - }; - }; + }); + }); - var _concat = function (eachfn, arr, fn, callback) { - var r = []; - eachfn(arr, function (x, cb) { + function _concat(eachfn, arr, fn, callback) { + var result = []; + eachfn(arr, function (x, index, cb) { fn(x, function (err, y) { - r = r.concat(y || []); + result = result.concat(y || []); cb(err); }); }, function (err) { - callback(err, r); + callback(err, result); }); - }; + } async.concat = doParallel(_concat); async.concatSeries = doSeries(_concat); async.whilst = function (test, iterator, callback) { + callback = callback || noop; if (test()) { - iterator(function (err) { + var next = _restParam(function(err, args) { if (err) { - return callback(err); + callback(err); + } else if (test.apply(this, args)) { + iterator(next); + } else { + callback(null); } - async.whilst(test, iterator, callback); }); - } - else { - callback(); + iterator(next); + } else { + callback(null); } }; async.doWhilst = function (iterator, test, callback) { - iterator(function (err) { - if (err) { - return callback(err); - } - var args = Array.prototype.slice.call(arguments, 1); - if (test.apply(null, args)) { - async.doWhilst(iterator, test, callback); - } - else { - callback(); - } - }); + var calls = 0; + return async.whilst(function() { + return ++calls <= 1 || test.apply(this, arguments); + }, iterator, callback); }; async.until = function (test, iterator, callback) { - if (!test()) { - iterator(function (err) { - if (err) { - return callback(err); - } - async.until(test, iterator, callback); - }); - } - else { - callback(); - } + return async.whilst(function() { + return !test.apply(this, arguments); + }, iterator, callback); }; async.doUntil = function (iterator, test, callback) { - iterator(function (err) { - if (err) { - return callback(err); - } - var args = Array.prototype.slice.call(arguments, 1); - if (!test.apply(null, args)) { - async.doUntil(iterator, test, callback); - } - else { - callback(); - } - }); + return async.doWhilst(iterator, function() { + return !test.apply(this, arguments); + }, callback); }; - async.queue = function (worker, concurrency) { - if (concurrency === undefined) { + async.during = function (test, iterator, callback) { + callback = callback || noop; + + var next = _restParam(function(err, args) { + if (err) { + callback(err); + } else { + args.push(check); + test.apply(this, args); + } + }); + + var check = function(err, truth) { + if (err) { + callback(err); + } else if (truth) { + iterator(next); + } else { + callback(null); + } + }; + + test(check); + }; + + async.doDuring = function (iterator, test, callback) { + var calls = 0; + async.during(function(next) { + if (calls++ < 1) { + next(null, true); + } else { + test.apply(this, arguments); + } + }, iterator, callback); + }; + + function _queue(worker, concurrency, payload) { + if (concurrency == null) { concurrency = 1; } + else if(concurrency === 0) { + throw new Error('Concurrency must not be zero'); + } function _insert(q, data, pos, callback) { - if (!q.started){ + if (callback != null && typeof callback !== "function") { + throw new Error("task callback must be a function"); + } q.started = true; - } - if (!_isArray(data)) { - data = [data]; - } - if(data.length == 0) { - // call drain immediately if there are no tasks - return async.setImmediate(function() { - if (q.drain) { - q.drain(); - } - }); - } - _each(data, function(task) { - var item = { - data: task, - callback: typeof callback === 'function' ? callback : null - }; + if (!_isArray(data)) { + data = [data]; + } + if(data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + q.drain(); + }); + } + _arrayEach(data, function(task) { + var item = { + data: task, + callback: callback || noop + }; - if (pos) { - q.tasks.unshift(item); - } else { - q.tasks.push(item); - } + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } - if (q.saturated && q.tasks.length === q.concurrency) { - q.saturated(); - } - async.setImmediate(q.process); - }); + if (q.tasks.length === q.concurrency) { + q.saturated(); + } + }); + async.setImmediate(q.process); + } + function _next(q, tasks) { + return function(){ + workers -= 1; + var args = arguments; + _arrayEach(tasks, function (task) { + task.callback.apply(task, args); + }); + if (q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; } var workers = 0; var q = { tasks: [], concurrency: concurrency, - saturated: null, - empty: null, - drain: null, + payload: payload, + saturated: noop, + empty: noop, + drain: noop, started: false, paused: false, push: function (data, callback) { - _insert(q, data, false, callback); + _insert(q, data, false, callback); }, kill: function () { - q.drain = null; - q.tasks = []; + q.drain = noop; + q.tasks = []; }, unshift: function (data, callback) { - _insert(q, data, true, callback); + _insert(q, data, true, callback); }, process: function () { if (!q.paused && workers < q.concurrency && q.tasks.length) { - var task = q.tasks.shift(); - if (q.empty && q.tasks.length === 0) { - q.empty(); + while(workers < q.concurrency && q.tasks.length){ + var tasks = q.payload ? + q.tasks.splice(0, q.payload) : + q.tasks.splice(0, q.tasks.length); + + var data = _map(tasks, function (task) { + return task.data; + }); + + if (q.tasks.length === 0) { + q.empty(); + } + workers += 1; + var cb = only_once(_next(q, tasks)); + worker(data, cb); } - workers += 1; - var next = function () { - workers -= 1; - if (task.callback) { - task.callback.apply(task, arguments); - } - if (q.drain && q.tasks.length + workers === 0) { - q.drain(); - } - q.process(); - }; - var cb = only_once(next); - worker(task.data, cb); } }, length: function () { @@ -819,78 +918,88 @@ return q.tasks.length + workers === 0; }, pause: function () { - if (q.paused === true) { return; } q.paused = true; - q.process(); }, resume: function () { if (q.paused === false) { return; } q.paused = false; - q.process(); + var resumeCount = Math.min(q.concurrency, q.tasks.length); + // Need to call q.process once per concurrent + // worker to preserve full concurrency after pause + for (var w = 1; w <= resumeCount; w++) { + async.setImmediate(q.process); + } } }; return q; - }; - - async.priorityQueue = function (worker, concurrency) { - - function _compareTasks(a, b){ - return a.priority - b.priority; - }; - - function _binarySearch(sequence, item, compare) { - var beg = -1, - end = sequence.length - 1; - while (beg < end) { - var mid = beg + ((end - beg + 1) >>> 1); - if (compare(item, sequence[mid]) >= 0) { - beg = mid; - } else { - end = mid - 1; - } - } - return beg; - } - - function _insert(q, data, priority, callback) { - if (!q.started){ - q.started = true; - } - if (!_isArray(data)) { - data = [data]; - } - if(data.length == 0) { - // call drain immediately if there are no tasks - return async.setImmediate(function() { - if (q.drain) { - q.drain(); - } - }); - } - _each(data, function(task) { - var item = { - data: task, - priority: priority, - callback: typeof callback === 'function' ? callback : null - }; - - q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); + } - if (q.saturated && q.tasks.length === q.concurrency) { - q.saturated(); - } - async.setImmediate(q.process); - }); + async.queue = function (worker, concurrency) { + var q = _queue(function (items, cb) { + worker(items[0], cb); + }, concurrency, 1); + + return q; + }; + + async.priorityQueue = function (worker, concurrency) { + + function _compareTasks(a, b){ + return a.priority - b.priority; } - + + function _binarySearch(sequence, item, compare) { + var beg = -1, + end = sequence.length - 1; + while (beg < end) { + var mid = beg + ((end - beg + 1) >>> 1); + if (compare(item, sequence[mid]) >= 0) { + beg = mid; + } else { + end = mid - 1; + } + } + return beg; + } + + function _insert(q, data, priority, callback) { + if (callback != null && typeof callback !== "function") { + throw new Error("task callback must be a function"); + } + q.started = true; + if (!_isArray(data)) { + data = [data]; + } + if(data.length === 0) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + q.drain(); + }); + } + _arrayEach(data, function(task) { + var item = { + data: task, + priority: priority, + callback: typeof callback === 'function' ? callback : noop + }; + + q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); + + if (q.tasks.length === q.concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + // Start with a normal queue var q = async.queue(worker, concurrency); - + // Override push to accept second parameter representing priority q.push = function (data, priority, callback) { - _insert(q, data, priority, callback); + _insert(q, data, priority, callback); }; - + // Remove unshift function delete q.unshift; @@ -898,78 +1007,12 @@ }; async.cargo = function (worker, payload) { - var working = false, - tasks = []; - - var cargo = { - tasks: tasks, - payload: payload, - saturated: null, - empty: null, - drain: null, - drained: true, - push: function (data, callback) { - if (!_isArray(data)) { - data = [data]; - } - _each(data, function(task) { - tasks.push({ - data: task, - callback: typeof callback === 'function' ? callback : null - }); - cargo.drained = false; - if (cargo.saturated && tasks.length === payload) { - cargo.saturated(); - } - }); - async.setImmediate(cargo.process); - }, - process: function process() { - if (working) return; - if (tasks.length === 0) { - if(cargo.drain && !cargo.drained) cargo.drain(); - cargo.drained = true; - return; - } - - var ts = typeof payload === 'number' - ? tasks.splice(0, payload) - : tasks.splice(0, tasks.length); - - var ds = _map(ts, function (task) { - return task.data; - }); - - if(cargo.empty) cargo.empty(); - working = true; - worker(ds, function () { - working = false; - - var args = arguments; - _each(ts, function (data) { - if (data.callback) { - data.callback.apply(null, args); - } - }); - - process(); - }); - }, - length: function () { - return tasks.length; - }, - running: function () { - return working; - } - }; - return cargo; + return _queue(worker, 1, payload); }; - var _console_fn = function (name) { - return function (fn) { - var args = Array.prototype.slice.call(arguments, 1); - fn.apply(null, args.concat([function (err) { - var args = Array.prototype.slice.call(arguments, 1); + function _console_fn(name) { + return _restParam(function (fn, args) { + fn.apply(null, args.concat([_restParam(function (err, args) { if (typeof console !== 'undefined') { if (err) { if (console.error) { @@ -977,14 +1020,14 @@ } } else if (console[name]) { - _each(args, function (x) { + _arrayEach(args, function (x) { console[name](x); }); } } - }])); - }; - }; + })])); + }); + } async.log = _console_fn('log'); async.dir = _console_fn('dir'); /*async.info = _console_fn('info'); @@ -994,11 +1037,8 @@ async.memoize = function (fn, hasher) { var memo = {}; var queues = {}; - hasher = hasher || function (x) { - return x; - }; - var memoized = function () { - var args = Array.prototype.slice.call(arguments); + hasher = hasher || identity; + var memoized = _restParam(function memoized(args) { var callback = args.pop(); var key = hasher.apply(null, args); if (key in memo) { @@ -1011,100 +1051,153 @@ } else { queues[key] = [callback]; - fn.apply(null, args.concat([function () { - memo[key] = arguments; + fn.apply(null, args.concat([_restParam(function (args) { + memo[key] = args; var q = queues[key]; delete queues[key]; for (var i = 0, l = q.length; i < l; i++) { - q[i].apply(null, arguments); + q[i].apply(null, args); } - }])); + })])); } - }; + }); memoized.memo = memo; memoized.unmemoized = fn; return memoized; }; async.unmemoize = function (fn) { - return function () { - return (fn.unmemoized || fn).apply(null, arguments); - }; + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; }; - async.times = function (count, iterator, callback) { - var counter = []; - for (var i = 0; i < count; i++) { - counter.push(i); - } - return async.map(counter, iterator, callback); - }; + function _times(mapper) { + return function (count, iterator, callback) { + mapper(_range(count), iterator, callback); + }; + } - async.timesSeries = function (count, iterator, callback) { - var counter = []; - for (var i = 0; i < count; i++) { - counter.push(i); - } - return async.mapSeries(counter, iterator, callback); + async.times = _times(async.map); + async.timesSeries = _times(async.mapSeries); + async.timesLimit = function (count, limit, iterator, callback) { + return async.mapLimit(_range(count), limit, iterator, callback); }; async.seq = function (/* functions... */) { var fns = arguments; - return function () { + return _restParam(function (args) { var that = this; - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); + + var callback = args[args.length - 1]; + if (typeof callback == 'function') { + args.pop(); + } else { + callback = noop; + } + async.reduce(fns, args, function (newargs, fn, cb) { - fn.apply(that, newargs.concat([function () { - var err = arguments[0]; - var nextargs = Array.prototype.slice.call(arguments, 1); + fn.apply(that, newargs.concat([_restParam(function (err, nextargs) { cb(err, nextargs); - }])) + })])); }, function (err, results) { callback.apply(that, [err].concat(results)); }); - }; + }); }; async.compose = function (/* functions... */) { - return async.seq.apply(null, Array.prototype.reverse.call(arguments)); + return async.seq.apply(null, Array.prototype.reverse.call(arguments)); }; - var _applyEach = function (eachfn, fns /*args...*/) { - var go = function () { - var that = this; - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - return eachfn(fns, function (fn, cb) { - fn.apply(that, args.concat([cb])); - }, - callback); - }; - if (arguments.length > 2) { - var args = Array.prototype.slice.call(arguments, 2); - return go.apply(this, args); - } - else { - return go; - } - }; - async.applyEach = doParallel(_applyEach); - async.applyEachSeries = doSeries(_applyEach); + + function _applyEach(eachfn) { + return _restParam(function(fns, args) { + var go = _restParam(function(args) { + var that = this; + var callback = args.pop(); + return eachfn(fns, function (fn, _, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }); + if (args.length) { + return go.apply(this, args); + } + else { + return go; + } + }); + } + + async.applyEach = _applyEach(async.eachOf); + async.applyEachSeries = _applyEach(async.eachOfSeries); + async.forever = function (fn, callback) { + var done = only_once(callback || noop); + var task = ensureAsync(fn); function next(err) { if (err) { - if (callback) { - return callback(err); - } - throw err; + return done(err); } - fn(next); + task(next); } next(); }; + function ensureAsync(fn) { + return _restParam(function (args) { + var callback = args.pop(); + args.push(function () { + var innerArgs = arguments; + if (sync) { + async.setImmediate(function () { + callback.apply(null, innerArgs); + }); + } else { + callback.apply(null, innerArgs); + } + }); + var sync = true; + fn.apply(this, args); + sync = false; + }); + } + + async.ensureAsync = ensureAsync; + + async.constant = _restParam(function(values) { + var args = [null].concat(values); + return function (callback) { + return callback.apply(this, args); + }; + }); + + async.wrapSync = + async.asyncify = function asyncify(func) { + return _restParam(function (args) { + var callback = args.pop(); + var result; + try { + result = func.apply(this, args); + } catch (e) { + return callback(e); + } + // if result is Promise object + if (typeof result !== 'undefined' && typeof result.then === "function") { + result.then(function(value) { + callback(null, value); + }).catch(function(err) { + callback(err.message ? err : new Error(err)); + }); + } else { + callback(null, result); + } + }); + }; + // Node.js if (typeof module !== 'undefined' && module.exports) { module.exports = async; diff --git a/node_modules/async/package.json b/node_modules/async/package.json index 78fc84d7..c540f718 100644 --- a/node_modules/async/package.json +++ b/node_modules/async/package.json @@ -1,28 +1,41 @@ { "name": "async", "description": "Higher-order functions and common patterns for asynchronous code", - "main": "./lib/async", + "main": "lib/async.js", "author": { "name": "Caolan McMahon" }, - "version": "0.9.0", + "version": "1.4.0", + "keywords": [ + "async", + "callback", + "utility", + "module" + ], "repository": { "type": "git", - "url": "https://github.com/caolan/async.git" + "url": "git+https://github.com/caolan/async.git" }, "bugs": { "url": "https://github.com/caolan/async/issues" }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/caolan/async/raw/master/LICENSE" - } - ], + "license": "MIT", "devDependencies": { + "benchmark": "github:bestiejs/benchmark.js", + "bluebird": "^2.9.32", + "coveralls": "^2.11.2", + "es6-promise": "^2.3.0", + "jscs": "^1.13.1", + "jshint": "~2.8.0", + "lodash": "^3.9.0", + "mkdirp": "~0.5.1", + "native-promise-only": "^0.8.0-a", "nodeunit": ">0.0.0", - "uglify-js": "1.2.x", - "nodelint": ">0.0.0" + "nyc": "^2.1.0", + "rsvp": "^3.0.18", + "uglify-js": "~2.4.0", + "xyz": "^0.5.0", + "yargs": "~3.9.1" }, "jam": { "main": "lib/async.js", @@ -30,16 +43,63 @@ "lib/async.js", "README.md", "LICENSE" + ], + "categories": [ + "Utilities" ] }, "scripts": { - "test": "nodeunit test/test-async.js" + "test": "npm run-script lint && nodeunit test/test-async.js", + "lint": "jshint lib/*.js test/*.js perf/*.js && jscs lib/*.js test/*.js perf/*.js", + "coverage": "nyc npm test && nyc report", + "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls" }, - "readme": "# Async.js\n\n[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async)\n\n\nAsync is a utility module which provides straight-forward, powerful functions\nfor working with asynchronous JavaScript. Although originally designed for\nuse with [Node.js](http://nodejs.org), it can also be used directly in the\nbrowser. Also supports [component](https://github.com/component/component).\n\nAsync provides around 20 functions that include the usual 'functional'\nsuspects (`map`, `reduce`, `filter`, `each`…) as well as some common patterns\nfor asynchronous control flow (`parallel`, `series`, `waterfall`…). All these\nfunctions assume you follow the Node.js convention of providing a single\ncallback as the last argument of your `async` function.\n\n\n## Quick Examples\n\n```javascript\nasync.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n});\n\nasync.filter(['file1','file2','file3'], fs.exists, function(results){\n // results now equals an array of the existing files\n});\n\nasync.parallel([\n function(){ ... },\n function(){ ... }\n], callback);\n\nasync.series([\n function(){ ... },\n function(){ ... }\n]);\n```\n\nThere are many more functions available so take a look at the docs below for a\nfull list. This module aims to be comprehensive, so if you feel anything is\nmissing please create a GitHub issue for it.\n\n## Common Pitfalls\n\n### Binding a context to an iterator\n\nThis section is really about `bind`, not about `async`. If you are wondering how to\nmake `async` execute your iterators in a given context, or are confused as to why\na method of another library isn't working as an iterator, study this example:\n\n```js\n// Here is a simple object with an (unnecessarily roundabout) squaring method\nvar AsyncSquaringLibrary = {\n squareExponent: 2,\n square: function(number, callback){ \n var result = Math.pow(number, this.squareExponent);\n setTimeout(function(){\n callback(null, result);\n }, 200);\n }\n};\n\nasync.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){\n // result is [NaN, NaN, NaN]\n // This fails because the `this.squareExponent` expression in the square\n // function is not evaluated in the context of AsyncSquaringLibrary, and is\n // therefore undefined.\n});\n\nasync.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){\n // result is [1, 4, 9]\n // With the help of bind we can attach a context to the iterator before\n // passing it to async. Now the square function will be executed in its \n // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent`\n // will be as expected.\n});\n```\n\n## Download\n\nThe source is available for download from\n[GitHub](http://github.com/caolan/async).\nAlternatively, you can install using Node Package Manager (`npm`):\n\n npm install async\n\n__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed\n\n## In the Browser\n\nSo far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. \n\nUsage:\n\n```html\n\n\n```\n\n## Documentation\n\n### Collections\n\n* [`each`](#each)\n* [`eachSeries`](#eachSeries)\n* [`eachLimit`](#eachLimit)\n* [`map`](#map)\n* [`mapSeries`](#mapSeries)\n* [`mapLimit`](#mapLimit)\n* [`filter`](#filter)\n* [`filterSeries`](#filterSeries)\n* [`reject`](#reject)\n* [`rejectSeries`](#rejectSeries)\n* [`reduce`](#reduce)\n* [`reduceRight`](#reduceRight)\n* [`detect`](#detect)\n* [`detectSeries`](#detectSeries)\n* [`sortBy`](#sortBy)\n* [`some`](#some)\n* [`every`](#every)\n* [`concat`](#concat)\n* [`concatSeries`](#concatSeries)\n\n### Control Flow\n\n* [`series`](#seriestasks-callback)\n* [`parallel`](#parallel)\n* [`parallelLimit`](#parallellimittasks-limit-callback)\n* [`whilst`](#whilst)\n* [`doWhilst`](#doWhilst)\n* [`until`](#until)\n* [`doUntil`](#doUntil)\n* [`forever`](#forever)\n* [`waterfall`](#waterfall)\n* [`compose`](#compose)\n* [`seq`](#seq)\n* [`applyEach`](#applyEach)\n* [`applyEachSeries`](#applyEachSeries)\n* [`queue`](#queue)\n* [`priorityQueue`](#priorityQueue)\n* [`cargo`](#cargo)\n* [`auto`](#auto)\n* [`retry`](#retry)\n* [`iterator`](#iterator)\n* [`apply`](#apply)\n* [`nextTick`](#nextTick)\n* [`times`](#times)\n* [`timesSeries`](#timesSeries)\n\n### Utils\n\n* [`memoize`](#memoize)\n* [`unmemoize`](#unmemoize)\n* [`log`](#log)\n* [`dir`](#dir)\n* [`noConflict`](#noConflict)\n\n\n## Collections\n\n\n\n### each(arr, iterator, callback)\n\nApplies the function `iterator` to each item in `arr`, in parallel.\nThe `iterator` is called with an item from the list, and a callback for when it\nhas finished. If the `iterator` passes an error to its `callback`, the main\n`callback` (for the `each` function) is immediately called with the error.\n\nNote, that since this function applies `iterator` to each item in parallel,\nthere is no guarantee that the iterator functions will complete in order.\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `iterator(item, callback)` - A function to apply to each item in `arr`.\n The iterator is passed a `callback(err)` which must be called once it has \n completed. If no error has occured, the `callback` should be run without \n arguments or with an explicit `null` argument.\n* `callback(err)` - A callback which is called when all `iterator` functions\n have finished, or an error occurs.\n\n__Examples__\n\n\n```js\n// assuming openFiles is an array of file names and saveFile is a function\n// to save the modified contents of that file:\n\nasync.each(openFiles, saveFile, function(err){\n // if any of the saves produced an error, err would equal that error\n});\n```\n\n```js\n// assuming openFiles is an array of file names \n\nasync.each(openFiles, function( file, callback) {\n \n // Perform operation on file here.\n console.log('Processing file ' + file);\n \n if( file.length > 32 ) {\n console.log('This file name is too long');\n callback('File name too long');\n } else {\n // Do work to process file here\n console.log('File processed');\n callback();\n }\n}, function(err){\n // if any of the file processing produced an error, err would equal that error\n if( err ) {\n // One of the iterations produced an error.\n // All processing will now stop.\n console.log('A file failed to process');\n } else {\n console.log('All files have been processed successfully');\n }\n});\n```\n\n---------------------------------------\n\n\n\n### eachSeries(arr, iterator, callback)\n\nThe same as [`each`](#each), only `iterator` is applied to each item in `arr` in\nseries. The next `iterator` is only called once the current one has completed. \nThis means the `iterator` functions will complete in order.\n\n\n---------------------------------------\n\n\n\n### eachLimit(arr, limit, iterator, callback)\n\nThe same as [`each`](#each), only no more than `limit` `iterator`s will be simultaneously \nrunning at any time.\n\nNote that the items in `arr` are not processed in batches, so there is no guarantee that \nthe first `limit` `iterator` functions will complete before any others are started.\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `limit` - The maximum number of `iterator`s to run at any time.\n* `iterator(item, callback)` - A function to apply to each item in `arr`.\n The iterator is passed a `callback(err)` which must be called once it has \n completed. If no error has occured, the callback should be run without \n arguments or with an explicit `null` argument.\n* `callback(err)` - A callback which is called when all `iterator` functions\n have finished, or an error occurs.\n\n__Example__\n\n```js\n// Assume documents is an array of JSON objects and requestApi is a\n// function that interacts with a rate-limited REST api.\n\nasync.eachLimit(documents, 20, requestApi, function(err){\n // if any of the saves produced an error, err would equal that error\n});\n```\n\n---------------------------------------\n\n\n### map(arr, iterator, callback)\n\nProduces a new array of values by mapping each value in `arr` through\nthe `iterator` function. The `iterator` is called with an item from `arr` and a\ncallback for when it has finished processing. Each of these callback takes 2 arguments: \nan `error`, and the transformed item from `arr`. If `iterator` passes an error to this \ncallback, the main `callback` (for the `map` function) is immediately called with the error.\n\nNote, that since this function applies the `iterator` to each item in parallel,\nthere is no guarantee that the `iterator` functions will complete in order. \nHowever, the results array will be in the same order as the original `arr`.\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `iterator(item, callback)` - A function to apply to each item in `arr`.\n The iterator is passed a `callback(err, transformed)` which must be called once \n it has completed with an error (which can be `null`) and a transformed item.\n* `callback(err, results)` - A callback which is called when all `iterator`\n functions have finished, or an error occurs. Results is an array of the\n transformed items from the `arr`.\n\n__Example__\n\n```js\nasync.map(['file1','file2','file3'], fs.stat, function(err, results){\n // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n\n### mapSeries(arr, iterator, callback)\n\nThe same as [`map`](#map), only the `iterator` is applied to each item in `arr` in\nseries. The next `iterator` is only called once the current one has completed. \nThe results array will be in the same order as the original.\n\n\n---------------------------------------\n\n\n### mapLimit(arr, limit, iterator, callback)\n\nThe same as [`map`](#map), only no more than `limit` `iterator`s will be simultaneously \nrunning at any time.\n\nNote that the items are not processed in batches, so there is no guarantee that \nthe first `limit` `iterator` functions will complete before any others are started.\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `limit` - The maximum number of `iterator`s to run at any time.\n* `iterator(item, callback)` - A function to apply to each item in `arr`.\n The iterator is passed a `callback(err, transformed)` which must be called once \n it has completed with an error (which can be `null`) and a transformed item.\n* `callback(err, results)` - A callback which is called when all `iterator`\n calls have finished, or an error occurs. The result is an array of the\n transformed items from the original `arr`.\n\n__Example__\n\n```js\nasync.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){\n // results is now an array of stats for each file\n});\n```\n\n---------------------------------------\n\n\n\n### filter(arr, iterator, callback)\n\n__Alias:__ `select`\n\nReturns a new array of all the values in `arr` which pass an async truth test.\n_The callback for each `iterator` call only accepts a single argument of `true` or\n`false`; it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like `fs.exists`. This operation is\nperformed in parallel, but the results array will be in the same order as the\noriginal.\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `iterator(item, callback)` - A truth test to apply to each item in `arr`.\n The `iterator` is passed a `callback(truthValue)`, which must be called with a \n boolean argument once it has completed.\n* `callback(results)` - A callback which is called after all the `iterator`\n functions have finished.\n\n__Example__\n\n```js\nasync.filter(['file1','file2','file3'], fs.exists, function(results){\n // results now equals an array of the existing files\n});\n```\n\n---------------------------------------\n\n\n\n### filterSeries(arr, iterator, callback)\n\n__Alias:__ `selectSeries`\n\nThe same as [`filter`](#filter) only the `iterator` is applied to each item in `arr` in\nseries. The next `iterator` is only called once the current one has completed. \nThe results array will be in the same order as the original.\n\n---------------------------------------\n\n\n### reject(arr, iterator, callback)\n\nThe opposite of [`filter`](#filter). Removes values that pass an `async` truth test.\n\n---------------------------------------\n\n\n### rejectSeries(arr, iterator, callback)\n\nThe same as [`reject`](#reject), only the `iterator` is applied to each item in `arr`\nin series.\n\n\n---------------------------------------\n\n\n### reduce(arr, memo, iterator, callback)\n\n__Aliases:__ `inject`, `foldl`\n\nReduces `arr` into a single value using an async `iterator` to return\neach successive step. `memo` is the initial state of the reduction. \nThis function only operates in series. \n\nFor performance reasons, it may make sense to split a call to this function into \na parallel map, and then use the normal `Array.prototype.reduce` on the results. \nThis function is for situations where each step in the reduction needs to be async; \nif you can get the data before reducing it, then it's probably a good idea to do so.\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `memo` - The initial state of the reduction.\n* `iterator(memo, item, callback)` - A function applied to each item in the\n array to produce the next step in the reduction. The `iterator` is passed a\n `callback(err, reduction)` which accepts an optional error as its first \n argument, and the state of the reduction as the second. If an error is \n passed to the callback, the reduction is stopped and the main `callback` is \n immediately called with the error.\n* `callback(err, result)` - A callback which is called after all the `iterator`\n functions have finished. Result is the reduced value.\n\n__Example__\n\n```js\nasync.reduce([1,2,3], 0, function(memo, item, callback){\n // pointless async:\n process.nextTick(function(){\n callback(null, memo + item)\n });\n}, function(err, result){\n // result is now equal to the last value of memo, which is 6\n});\n```\n\n---------------------------------------\n\n\n### reduceRight(arr, memo, iterator, callback)\n\n__Alias:__ `foldr`\n\nSame as [`reduce`](#reduce), only operates on `arr` in reverse order.\n\n\n---------------------------------------\n\n\n### detect(arr, iterator, callback)\n\nReturns the first value in `arr` that passes an async truth test. The\n`iterator` is applied in parallel, meaning the first iterator to return `true` will\nfire the detect `callback` with that result. That means the result might not be\nthe first item in the original `arr` (in terms of order) that passes the test.\n\nIf order within the original `arr` is important, then look at [`detectSeries`](#detectSeries).\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `iterator(item, callback)` - A truth test to apply to each item in `arr`.\n The iterator is passed a `callback(truthValue)` which must be called with a \n boolean argument once it has completed.\n* `callback(result)` - A callback which is called as soon as any iterator returns\n `true`, or after all the `iterator` functions have finished. Result will be\n the first item in the array that passes the truth test (iterator) or the\n value `undefined` if none passed.\n\n__Example__\n\n```js\nasync.detect(['file1','file2','file3'], fs.exists, function(result){\n // result now equals the first file in the list that exists\n});\n```\n\n---------------------------------------\n\n\n### detectSeries(arr, iterator, callback)\n\nThe same as [`detect`](#detect), only the `iterator` is applied to each item in `arr`\nin series. This means the result is always the first in the original `arr` (in\nterms of array order) that passes the truth test.\n\n\n---------------------------------------\n\n\n### sortBy(arr, iterator, callback)\n\nSorts a list by the results of running each `arr` value through an async `iterator`.\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `iterator(item, callback)` - A function to apply to each item in `arr`.\n The iterator is passed a `callback(err, sortValue)` which must be called once it\n has completed with an error (which can be `null`) and a value to use as the sort\n criteria.\n* `callback(err, results)` - A callback which is called after all the `iterator`\n functions have finished, or an error occurs. Results is the items from\n the original `arr` sorted by the values returned by the `iterator` calls.\n\n__Example__\n\n```js\nasync.sortBy(['file1','file2','file3'], function(file, callback){\n fs.stat(file, function(err, stats){\n callback(err, stats.mtime);\n });\n}, function(err, results){\n // results is now the original array of files sorted by\n // modified date\n});\n```\n\n__Sort Order__\n\nBy modifying the callback parameter the sorting order can be influenced:\n\n```js\n//ascending order\nasync.sortBy([1,9,3,5], function(x, callback){\n callback(err, x);\n}, function(err,result){\n //result callback\n} );\n\n//descending order\nasync.sortBy([1,9,3,5], function(x, callback){\n callback(err, x*-1); //<- x*-1 instead of x, turns the order around\n}, function(err,result){\n //result callback\n} );\n```\n\n---------------------------------------\n\n\n### some(arr, iterator, callback)\n\n__Alias:__ `any`\n\nReturns `true` if at least one element in the `arr` satisfies an async test.\n_The callback for each iterator call only accepts a single argument of `true` or\n`false`; it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like `fs.exists`. Once any iterator\ncall returns `true`, the main `callback` is immediately called.\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `iterator(item, callback)` - A truth test to apply to each item in the array\n in parallel. The iterator is passed a callback(truthValue) which must be \n called with a boolean argument once it has completed.\n* `callback(result)` - A callback which is called as soon as any iterator returns\n `true`, or after all the iterator functions have finished. Result will be\n either `true` or `false` depending on the values of the async tests.\n\n__Example__\n\n```js\nasync.some(['file1','file2','file3'], fs.exists, function(result){\n // if result is true then at least one of the files exists\n});\n```\n\n---------------------------------------\n\n\n### every(arr, iterator, callback)\n\n__Alias:__ `all`\n\nReturns `true` if every element in `arr` satisfies an async test.\n_The callback for each `iterator` call only accepts a single argument of `true` or\n`false`; it does not accept an error argument first!_ This is in-line with the\nway node libraries work with truth tests like `fs.exists`.\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `iterator(item, callback)` - A truth test to apply to each item in the array\n in parallel. The iterator is passed a callback(truthValue) which must be \n called with a boolean argument once it has completed.\n* `callback(result)` - A callback which is called after all the `iterator`\n functions have finished. Result will be either `true` or `false` depending on\n the values of the async tests.\n\n__Example__\n\n```js\nasync.every(['file1','file2','file3'], fs.exists, function(result){\n // if result is true then every file exists\n});\n```\n\n---------------------------------------\n\n\n### concat(arr, iterator, callback)\n\nApplies `iterator` to each item in `arr`, concatenating the results. Returns the\nconcatenated list. The `iterator`s are called in parallel, and the results are\nconcatenated as they return. There is no guarantee that the results array will\nbe returned in the original order of `arr` passed to the `iterator` function.\n\n__Arguments__\n\n* `arr` - An array to iterate over.\n* `iterator(item, callback)` - A function to apply to each item in `arr`.\n The iterator is passed a `callback(err, results)` which must be called once it \n has completed with an error (which can be `null`) and an array of results.\n* `callback(err, results)` - A callback which is called after all the `iterator`\n functions have finished, or an error occurs. Results is an array containing\n the concatenated results of the `iterator` function.\n\n__Example__\n\n```js\nasync.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){\n // files is now a list of filenames that exist in the 3 directories\n});\n```\n\n---------------------------------------\n\n\n### concatSeries(arr, iterator, callback)\n\nSame as [`concat`](#concat), but executes in series instead of parallel.\n\n\n## Control Flow\n\n\n### series(tasks, [callback])\n\nRun the functions in the `tasks` array in series, each one running once the previous\nfunction has completed. If any functions in the series pass an error to its\ncallback, no more functions are run, and `callback` is immediately called with the value of the error. \nOtherwise, `callback` receives an array of results when `tasks` have completed.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function, and the results will be passed to the final `callback` as an object\ninstead of an array. This can be a more readable way of handling results from\n[`series`](#series).\n\n**Note** that while many implementations preserve the order of object properties, the\n[ECMAScript Language Specifcation](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) \nexplicitly states that\n\n> The mechanics and order of enumerating the properties is not specified.\n\nSo if you rely on the order in which your series of functions are executed, and want\nthis to work on all platforms, consider using an array. \n\n__Arguments__\n\n* `tasks` - An array or object containing functions to run, each function is passed\n a `callback(err, result)` it must call on completion with an error `err` (which can\n be `null`) and an optional `result` value.\n* `callback(err, results)` - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the `task` callbacks.\n\n__Example__\n\n```js\nasync.series([\n function(callback){\n // do some stuff ...\n callback(null, 'one');\n },\n function(callback){\n // do some more stuff ...\n callback(null, 'two');\n }\n],\n// optional callback\nfunction(err, results){\n // results is now equal to ['one', 'two']\n});\n\n\n// an example using an object instead of an array\nasync.series({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n }\n},\nfunction(err, results) {\n // results is now equal to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n\n### parallel(tasks, [callback])\n\nRun the `tasks` array of functions in parallel, without waiting until the previous\nfunction has completed. If any of the functions pass an error to its\ncallback, the main `callback` is immediately called with the value of the error.\nOnce the `tasks` have completed, the results are passed to the final `callback` as an\narray.\n\nIt is also possible to use an object instead of an array. Each property will be\nrun as a function and the results will be passed to the final `callback` as an object\ninstead of an array. This can be a more readable way of handling results from\n[`parallel`](#parallel).\n\n\n__Arguments__\n\n* `tasks` - An array or object containing functions to run. Each function is passed \n a `callback(err, result)` which it must call on completion with an error `err` \n (which can be `null`) and an optional `result` value.\n* `callback(err, results)` - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the task callbacks.\n\n__Example__\n\n```js\nasync.parallel([\n function(callback){\n setTimeout(function(){\n callback(null, 'one');\n }, 200);\n },\n function(callback){\n setTimeout(function(){\n callback(null, 'two');\n }, 100);\n }\n],\n// optional callback\nfunction(err, results){\n // the results array will equal ['one','two'] even though\n // the second function had a shorter timeout.\n});\n\n\n// an example using an object instead of an array\nasync.parallel({\n one: function(callback){\n setTimeout(function(){\n callback(null, 1);\n }, 200);\n },\n two: function(callback){\n setTimeout(function(){\n callback(null, 2);\n }, 100);\n }\n},\nfunction(err, results) {\n // results is now equals to: {one: 1, two: 2}\n});\n```\n\n---------------------------------------\n\n\n### parallelLimit(tasks, limit, [callback])\n\nThe same as [`parallel`](#parallel), only `tasks` are executed in parallel \nwith a maximum of `limit` tasks executing at any time.\n\nNote that the `tasks` are not executed in batches, so there is no guarantee that \nthe first `limit` tasks will complete before any others are started.\n\n__Arguments__\n\n* `tasks` - An array or object containing functions to run, each function is passed \n a `callback(err, result)` it must call on completion with an error `err` (which can\n be `null`) and an optional `result` value.\n* `limit` - The maximum number of `tasks` to run at any time.\n* `callback(err, results)` - An optional callback to run once all the functions\n have completed. This function gets a results array (or object) containing all \n the result arguments passed to the `task` callbacks.\n\n---------------------------------------\n\n\n### whilst(test, fn, callback)\n\nRepeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped,\nor an error occurs.\n\n__Arguments__\n\n* `test()` - synchronous truth test to perform before each execution of `fn`.\n* `fn(callback)` - A function which is called each time `test` passes. The function is\n passed a `callback(err)`, which must be called once it has completed with an \n optional `err` argument.\n* `callback(err)` - A callback which is called after the test fails and repeated\n execution of `fn` has stopped.\n\n__Example__\n\n```js\nvar count = 0;\n\nasync.whilst(\n function () { return count < 5; },\n function (callback) {\n count++;\n setTimeout(callback, 1000);\n },\n function (err) {\n // 5 seconds have passed\n }\n);\n```\n\n---------------------------------------\n\n\n### doWhilst(fn, test, callback)\n\nThe post-check version of [`whilst`](#whilst). To reflect the difference in \nthe order of operations, the arguments `test` and `fn` are switched. \n\n`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.\n\n---------------------------------------\n\n\n### until(test, fn, callback)\n\nRepeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped,\nor an error occurs.\n\nThe inverse of [`whilst`](#whilst).\n\n---------------------------------------\n\n\n### doUntil(fn, test, callback)\n\nLike [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`.\n\n---------------------------------------\n\n\n### forever(fn, errback)\n\nCalls the asynchronous function `fn` with a callback parameter that allows it to\ncall itself again, in series, indefinitely.\n\nIf an error is passed to the callback then `errback` is called with the\nerror, and execution stops, otherwise it will never be called.\n\n```js\nasync.forever(\n function(next) {\n // next is suitable for passing to things that need a callback(err [, whatever]);\n // it will result in this function being called again.\n },\n function(err) {\n // if next is called with a value in its first parameter, it will appear\n // in here as 'err', and execution will stop.\n }\n);\n```\n\n---------------------------------------\n\n\n### waterfall(tasks, [callback])\n\nRuns the `tasks` array of functions in series, each passing their results to the next in\nthe array. However, if any of the `tasks` pass an error to their own callback, the\nnext function is not executed, and the main `callback` is immediately called with\nthe error.\n\n__Arguments__\n\n* `tasks` - An array of functions to run, each function is passed a \n `callback(err, result1, result2, ...)` it must call on completion. The first\n argument is an error (which can be `null`) and any further arguments will be \n passed as arguments in order to the next task.\n* `callback(err, [results])` - An optional callback to run once all the functions\n have completed. This will be passed the results of the last task's callback.\n\n\n\n__Example__\n\n```js\nasync.waterfall([\n function(callback){\n callback(null, 'one', 'two');\n },\n function(arg1, arg2, callback){\n // arg1 now equals 'one' and arg2 now equals 'two'\n callback(null, 'three');\n },\n function(arg1, callback){\n // arg1 now equals 'three'\n callback(null, 'done');\n }\n], function (err, result) {\n // result now equals 'done' \n});\n```\n\n---------------------------------------\n\n### compose(fn1, fn2...)\n\nCreates a function which is a composition of the passed asynchronous\nfunctions. Each function consumes the return value of the function that\nfollows. Composing functions `f()`, `g()`, and `h()` would produce the result of\n`f(g(h()))`, only this version uses callbacks to obtain the return values.\n\nEach function is executed with the `this` binding of the composed function.\n\n__Arguments__\n\n* `functions...` - the asynchronous functions to compose\n\n\n__Example__\n\n```js\nfunction add1(n, callback) {\n setTimeout(function () {\n callback(null, n + 1);\n }, 10);\n}\n\nfunction mul3(n, callback) {\n setTimeout(function () {\n callback(null, n * 3);\n }, 10);\n}\n\nvar add1mul3 = async.compose(mul3, add1);\n\nadd1mul3(4, function (err, result) {\n // result now equals 15\n});\n```\n\n---------------------------------------\n\n### seq(fn1, fn2...)\n\nVersion of the compose function that is more natural to read.\nEach following function consumes the return value of the latter function. \n\nEach function is executed with the `this` binding of the composed function.\n\n__Arguments__\n\n* functions... - the asynchronous functions to compose\n\n\n__Example__\n\n```js\n// Requires lodash (or underscore), express3 and dresende's orm2.\n// Part of an app, that fetches cats of the logged user.\n// This example uses `seq` function to avoid overnesting and error \n// handling clutter.\napp.get('/cats', function(request, response) {\n function handleError(err, data, callback) {\n if (err) {\n console.error(err);\n response.json({ status: 'error', message: err.message });\n }\n else {\n callback(data);\n }\n }\n var User = request.models.User;\n async.seq(\n _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data))\n handleError,\n function(user, fn) {\n user.getCats(fn); // 'getCats' has signature (callback(err, data))\n },\n handleError,\n function(cats) {\n response.json({ status: 'ok', message: 'Cats found', data: cats });\n }\n )(req.session.user_id);\n }\n});\n```\n\n---------------------------------------\n\n### applyEach(fns, args..., callback)\n\nApplies the provided arguments to each function in the array, calling \n`callback` after all functions have completed. If you only provide the first\nargument, then it will return a function which lets you pass in the\narguments as if it were a single function call.\n\n__Arguments__\n\n* `fns` - the asynchronous functions to all call with the same arguments\n* `args...` - any number of separate arguments to pass to the function\n* `callback` - the final argument should be the callback, called when all\n functions have completed processing\n\n\n__Example__\n\n```js\nasync.applyEach([enableSearch, updateSchema], 'bucket', callback);\n\n// partial application example:\nasync.each(\n buckets,\n async.applyEach([enableSearch, updateSchema]),\n callback\n);\n```\n\n---------------------------------------\n\n\n### applyEachSeries(arr, iterator, callback)\n\nThe same as [`applyEach`](#applyEach) only the functions are applied in series.\n\n---------------------------------------\n\n\n### queue(worker, concurrency)\n\nCreates a `queue` object with the specified `concurrency`. Tasks added to the\n`queue` are processed in parallel (up to the `concurrency` limit). If all\n`worker`s are in progress, the task is queued until one becomes available. \nOnce a `worker` completes a `task`, that `task`'s callback is called.\n\n__Arguments__\n\n* `worker(task, callback)` - An asynchronous function for processing a queued\n task, which must call its `callback(err)` argument when finished, with an \n optional `error` as an argument.\n* `concurrency` - An `integer` for determining how many `worker` functions should be\n run in parallel.\n\n__Queue objects__\n\nThe `queue` object returned by this function has the following properties and\nmethods:\n\n* `length()` - a function returning the number of items waiting to be processed.\n* `started` - a function returning whether or not any items have been pushed and processed by the queue\n* `running()` - a function returning the number of items currently being processed.\n* `idle()` - a function returning false if there are items waiting or being processed, or true if not.\n* `concurrency` - an integer for determining how many `worker` functions should be\n run in parallel. This property can be changed after a `queue` is created to\n alter the concurrency on-the-fly.\n* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once \n the `worker` has finished processing the task. Instead of a single task, a `tasks` array\n can be submitted. The respective callback is used for every task in the list.\n* `unshift(task, [callback])` - add a new task to the front of the `queue`.\n* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, \n and further tasks will be queued.\n* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`.\n* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`.\n* `paused` - a boolean for determining whether the queue is in a paused state\n* `pause()` - a function that pauses the processing of tasks until `resume()` is called.\n* `resume()` - a function that resumes the processing of queued tasks when the queue is paused.\n* `kill()` - a function that empties remaining tasks from the queue forcing it to go idle.\n\n__Example__\n\n```js\n// create a queue object with concurrency 2\n\nvar q = async.queue(function (task, callback) {\n console.log('hello ' + task.name);\n callback();\n}, 2);\n\n\n// assign a callback\nq.drain = function() {\n console.log('all items have been processed');\n}\n\n// add some items to the queue\n\nq.push({name: 'foo'}, function (err) {\n console.log('finished processing foo');\n});\nq.push({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n});\n\n// add some items to the queue (batch-wise)\n\nq.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {\n console.log('finished processing bar');\n});\n\n// add some items to the front of the queue\n\nq.unshift({name: 'bar'}, function (err) {\n console.log('finished processing bar');\n});\n```\n\n\n---------------------------------------\n\n\n### priorityQueue(worker, concurrency)\n\nThe same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects:\n\n* `push(task, priority, [callback])` - `priority` should be a number. If an array of\n `tasks` is given, all tasks will be assigned the same priority.\n* The `unshift` method was removed.\n\n---------------------------------------\n\n\n### cargo(worker, [payload])\n\nCreates a `cargo` object with the specified payload. Tasks added to the\ncargo will be processed altogether (up to the `payload` limit). If the\n`worker` is in progress, the task is queued until it becomes available. Once\nthe `worker` has completed some tasks, each callback of those tasks is called.\nCheck out [this animation](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) for how `cargo` and `queue` work.\n\nWhile [queue](#queue) passes only one task to one of a group of workers\nat a time, cargo passes an array of tasks to a single worker, repeating\nwhen the worker is finished.\n\n__Arguments__\n\n* `worker(tasks, callback)` - An asynchronous function for processing an array of\n queued tasks, which must call its `callback(err)` argument when finished, with \n an optional `err` argument.\n* `payload` - An optional `integer` for determining how many tasks should be\n processed per round; if omitted, the default is unlimited.\n\n__Cargo objects__\n\nThe `cargo` object returned by this function has the following properties and\nmethods:\n\n* `length()` - A function returning the number of items waiting to be processed.\n* `payload` - An `integer` for determining how many tasks should be\n process per round. This property can be changed after a `cargo` is created to\n alter the payload on-the-fly.\n* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called\n once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` \n can be submitted. The respective callback is used for every task in the list.\n* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued.\n* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`.\n* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`.\n\n__Example__\n\n```js\n// create a cargo object with payload 2\n\nvar cargo = async.cargo(function (tasks, callback) {\n for(var i=0; i\n### auto(tasks, [callback])\n\nDetermines the best order for running the functions in `tasks`, based on their \nrequirements. Each function can optionally depend on other functions being completed \nfirst, and each function is run as soon as its requirements are satisfied. \n\nIf any of the functions pass an error to their callback, it will not \ncomplete (so any other functions depending on it will not run), and the main \n`callback` is immediately called with the error. Functions also receive an \nobject containing the results of functions which have completed so far.\n\nNote, all functions are called with a `results` object as a second argument, \nso it is unsafe to pass functions in the `tasks` object which cannot handle the\nextra argument. \n\nFor example, this snippet of code:\n\n```js\nasync.auto({\n readData: async.apply(fs.readFile, 'data.txt', 'utf-8')\n}, callback);\n```\n\nwill have the effect of calling `readFile` with the results object as the last\nargument, which will fail:\n\n```js\nfs.readFile('data.txt', 'utf-8', cb, {});\n```\n\nInstead, wrap the call to `readFile` in a function which does not forward the \n`results` object:\n\n```js\nasync.auto({\n readData: function(cb, results){\n fs.readFile('data.txt', 'utf-8', cb);\n }\n}, callback);\n```\n\n__Arguments__\n\n* `tasks` - An object. Each of its properties is either a function or an array of\n requirements, with the function itself the last item in the array. The object's key\n of a property serves as the name of the task defined by that property,\n i.e. can be used when specifying requirements for other tasks.\n The function receives two arguments: (1) a `callback(err, result)` which must be \n called when finished, passing an `error` (which can be `null`) and the result of \n the function's execution, and (2) a `results` object, containing the results of\n the previously executed functions.\n* `callback(err, results)` - An optional callback which is called when all the\n tasks have been completed. It receives the `err` argument if any `tasks` \n pass an error to their callback. Results are always returned; however, if \n an error occurs, no further `tasks` will be performed, and the results\n object will only contain partial results.\n\n\n__Example__\n\n```js\nasync.auto({\n get_data: function(callback){\n console.log('in get_data');\n // async code to get some data\n callback(null, 'data', 'converted to array');\n },\n make_folder: function(callback){\n console.log('in make_folder');\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n callback(null, 'folder');\n },\n write_file: ['get_data', 'make_folder', function(callback, results){\n console.log('in write_file', JSON.stringify(results));\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n callback(null, 'filename');\n }],\n email_link: ['write_file', function(callback, results){\n console.log('in email_link', JSON.stringify(results));\n // once the file is written let's email a link to it...\n // results.write_file contains the filename returned by write_file.\n callback(null, {'file':results.write_file, 'email':'user@example.com'});\n }]\n}, function(err, results) {\n console.log('err = ', err);\n console.log('results = ', results);\n});\n```\n\nThis is a fairly trivial example, but to do this using the basic parallel and\nseries functions would look like this:\n\n```js\nasync.parallel([\n function(callback){\n console.log('in get_data');\n // async code to get some data\n callback(null, 'data', 'converted to array');\n },\n function(callback){\n console.log('in make_folder');\n // async code to create a directory to store a file in\n // this is run at the same time as getting the data\n callback(null, 'folder');\n }\n],\nfunction(err, results){\n async.series([\n function(callback){\n console.log('in write_file', JSON.stringify(results));\n // once there is some data and the directory exists,\n // write the data to a file in the directory\n results.push('filename');\n callback(null);\n },\n function(callback){\n console.log('in email_link', JSON.stringify(results));\n // once the file is written let's email a link to it...\n callback(null, {'file':results.pop(), 'email':'user@example.com'});\n }\n ]);\n});\n```\n\nFor a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding\nnew tasks much easier (and the code more readable).\n\n\n---------------------------------------\n\n\n### retry([times = 5], task, [callback])\n\nAttempts to get a successful response from `task` no more than `times` times before\nreturning an error. If the task is successful, the `callback` will be passed the result\nof the successfull task. If all attemps fail, the callback will be passed the error and\nresult (if any) of the final attempt.\n\n__Arguments__\n\n* `times` - An integer indicating how many times to attempt the `task` before giving up. Defaults to 5.\n* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)`\n which must be called when finished, passing `err` (which can be `null`) and the `result` of \n the function's execution, and (2) a `results` object, containing the results of\n the previously executed functions (if nested inside another control flow).\n* `callback(err, results)` - An optional callback which is called when the\n task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`.\n\nThe [`retry`](#retry) function can be used as a stand-alone control flow by passing a\ncallback, as shown below:\n\n```js\nasync.retry(3, apiMethod, function(err, result) {\n // do something with the result\n});\n```\n\nIt can also be embeded within other control flow functions to retry individual methods\nthat are not as reliable, like this:\n\n```js\nasync.auto({\n users: api.getUsers.bind(api),\n payments: async.retry(3, api.getPayments.bind(api))\n}, function(err, results) {\n // do something with the results\n});\n```\n\n\n---------------------------------------\n\n\n### iterator(tasks)\n\nCreates an iterator function which calls the next function in the `tasks` array,\nreturning a continuation to call the next one after that. It's also possible to\n“peek” at the next iterator with `iterator.next()`.\n\nThis function is used internally by the `async` module, but can be useful when\nyou want to manually control the flow of functions in series.\n\n__Arguments__\n\n* `tasks` - An array of functions to run.\n\n__Example__\n\n```js\nvar iterator = async.iterator([\n function(){ sys.p('one'); },\n function(){ sys.p('two'); },\n function(){ sys.p('three'); }\n]);\n\nnode> var iterator2 = iterator();\n'one'\nnode> var iterator3 = iterator2();\n'two'\nnode> iterator3();\n'three'\nnode> var nextfn = iterator2.next();\nnode> nextfn();\n'three'\n```\n\n---------------------------------------\n\n\n### apply(function, arguments..)\n\nCreates a continuation function with some arguments already applied. \n\nUseful as a shorthand when combined with other control flow functions. Any arguments\npassed to the returned function are added to the arguments originally passed\nto apply.\n\n__Arguments__\n\n* `function` - The function you want to eventually apply all arguments to.\n* `arguments...` - Any number of arguments to automatically apply when the\n continuation is called.\n\n__Example__\n\n```js\n// using apply\n\nasync.parallel([\n async.apply(fs.writeFile, 'testfile1', 'test1'),\n async.apply(fs.writeFile, 'testfile2', 'test2'),\n]);\n\n\n// the same process without using apply\n\nasync.parallel([\n function(callback){\n fs.writeFile('testfile1', 'test1', callback);\n },\n function(callback){\n fs.writeFile('testfile2', 'test2', callback);\n }\n]);\n```\n\nIt's possible to pass any number of additional arguments when calling the\ncontinuation:\n\n```js\nnode> var fn = async.apply(sys.puts, 'one');\nnode> fn('two', 'three');\none\ntwo\nthree\n```\n\n---------------------------------------\n\n\n### nextTick(callback)\n\nCalls `callback` on a later loop around the event loop. In Node.js this just\ncalls `process.nextTick`; in the browser it falls back to `setImmediate(callback)`\nif available, otherwise `setTimeout(callback, 0)`, which means other higher priority\nevents may precede the execution of `callback`.\n\nThis is used internally for browser-compatibility purposes.\n\n__Arguments__\n\n* `callback` - The function to call on a later loop around the event loop.\n\n__Example__\n\n```js\nvar call_order = [];\nasync.nextTick(function(){\n call_order.push('two');\n // call_order now equals ['one','two']\n});\ncall_order.push('one')\n```\n\n\n### times(n, callback)\n\nCalls the `callback` function `n` times, and accumulates results in the same manner\nyou would use with [`map`](#map).\n\n__Arguments__\n\n* `n` - The number of times to run the function.\n* `callback` - The function to call `n` times.\n\n__Example__\n\n```js\n// Pretend this is some complicated async factory\nvar createUser = function(id, callback) {\n callback(null, {\n id: 'user' + id\n })\n}\n// generate 5 users\nasync.times(5, function(n, next){\n createUser(n, function(err, user) {\n next(err, user)\n })\n}, function(err, users) {\n // we should now have 5 users\n});\n```\n\n\n### timesSeries(n, callback)\n\nThe same as [`times`](#times), only the iterator is applied to each item in `arr` in\nseries. The next `iterator` is only called once the current one has completed. \nThe results array will be in the same order as the original.\n\n\n## Utils\n\n\n### memoize(fn, [hasher])\n\nCaches the results of an `async` function. When creating a hash to store function\nresults against, the callback is omitted from the hash and an optional hash\nfunction can be used.\n\nThe cache of results is exposed as the `memo` property of the function returned\nby `memoize`.\n\n__Arguments__\n\n* `fn` - The function to proxy and cache results from.\n* `hasher` - Tn optional function for generating a custom hash for storing\n results. It has all the arguments applied to it apart from the callback, and\n must be synchronous.\n\n__Example__\n\n```js\nvar slow_fn = function (name, callback) {\n // do something\n callback(null, result);\n};\nvar fn = async.memoize(slow_fn);\n\n// fn can now be used as if it were slow_fn\nfn('some name', function () {\n // callback\n});\n```\n\n\n### unmemoize(fn)\n\nUndoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized\nform. Handy for testing.\n\n__Arguments__\n\n* `fn` - the memoized function\n\n\n### log(function, arguments)\n\nLogs the result of an `async` function to the `console`. Only works in Node.js or\nin browsers that support `console.log` and `console.error` (such as FF and Chrome).\nIf multiple arguments are returned from the async function, `console.log` is\ncalled on each argument in order.\n\n__Arguments__\n\n* `function` - The function you want to eventually apply all arguments to.\n* `arguments...` - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n setTimeout(function(){\n callback(null, 'hello ' + name);\n }, 1000);\n};\n```\n```js\nnode> async.log(hello, 'world');\n'hello world'\n```\n\n---------------------------------------\n\n\n### dir(function, arguments)\n\nLogs the result of an `async` function to the `console` using `console.dir` to\ndisplay the properties of the resulting object. Only works in Node.js or\nin browsers that support `console.dir` and `console.error` (such as FF and Chrome).\nIf multiple arguments are returned from the async function, `console.dir` is\ncalled on each argument in order.\n\n__Arguments__\n\n* `function` - The function you want to eventually apply all arguments to.\n* `arguments...` - Any number of arguments to apply to the function.\n\n__Example__\n\n```js\nvar hello = function(name, callback){\n setTimeout(function(){\n callback(null, {hello: name});\n }, 1000);\n};\n```\n```js\nnode> async.dir(hello, 'world');\n{hello: 'world'}\n```\n\n---------------------------------------\n\n\n### noConflict()\n\nChanges the value of `async` back to its original value, returning a reference to the\n`async` object.\n", - "readmeFilename": "README.md", - "homepage": "https://github.com/caolan/async", - "_id": "async@0.9.0", - "_shasum": "ac3613b1da9bed1b47510bb4651b8931e47146c7", - "_from": "async@0.9.0", - "_resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz" + "spm": { + "main": "lib/async.js" + }, + "volo": { + "main": "lib/async.js", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] + }, + "gitHead": "5bfcd31c72e003f96df025e75753463da61f49f9", + "homepage": "https://github.com/caolan/async#readme", + "_id": "async@1.4.0", + "_shasum": "35f86f83c59e0421d099cd9a91d8278fb578c00d", + "_from": "async@1.4.0", + "_npmVersion": "2.13.0", + "_nodeVersion": "2.4.0", + "_npmUser": { + "name": "megawac", + "email": "megawac@gmail.com" + }, + "dist": { + "shasum": "35f86f83c59e0421d099cd9a91d8278fb578c00d", + "tarball": "http://registry.npmjs.org/async/-/async-1.4.0.tgz" + }, + "maintainers": [ + { + "name": "caolan", + "email": "caolan.mcmahon@gmail.com" + }, + { + "name": "beaugunderson", + "email": "beau@beaugunderson.com" + }, + { + "name": "aearly", + "email": "alexander.early@gmail.com" + }, + { + "name": "megawac", + "email": "megawac@gmail.com" + } + ], + "directories": {}, + "_resolved": "https://registry.npmjs.org/async/-/async-1.4.0.tgz" } diff --git a/node_modules/bluebird/LICENSE b/node_modules/bluebird/LICENSE index a3966cf9..8d4ca280 100644 --- a/node_modules/bluebird/LICENSE +++ b/node_modules/bluebird/LICENSE @@ -7,7 +7,7 @@ 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:

+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. diff --git a/node_modules/bluebird/js/main/async.js b/node_modules/bluebird/js/main/async.js index 7917e088..01044596 100644 --- a/node_modules/bluebird/js/main/async.js +++ b/node_modules/bluebird/js/main/async.js @@ -3,12 +3,13 @@ var firstLineError; try {throw new Error(); } catch (e) {firstLineError = e;} var schedule = require("./schedule.js"); var Queue = require("./queue.js"); -var _process = typeof process !== "undefined" ? process : undefined; +var util = require("./util.js"); function Async() { this._isTickUsed = false; this._lateQueue = new Queue(16); this._normalQueue = new Queue(16); + this._trampolineEnabled = true; var self = this; this.drainQueues = function () { self._drainQueues(); @@ -17,17 +18,23 @@ function Async() { schedule.isStatic ? schedule(this.drainQueues) : schedule; } -Async.prototype.haveItemsQueued = function () { - return this._normalQueue.length() > 0; +Async.prototype.disableTrampolineIfNecessary = function() { + if (util.hasDevTools) { + this._trampolineEnabled = false; + } }; -Async.prototype._withDomain = function(fn) { - if (_process !== undefined && - _process.domain != null && - !fn.domain) { - fn = _process.domain.bind(fn); +Async.prototype.enableTrampoline = function() { + if (!this._trampolineEnabled) { + this._trampolineEnabled = true; + this._schedule = function(fn) { + setTimeout(fn, 0); + }; } - return fn; +}; + +Async.prototype.haveItemsQueued = function () { + return this._normalQueue.length() > 0; }; Async.prototype.throwLater = function(fn, arg) { @@ -35,7 +42,6 @@ Async.prototype.throwLater = function(fn, arg) { arg = fn; fn = function () { throw arg; }; } - fn = this._withDomain(fn); if (typeof setTimeout !== "undefined") { setTimeout(function() { fn(arg); @@ -49,27 +55,65 @@ Async.prototype.throwLater = function(fn, arg) { } }; -Async.prototype.invokeLater = function (fn, receiver, arg) { - fn = this._withDomain(fn); +function AsyncInvokeLater(fn, receiver, arg) { this._lateQueue.push(fn, receiver, arg); this._queueTick(); -}; +} -Async.prototype.invokeFirst = function (fn, receiver, arg) { - fn = this._withDomain(fn); - this._normalQueue.unshift(fn, receiver, arg); - this._queueTick(); -}; - -Async.prototype.invoke = function (fn, receiver, arg) { - fn = this._withDomain(fn); +function AsyncInvoke(fn, receiver, arg) { this._normalQueue.push(fn, receiver, arg); this._queueTick(); -}; +} -Async.prototype.settlePromises = function(promise) { +function AsyncSettlePromises(promise) { this._normalQueue._pushOne(promise); this._queueTick(); +} + +if (!util.hasDevTools) { + Async.prototype.invokeLater = AsyncInvokeLater; + Async.prototype.invoke = AsyncInvoke; + Async.prototype.settlePromises = AsyncSettlePromises; +} else { + if (schedule.isStatic) { + schedule = function(fn) { setTimeout(fn, 0); }; + } + Async.prototype.invokeLater = function (fn, receiver, arg) { + if (this._trampolineEnabled) { + AsyncInvokeLater.call(this, fn, receiver, arg); + } else { + this._schedule(function() { + setTimeout(function() { + fn.call(receiver, arg); + }, 100); + }); + } + }; + + Async.prototype.invoke = function (fn, receiver, arg) { + if (this._trampolineEnabled) { + AsyncInvoke.call(this, fn, receiver, arg); + } else { + this._schedule(function() { + fn.call(receiver, arg); + }); + } + }; + + Async.prototype.settlePromises = function(promise) { + if (this._trampolineEnabled) { + AsyncSettlePromises.call(this, promise); + } else { + this._schedule(function() { + promise._settlePromises(); + }); + } + }; +} + +Async.prototype.invokeFirst = function (fn, receiver, arg) { + this._normalQueue.unshift(fn, receiver, arg); + this._queueTick(); }; Async.prototype._drainQueue = function(queue) { diff --git a/node_modules/bluebird/js/main/bind.js b/node_modules/bluebird/js/main/bind.js index d6f6da25..9d8257ae 100644 --- a/node_modules/bluebird/js/main/bind.js +++ b/node_modules/bluebird/js/main/bind.js @@ -10,7 +10,6 @@ var targetRejected = function(e, context) { }; var bindingResolved = function(thisArg, context) { - this._setBoundTo(thisArg); if (this._isPending()) { this._resolveCallback(context.target); } @@ -25,6 +24,8 @@ Promise.prototype.bind = function (thisArg) { var ret = new Promise(INTERNAL); ret._propagateFrom(this, 1); var target = this._target(); + + ret._setBoundTo(maybePromise); if (maybePromise instanceof Promise) { var context = { promiseRejectionQueued: false, @@ -36,7 +37,6 @@ Promise.prototype.bind = function (thisArg) { maybePromise._then( bindingResolved, bindingRejected, ret._progress, ret, context); } else { - ret._setBoundTo(thisArg); ret._resolveCallback(target); } return ret; @@ -59,13 +59,12 @@ Promise.bind = function (thisArg, value) { var maybePromise = tryConvertToPromise(thisArg); var ret = new Promise(INTERNAL); + ret._setBoundTo(maybePromise); if (maybePromise instanceof Promise) { - maybePromise._then(function(thisArg) { - ret._setBoundTo(thisArg); + maybePromise._then(function() { ret._resolveCallback(value); }, ret._reject, ret._progress, ret, null); } else { - ret._setBoundTo(thisArg); ret._resolveCallback(value); } return ret; diff --git a/node_modules/bluebird/js/main/cancel.js b/node_modules/bluebird/js/main/cancel.js index 99c5b694..9eb40b6f 100644 --- a/node_modules/bluebird/js/main/cancel.js +++ b/node_modules/bluebird/js/main/cancel.js @@ -25,6 +25,7 @@ Promise.prototype.cancel = function (reason) { Promise.prototype.cancellable = function () { if (this._cancellable()) return this; + async.enableTrampoline(); this._setCancellable(); this._cancellationParent = undefined; return this; diff --git a/node_modules/bluebird/js/main/captured_trace.js b/node_modules/bluebird/js/main/captured_trace.js index 4d678704..802acd35 100644 --- a/node_modules/bluebird/js/main/captured_trace.js +++ b/node_modules/bluebird/js/main/captured_trace.js @@ -87,7 +87,7 @@ CapturedTrace.prototype.attachExtraTrace = function(error) { } removeCommonRoots(stacks); removeDuplicateOrEmptyJumps(stacks); - error.stack = reconstructStack(message, stacks); + util.notEnumerableProp(error, "stack", reconstructStack(message, stacks)); util.notEnumerableProp(error, "__stackCleaned__", true); }; @@ -382,7 +382,8 @@ var captureStackTrace = (function stackDetection() { catch(e) { hasStackAfterThrow = ("stack" in e); } - if (!("stack" in err) && hasStackAfterThrow) { + if (!("stack" in err) && hasStackAfterThrow && + typeof Error.stackTraceLimit === "number") { stackFramePattern = v8stackFramePattern; formatStack = v8stackFormatter; return function captureStackTrace(o) { diff --git a/node_modules/bluebird/js/main/catch_filter.js b/node_modules/bluebird/js/main/catch_filter.js index 040f0572..df127333 100644 --- a/node_modules/bluebird/js/main/catch_filter.js +++ b/node_modules/bluebird/js/main/catch_filter.js @@ -30,7 +30,7 @@ function safePredicate(predicate, e) { CatchFilter.prototype.doFilter = function (e) { var cb = this._callback; var promise = this._promise; - var boundTo = promise._boundTo; + var boundTo = promise._boundValue(); for (var i = 0, len = this._instances.length; i < len; ++i) { var item = this._instances[i]; var itemIsErrorType = item === Error || diff --git a/node_modules/bluebird/js/main/debuggability.js b/node_modules/bluebird/js/main/debuggability.js index 2cec5e7b..f377ffa1 100644 --- a/node_modules/bluebird/js/main/debuggability.js +++ b/node_modules/bluebird/js/main/debuggability.js @@ -1,5 +1,6 @@ "use strict"; module.exports = function(Promise, CapturedTrace) { +var getDomain = Promise._getDomain; var async = require("./async.js"); var Warning = require("./errors.js").Warning; var util = require("./util.js"); @@ -10,7 +11,17 @@ var debugging = false || (util.isNode && (!!process.env["BLUEBIRD_DEBUG"] || process.env["NODE_ENV"] === "development")); +if (debugging) { + async.disableTrampolineIfNecessary(); +} + +Promise.prototype._ignoreRejections = function() { + this._unsetRejectionIsUnhandled(); + this._bitField = this._bitField | 16777216; +}; + Promise.prototype._ensurePossibleRejectionHandled = function () { + if ((this._bitField & 16777216) !== 0) return; this._setRejectionIsUnhandled(); async.invokeLater(this._notifyUnhandledRejection, this, undefined); }; @@ -89,7 +100,8 @@ Promise.prototype._attachExtraTrace = function (error, ignoreSelf) { trace.attachExtraTrace(error); } else if (!error.__stackCleaned__) { var parsed = CapturedTrace.parseStackAndMessage(error); - error.stack = parsed.message + "\n" + parsed.stack.join("\n"); + util.notEnumerableProp(error, "stack", + parsed.message + "\n" + parsed.stack.join("\n")); util.notEnumerableProp(error, "__stackCleaned__", true); } } @@ -108,11 +120,17 @@ Promise.prototype._warn = function(message) { }; Promise.onPossiblyUnhandledRejection = function (fn) { - possiblyUnhandledRejection = typeof fn === "function" ? fn : undefined; + var domain = getDomain(); + possiblyUnhandledRejection = + typeof fn === "function" ? (domain === null ? fn : domain.bind(fn)) + : undefined; }; Promise.onUnhandledRejectionHandled = function (fn) { - unhandledRejectionHandled = typeof fn === "function" ? fn : undefined; + var domain = getDomain(); + unhandledRejectionHandled = + typeof fn === "function" ? (domain === null ? fn : domain.bind(fn)) + : undefined; }; Promise.longStackTraces = function () { @@ -122,6 +140,9 @@ Promise.longStackTraces = function () { throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a See http://goo.gl/DT1qyG\u000a"); } debugging = CapturedTrace.isSupported(); + if (debugging) { + async.disableTrampolineIfNecessary(); + } }; Promise.hasLongStackTraces = function () { diff --git a/node_modules/bluebird/js/main/direct_resolve.js b/node_modules/bluebird/js/main/direct_resolve.js index c61a367f..f1c2efd7 100644 --- a/node_modules/bluebird/js/main/direct_resolve.js +++ b/node_modules/bluebird/js/main/direct_resolve.js @@ -1,7 +1,6 @@ "use strict"; var util = require("./util.js"); var isPrimitive = util.isPrimitive; -var wrapsPrimitiveReceiver = util.wrapsPrimitiveReceiver; module.exports = function(Promise) { var returner = function () { @@ -10,6 +9,10 @@ var returner = function () { var thrower = function () { throw this; }; +var returnUndefined = function() {}; +var throwUndefined = function() { + throw undefined; +}; var wrapper = function (value, action) { if (action === 1) { @@ -26,7 +29,9 @@ var wrapper = function (value, action) { Promise.prototype["return"] = Promise.prototype.thenReturn = function (value) { - if (wrapsPrimitiveReceiver && isPrimitive(value)) { + if (value === undefined) return this.then(returnUndefined); + + if (isPrimitive(value)) { return this._then( wrapper(value, 2), undefined, @@ -40,7 +45,9 @@ Promise.prototype.thenReturn = function (value) { Promise.prototype["throw"] = Promise.prototype.thenThrow = function (reason) { - if (wrapsPrimitiveReceiver && isPrimitive(reason)) { + if (reason === undefined) return this.then(throwUndefined); + + if (isPrimitive(reason)) { return this._then( wrapper(reason, 1), undefined, diff --git a/node_modules/bluebird/js/main/finally.js b/node_modules/bluebird/js/main/finally.js index ed84a2a1..c9342bcf 100644 --- a/node_modules/bluebird/js/main/finally.js +++ b/node_modules/bluebird/js/main/finally.js @@ -1,7 +1,6 @@ "use strict"; module.exports = function(Promise, NEXT_FILTER, tryConvertToPromise) { var util = require("./util.js"); -var wrapsPrimitiveReceiver = util.wrapsPrimitiveReceiver; var isPrimitive = util.isPrimitive; var thrower = util.thrower; @@ -23,7 +22,7 @@ function throw$(r) { } function promisedFinally(ret, reasonOrValue, isFulfilled) { var then; - if (wrapsPrimitiveReceiver && isPrimitive(reasonOrValue)) { + if (isPrimitive(reasonOrValue)) { then = isFulfilled ? return$(reasonOrValue) : throw$(reasonOrValue); } else { then = isFulfilled ? returnThis : throwThis; @@ -36,7 +35,7 @@ function finallyHandler(reasonOrValue) { var handler = this.handler; var ret = promise._isBound() - ? handler.call(promise._boundTo) + ? handler.call(promise._boundValue()) : handler(); if (ret !== undefined) { @@ -61,7 +60,7 @@ function tapHandler(value) { var handler = this.handler; var ret = promise._isBound() - ? handler.call(promise._boundTo, value) + ? handler.call(promise._boundValue(), value) : handler(value); if (ret !== undefined) { diff --git a/node_modules/bluebird/js/main/map.js b/node_modules/bluebird/js/main/map.js index 66a5b179..2f40efd2 100644 --- a/node_modules/bluebird/js/main/map.js +++ b/node_modules/bluebird/js/main/map.js @@ -4,6 +4,7 @@ module.exports = function(Promise, apiRejection, tryConvertToPromise, INTERNAL) { +var getDomain = Promise._getDomain; var async = require("./async.js"); var util = require("./util.js"); var tryCatch = util.tryCatch; @@ -14,7 +15,8 @@ var EMPTY_ARRAY = []; function MappingPromiseArray(promises, fn, limit, _filter) { this.constructor$(promises); this._promise._captureStackTrace(); - this._callback = fn; + var domain = getDomain(); + this._callback = domain === null ? fn : domain.bind(fn); this._preservedValues = _filter === INTERNAL ? new Array(this.length()) : null; @@ -49,7 +51,7 @@ MappingPromiseArray.prototype._promiseFulfilled = function (value, index) { if (preservedValues !== null) preservedValues[index] = value; var callback = this._callback; - var receiver = this._promise._boundTo; + var receiver = this._promise._boundValue(); this._promise._pushContext(); var ret = tryCatch(callback).call(receiver, value, index, length); this._promise._popContext(); diff --git a/node_modules/bluebird/js/main/nodeify.js b/node_modules/bluebird/js/main/nodeify.js index 4bbafc4d..257565db 100644 --- a/node_modules/bluebird/js/main/nodeify.js +++ b/node_modules/bluebird/js/main/nodeify.js @@ -8,7 +8,8 @@ var errorObj = util.errorObj; function spreadAdapter(val, nodeback) { var promise = this; if (!util.isArray(val)) return successAdapter.call(promise, val, nodeback); - var ret = tryCatch(nodeback).apply(promise._boundTo, [null].concat(val)); + var ret = + tryCatch(nodeback).apply(promise._boundValue(), [null].concat(val)); if (ret === errorObj) { async.throwLater(ret.e); } @@ -16,7 +17,7 @@ function spreadAdapter(val, nodeback) { function successAdapter(val, nodeback) { var promise = this; - var receiver = promise._boundTo; + var receiver = promise._boundValue(); var ret = val === undefined ? tryCatch(nodeback).call(receiver, null) : tryCatch(nodeback).call(receiver, null, val); @@ -32,12 +33,13 @@ function errorAdapter(reason, nodeback) { newReason.cause = reason; reason = newReason; } - var ret = tryCatch(nodeback).call(promise._boundTo, reason); + var ret = tryCatch(nodeback).call(promise._boundValue(), reason); if (ret === errorObj) { async.throwLater(ret.e); } } +Promise.prototype.asCallback = Promise.prototype.nodeify = function (nodeback, options) { if (typeof nodeback == "function") { var adapter = successAdapter; diff --git a/node_modules/bluebird/js/main/promise.js b/node_modules/bluebird/js/main/promise.js index d91976b3..eb081181 100644 --- a/node_modules/bluebird/js/main/promise.js +++ b/node_modules/bluebird/js/main/promise.js @@ -9,7 +9,23 @@ var reflect = function() { var apiRejection = function(msg) { return Promise.reject(new TypeError(msg)); }; + var util = require("./util.js"); + +var getDomain; +if (util.isNode) { + getDomain = function() { + var ret = process.domain; + if (ret === undefined) ret = null; + return ret; + }; +} else { + getDomain = function() { + return null; + }; +} +util.notEnumerableProp(Promise, "_getDomain", getDomain); + var async = require("./async.js"); var errors = require("./errors.js"); var TypeError = Promise.TypeError = errors.TypeError; @@ -208,8 +224,12 @@ Promise.prototype._then = function ( if (!haveInternalData) ret._setIsMigrated(); } - var callbackIndex = - target._addCallbacks(didFulfill, didReject, didProgress, ret, receiver); + var callbackIndex = target._addCallbacks(didFulfill, + didReject, + didProgress, + ret, + receiver, + getDomain()); if (target._isResolved() && !target._isSettlePromisesQueued()) { async.invoke( @@ -291,7 +311,7 @@ Promise.prototype._receiverAt = function (index) { : this[ index * 5 - 5 + 4]; if (ret === undefined && this._isBound()) { - return this._boundTo; + return this._boundValue(); } return ret; }; @@ -314,6 +334,20 @@ Promise.prototype._rejectionHandlerAt = function (index) { : this[index * 5 - 5 + 1]; }; +Promise.prototype._boundValue = function() { + var ret = this._boundTo; + if (ret !== undefined) { + if (ret instanceof Promise) { + if (ret.isFulfilled()) { + return ret.value(); + } else { + return undefined; + } + } + } + return ret; +}; + Promise.prototype._migrateCallbacks = function (follower, index) { var fulfill = follower._fulfillmentHandlerAt(index); var reject = follower._rejectionHandlerAt(index); @@ -321,7 +355,7 @@ Promise.prototype._migrateCallbacks = function (follower, index) { var promise = follower._promiseAt(index); var receiver = follower._receiverAt(index); if (promise instanceof Promise) promise._setIsMigrated(); - this._addCallbacks(fulfill, reject, progress, promise, receiver); + this._addCallbacks(fulfill, reject, progress, promise, receiver, null); }; Promise.prototype._addCallbacks = function ( @@ -329,7 +363,8 @@ Promise.prototype._addCallbacks = function ( reject, progress, promise, - receiver + receiver, + domain ) { var index = this._length(); @@ -341,20 +376,34 @@ Promise.prototype._addCallbacks = function ( if (index === 0) { this._promise0 = promise; if (receiver !== undefined) this._receiver0 = receiver; - if (typeof fulfill === "function" && !this._isCarryingStackTrace()) - this._fulfillmentHandler0 = fulfill; - if (typeof reject === "function") this._rejectionHandler0 = reject; - if (typeof progress === "function") this._progressHandler0 = progress; + if (typeof fulfill === "function" && !this._isCarryingStackTrace()) { + this._fulfillmentHandler0 = + domain === null ? fulfill : domain.bind(fulfill); + } + if (typeof reject === "function") { + this._rejectionHandler0 = + domain === null ? reject : domain.bind(reject); + } + if (typeof progress === "function") { + this._progressHandler0 = + domain === null ? progress : domain.bind(progress); + } } else { var base = index * 5 - 5; this[base + 3] = promise; this[base + 4] = receiver; - if (typeof fulfill === "function") - this[base + 0] = fulfill; - if (typeof reject === "function") - this[base + 1] = reject; - if (typeof progress === "function") - this[base + 2] = progress; + if (typeof fulfill === "function") { + this[base + 0] = + domain === null ? fulfill : domain.bind(fulfill); + } + if (typeof reject === "function") { + this[base + 1] = + domain === null ? reject : domain.bind(reject); + } + if (typeof progress === "function") { + this[base + 2] = + domain === null ? progress : domain.bind(progress); + } } this._setLength(index + 1); return index; @@ -449,7 +498,7 @@ Promise.prototype._settlePromiseFromHandler = function ( promise._pushContext(); var x; if (receiver === APPLY && !this._isRejected()) { - x = tryCatch(handler).apply(this._boundTo, value); + x = tryCatch(handler).apply(this._boundValue(), value); } else { x = tryCatch(handler).call(receiver, value); } @@ -519,8 +568,6 @@ Promise.prototype._settlePromiseAt = function (index) { this._isCarryingStackTrace() ? this._getCarriedStackTrace() : undefined; var value = this._settledValue; var receiver = this._receiverAt(index); - - this._clearCallbackDataAtIndex(index); if (typeof handler === "function") { @@ -647,7 +694,11 @@ Promise.prototype._settlePromises = function () { } }; -Promise._makeSelfResolutionError = makeSelfResolutionError; +util.notEnumerableProp(Promise, + "_makeSelfResolutionError", + makeSelfResolutionError); + +require("./progress.js")(Promise, PromiseArray); require("./method.js")(Promise, INTERNAL, tryConvertToPromise, apiRejection); require("./bind.js")(Promise, INTERNAL, tryConvertToPromise); require("./finally.js")(Promise, NEXT_FILTER, tryConvertToPromise); @@ -656,18 +707,17 @@ require("./synchronous_inspection.js")(Promise); require("./join.js")(Promise, PromiseArray, tryConvertToPromise, INTERNAL); Promise.Promise = Promise; require('./map.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL); +require('./cancel.js')(Promise); require('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext); require('./generators.js')(Promise, apiRejection, INTERNAL, tryConvertToPromise); require('./nodeify.js')(Promise); -require('./cancel.js')(Promise); -require('./promisify.js')(Promise, INTERNAL); +require('./call_get.js')(Promise); require('./props.js')(Promise, PromiseArray, tryConvertToPromise, apiRejection); require('./race.js')(Promise, INTERNAL, tryConvertToPromise, apiRejection); require('./reduce.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL); require('./settle.js')(Promise, PromiseArray); -require('./call_get.js')(Promise); require('./some.js')(Promise, PromiseArray, apiRejection); -require('./progress.js')(Promise, PromiseArray); +require('./promisify.js')(Promise, INTERNAL); require('./any.js')(Promise); require('./each.js')(Promise, INTERNAL); require('./timers.js')(Promise, INTERNAL); diff --git a/node_modules/bluebird/js/main/promise_array.js b/node_modules/bluebird/js/main/promise_array.js index 6dac8664..b2e8f1cc 100644 --- a/node_modules/bluebird/js/main/promise_array.js +++ b/node_modules/bluebird/js/main/promise_array.js @@ -80,7 +80,7 @@ PromiseArray.prototype._init = function init(_, resolveValueIfEmpty) { if (maybePromise instanceof Promise) { maybePromise = maybePromise._target(); if (isResolved) { - maybePromise._unsetRejectionIsUnhandled(); + maybePromise._ignoreRejections(); } else if (maybePromise._isPending()) { maybePromise._proxyPromiseArray(this, i); } else if (maybePromise._isFulfilled()) { diff --git a/node_modules/bluebird/js/main/promisify.js b/node_modules/bluebird/js/main/promisify.js index 8bcfc8ed..2f088a30 100644 --- a/node_modules/bluebird/js/main/promisify.js +++ b/node_modules/bluebird/js/main/promisify.js @@ -10,12 +10,21 @@ var canEvaluate = util.canEvaluate; var TypeError = require("./errors").TypeError; var defaultSuffix = "Async"; var defaultPromisified = {__isPromisified__: true}; -var noCopyPropsPattern = - /^(?:length|name|arguments|caller|prototype|__isPromisified__)$/; -var defaultFilter = function(name, func) { +var noCopyProps = [ + "arity", "length", + "name", + "arguments", + "caller", + "callee", + "prototype", + "__isPromisified__" +]; +var noCopyPropsPattern = new RegExp("^(?:" + noCopyProps.join("|") + ")$"); + +var defaultFilter = function(name) { return util.isIdentifier(name) && name.charAt(0) !== "_" && - !util.isClass(func); + name !== "constructor"; }; function propsFilter(key) { @@ -159,6 +168,7 @@ function(callback, receiver, originalName, fn) { "nodebackForPromise", "tryCatch", "errorObj", + "notEnumerableProp", "INTERNAL","'use strict'; \n\ var ret = function (Parameters) { \n\ 'use strict'; \n\ @@ -176,7 +186,7 @@ function(callback, receiver, originalName, fn) { } \n\ return promise; \n\ }; \n\ - ret.__isPromisified__ = true; \n\ + notEnumerableProp(ret, '__isPromisified__', true); \n\ return ret; \n\ " .replace("Parameters", parameterDeclaration(newParameterCount)) @@ -190,6 +200,7 @@ function(callback, receiver, originalName, fn) { nodebackForPromise, util.tryCatch, util.errorObj, + util.notEnumerableProp, INTERNAL ); }; @@ -216,7 +227,7 @@ function makeNodePromisifiedClosure(callback, receiver, _, fn) { } return promise; } - promisified.__isPromisified__ = true; + util.notEnumerableProp(promisified, "__isPromisified__", true); return promisified; } diff --git a/node_modules/bluebird/js/main/reduce.js b/node_modules/bluebird/js/main/reduce.js index 31922201..1f92dafa 100644 --- a/node_modules/bluebird/js/main/reduce.js +++ b/node_modules/bluebird/js/main/reduce.js @@ -4,6 +4,7 @@ module.exports = function(Promise, apiRejection, tryConvertToPromise, INTERNAL) { +var getDomain = Promise._getDomain; var async = require("./async.js"); var util = require("./util.js"); var tryCatch = util.tryCatch; @@ -32,7 +33,8 @@ function ReductionPromiseArray(promises, fn, accum, _each) { } } if (!(isPromise || this._zerothIsAccum)) this._gotAccum = true; - this._callback = fn; + var domain = getDomain(); + this._callback = domain === null ? fn : domain.bind(fn); this._accum = accum; if (!rejected) async.invoke(init, this, undefined); } @@ -86,7 +88,7 @@ ReductionPromiseArray.prototype._promiseFulfilled = function (value, index) { if (!gotAccum) return; var callback = this._callback; - var receiver = this._promise._boundTo; + var receiver = this._promise._boundValue(); var ret; for (var i = this._reducingIndex; i < length; ++i) { diff --git a/node_modules/bluebird/js/main/schedule.js b/node_modules/bluebird/js/main/schedule.js index fa0abed0..bb04a8a2 100644 --- a/node_modules/bluebird/js/main/schedule.js +++ b/node_modules/bluebird/js/main/schedule.js @@ -1,8 +1,19 @@ "use strict"; var schedule; -if (require("./util.js").isNode) { - schedule = process.nextTick; -} else if (typeof MutationObserver !== "undefined") { +var util = require("./util"); +var noAsyncScheduler = function() { + throw new Error("No async scheduler available\u000a\u000a See http://goo.gl/m3OTXk\u000a"); +}; +if (util.isNode && typeof MutationObserver === "undefined") { + var GlobalSetImmediate = global.setImmediate; + var ProcessNextTick = process.nextTick; + schedule = util.isRecentNode + ? function(fn) { GlobalSetImmediate.call(global, fn); } + : function(fn) { ProcessNextTick.call(process, fn); }; +} else if ((typeof MutationObserver !== "undefined") && + !(typeof window !== "undefined" && + window.navigator && + window.navigator.standalone)) { schedule = function(fn) { var div = document.createElement("div"); var observer = new MutationObserver(fn); @@ -10,13 +21,15 @@ if (require("./util.js").isNode) { return function() { div.classList.toggle("foo"); }; }; schedule.isStatic = true; +} else if (typeof setImmediate !== "undefined") { + schedule = function (fn) { + setImmediate(fn); + }; } else if (typeof setTimeout !== "undefined") { schedule = function (fn) { setTimeout(fn, 0); }; } else { - schedule = function() { - throw new Error("No async scheduler available\u000a\u000a See http://goo.gl/m3OTXk\u000a"); - }; + schedule = noAsyncScheduler; } module.exports = schedule; diff --git a/node_modules/bluebird/js/main/thenables.js b/node_modules/bluebird/js/main/thenables.js index c858f86a..eadfffb5 100644 --- a/node_modules/bluebird/js/main/thenables.js +++ b/node_modules/bluebird/js/main/thenables.js @@ -61,12 +61,7 @@ function doThenable(x, then, context) { function resolveFromThenable(value) { if (!promise) return; - if (x === value) { - promise._rejectCallback( - Promise._makeSelfResolutionError(), false, true); - } else { - promise._resolveCallback(value); - } + promise._resolveCallback(value); promise = null; } diff --git a/node_modules/bluebird/js/main/util.js b/node_modules/bluebird/js/main/util.js index 54d7a855..ea393447 100644 --- a/node_modules/bluebird/js/main/util.js +++ b/node_modules/bluebird/js/main/util.js @@ -21,7 +21,9 @@ var errorObj = {e: {}}; var tryCatchTarget; function tryCatcher() { try { - return tryCatchTarget.apply(this, arguments); + var target = tryCatchTarget; + tryCatchTarget = null; + return target.apply(this, arguments); } catch (e) { errorObj.e = e; return errorObj; @@ -82,6 +84,7 @@ function withAppended(target, appendee) { function getDataPropertyOrDefault(obj, key, defaultValue) { if (es5.isES5) { var desc = Object.getOwnPropertyDescriptor(obj, key); + if (desc != null) { return desc.get == null && desc.set == null ? desc.value @@ -104,23 +107,32 @@ function notEnumerableProp(obj, name, value) { return obj; } - -var wrapsPrimitiveReceiver = (function() { - return this !== "string"; -}).call("string"); - function thrower(r) { throw r; } var inheritedDataKeys = (function() { + var excludedPrototypes = [ + Array.prototype, + Object.prototype, + Function.prototype + ]; + + var isExcludedProto = function(val) { + for (var i = 0; i < excludedPrototypes.length; ++i) { + if (excludedPrototypes[i] === val) { + return true; + } + } + return false; + }; + if (es5.isES5) { - var oProto = Object.prototype; var getKeys = Object.getOwnPropertyNames; return function(obj) { var ret = []; var visitedKeys = Object.create(null); - while (obj != null && obj !== oProto) { + while (obj != null && !isExcludedProto(obj)) { var keys; try { keys = getKeys(obj); @@ -141,11 +153,23 @@ var inheritedDataKeys = (function() { return ret; }; } else { + var hasProp = {}.hasOwnProperty; return function(obj) { + if (isExcludedProto(obj)) return []; var ret = []; + /*jshint forin:false */ - for (var key in obj) { - ret.push(key); + enumeration: for (var key in obj) { + if (hasProp.call(obj, key)) { + ret.push(key); + } else { + for (var i = 0; i < excludedPrototypes.length; ++i) { + if (hasProp.call(excludedPrototypes[i], key)) { + continue enumeration; + } + } + ret.push(key); + } } return ret; }; @@ -153,13 +177,22 @@ var inheritedDataKeys = (function() { })(); +var thisAssignmentPattern = /this\s*\.\s*\S+\s*=/; function isClass(fn) { try { if (typeof fn === "function") { var keys = es5.names(fn.prototype); - if (es5.isES5) return keys.length > 1; - return keys.length > 0 && - !(keys.length === 1 && keys[0] === "constructor"); + + var hasMethods = es5.isES5 && keys.length > 1; + var hasMethodsOtherThanConstructor = keys.length > 0 && + !(keys.length === 1 && keys[0] === "constructor"); + var hasThisAssignmentAndStaticMethods = + thisAssignmentPattern.test(fn + "") && es5.names(fn).length > 0; + + if (hasMethods || hasMethodsOtherThanConstructor || + hasThisAssignmentAndStaticMethods) { + return true; + } } return false; } catch (e) { @@ -168,10 +201,12 @@ function isClass(fn) { } function toFastProperties(obj) { - /*jshint -W027*/ + /*jshint -W027,-W055,-W031*/ function f() {} f.prototype = obj; - return f; + var l = 8; + while (l--) new f(); + return obj; eval(obj); } @@ -237,7 +272,9 @@ function copyDescriptors(from, to, filter) { for (var i = 0; i < keys.length; ++i) { var key = keys[i]; if (filter(key)) { - es5.defineProperty(to, key, es5.getDescriptor(from, key)); + try { + es5.defineProperty(to, key, es5.getDescriptor(from, key)); + } catch (ignore) {} } } } @@ -259,7 +296,6 @@ var ret = { inherits: inherits, withAppended: withAppended, maybeWrapAsError: maybeWrapAsError, - wrapsPrimitiveReceiver: wrapsPrimitiveReceiver, toFastProperties: toFastProperties, filledRange: filledRange, toString: safeToString, @@ -269,8 +305,17 @@ var ret = { markAsOriginatingFromRejection: markAsOriginatingFromRejection, classString: classString, copyDescriptors: copyDescriptors, + hasDevTools: typeof chrome !== "undefined" && chrome && + typeof chrome.loadTimes === "function", isNode: typeof process !== "undefined" && classString(process).toLowerCase() === "[object process]" }; +ret.isRecentNode = ret.isNode && (function() { + var version = process.versions.node.split(".").map(Number); + return (version[0] === 0 && version[1] > 10) || (version[0] > 0); +})(); + +if (ret.isNode) ret.toFastProperties(process); + try {throw new Error(); } catch (e) {ret.lastLineError = e;} module.exports = ret; diff --git a/node_modules/bluebird/package.json b/node_modules/bluebird/package.json index 4f863fd3..609f5dc5 100644 --- a/node_modules/bluebird/package.json +++ b/node_modules/bluebird/package.json @@ -1,7 +1,7 @@ { "name": "bluebird", "description": "Full featured Promises/A+ implementation with exceptionally good performance", - "version": "2.9.14", + "version": "2.9.34", "keywords": [ "promise", "performance", @@ -15,7 +15,10 @@ "future", "flow control", "dsl", - "fluent interface" + "fluent interface", + "parallel", + "thread", + "concurrency" ], "scripts": { "lint": "node scripts/jshint.js", @@ -60,7 +63,8 @@ "rx": "^2.3.25", "serve-static": "^1.7.1", "sinon": "~1.7.3", - "uglify-js": "~2.4.16" + "uglify-js": "~2.4.16", + "kefir": "^2.4.1" }, "main": "./js/main/bluebird.js", "browser": "./js/browser/bluebird.js", @@ -68,15 +72,14 @@ "js/browser", "js/main", "js/zalgo", - "LICENSE", "zalgo.js" ], - "gitHead": "b61407f36f0051efc1b49d07ef9b9fba5ac31e10", - "_id": "bluebird@2.9.14", - "_shasum": "5ead2aedbb783f93cf0bdfce5391f179ecab497e", - "_from": "bluebird@>=2.9.14 <3.0.0", - "_npmVersion": "2.7.0", - "_nodeVersion": "1.5.1", + "gitHead": "386ba4f7d588693e5d675290a6b7fade08e0d626", + "_id": "bluebird@2.9.34", + "_shasum": "2f7b4ec80216328a9fddebdf69c8d4942feff7d8", + "_from": "bluebird@>=2.9.34 <2.10.0", + "_npmVersion": "2.11.1", + "_nodeVersion": "2.3.0", "_npmUser": { "name": "esailija", "email": "petka_antonov@hotmail.com" @@ -88,10 +91,9 @@ } ], "dist": { - "shasum": "5ead2aedbb783f93cf0bdfce5391f179ecab497e", - "tarball": "http://registry.npmjs.org/bluebird/-/bluebird-2.9.14.tgz" + "shasum": "2f7b4ec80216328a9fddebdf69c8d4942feff7d8", + "tarball": "http://registry.npmjs.org/bluebird/-/bluebird-2.9.34.tgz" }, "directories": {}, - "_resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.9.14.tgz", - "readme": "ERROR: No README data found!" + "_resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.9.34.tgz" } diff --git a/node_modules/escape-string-regexp/package.json b/node_modules/escape-string-regexp/package.json index 63b469b5..9e9f3d7c 100644 --- a/node_modules/escape-string-regexp/package.json +++ b/node_modules/escape-string-regexp/package.json @@ -1,17 +1,27 @@ { "name": "escape-string-regexp", - "version": "1.0.2", + "version": "1.0.3", "description": "Escape RegExp special characters", "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/sindresorhus/escape-string-regexp" + "url": "git+https://github.com/sindresorhus/escape-string-regexp.git" }, "author": { "name": "Sindre Sorhus", "email": "sindresorhus@gmail.com", "url": "http://sindresorhus.com" }, + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "jbnicolai", + "email": "jappelman@xebia.com" + } + ], "engines": { "node": ">=0.8.0" }, @@ -36,34 +46,25 @@ "devDependencies": { "mocha": "*" }, - "gitHead": "0587ee0ee03ea3fcbfa3c15cf67b47f214e20987", + "gitHead": "1e446e6b4449b5f1f8868cd31bf8fd25ee37fb4b", "bugs": { "url": "https://github.com/sindresorhus/escape-string-regexp/issues" }, "homepage": "https://github.com/sindresorhus/escape-string-regexp", - "_id": "escape-string-regexp@1.0.2", - "_shasum": "4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1", - "_from": "escape-string-regexp@~1.0.2", - "_npmVersion": "1.4.23", + "_id": "escape-string-regexp@1.0.3", + "_shasum": "9e2d8b25bc2555c3336723750e03f099c2735bb5", + "_from": "escape-string-regexp@>=1.0.3 <1.1.0", + "_npmVersion": "2.1.16", + "_nodeVersion": "0.10.35", "_npmUser": { "name": "jbnicolai", "email": "jappelman@xebia.com" }, - "maintainers": [ - { - "name": "sindresorhus", - "email": "sindresorhus@gmail.com" - }, - { - "name": "jbnicolai", - "email": "jappelman@xebia.com" - } - ], "dist": { - "shasum": "4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1", - "tarball": "http://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz" + "shasum": "9e2d8b25bc2555c3336723750e03f099c2735bb5", + "tarball": "http://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz" }, "directories": {}, - "_resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", + "_resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz", "readme": "ERROR: No README data found!" } diff --git a/node_modules/espree/espree.js b/node_modules/espree/espree.js index 86f9436e..36e32d4e 100644 --- a/node_modules/espree/espree.js +++ b/node_modules/espree/espree.js @@ -580,6 +580,7 @@ function scanPunctuator() { // The ... operator (spread, restParams, JSX, etc.) if (extra.ecmaFeatures.spread || extra.ecmaFeatures.restParams || + extra.ecmaFeatures.experimentalObjectRestSpread || (extra.ecmaFeatures.jsx && state.inJSXSpreadAttribute) ) { if (ch1 === "." && ch2 === "." && ch3 === ".") { @@ -2069,7 +2070,7 @@ function throwError(token, messageFormat) { error = new Error("Line " + token.lineNumber + ": " + msg); error.index = token.range[0]; error.lineNumber = token.lineNumber; - error.column = token.range[0] - lineStart + 1; + error.column = token.range[0] - token.lineStart + 1; } else { error = new Error("Line " + lineNumber + ": " + msg); error.index = index; @@ -2117,7 +2118,7 @@ function throwUnexpected(token) { if (token.type === Token.Keyword) { if (syntax.isFutureReservedWord(token.value)) { throwError(token, Messages.UnexpectedReserved); - } else if (strict && syntax.isStrictModeReservedWord(token.value)) { + } else if (strict && syntax.isStrictModeReservedWord(token.value, extra.ecmaFeatures)) { throwErrorTolerant(token, Messages.StrictReservedWord); return; } @@ -2464,6 +2465,7 @@ function parseObjectProperty() { allowShorthand = extra.ecmaFeatures.objectLiteralShorthandProperties, allowGenerators = extra.ecmaFeatures.generators, allowDestructuring = extra.ecmaFeatures.destructuring, + allowSpread = extra.ecmaFeatures.experimentalObjectRestSpread, marker = markerCreate(); token = lookahead; @@ -2612,6 +2614,12 @@ function parseObjectProperty() { ); } + // object spread property + if (allowSpread && match("...")) { + lex(); + return markerApply(marker, astNodeFactory.createExperimentalSpreadProperty(parseAssignmentExpression())); + } + // only possibility in this branch is a shorthand generator if (token.type === Token.EOF || token.type === Token.Punctuator) { if (!allowGenerators || !match("*") || !allowMethod) { @@ -2696,7 +2704,7 @@ function parseObjectInitialiser() { property = parseObjectProperty(); - if (!property.computed) { + if (!property.computed && property.type.indexOf("Experimental") === -1) { name = getFieldName(property.key); propertyFn = (property.kind === "get") ? PropertyKind.Get : PropertyKind.Set; @@ -2959,6 +2967,19 @@ function parseNewExpression() { marker = markerCreate(); expectKeyword("new"); + + if (extra.ecmaFeatures.newTarget && match(".")) { + lex(); + if (lookahead.type === Token.Identifier && lookahead.value === "target") { + if (state.inFunctionBody) { + lex(); + return markerApply(marker, astNodeFactory.createMetaProperty("new", "target")); + } + } + + throwUnexpected(lookahead); + } + callee = parseLeftHandSideExpression(); args = match("(") ? parseArguments() : []; @@ -3300,6 +3321,17 @@ function reinterpretAsCoverFormalsList(expressions) { param.type = astNodeTypes.AssignmentPattern; delete param.operator; + if (param.right.type === astNodeTypes.YieldExpression) { + if (param.right.argument) { + throwUnexpected(lookahead); + } + + param.right.type = astNodeTypes.Identifier; + param.right.name = "yield"; + delete param.right.argument; + delete param.right.delegate; + } + params.push(param); validateParam(options, param.left, param.left.name); } else { @@ -3351,7 +3383,8 @@ function parseArrowFunctionExpression(options, marker) { function reinterpretAsAssignmentBindingPattern(expr) { var i, len, property, element, - allowDestructuring = extra.ecmaFeatures.destructuring; + allowDestructuring = extra.ecmaFeatures.destructuring, + allowRest = extra.ecmaFeatures.experimentalObjectRestSpread; if (!allowDestructuring) { throwUnexpected(lex()); @@ -3361,6 +3394,18 @@ function reinterpretAsAssignmentBindingPattern(expr) { expr.type = astNodeTypes.ObjectPattern; for (i = 0, len = expr.properties.length; i < len; i += 1) { property = expr.properties[i]; + + if (allowRest && property.type === astNodeTypes.ExperimentalSpreadProperty) { + + // only allow identifiers + if (property.argument.type !== astNodeTypes.Identifier) { + throwErrorTolerant({}, "Invalid object rest."); + } + + property.type = astNodeTypes.ExperimentalRestProperty; + return; + } + if (property.kind !== "init") { throwErrorTolerant({}, Messages.InvalidLHSInAssignment); } @@ -3594,7 +3639,7 @@ function parseVariableIdentifier() { token = lex(); if (token.type !== Token.Identifier) { - if (strict && token.type === Token.Keyword && syntax.isStrictModeReservedWord(token.value)) { + if (strict && token.type === Token.Keyword && syntax.isStrictModeReservedWord(token.value, extra.ecmaFeatures)) { throwErrorTolerant(token, Messages.StrictReservedWord); } else { throwUnexpected(token); @@ -4402,7 +4447,7 @@ function validateParam(options, param, name) { if (syntax.isRestrictedWord(name)) { options.firstRestricted = param; options.message = Messages.StrictParamName; - } else if (syntax.isStrictModeReservedWord(name)) { + } else if (syntax.isStrictModeReservedWord(name, extra.ecmaFeatures)) { options.firstRestricted = param; options.message = Messages.StrictReservedWord; } else if (options.paramSet.has(name)) { @@ -4532,7 +4577,7 @@ function parseFunctionDeclaration(identifierIsOptional) { if (syntax.isRestrictedWord(token.value)) { firstRestricted = token; message = Messages.StrictFunctionName; - } else if (syntax.isStrictModeReservedWord(token.value)) { + } else if (syntax.isStrictModeReservedWord(token.value, extra.ecmaFeatures)) { firstRestricted = token; message = Messages.StrictReservedWord; } @@ -4597,7 +4642,7 @@ function parseFunctionExpression() { if (syntax.isRestrictedWord(token.value)) { firstRestricted = token; message = Messages.StrictFunctionName; - } else if (syntax.isStrictModeReservedWord(token.value)) { + } else if (syntax.isStrictModeReservedWord(token.value, extra.ecmaFeatures)) { firstRestricted = token; message = Messages.StrictReservedWord; } @@ -5403,7 +5448,8 @@ function parse(code, options) { generators: true, destructuring: true, classes: true, - modules: true + modules: true, + newTarget: true }; } diff --git a/node_modules/espree/lib/ast-node-factory.js b/node_modules/espree/lib/ast-node-factory.js index 56bdbcad..8d867393 100644 --- a/node_modules/espree/lib/ast-node-factory.js +++ b/node_modules/espree/lib/ast-node-factory.js @@ -212,6 +212,14 @@ module.exports = { }; }, + createMetaProperty: function(meta, property) { + return { + type: astNodeTypes.MetaProperty, + meta: meta, + property: property + }; + }, + /** * Create an ASTNode representation of a conditional expression * @param {ASTNode} test The conditional to evaluate @@ -498,6 +506,30 @@ module.exports = { }; }, + /** + * Create an ASTNode representation of an experimental rest property + * @param {ASTNode} argument The identifier being rested + * @returns {ASTNode} An ASTNode representing a rest element + */ + createExperimentalRestProperty: function(argument) { + return { + type: astNodeTypes.ExperimentalRestProperty, + argument: argument + }; + }, + + /** + * Create an ASTNode representation of an experimental spread property + * @param {ASTNode} argument The identifier being spread + * @returns {ASTNode} An ASTNode representing a spread element + */ + createExperimentalSpreadProperty: function(argument) { + return { + type: astNodeTypes.ExperimentalSpreadProperty, + argument: argument + }; + }, + /** * Create an ASTNode tagged template expression * @param {ASTNode} tag The tag expression diff --git a/node_modules/espree/lib/ast-node-types.js b/node_modules/espree/lib/ast-node-types.js index 5d14b7f4..ec9eaa1f 100644 --- a/node_modules/espree/lib/ast-node-types.js +++ b/node_modules/espree/lib/ast-node-types.js @@ -56,6 +56,8 @@ module.exports = { DoWhileStatement: "DoWhileStatement", DebuggerStatement: "DebuggerStatement", EmptyStatement: "EmptyStatement", + ExperimentalRestProperty: "ExperimentalRestProperty", + ExperimentalSpreadProperty: "ExperimentalSpreadProperty", ExpressionStatement: "ExpressionStatement", ForStatement: "ForStatement", ForInStatement: "ForInStatement", @@ -68,6 +70,7 @@ module.exports = { LabeledStatement: "LabeledStatement", LogicalExpression: "LogicalExpression", MemberExpression: "MemberExpression", + MetaProperty: "MetaProperty", MethodDefinition: "MethodDefinition", NewExpression: "NewExpression", ObjectExpression: "ObjectExpression", diff --git a/node_modules/espree/lib/comment-attachment.js b/node_modules/espree/lib/comment-attachment.js index 3618bb3b..dc98fd2e 100644 --- a/node_modules/espree/lib/comment-attachment.js +++ b/node_modules/espree/lib/comment-attachment.js @@ -109,9 +109,21 @@ module.exports = { } if (lastChild) { - if (lastChild.leadingComments && lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= node.range[0]) { - node.leadingComments = lastChild.leadingComments; - delete lastChild.leadingComments; + if (lastChild.leadingComments) { + if (lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= node.range[0]) { + node.leadingComments = lastChild.leadingComments; + delete lastChild.leadingComments; + } else { + // A leading comment for an anonymous class had been stolen by its first MethodDefinition, + // so this takes back the leading comment. + // See Also: https://github.com/eslint/espree/issues/158 + for (i = lastChild.leadingComments.length - 2; i >= 0; --i) { + if (lastChild.leadingComments[i].range[1] <= node.range[0]) { + node.leadingComments = lastChild.leadingComments.splice(0, i + 1); + break; + } + } + } } } else if (extra.leadingComments.length > 0) { diff --git a/node_modules/espree/lib/features.js b/node_modules/espree/lib/features.js index c33274a4..209137dc 100644 --- a/node_modules/espree/lib/features.js +++ b/node_modules/espree/lib/features.js @@ -100,6 +100,9 @@ module.exports = { // enable parsing of classes classes: false, + // enable parsing of new.target + newTarget: false, + // enable parsing of modules modules: false, @@ -107,5 +110,8 @@ module.exports = { jsx: false, // allow return statement in global scope - globalReturn: false + globalReturn: false, + + // allow experimental object rest/spread + experimentalObjectRestSpread: false }; diff --git a/node_modules/espree/lib/syntax.js b/node_modules/espree/lib/syntax.js index 7cad1afc..b69754a8 100644 --- a/node_modules/espree/lib/syntax.js +++ b/node_modules/espree/lib/syntax.js @@ -113,7 +113,7 @@ module.exports = { } }, - isStrictModeReservedWord: function(id) { + isStrictModeReservedWord: function(id, ecmaFeatures) { switch (id) { case "implements": case "interface": @@ -125,6 +125,8 @@ module.exports = { case "yield": case "let": return true; + case "await": + return ecmaFeatures.modules; default: return false; } @@ -138,7 +140,7 @@ module.exports = { isKeyword: function(id, strict, ecmaFeatures) { - if (strict && this.isStrictModeReservedWord(id)) { + if (strict && this.isStrictModeReservedWord(id, ecmaFeatures)) { return true; } diff --git a/node_modules/espree/package.json b/node_modules/espree/package.json index 255bdc07..f0899bcd 100644 --- a/node_modules/espree/package.json +++ b/node_modules/espree/package.json @@ -11,7 +11,7 @@ "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" }, - "version": "2.0.3", + "version": "2.2.3", "files": [ "bin", "lib", @@ -27,7 +27,7 @@ }, "repository": { "type": "git", - "url": "git+ssh://git@github.com/eslint/espree.git" + "url": "http://github.com/eslint/espree.git" }, "bugs": { "url": "http://github.com/eslint/espree.git" @@ -44,7 +44,7 @@ "complexity-report": "~0.6.1", "dateformat": "^1.0.11", "eslint": "^0.9.2", - "esprima": "git://github.com/jquery/esprima.git", + "esprima": "git://github.com/jquery/esprima", "esprima-fb": "^8001.2001.0-dev-harmony-fb", "istanbul": "~0.2.6", "json-diff": "~0.3.1", @@ -83,10 +83,10 @@ "benchmark-quick": "node test/benchmarks.js quick" }, "dependencies": {}, - "gitHead": "b60b597cfe4834aacd16c90179ce73e22705c132", - "_id": "espree@2.0.3", - "_shasum": "1fbdff60a410bd0d416b1ab3d6230d34b7a450e1", - "_from": "espree@>=2.0.3 <2.1.0", + "gitHead": "4e72bb00332dbbced9a77d7c281962a46a6759cc", + "_id": "espree@2.2.3", + "_shasum": "158cfc10f6e57c6bbc5a7438eb8bc40f267f9b54", + "_from": "espree@>=2.2.3 <2.3.0", "_npmVersion": "1.4.28", "_npmUser": { "name": "nzakas", @@ -99,10 +99,9 @@ } ], "dist": { - "shasum": "1fbdff60a410bd0d416b1ab3d6230d34b7a450e1", - "tarball": "http://registry.npmjs.org/espree/-/espree-2.0.3.tgz" + "shasum": "158cfc10f6e57c6bbc5a7438eb8bc40f267f9b54", + "tarball": "http://registry.npmjs.org/espree/-/espree-2.2.3.tgz" }, "directories": {}, - "_resolved": "https://registry.npmjs.org/espree/-/espree-2.0.3.tgz", - "readme": "ERROR: No README data found!" + "_resolved": "https://registry.npmjs.org/espree/-/espree-2.2.3.tgz" } diff --git a/node_modules/js2xmlparser/LICENSE.md b/node_modules/js2xmlparser/LICENSE.md index 31947432..335c667e 100644 --- a/node_modules/js2xmlparser/LICENSE.md +++ b/node_modules/js2xmlparser/LICENSE.md @@ -1,16 +1,194 @@ -js2xmlparser is licensed under the MIT license: +Apache License +============== -> Copyright © 2012 Michael Kourlas and other 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. \ No newline at end of file +_Version 2.0, January 2004_ +_<>_ + +### Terms and Conditions for use, reproduction, and distribution + +#### 1. Definitions + +“License” shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +“Licensor” shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +“Legal Entity” shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, “control” means **(i)** the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the +outstanding shares, or **(iii)** beneficial ownership of such entity. + +“You” (or “Your”) shall mean an individual or Legal Entity exercising +permissions granted by this License. + +“Source” form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +“Object” form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +“Work” shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +“Derivative Works” shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +“Contribution” shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +“submitted” means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as “Not a Contribution.” + +“Contributor” shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +#### 2. Grant of Copyright License + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +#### 3. Grant of Patent License + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +#### 4. Redistribution + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +* **(a)** You must give any other recipients of the Work or Derivative Works a copy of +this License; and +* **(b)** You must cause any modified files to carry prominent notices stating that You +changed the files; and +* **(c)** You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. + +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +#### 5. Submission of Contributions + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +#### 6. Trademarks + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +#### 7. Disclaimer of Warranty + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +#### 8. Limitation of Liability + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +#### 9. Accepting Warranty or Additional Liability + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +_END OF TERMS AND CONDITIONS_ + +### APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets `[]` replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same “printed page” as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/js2xmlparser/lib/js2xmlparser.js b/node_modules/js2xmlparser/lib/js2xmlparser.js index e00748a7..d87aa240 100644 --- a/node_modules/js2xmlparser/lib/js2xmlparser.js +++ b/node_modules/js2xmlparser/lib/js2xmlparser.js @@ -30,6 +30,7 @@ var prettyPrinting = true; var indentString = "\t"; var convertMap = {}; + var arrayMap = {}; var useCDATA = false; module.exports = function (root, data, options) { @@ -121,6 +122,14 @@ throw new Error("convertMap option must be an object"); } } + if ("arrayMap" in options) { + if (Object.prototype.toString.call(options.arrayMap) === "[object Object]") { + arrayMap = options.arrayMap; + } + else { + throw new Error("arrayMap option must be an object"); + } + } if ("useCDATA" in options) { if (typeof options.useCDATA === "boolean") { useCDATA = options.useCDATA; @@ -141,8 +150,8 @@ throw new Error("data must be an object (excluding arrays) or a JSON string"); } - if (Object.prototype.toString.call(data) === "[object Array]") { - throw new Error("data must be an object (excluding arrays) or a JSON string"); + if (Object.prototype.toString.call(data) === "[object Array]" && !(arrayMap && arrayMap[root])) { + throw new Error("data must be an object (excluding arrays) or a JSON string, unless an arrayMap option exists for root"); } if (typeof data === "string") { @@ -185,12 +194,31 @@ // Arrays if (Object.prototype.toString.call(object[property]) === "[object Array]") { + // Wrap array with outer tag if arrayMap is used + if (arrayMap[property]) { + xml += addIndent("<" + elementName, level); + xml += addBreak(">"); + } + // Create separate XML elements for each array element for (i = 0; i < object[property].length; i++) { tempObject = {}; - tempObject[property] = object[property][i]; + var newLevel = level; - xml = toXML(tempObject, xml, level); + // When arrayMap is used, use the arrayMap tag instead and increment level + if (arrayMap[property]) { + tempObject[arrayMap[property]] = object[property][i]; + newLevel = level + 1; + } else { + tempObject[property] = object[property][i]; + } + + xml = toXML(tempObject, xml, newLevel); + } + + // Wrap array with outer tag if arrayMap is used + if (arrayMap[property]) { + xml += addBreak(addIndent("", level)); } } // JSON-type objects with properties @@ -204,7 +232,7 @@ for (var attribute in object[property][attributeString]) { if (object[property][attributeString].hasOwnProperty(attribute)) { xml += " " + attribute + "=\"" + - toString(object[property][attributeString][attribute], true) + "\""; + toString(object[property][attributeString][attribute], true) + "\""; } } } @@ -223,7 +251,7 @@ (lengthExcludingAttributes === 2 && aliasString in object[property])) && valueString in object[property]) { // Value string only xml += addBreak(">" + toString(object[property][valueString], false) + ""); + ">"); } else { // Object with properties xml += addBreak(">"); @@ -245,7 +273,7 @@ // Everything else else { xml += addBreak(addIndent("<" + elementName + ">" + toString(object[property], false) + "", level)); + elementName + ">", level)); } } } @@ -341,6 +369,7 @@ var setOptionDefaults = function () { useCDATA = false; convertMap = {}; + arrayMap = {}; xmlDeclaration = true; xmlVersion = "1.0"; xmlEncoding = "UTF-8"; diff --git a/node_modules/js2xmlparser/package.json b/node_modules/js2xmlparser/package.json index 6204d6c4..ba702956 100644 --- a/node_modules/js2xmlparser/package.json +++ b/node_modules/js2xmlparser/package.json @@ -13,7 +13,7 @@ "xml" ], "homepage": "http://www.kourlas.net", - "version": "0.1.7", + "version": "1.0.0", "author": { "name": "Michael Kourlas", "email": "michael@kourlas.net" @@ -27,14 +27,31 @@ "mocha": "*", "should": "*" }, - "license": "MIT", - "readme": "# js2xmlparser #\r\n\r\n## Overview ##\r\n\r\njs2xmlparser is a Node.js module that parses JavaScript objects into XML.\r\n\r\n## Features ##\r\n\r\nSince XML is a data-interchange format, js2xmlparser is designed primarily for JSON-type objects, arrays and primitive\r\ndata types, like many of the other JavaScript to XML parsers currently available for Node.js.\r\n\r\nHowever, js2xmlparser is capable of parsing any object, including native JavaScript objects such as Date and RegExp, by\r\ntaking advantage of each object's toString function. Functions are a special case where the return value of the function\r\nitself is used instead of the toString function, if available.\r\n\r\njs2xmlparser also supports a number of constructs unique to XML:\r\n\r\n* attributes (through a unique attribute property in objects)\r\n* mixed content (through a unique value property in objects)\r\n* multiple elements with the same name (through arrays)\r\n\r\njs2xmlparser can also pretty-print the XML it outputs with the option of customizing the indent string.\r\n\r\n## Installation ##\r\n\r\nThe easiest way to install js2xmlparser is to use npm: `npm install js2xmlparser`.\r\n\r\nAlternatively, you may download the source from GitHub and copy it to a folder named \"js2xmlparser\" within your\r\n\"node_modules\" directory.\r\n\r\n## Usage ##\r\n\r\nThe js2xmlparser module contains one function which takes the following arguments:\r\n\r\n* `root` - the XML root element's name (string, mandatory)\r\n* `data` - the data to be converted to XML; while the data object can contain arrays, it cannot itself be an array\r\n (object or JSON string, mandatory)\r\n* `options` - module options (object, optional)\r\n * `declaration` - XML declaration options (object, optional)\r\n * `include` - specifies whether an XML declaration should be included (boolean, optional, default: true)\r\n * `encoding` - value of XML encoding attribute in declaration; a value of null represents no encoding attribute\r\n (string, optional, default: \"UTF-8\")\r\n * `attributeString` - the name of the property representing an element's attributes; note that any property with a\r\n name equal to the attribute string is ignored except in the context of XML attributes (string, optional, default:\r\n \"@\")\r\n * `valueString` - the name of the property representing an element's value; note that any property with a name equal\r\n to the value string is ignored except in the context of supplying a value for a tag containing attributes (string,\r\n optional, default: \"#\")\r\n * `aliasString` - the name of the property representing an element's alias; the name of the containing element will\r\n be replaced with the alias (string, optional, default: \"=\")\r\n * `prettyPrinting` - pretty-printing options (object, optional)\r\n * `enabled` - specifies whether pretty-printing is enabled (boolean, optional, default: true)\r\n * `indentString` - indent string (string, optional, default: \"\\t\")\r\n * `convertMap` - maps object types (as given by the `Object.prototype.toString.call` method) to functions to convert\r\n those objects to a particular string representation; `*` can be used as a wildcard for all types of objects\r\n (object, optional, default: {})\r\n * `useCDATA` - specifies whether strings should be enclosed in CDATA tags; otherwise, illegal XML characters will\r\n be escaped (boolean, optional, default: false)\r\n\r\n## Examples ##\r\n\r\nThe following example illustrates the basic usage of js2xmlparser:\r\n\r\n var js2xmlparser = require(\"js2xmlparser\");\r\n\r\n var data = {\r\n \"firstName\": \"John\",\r\n \"lastName\": \"Smith\"\r\n };\r\n\r\n console.log(js2xmlparser(\"person\", data));\r\n\r\n > \r\n > \r\n > John\r\n > Smith\r\n > \r\n\r\nThis is a more complex example that builds on the first:\r\n\r\n var js2xmlparser = require(\"js2xmlparser\");\r\n\r\n var data = {\r\n \"@\": {\r\n \"type\": \"individual\"\r\n },\r\n \"firstName\": \"John\",\r\n \"lastName\": \"Smith\",\r\n \"dateOfBirth\": new Date(1964, 7, 26),\r\n \"address\": {\r\n \"@\": {\r\n \"type\": \"home\"\r\n },\r\n \"streetAddress\": \"3212 22nd St\",\r\n \"city\": \"Chicago\",\r\n \"state\": \"Illinois\",\r\n \"zip\": 10000\r\n },\r\n \"phone\": [\r\n {\r\n \"@\": {\r\n \"type\": \"home\"\r\n },\r\n \"#\": \"123-555-4567\"\r\n },\r\n {\r\n \"@\": {\r\n \"type\": \"work\"\r\n },\r\n \"#\": \"123-555-4567\",\r\n \"=\": \"telephone\"\r\n },\r\n {\r\n \"@\": {\r\n \"type\": \"cell\"\r\n },\r\n \"#\": \"456-555-7890\"\r\n }\r\n ],\r\n \"email\": function() {return \"john@smith.com\";},\r\n \"notes\": \"John's profile is not complete.\"\r\n };\r\n\r\n console.log(js2xmlparser(\"person\", data));\r\n\r\n > \r\n > \r\n > John\r\n > Smith\r\n > Wed Aug 26 1964 00:00:00 GMT-0400 (Eastern Daylight Time)\r\n >
\r\n > 3212 22nd St\r\n > Chicago\r\n > Illinois\r\n > 10000\r\n >
\r\n > 123-555-4567\r\n > 123-555-4567\r\n > 456-555-7890\r\n > john@smith.com\r\n > John's profile is not complete.\r\n >
\r\n\r\nThis example uses the alias string feature:\r\n\r\n var js2xmlparser = require(\"js2xmlparser\");\r\n\r\n var data = {\r\n \"phone\": [\r\n {\r\n \"@\": {\r\n \"type\": \"home\"\r\n },\r\n \"#\": \"123-555-4567\"\r\n },\r\n {\r\n \"@\": {\r\n \"type\": \"work\"\r\n },\r\n \"#\": \"123-555-4567\",\r\n \"=\": \"telephone\"\r\n },\r\n {\r\n \"@\": {\r\n \"type\": \"cell\"\r\n },\r\n \"#\": \"456-555-7890\"\r\n }\r\n ]\r\n };\r\n\r\n console.log(js2xmlparser(\"person\", data));\r\n\r\n > \r\n > \r\n > \t123-555-4567\r\n > \t123-555-4567\r\n > \t456-555-7890\r\n > \r\n\r\nThe following an example that uses the convert map feature:\r\n\r\n var js2xmlparser = require(\"js2xmlparser\");\r\n\r\n var data = {\r\n \"email\": function() {return \"john@smith.com\";},\r\n \"dateOfBirth\": new Date(1964, 7, 26)\r\n }\r\n\r\n var options = {\r\n convertMap: {\r\n \"[object Date]\": function(date) {\r\n return date.toISOString();\r\n },\r\n \"[object Function]\": function(func) {\r\n return func.toString();\r\n }\r\n }\r\n };\r\n\r\n console.log(js2xmlparser(\"person\", data, options));\r\n\r\n > \r\n > \r\n > function () {return "john@smith.com";}\r\n > 1964-08-26T04:00:00.000Z\r\n > \r\n\r\nHere's an example that wraps strings in CDATA tags instead of escaping invalid characters:\r\n\r\n var js2xmlparser = require(\"js2xmlparser\");\r\n\r\n var data = {\r\n \"notes\": {\r\n \"@\": {\r\n \"type\": \"status\"\r\n },\r\n \"#\": \"John's profile is not complete.\"\r\n }\r\n };\r\n\r\n var options = {\r\n useCDATA: true\r\n };\r\n\r\n console.log(js2xmlparser(\"person\", data, options));\r\n\r\n > \r\n > \r\n > \r\n > \r\n\r\n## Tests ##\r\n\r\njs2xmlparser comes with a set of tests that evaluate and verify the package's core functionality. To run the tests:\r\n\r\n* Install the test dependencies with `npm install`.\r\n* Run the tests with `mocha`.\r\n\r\n## License ##\r\n\r\njs2xmlparser is licensed under the [MIT license](http://opensource.org/licenses/MIT). Please see the LICENSE.md file\r\nfor more information.\r\n", - "readmeFilename": "README.md", + "license": "Apache-2.0", + "gitHead": "f6b92bf15695e6436d4bf52393ba104ac46dab56", "bugs": { "url": "https://github.com/michaelkourlas/node-js2xmlparser/issues" }, - "_id": "js2xmlparser@0.1.7", - "_shasum": "c8a4bf9ba00577c4b2ce0bd6e714ee8341a586ae", - "_from": "js2xmlparser@~0.1.7", - "_resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-0.1.7.tgz" + "_id": "js2xmlparser@1.0.0", + "scripts": {}, + "_shasum": "5a170f2e8d6476ce45405e04823242513782fe30", + "_from": "js2xmlparser@>=1.0.0 <1.1.0", + "_npmVersion": "2.7.4", + "_nodeVersion": "0.12.2", + "_npmUser": { + "name": "michaelkourlas", + "email": "michael@kourlas.net" + }, + "maintainers": [ + { + "name": "michaelkourlas", + "email": "michaelkourlas@gmail.com" + } + ], + "dist": { + "shasum": "5a170f2e8d6476ce45405e04823242513782fe30", + "tarball": "http://registry.npmjs.org/js2xmlparser/-/js2xmlparser-1.0.0.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-1.0.0.tgz" } diff --git a/node_modules/marked/lib/marked.js b/node_modules/marked/lib/marked.js index e2f08c99..97f18cdb 100644 --- a/node_modules/marked/lib/marked.js +++ b/node_modules/marked/lib/marked.js @@ -20,7 +20,7 @@ var block = { lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/, blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/, list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, - html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/, + html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/, def: /^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, table: noop, paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/, @@ -75,8 +75,9 @@ block.normal = merge({}, block); */ block.gfm = merge({}, block.normal, { - fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/, - paragraph: /^/ + fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/, + paragraph: /^/, + heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/ }); block.gfm.paragraph = replace(block.paragraph) @@ -359,7 +360,8 @@ Lexer.prototype.token = function(src, top, bq) { type: this.options.sanitize ? 'paragraph' : 'html', - pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style', + pre: !this.options.sanitizer + && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'), text: cap[0] }); continue; @@ -454,7 +456,7 @@ var inline = { reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/, nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/, strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/, - em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, + em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/, br: /^ {2,}\n(?!\s*$)/, del: noop, @@ -606,8 +608,10 @@ InlineLexer.prototype.output = function(src) { } src = src.substring(cap[0].length); out += this.options.sanitize - ? escape(cap[0]) - : cap[0]; + ? this.options.sanitizer + ? this.options.sanitizer(cap[0]) + : escape(cap[0]) + : cap[0] continue; } @@ -678,7 +682,7 @@ InlineLexer.prototype.output = function(src) { // text if (cap = this.rules.text.exec(src)) { src = src.substring(cap[0].length); - out += escape(this.smartypants(cap[0])); + out += this.renderer.text(escape(this.smartypants(cap[0]))); continue; } @@ -712,7 +716,9 @@ InlineLexer.prototype.smartypants = function(text) { if (!this.options.smartypants) return text; return text // em-dashes - .replace(/--/g, '\u2014') + .replace(/---/g, '\u2014') + // en-dashes + .replace(/--/g, '\u2013') // opening singles .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018') // closing singles & apostrophes @@ -730,6 +736,7 @@ InlineLexer.prototype.smartypants = function(text) { */ InlineLexer.prototype.mangle = function(text) { + if (!this.options.mangle) return text; var out = '' , l = text.length , i = 0 @@ -868,7 +875,7 @@ Renderer.prototype.link = function(href, title, text) { } catch (e) { return ''; } - if (prot.indexOf('javascript:') === 0) { + if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) { return ''; } } @@ -889,6 +896,10 @@ Renderer.prototype.image = function(href, title, text) { return out; }; +Renderer.prototype.text = function(text) { + return text; +}; + /** * Parsing & Compiling */ @@ -1154,8 +1165,13 @@ function marked(src, opt, callback) { pending = tokens.length; - var done = function() { - var out, err; + var done = function(err) { + if (err) { + opt.highlight = highlight; + return callback(err); + } + + var out; try { out = Parser.parse(tokens, opt); @@ -1184,6 +1200,7 @@ function marked(src, opt, callback) { return --pending || done(); } return highlight(token.text, token.lang, function(err, code) { + if (err) return done(err); if (code == null || code === token.text) { return --pending || done(); } @@ -1226,6 +1243,8 @@ marked.defaults = { breaks: false, pedantic: false, sanitize: false, + sanitizer: null, + mangle: true, smartLists: false, silent: false, highlight: null, @@ -1253,7 +1272,7 @@ marked.inlineLexer = InlineLexer.output; marked.parse = marked; -if (typeof exports === 'object') { +if (typeof module !== 'undefined' && typeof exports === 'object') { module.exports = marked; } else if (typeof define === 'function' && define.amd) { define(function() { return marked; }); diff --git a/node_modules/marked/package.json b/node_modules/marked/package.json index baa0adb4..ec9322ae 100644 --- a/node_modules/marked/package.json +++ b/node_modules/marked/package.json @@ -4,7 +4,7 @@ "author": { "name": "Christopher Jeffrey" }, - "version": "0.3.2", + "version": "0.3.4", "main": "./lib/marked.js", "bin": { "marked": "./bin/marked" @@ -35,16 +35,35 @@ "devDependencies": { "markdown": "*", "showdown": "*", - "robotskirt": "*" + "robotskirt": "*", + "gulp": "^3.8.11", + "gulp-uglify": "^1.1.0", + "gulp-concat": "^2.5.2" }, "scripts": { "test": "node test", "bench": "node test --bench" }, - "readme": "# marked\n\n> A full-featured markdown parser and compiler, written in JavaScript. Built\n> for speed.\n\n[![NPM version](https://badge.fury.io/js/marked.png)][badge]\n\n## Install\n\n``` bash\nnpm install marked --save\n```\n\n## Usage\n\nMinimal usage:\n\n```js\nvar marked = require('marked');\nconsole.log(marked('I am using __markdown__.'));\n// Outputs:

I am using markdown.

\n```\n\nExample setting options with default values:\n\n```js\nvar marked = require('marked');\nmarked.setOptions({\n renderer: new marked.Renderer(),\n gfm: true,\n tables: true,\n breaks: false,\n pedantic: false,\n sanitize: true,\n smartLists: true,\n smartypants: false\n});\n\nconsole.log(marked('I am using __markdown__.'));\n```\n\n## marked(markdownString [,options] [,callback])\n\n### markdownString\n\nType: `string`\n\nString of markdown source to be compiled.\n\n### options\n\nType: `object`\n\nHash of options. Can also be set using the `marked.setOptions` method as seen\nabove.\n\n### callback\n\nType: `function`\n\nFunction called when the `markdownString` has been fully parsed when using\nasync highlighting. If the `options` argument is omitted, this can be used as\nthe second argument.\n\n## Options\n\n### highlight\n\nType: `function`\n\nA function to highlight code blocks. The first example below uses async highlighting with\n[node-pygmentize-bundled][pygmentize], and the second is a synchronous example using\n[highlight.js][highlight]:\n\n```js\nvar marked = require('marked');\n\nvar markdownString = '```js\\n console.log(\"hello\"); \\n```';\n\n// Async highlighting with pygmentize-bundled\nmarked.setOptions({\n highlight: function (code, lang, callback) {\n require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) {\n callback(err, result.toString());\n });\n }\n});\n\n// Using async version of marked\nmarked(markdownString, function (err, content) {\n if (err) throw err;\n console.log(content);\n});\n\n// Synchronous highlighting with highlight.js\nmarked.setOptions({\n highlight: function (code) {\n return require('highlight.js').highlightAuto(code).value;\n }\n});\n\nconsole.log(marked(markdownString));\n```\n\n#### highlight arguments\n\n`code`\n\nType: `string`\n\nThe section of code to pass to the highlighter.\n\n`lang`\n\nType: `string`\n\nThe programming language specified in the code block.\n\n`callback`\n\nType: `function`\n\nThe callback function to call when using an async highlighter.\n\n### renderer\n\nType: `object`\nDefault: `new Renderer()`\n\nAn object containing functions to render tokens to HTML.\n\n#### Overriding renderer methods\n\nThe renderer option allows you to render tokens in a custom manor. Here is an\nexample of overriding the default heading token rendering by adding an embedded anchor tag like on GitHub:\n\n```javascript\nvar marked = require('marked');\nvar renderer = new marked.Renderer();\n\nrenderer.heading = function (text, level) {\n var escapedText = text.toLowerCase().replace(/[^\\w]+/g, '-');\n\n return '
' +\n text + '';\n},\n\nconsole.log(marked('# heading+', { renderer: renderer }));\n```\nThis code will output the following HTML:\n```html\n

\n \n \n \n heading+\n

\n```\n\n#### Block level renderer methods\n\n- code(*string* code, *string* language)\n- blockquote(*string* quote)\n- html(*string* html)\n- heading(*string* text, *number* level)\n- hr()\n- list(*string* body, *boolean* ordered)\n- listitem(*string* text)\n- paragraph(*string* text)\n- table(*string* header, *string* body)\n- tablerow(*string* content)\n- tablecell(*string* content, *object* flags)\n\n`flags` has the following properties:\n\n```js\n{\n header: true || false,\n align: 'center' || 'left' || 'right'\n}\n```\n\n#### Inline level renderer methods\n\n- strong(*string* text)\n- em(*string* text)\n- codespan(*string* code)\n- br()\n- del(*string* text)\n- link(*string* href, *string* title, *string* text)\n- image(*string* href, *string* title, *string* text)\n\n### gfm\n\nType: `boolean`\nDefault: `true`\n\nEnable [GitHub flavored markdown][gfm].\n\n### tables\n\nType: `boolean`\nDefault: `true`\n\nEnable GFM [tables][tables].\nThis option requires the `gfm` option to be true.\n\n### breaks\n\nType: `boolean`\nDefault: `false`\n\nEnable GFM [line breaks][breaks].\nThis option requires the `gfm` option to be true.\n\n### pedantic\n\nType: `boolean`\nDefault: `false`\n\nConform to obscure parts of `markdown.pl` as much as possible. Don't fix any of\nthe original markdown bugs or poor behavior.\n\n### sanitize\n\nType: `boolean`\nDefault: `false`\n\nSanitize the output. Ignore any HTML that has been input.\n\n### smartLists\n\nType: `boolean`\nDefault: `true`\n\nUse smarter list behavior than the original markdown. May eventually be\ndefault with the old behavior moved into `pedantic`.\n\n### smartypants\n\nType: `boolean`\nDefault: `false`\n\nUse \"smart\" typograhic punctuation for things like quotes and dashes.\n\n## Access to lexer and parser\n\nYou also have direct access to the lexer and parser if you so desire.\n\n``` js\nvar tokens = marked.lexer(text, options);\nconsole.log(marked.parser(tokens));\n```\n\n``` js\nvar lexer = new marked.Lexer(options);\nvar tokens = lexer.lex(text);\nconsole.log(tokens);\nconsole.log(lexer.rules);\n```\n\n## CLI\n\n``` bash\n$ marked -o hello.html\nhello world\n^D\n$ cat hello.html\n

hello world

\n```\n\n## Philosophy behind marked\n\nThe point of marked was to create a markdown compiler where it was possible to\nfrequently parse huge chunks of markdown without having to worry about\ncaching the compiled output somehow...or blocking for an unnecesarily long time.\n\nmarked is very concise and still implements all markdown features. It is also\nnow fully compatible with the client-side.\n\nmarked more or less passes the official markdown test suite in its\nentirety. This is important because a surprising number of markdown compilers\ncannot pass more than a few tests. It was very difficult to get marked as\ncompliant as it is. It could have cut corners in several areas for the sake\nof performance, but did not in order to be exactly what you expect in terms\nof a markdown rendering. In fact, this is why marked could be considered at a\ndisadvantage in the benchmarks above.\n\nAlong with implementing every markdown feature, marked also implements [GFM\nfeatures][gfmf].\n\n## Benchmarks\n\nnode v0.8.x\n\n``` bash\n$ node test --bench\nmarked completed in 3411ms.\nmarked (gfm) completed in 3727ms.\nmarked (pedantic) completed in 3201ms.\nrobotskirt completed in 808ms.\nshowdown (reuse converter) completed in 11954ms.\nshowdown (new converter) completed in 17774ms.\nmarkdown-js completed in 17191ms.\n```\n\n__Marked is now faster than Discount, which is written in C.__\n\nFor those feeling skeptical: These benchmarks run the entire markdown test suite 1000 times. The test suite tests every feature. It doesn't cater to specific aspects.\n\n### Pro level\n\nYou also have direct access to the lexer and parser if you so desire.\n\n``` js\nvar tokens = marked.lexer(text, options);\nconsole.log(marked.parser(tokens));\n```\n\n``` js\nvar lexer = new marked.Lexer(options);\nvar tokens = lexer.lex(text);\nconsole.log(tokens);\nconsole.log(lexer.rules);\n```\n\n``` bash\n$ node\n> require('marked').lexer('> i am using marked.')\n[ { type: 'blockquote_start' },\n { type: 'paragraph',\n text: 'i am using marked.' },\n { type: 'blockquote_end' },\n links: {} ]\n```\n\n## Running Tests & Contributing\n\nIf you want to submit a pull request, make sure your changes pass the test\nsuite. If you're adding a new feature, be sure to add your own test.\n\nThe marked test suite is set up slightly strangely: `test/new` is for all tests\nthat are not part of the original markdown.pl test suite (this is where your\ntest should go if you make one). `test/original` is only for the original\nmarkdown.pl tests. `test/tests` houses both types of tests after they have been\ncombined and moved/generated by running `node test --fix` or `marked --test\n--fix`.\n\nIn other words, if you have a test to add, add it to `test/new/` and then\nregenerate the tests with `node test --fix`. Commit the result. If your test\nuses a certain feature, for example, maybe it assumes GFM is *not* enabled, you\ncan add `.nogfm` to the filename. So, `my-test.text` becomes\n`my-test.nogfm.text`. You can do this with any marked option. Say you want\nline breaks and smartypants enabled, your filename should be:\n`my-test.breaks.smartypants.text`.\n\nTo run the tests:\n\n``` bash\ncd marked/\nnode test\n```\n\n### Contribution and License Agreement\n\nIf you contribute code to this project, you are implicitly allowing your code\nto be distributed under the MIT license. You are also implicitly verifying that\nall code is your original work. ``\n\n## License\n\nCopyright (c) 2011-2014, Christopher Jeffrey. (MIT License)\n\nSee LICENSE for more info.\n\n[gfm]: https://help.github.com/articles/github-flavored-markdown\n[gfmf]: http://github.github.com/github-flavored-markdown/\n[pygmentize]: https://github.com/rvagg/node-pygmentize-bundled\n[highlight]: https://github.com/isagalaev/highlight.js\n[badge]: http://badge.fury.io/js/marked\n[tables]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-tables\n[breaks]: https://help.github.com/articles/github-flavored-markdown#newlines\n", - "readmeFilename": "README.md", - "_id": "marked@0.3.2", - "_shasum": "015db158864438f24a64bdd61a0428b418706d09", - "_from": "marked@~0.3.2", - "_resolved": "https://registry.npmjs.org/marked/-/marked-0.3.2.tgz" + "gitHead": "cb4981c553d8ee22953f5eacca989e65a821c764", + "_id": "marked@0.3.4", + "_shasum": "b0afa8e0b33f80c9265e864a333ec99ecebdf2b0", + "_from": "marked@>=0.3.4 <0.4.0", + "_npmVersion": "2.13.2", + "_nodeVersion": "0.12.7", + "_npmUser": { + "name": "chjj", + "email": "chjjeffrey@gmail.com" + }, + "maintainers": [ + { + "name": "chjj", + "email": "chjjeffrey@gmail.com" + } + ], + "dist": { + "shasum": "b0afa8e0b33f80c9265e864a333ec99ecebdf2b0", + "tarball": "http://registry.npmjs.org/marked/-/marked-0.3.4.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/marked/-/marked-0.3.4.tgz" } diff --git a/node_modules/underscore/LICENSE b/node_modules/underscore/LICENSE index 0d6b8739..ad0e71bc 100644 --- a/node_modules/underscore/LICENSE +++ b/node_modules/underscore/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative +Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors Permission is hereby granted, free of charge, to any person diff --git a/node_modules/underscore/package.json b/node_modules/underscore/package.json index 5a82a144..3b021d07 100644 --- a/node_modules/underscore/package.json +++ b/node_modules/underscore/package.json @@ -18,37 +18,38 @@ "url": "git://github.com/jashkenas/underscore.git" }, "main": "underscore.js", - "version": "1.7.0", + "version": "1.8.3", "devDependencies": { - "docco": "0.6.x", - "phantomjs": "1.9.7-1", - "uglify-js": "2.4.x", - "eslint": "0.6.x" + "docco": "*", + "eslint": "0.6.x", + "karma": "~0.12.31", + "karma-qunit": "~0.1.4", + "qunit-cli": "~0.2.0", + "uglify-js": "2.4.x" }, "scripts": { - "test": "phantomjs test/vendor/runner.js test/index.html?noglobals=true && eslint underscore.js test/*.js test/vendor/runner.js", + "test": "npm run test-node && npm run lint", + "lint": "eslint underscore.js test/*.js", + "test-node": "qunit-cli test/*.js", + "test-browser": "npm i karma-phantomjs-launcher && ./node_modules/karma/bin/karma start", "build": "uglifyjs underscore.js -c \"evaluate=false\" --comments \"/ .*/\" -m --source-map underscore-min.map -o underscore-min.js", "doc": "docco underscore.js" }, - "licenses": [ - { - "type": "MIT", - "url": "https://raw.github.com/jashkenas/underscore/master/LICENSE" - } - ], + "license": "MIT", "files": [ "underscore.js", "underscore-min.js", + "underscore-min.map", "LICENSE" ], - "gitHead": "da996e665deb0b69b257e80e3e257c04fde4191c", + "gitHead": "e4743ab712b8ab42ad4ccb48b155034d02394e4d", "bugs": { "url": "https://github.com/jashkenas/underscore/issues" }, - "_id": "underscore@1.7.0", - "_shasum": "6bbaf0877500d36be34ecaa584e0db9fef035209", - "_from": "underscore@~1.7.0", - "_npmVersion": "1.4.24", + "_id": "underscore@1.8.3", + "_shasum": "4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022", + "_from": "underscore@1.8.3", + "_npmVersion": "1.4.28", "_npmUser": { "name": "jashkenas", "email": "jashkenas@gmail.com" @@ -60,10 +61,9 @@ } ], "dist": { - "shasum": "6bbaf0877500d36be34ecaa584e0db9fef035209", - "tarball": "http://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz" + "shasum": "4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022", + "tarball": "http://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz" }, "directories": {}, - "_resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", - "readme": "ERROR: No README data found!" + "_resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz" } diff --git a/node_modules/underscore/underscore.js b/node_modules/underscore/underscore.js index b4f49a02..b29332f9 100644 --- a/node_modules/underscore/underscore.js +++ b/node_modules/underscore/underscore.js @@ -1,6 +1,6 @@ -// Underscore.js 1.7.0 +// Underscore.js 1.8.3 // http://underscorejs.org -// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. (function() { @@ -21,7 +21,6 @@ var push = ArrayProto.push, slice = ArrayProto.slice, - concat = ArrayProto.concat, toString = ObjProto.toString, hasOwnProperty = ObjProto.hasOwnProperty; @@ -30,7 +29,11 @@ var nativeIsArray = Array.isArray, nativeKeys = Object.keys, - nativeBind = FuncProto.bind; + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; // Create a safe reference to the Underscore object for use below. var _ = function(obj) { @@ -52,12 +55,12 @@ } // Current version. - _.VERSION = '1.7.0'; + _.VERSION = '1.8.3'; // Internal function that returns an efficient (for current engines) version // of the passed-in callback, to be repeatedly applied in other Underscore // functions. - var createCallback = function(func, context, argCount) { + var optimizeCb = function(func, context, argCount) { if (context === void 0) return func; switch (argCount == null ? 3 : argCount) { case 1: return function(value) { @@ -81,12 +84,60 @@ // A mostly-internal function to generate callbacks that can be applied // to each element in a collection, returning the desired result — either // identity, an arbitrary callback, a property matcher, or a property accessor. - _.iteratee = function(value, context, argCount) { + var cb = function(value, context, argCount) { if (value == null) return _.identity; - if (_.isFunction(value)) return createCallback(value, context, argCount); - if (_.isObject(value)) return _.matches(value); + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); return _.property(value); }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; // Collection Functions // -------------------- @@ -95,11 +146,10 @@ // Handles raw objects in addition to array-likes. Treats all // sparse array-likes as if they were dense. _.each = _.forEach = function(obj, iteratee, context) { - if (obj == null) return obj; - iteratee = createCallback(iteratee, context); - var i, length = obj.length; - if (length === +length) { - for (i = 0; i < length; i++) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { iteratee(obj[i], i, obj); } } else { @@ -113,77 +163,66 @@ // Return the results of applying the iteratee to each element. _.map = _.collect = function(obj, iteratee, context) { - if (obj == null) return []; - iteratee = _.iteratee(iteratee, context); - var keys = obj.length !== +obj.length && _.keys(obj), + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), length = (keys || obj).length, - results = Array(length), - currentKey; + results = Array(length); for (var index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; + var currentKey = keys ? keys[index] : index; results[index] = iteratee(obj[currentKey], currentKey, obj); } return results; }; - var reduceError = 'Reduce of empty array with no initial value'; + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } // **Reduce** builds up a single result from a list of values, aka `inject`, // or `foldl`. - _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) { - if (obj == null) obj = []; - iteratee = createCallback(iteratee, context, 4); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index = 0, currentKey; - if (arguments.length < 3) { - if (!length) throw new TypeError(reduceError); - memo = obj[keys ? keys[index++] : index++]; - } - for (; index < length; index++) { - currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; + _.reduce = _.foldl = _.inject = createReduce(1); // The right-associative version of reduce, also known as `foldr`. - _.reduceRight = _.foldr = function(obj, iteratee, memo, context) { - if (obj == null) obj = []; - iteratee = createCallback(iteratee, context, 4); - var keys = obj.length !== + obj.length && _.keys(obj), - index = (keys || obj).length, - currentKey; - if (arguments.length < 3) { - if (!index) throw new TypeError(reduceError); - memo = obj[keys ? keys[--index] : --index]; - } - while (index--) { - currentKey = keys ? keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; + _.reduceRight = _.foldr = createReduce(-1); // Return the first value which passes a truth test. Aliased as `detect`. _.find = _.detect = function(obj, predicate, context) { - var result; - predicate = _.iteratee(predicate, context); - _.some(obj, function(value, index, list) { - if (predicate(value, index, list)) { - result = value; - return true; - } - }); - return result; + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; }; // Return all the elements that pass a truth test. // Aliased as `select`. _.filter = _.select = function(obj, predicate, context) { var results = []; - if (obj == null) return results; - predicate = _.iteratee(predicate, context); + predicate = cb(predicate, context); _.each(obj, function(value, index, list) { if (predicate(value, index, list)) results.push(value); }); @@ -192,19 +231,17 @@ // Return all the elements for which a truth test fails. _.reject = function(obj, predicate, context) { - return _.filter(obj, _.negate(_.iteratee(predicate)), context); + return _.filter(obj, _.negate(cb(predicate)), context); }; // Determine whether all of the elements match a truth test. // Aliased as `all`. _.every = _.all = function(obj, predicate, context) { - if (obj == null) return true; - predicate = _.iteratee(predicate, context); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index, currentKey; - for (index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; if (!predicate(obj[currentKey], currentKey, obj)) return false; } return true; @@ -213,24 +250,22 @@ // Determine if at least one element in the object matches a truth test. // Aliased as `any`. _.some = _.any = function(obj, predicate, context) { - if (obj == null) return false; - predicate = _.iteratee(predicate, context); - var keys = obj.length !== +obj.length && _.keys(obj), - length = (keys || obj).length, - index, currentKey; - for (index = 0; index < length; index++) { - currentKey = keys ? keys[index] : index; + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; if (predicate(obj[currentKey], currentKey, obj)) return true; } return false; }; - // Determine if the array or object contains a given value (using `===`). - // Aliased as `include`. - _.contains = _.include = function(obj, target) { - if (obj == null) return false; - if (obj.length !== +obj.length) obj = _.values(obj); - return _.indexOf(obj, target) >= 0; + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; }; // Invoke a method (with arguments) on every item in a collection. @@ -238,7 +273,8 @@ var args = slice.call(arguments, 2); var isFunc = _.isFunction(method); return _.map(obj, function(value) { - return (isFunc ? method : value[method]).apply(value, args); + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); }); }; @@ -250,13 +286,13 @@ // Convenience version of a common use case of `filter`: selecting only objects // containing specific `key:value` pairs. _.where = function(obj, attrs) { - return _.filter(obj, _.matches(attrs)); + return _.filter(obj, _.matcher(attrs)); }; // Convenience version of a common use case of `find`: getting the first object // containing specific `key:value` pairs. _.findWhere = function(obj, attrs) { - return _.find(obj, _.matches(attrs)); + return _.find(obj, _.matcher(attrs)); }; // Return the maximum element (or element-based computation). @@ -264,7 +300,7 @@ var result = -Infinity, lastComputed = -Infinity, value, computed; if (iteratee == null && obj != null) { - obj = obj.length === +obj.length ? obj : _.values(obj); + obj = isArrayLike(obj) ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value > result) { @@ -272,7 +308,7 @@ } } } else { - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed > lastComputed || computed === -Infinity && result === -Infinity) { @@ -289,7 +325,7 @@ var result = Infinity, lastComputed = Infinity, value, computed; if (iteratee == null && obj != null) { - obj = obj.length === +obj.length ? obj : _.values(obj); + obj = isArrayLike(obj) ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value < result) { @@ -297,7 +333,7 @@ } } } else { - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed < lastComputed || computed === Infinity && result === Infinity) { @@ -312,7 +348,7 @@ // Shuffle a collection, using the modern version of the // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). _.shuffle = function(obj) { - var set = obj && obj.length === +obj.length ? obj : _.values(obj); + var set = isArrayLike(obj) ? obj : _.values(obj); var length = set.length; var shuffled = Array(length); for (var index = 0, rand; index < length; index++) { @@ -328,7 +364,7 @@ // The internal `guard` argument allows it to work with `map`. _.sample = function(obj, n, guard) { if (n == null || guard) { - if (obj.length !== +obj.length) obj = _.values(obj); + if (!isArrayLike(obj)) obj = _.values(obj); return obj[_.random(obj.length - 1)]; } return _.shuffle(obj).slice(0, Math.max(0, n)); @@ -336,7 +372,7 @@ // Sort the object's values by a criterion produced by an iteratee. _.sortBy = function(obj, iteratee, context) { - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); return _.pluck(_.map(obj, function(value, index, list) { return { value: value, @@ -358,7 +394,7 @@ var group = function(behavior) { return function(obj, iteratee, context) { var result = {}; - iteratee = _.iteratee(iteratee, context); + iteratee = cb(iteratee, context); _.each(obj, function(value, index) { var key = iteratee(value, index, obj); behavior(result, value, key); @@ -386,37 +422,24 @@ if (_.has(result, key)) result[key]++; else result[key] = 1; }); - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iteratee, context) { - iteratee = _.iteratee(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = array.length; - while (low < high) { - var mid = low + high >>> 1; - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; - }; - // Safely create a real, live array from anything iterable. _.toArray = function(obj) { if (!obj) return []; if (_.isArray(obj)) return slice.call(obj); - if (obj.length === +obj.length) return _.map(obj, _.identity); + if (isArrayLike(obj)) return _.map(obj, _.identity); return _.values(obj); }; // Return the number of elements in an object. _.size = function(obj) { if (obj == null) return 0; - return obj.length === +obj.length ? obj.length : _.keys(obj).length; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; }; // Split a collection into two arrays: one whose elements all satisfy the given // predicate, and one whose elements all do not satisfy the predicate. _.partition = function(obj, predicate, context) { - predicate = _.iteratee(predicate, context); + predicate = cb(predicate, context); var pass = [], fail = []; _.each(obj, function(value, key, obj) { (predicate(value, key, obj) ? pass : fail).push(value); @@ -433,30 +456,27 @@ _.first = _.head = _.take = function(array, n, guard) { if (array == null) return void 0; if (n == null || guard) return array[0]; - if (n < 0) return []; - return slice.call(array, 0, n); + return _.initial(array, array.length - n); }; // Returns everything but the last entry of the array. Especially useful on // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. The **guard** check allows it to work with - // `_.map`. + // the array, excluding the last N. _.initial = function(array, n, guard) { return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); }; // Get the last element of an array. Passing **n** will return the last N - // values in the array. The **guard** check allows it to work with `_.map`. + // values in the array. _.last = function(array, n, guard) { if (array == null) return void 0; if (n == null || guard) return array[array.length - 1]; - return slice.call(array, Math.max(array.length - n, 0)); + return _.rest(array, Math.max(0, array.length - n)); }; // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. The **guard** - // check allows it to work with `_.map`. + // the rest N values in the array. _.rest = _.tail = _.drop = function(array, n, guard) { return slice.call(array, n == null || guard ? 1 : n); }; @@ -467,18 +487,20 @@ }; // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, strict, output) { - if (shallow && _.every(input, _.isArray)) { - return concat.apply(output, input); - } - for (var i = 0, length = input.length; i < length; i++) { + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { var value = input[i]; - if (!_.isArray(value) && !_.isArguments(value)) { - if (!strict) output.push(value); - } else if (shallow) { - push.apply(output, value); - } else { - flatten(value, shallow, strict, output); + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; } } return output; @@ -486,7 +508,7 @@ // Flatten out an array, either recursively (by default), or just one level. _.flatten = function(array, shallow) { - return flatten(array, shallow, false, []); + return flatten(array, shallow, false); }; // Return a version of the array that does not contain the specified value(s). @@ -498,27 +520,26 @@ // been sorted, you have the option of using a faster algorithm. // Aliased as `unique`. _.uniq = _.unique = function(array, isSorted, iteratee, context) { - if (array == null) return []; if (!_.isBoolean(isSorted)) { context = iteratee; iteratee = isSorted; isSorted = false; } - if (iteratee != null) iteratee = _.iteratee(iteratee, context); + if (iteratee != null) iteratee = cb(iteratee, context); var result = []; var seen = []; - for (var i = 0, length = array.length; i < length; i++) { - var value = array[i]; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; if (isSorted) { - if (!i || seen !== value) result.push(value); - seen = value; + if (!i || seen !== computed) result.push(value); + seen = computed; } else if (iteratee) { - var computed = iteratee(value, i, array); - if (_.indexOf(seen, computed) < 0) { + if (!_.contains(seen, computed)) { seen.push(computed); result.push(value); } - } else if (_.indexOf(result, value) < 0) { + } else if (!_.contains(result, value)) { result.push(value); } } @@ -528,16 +549,15 @@ // Produce an array that contains the union: each distinct element from all of // the passed-in arrays. _.union = function() { - return _.uniq(flatten(arguments, true, true, [])); + return _.uniq(flatten(arguments, true, true)); }; // Produce an array that contains every item shared between all the // passed-in arrays. _.intersection = function(array) { - if (array == null) return []; var result = []; var argsLength = arguments.length; - for (var i = 0, length = array.length; i < length; i++) { + for (var i = 0, length = getLength(array); i < length; i++) { var item = array[i]; if (_.contains(result, item)) continue; for (var j = 1; j < argsLength; j++) { @@ -551,7 +571,7 @@ // Take the difference between one array and a number of other arrays. // Only the elements present in just the first array will remain. _.difference = function(array) { - var rest = flatten(slice.call(arguments, 1), true, true, []); + var rest = flatten(arguments, true, true, 1); return _.filter(array, function(value){ return !_.contains(rest, value); }); @@ -559,23 +579,28 @@ // Zip together multiple lists into a single array -- elements that share // an index go together. - _.zip = function(array) { - if (array == null) return []; - var length = _.max(arguments, 'length').length; - var results = Array(length); - for (var i = 0; i < length; i++) { - results[i] = _.pluck(arguments, i); + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); } - return results; + return result; }; // Converts lists into objects. Pass either a single array of `[key, value]` // pairs, or two parallel arrays of the same length -- one of keys, and one of // the corresponding values. _.object = function(list, values) { - if (list == null) return {}; var result = {}; - for (var i = 0, length = list.length; i < length; i++) { + for (var i = 0, length = getLength(list); i < length; i++) { if (values) { result[list[i]] = values[i]; } else { @@ -585,40 +610,73 @@ return result; }; + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + // Return the position of the first occurrence of an item in an array, // or -1 if the item is not included in the array. // If the array is large and already in sort order, pass `true` // for **isSorted** to use binary search. - _.indexOf = function(array, item, isSorted) { - if (array == null) return -1; - var i = 0, length = array.length; - if (isSorted) { - if (typeof isSorted == 'number') { - i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted; - } else { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } - } - for (; i < length; i++) if (array[i] === item) return i; - return -1; - }; - - _.lastIndexOf = function(array, item, from) { - if (array == null) return -1; - var idx = array.length; - if (typeof from == 'number') { - idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1); - } - while (--idx >= 0) if (array[idx] === item) return idx; - return -1; - }; + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); // Generate an integer Array containing an arithmetic progression. A port of // the native Python `range()` function. See // [the Python documentation](http://docs.python.org/library/functions.html#range). _.range = function(start, stop, step) { - if (arguments.length <= 1) { + if (stop == null) { stop = start || 0; start = 0; } @@ -637,25 +695,25 @@ // Function (ahem) Functions // ------------------ - // Reusable constructor function for prototype setting. - var Ctor = function(){}; + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; // Create a function bound to a given object (assigning `this`, and arguments, // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if // available. _.bind = function(func, context) { - var args, bound; if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); - args = slice.call(arguments, 2); - bound = function() { - if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); - Ctor.prototype = func.prototype; - var self = new Ctor; - Ctor.prototype = null; - var result = func.apply(self, args.concat(slice.call(arguments))); - if (_.isObject(result)) return result; - return self; + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); }; return bound; }; @@ -665,15 +723,16 @@ // as a placeholder, allowing any combination of arguments to be pre-filled. _.partial = function(func) { var boundArgs = slice.call(arguments, 1); - return function() { - var position = 0; - var args = boundArgs.slice(); - for (var i = 0, length = args.length; i < length; i++) { - if (args[i] === _) args[i] = arguments[position++]; + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; } while (position < arguments.length) args.push(arguments[position++]); - return func.apply(this, args); + return executeBound(func, bound, this, this, args); }; + return bound; }; // Bind a number of an object's methods to that object. Remaining arguments @@ -693,7 +752,7 @@ _.memoize = function(func, hasher) { var memoize = function(key) { var cache = memoize.cache; - var address = hasher ? hasher.apply(this, arguments) : key; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); return cache[address]; }; @@ -712,9 +771,7 @@ // Defers a function, scheduling it to run after the current call stack has // cleared. - _.defer = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); - }; + _.defer = _.partial(_.delay, _, 1); // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. Normally, the throttled function will run @@ -739,8 +796,10 @@ context = this; args = arguments; if (remaining <= 0 || remaining > wait) { - clearTimeout(timeout); - timeout = null; + if (timeout) { + clearTimeout(timeout); + timeout = null; + } previous = now; result = func.apply(context, args); if (!timeout) context = args = null; @@ -761,7 +820,7 @@ var later = function() { var last = _.now() - timestamp; - if (last < wait && last > 0) { + if (last < wait && last >= 0) { timeout = setTimeout(later, wait - last); } else { timeout = null; @@ -814,7 +873,7 @@ }; }; - // Returns a function that will only be executed after being called N times. + // Returns a function that will only be executed on and after the Nth call. _.after = function(times, func) { return function() { if (--times < 1) { @@ -823,15 +882,14 @@ }; }; - // Returns a function that will only be executed before being called N times. + // Returns a function that will only be executed up to (but not including) the Nth call. _.before = function(times, func) { var memo; return function() { if (--times > 0) { memo = func.apply(this, arguments); - } else { - func = null; } + if (times <= 1) func = null; return memo; }; }; @@ -843,13 +901,47 @@ // Object Functions // ---------------- - // Retrieve the names of an object's properties. + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. // Delegates to **ECMAScript 5**'s native `Object.keys` _.keys = function(obj) { if (!_.isObject(obj)) return []; if (nativeKeys) return nativeKeys(obj); var keys = []; for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); return keys; }; @@ -864,6 +956,21 @@ return values; }; + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + // Convert an object into a list of `[key, value]` pairs. _.pairs = function(obj) { var keys = _.keys(obj); @@ -896,37 +1003,38 @@ }; // Extend a given object with all the properties in passed-in object(s). - _.extend = function(obj) { - if (!_.isObject(obj)) return obj; - var source, prop; - for (var i = 1, length = arguments.length; i < length; i++) { - source = arguments[i]; - for (prop in source) { - if (hasOwnProperty.call(source, prop)) { - obj[prop] = source[prop]; - } - } + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; } - return obj; }; // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj, iteratee, context) { - var result = {}, key; + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; if (obj == null) return result; - if (_.isFunction(iteratee)) { - iteratee = createCallback(iteratee, context); - for (key in obj) { - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); } else { - var keys = concat.apply([], slice.call(arguments, 1)); - obj = new Object(obj); - for (var i = 0, length = keys.length; i < length; i++) { - key = keys[i]; - if (key in obj) result[key] = obj[key]; - } + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; } return result; }; @@ -936,7 +1044,7 @@ if (_.isFunction(iteratee)) { iteratee = _.negate(iteratee); } else { - var keys = _.map(concat.apply([], slice.call(arguments, 1)), String); + var keys = _.map(flatten(arguments, false, false, 1), String); iteratee = function(value, key) { return !_.contains(keys, key); }; @@ -945,15 +1053,15 @@ }; // Fill in a given object with default properties. - _.defaults = function(obj) { - if (!_.isObject(obj)) return obj; - for (var i = 1, length = arguments.length; i < length; i++) { - var source = arguments[i]; - for (var prop in source) { - if (obj[prop] === void 0) obj[prop] = source[prop]; - } - } - return obj; + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; }; // Create a (shallow-cloned) duplicate of an object. @@ -970,6 +1078,19 @@ return obj; }; + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + // Internal recursive comparison function for `isEqual`. var eq = function(a, b, aStack, bStack) { // Identical objects are equal. `0 === -0`, but they aren't identical. @@ -1004,74 +1125,76 @@ // of `NaN` are not equivalent. return +a === +b; } - if (typeof a != 'object' || typeof b != 'object') return false; + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } // Assume equality for cyclic structures. The algorithm for detecting cyclic // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; var length = aStack.length; while (length--) { // Linear search. Performance is inversely proportional to the number of // unique nested structures. if (aStack[length] === a) return bStack[length] === b; } - // Objects with different constructors are not equivalent, but `Object`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if ( - aCtor !== bCtor && - // Handle Object.create(x) cases - 'constructor' in a && 'constructor' in b && - !(_.isFunction(aCtor) && aCtor instanceof aCtor && - _.isFunction(bCtor) && bCtor instanceof bCtor) - ) { - return false; - } + // Add the first object to the stack of traversed objects. aStack.push(a); bStack.push(b); - var size, result; + // Recursively compare objects and arrays. - if (className === '[object Array]') { + if (areArrays) { // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size === b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - if (!(result = eq(a[size], b[size], aStack, bStack))) break; - } + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; } } else { // Deep compare objects. var keys = _.keys(a), key; - size = keys.length; + length = keys.length; // Ensure that both objects contain the same number of properties before comparing deep equality. - result = _.keys(b).length === size; - if (result) { - while (size--) { - // Deep compare each member - key = keys[size]; - if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; - } + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; } } // Remove the first object from the stack of traversed objects. aStack.pop(); bStack.pop(); - return result; + return true; }; // Perform a deep comparison to check if two objects are equal. _.isEqual = function(a, b) { - return eq(a, b, [], []); + return eq(a, b); }; // Is a given array, string, or object empty? // An "empty" object has no enumerable own-properties. _.isEmpty = function(obj) { if (obj == null) return true; - if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; }; // Is a given value a DOM element? @@ -1091,14 +1214,14 @@ return type === 'function' || type === 'object' && !!obj; }; - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. - _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { _['is' + name] = function(obj) { return toString.call(obj) === '[object ' + name + ']'; }; }); - // Define a fallback version of the method in browsers (ahem, IE), where + // Define a fallback version of the method in browsers (ahem, IE < 9), where // there isn't any inspectable "Arguments" type. if (!_.isArguments(arguments)) { _.isArguments = function(obj) { @@ -1106,8 +1229,9 @@ }; } - // Optimize `isFunction` if appropriate. Work around an IE 11 bug. - if (typeof /./ !== 'function') { + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { _.isFunction = function(obj) { return typeof obj == 'function' || false; }; @@ -1159,6 +1283,7 @@ return value; }; + // Predicate-generating functions. Often useful outside of Underscore. _.constant = function(value) { return function() { return value; @@ -1167,30 +1292,28 @@ _.noop = function(){}; - _.property = function(key) { - return function(obj) { + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { return obj[key]; }; }; - // Returns a predicate for checking whether an object has a given set of `key:value` pairs. - _.matches = function(attrs) { - var pairs = _.pairs(attrs), length = pairs.length; + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); return function(obj) { - if (obj == null) return !length; - obj = new Object(obj); - for (var i = 0; i < length; i++) { - var pair = pairs[i], key = pair[0]; - if (pair[1] !== obj[key] || !(key in obj)) return false; - } - return true; + return _.isMatch(obj, attrs); }; }; // Run a function **n** times. _.times = function(n, iteratee, context) { var accum = Array(Math.max(0, n)); - iteratee = createCallback(iteratee, context, 1); + iteratee = optimizeCb(iteratee, context, 1); for (var i = 0; i < n; i++) accum[i] = iteratee(i); return accum; }; @@ -1239,10 +1362,12 @@ // If the value of the named `property` is a function then invoke it with the // `object` as context; otherwise, return it. - _.result = function(object, property) { - if (object == null) return void 0; - var value = object[property]; - return _.isFunction(value) ? object[property]() : value; + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; }; // Generate a unique integer id (unique within the entire client session). @@ -1357,8 +1482,8 @@ // underscore functions. Wrapped objects may be chained. // Helper function to continue chaining intermediate results. - var result = function(obj) { - return this._chain ? _(obj).chain() : obj; + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; }; // Add your own custom functions to the Underscore object. @@ -1368,7 +1493,7 @@ _.prototype[name] = function() { var args = [this._wrapped]; push.apply(args, arguments); - return result.call(this, func.apply(_, args)); + return result(this, func.apply(_, args)); }; }); }; @@ -1383,7 +1508,7 @@ var obj = this._wrapped; method.apply(obj, arguments); if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; - return result.call(this, obj); + return result(this, obj); }; }); @@ -1391,7 +1516,7 @@ _.each(['concat', 'join', 'slice'], function(name) { var method = ArrayProto[name]; _.prototype[name] = function() { - return result.call(this, method.apply(this._wrapped, arguments)); + return result(this, method.apply(this._wrapped, arguments)); }; }); @@ -1400,6 +1525,14 @@ return this._wrapped; }; + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + // AMD registration happens at the end for compatibility with AMD loaders // that may not enforce next-turn semantics on modules. Even though general // practice for AMD registration is to be anonymous, underscore registers diff --git a/package.json b/package.json index e2206dd9..05e6a486 100644 --- a/package.json +++ b/package.json @@ -13,24 +13,24 @@ "url": "https://github.com/jsdoc3/jsdoc" }, "dependencies": { - "async": "~0.9.0", - "bluebird": "~2.9.14", + "async": "~1.4.0", + "bluebird": "~2.9.34", "catharsis": "~0.8.7", - "escape-string-regexp": "~1.0.2", - "espree": "~2.0.3", - "js2xmlparser": "~0.1.7", - "marked": "~0.3.2", + "escape-string-regexp": "~1.0.3", + "espree": "~2.2.3", + "js2xmlparser": "~1.0.0", + "marked": "~0.3.4", "requizzle": "~0.2.0", "strip-json-comments": "~1.0.2", "taffydb": "https://github.com/hegemonic/taffydb/tarball/7d100bcee0e997ee4977e273cdce60bd8933050e", - "underscore": "~1.7.0", + "underscore": "~1.8.3", "wrench": "~1.5.8" }, "devDependencies": { - "gulp": "~3.8.5", - "gulp-eslint": "~0.13.2", - "gulp-json-editor": "~2.0.2", - "istanbul": "~0.2.16", + "gulp": "~3.9.0", + "gulp-eslint": "~0.15.0", + "gulp-json-editor": "~2.2.1", + "istanbul": "~0.3.17", "tv4": "https://github.com/hegemonic/tv4/tarball/own-properties" }, "engines": {