[
  {
    "path": ".editorconfig",
    "content": "# This file is for unifying the coding style for different editors and IDEs\n# editorconfig.org\n\nroot = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[**.js]\nindent_style = space\nindent_size = 4\n"
  },
  {
    "path": ".gitignore",
    "content": "docs/Gemfile.lock\ngh-pages\nnode_modules\ngh-pages\ntest/browser/bundle.js\ntest/browser/worker_bundle.js\njs/*\nzalgo.js\ncoverage/*\n.vscode\n.idea\n.jekyll-cache/*\n_site\n"
  },
  {
    "path": ".istanbul.yml",
    "content": "verbose: false\ninstrumentation:\n    root: .\n    default-excludes: true\n    excludes: []\n    embed-source: false\n    variable: __coverage__\n    compact: true\n    preserve-comments: false\n    complete-copy: false\n    save-baseline: false\n    baseline-file: ./coverage/coverage-baseline.json\n    include-all-sources: false\nreporting:\n    print: summary\n    reports:\n        - lcov\n    dir: ./coverage\n    watermarks:\n        statements: [50, 80]\n        lines: [50, 80]\n        functions: [50, 80]\n        branches: [50, 80]\n    report-config:\n        clover: {file: clover.xml}\n        cobertura: {file: cobertura-coverage.xml}\n        json: {file: coverage-final.json}\n        json-summary: {file: coverage-summary.json}\n        lcovonly: {file: lcov.info}\n        teamcity: {file: null}\n        text: {file: null, maxCols: 0}\n        text-summary: {file: null}\nhooks:\n    hook-run-in-context: false\n    post-require-hook: null\n    handle-sigint: false\ncheck:\n    global:\n        statements: 0\n        lines: 0\n        branches: 0\n        functions: 0\n        excludes: []\n    each:\n        statements: 0\n        lines: 0\n        branches: 0\n        functions: 0\n        excludes: []\n"
  },
  {
    "path": ".jshintignore",
    "content": "src/constants.js\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n    \"bitwise\": false,\n    \"camelcase\": true,\n    \"curly\": true,\n    \"eqeqeq\": true,\n    \"es3\": true,\n    \"forin\": true,\n    \"immed\": true,\n    \"latedef\": false,\n    \"newcap\": true,\n    \"noarg\": true,\n    \"noempty\": true,\n    \"nonew\": true,\n    \"plusplus\": false,\n    \"quotmark\": \"double\",\n    \"undef\": true,\n    \"unused\": true,\n    \"strict\": false,\n    \"maxparams\": 6,\n    \"maxlen\": 80,\n    \"asi\": false,\n    \"boss\": true,\n    \"eqnull\": true,\n    \"evil\": true,\n    \"expr\": false,\n    \"funcscope\": false,\n    \"globalstrict\": false,\n    \"lastsemic\": false,\n    \"laxcomma\": false,\n    \"laxbreak\": false,\n    \"loopfunc\": true,\n    \"multistr\": true,\n    \"proto\": false,\n    \"scripturl\": true,\n    \"shadow\": true,\n    \"sub\": true,\n    \"supernew\": false,\n    \"validthis\": true,\n    \"browser\": true,\n    \"jquery\": true,\n    \"devel\": true,\n    \"-W014\": true,\n    \"-W116\": true,\n    \"-W106\": true,\n    \"-W064\": true,\n    \"-W097\": true,\n    \"globals\": {\n        \"Symbol\": false,\n        \"Map\": false,\n        \"JSON\": false,\n        \"Error\": true,\n        \"args\": true,\n        \"chrome\": true,\n        \"INLINE_SLICE\": false,\n        \"INLINE_SLICE_LEFT_PADDED\": false,\n        \"BIT_FIELD_CHECK\": false,\n        \"BIT_FIELD_READ\": false,\n        \"USE\": false,\n        \"global\": true,\n        \"setImmediate\": true,\n        \"Promise\": true,\n        \"WebKitMutationObserver\": true,\n        \"TypeError\": true,\n        \"RangeError\": true,\n        \"__DEBUG__\": false,\n        \"__BROWSER__\": false,\n        \"process\": true,\n        \"self\": true,\n        \"console\": false,\n        \"require\": false,\n        \"module\": false,\n        \"define\": false,\n        \"LATE_QUEUE_CAPACITY\": false,\n        \"NORMAL_QUEUE_CAPACITY\": false,\n        \"ERROR_HANDLED_KEY\": false,\n        \"OPERATIONAL_ERROR_KEY\": false,\n        \"DEFAULT_STATE\": false,\n        \"STACK_ATTACHED\": false,\n        \"ERROR_HANDLED\": false,\n        \"GENERATED_CLASS_COUNT\": false,\n        \"USE_BOUND\": false,\n        \"DONT_USE_BOUND\": false,\n        \"PROPAGATE_CANCEL\": false,\n        \"PROPAGATE_BIND\": false,\n        \"PROPAGATE_ALL\": false,\n        \"CALLBACK_FULFILL_OFFSET\": false,\n        \"CALLBACK_REJECT_OFFSET\": false,\n        \"CALLBACK_PROMISE_OFFSET\": false,\n        \"CALLBACK_RECEIVER_OFFSET\": false,\n        \"CALLBACK_SIZE\": false,\n        \"ASYNC_GUARANTEE_SHIFT\": false,\n        \"NO_STATE\": false,\n        \"NO_ASYNC_GUARANTEE\": false,\n        \"RETURNED_NON_UNDEFINED\": false,\n        \"IS_ASYNC_GUARANTEED\": false,\n        \"IS_FOLLOWING\": false,\n        \"IS_FULFILLED\": false,\n        \"IS_REJECTED\": false,\n        \"WILL_BE_CANCELLED\": false,\n        \"IS_FINAL\": false,\n        \"IS_BOUND\": false,\n        \"IS_REJECTION_UNHANDLED\": false,\n        \"IS_REJECTION_IGNORED\": false,\n        \"IS_UNHANDLED_REJECTION_NOTIFIED\": false,\n        \"IS_DISPOSABLE\": false,\n        \"IS_CANCELLED\": false,\n        \"IS_CANCELLED_OR_WILL_BE_CANCELLED\": false,\n        \"LENGTH_MASK\": false,\n        \"LENGTH_CLEAR_MASK\": false,\n        \"MAX_LENGTH\": false,\n        \"IS_REJECTED_OR_CANCELLED\": false,\n        \"IS_REJECTED_OR_FULFILLED\": false,\n        \"IS_REJECTED_OR_FULFILLED_OR_CANCELLED\": false,\n        \"IS_PENDING_AND_WAITING_NEG\": false,\n        \"IS_FATE_SEALED\": false,\n        \"AFTER_PROMISIFIED_SUFFIX\": false,\n        \"UNHANDLED_REJECTION_EVENT\": false,\n        \"REJECTION_HANDLED_EVENT\": false,\n        \"RESOLVE_UNDEFINED\": false,\n        \"RESOLVE_ARRAY\": false,\n        \"RESOLVE_OBJECT\": false,\n        \"RESOLVE_FOREVER_PENDING\": false,\n        \"RESOLVE_CALL_METHOD\": false,\n        \"RESOLVE_MAP\": false,\n        \"QUEUE_MAX_CAPACITY\": false,\n        \"QUEUE_MIN_CAPACITY\": false,\n        \"FROM_PREVIOUS_EVENT\": false,\n        \"NO_STACK_TRACE\": false,\n        \"ADDITIONAL_STACK_TRACE\": false,\n        \"UNHANDLED_REJECTION_HEADER\": false,\n        \"FINALLY_TYPE\": false,\n        \"TAP_TYPE\": false,\n        \"THROW\": false,\n        \"RETURN\": false,\n        \"MAX_PARAM_COUNT\": false,\n        \"PARAM_COUNTS_TO_TRY\": false,\n        \"BLUEBIRD_ERRORS\": false,\n        \"OBJECT_PROMISIFY_DEPRECATED\": false,\n        \"SPAWN_DEPRECATED\": false,\n        \"LATE_CANCELLATION_OBSERVER\": false,\n        \"TIMEOUT_ERROR\": false,\n        \"COLLECTION_ERROR\": false,\n        \"OBJECT_ERROR\": false,\n        \"FUNCTION_ERROR\": false,\n        \"CONSTRUCT_ERROR_INVOCATION\": false,\n        \"NOT_GENERATOR_ERROR\": false,\n        \"LONG_STACK_TRACES_ERROR\": false,\n        \"INSPECTION_VALUE_ERROR\": false,\n        \"INSPECTION_REASON_ERROR\": false,\n        \"PROMISIFY_TYPE_ERROR\": false,\n        \"CIRCULAR_RESOLUTION_ERROR\": false,\n        \"PROPS_TYPE_ERROR\": false,\n        \"POSITIVE_INTEGER_ERROR\": false,\n        \"YIELDED_NON_PROMISE_ERROR\": false,\n        \"FROM_COROUTINE_CREATED_AT\": false,\n        \"UNBOUND_RESOLVER_INVOCATION\": false,\n        \"PROMISIFICATION_NORMAL_METHODS_ERROR\": false,\n        \"SUFFIX_NOT_IDENTIFIER\": false,\n        \"NO_ASYNC_SCHEDULER\": false\n    }\n}"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nsudo: false\nmatrix:\n  include:\n    - node_js: \"0.10\"\n    - node_js: \"0.12\"\n    - node_js: \"4\"\n    - node_js: \"5\"\n    - node_js: \"6\"\n    - node_js: \"7\"\n    - node_js: \"8\"\n    - node_js: \"10\"\n  fast_finish: true\ngit:\n  depth: 5\nenv:\n  - \"NODE_FLAGS='--expose-gc' SCRIPT_FLAGS=''\"\nbefore_script:\n- git submodule update --init --recursive\nscript: \"node $NODE_FLAGS tools/test.js $SCRIPT_FLAGS\"\nbranches:\n  only:\n    - master\ncache:\n  directories:\n  - \"$HOME/.npm\"\n"
  },
  {
    "path": "API.md",
    "content": "[http://bluebirdjs.com/docs/api-reference.html](http://bluebirdjs.com/docs/api-reference.html)\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "\n# Questions and issues\n\nPlease see [The Support Page](http://bluebirdjs.com/docs/support.html)\nThe [github issue tracker](https://github.com/petkaantonov/bluebird/issues) is **_only_** for bug reports and feature requests.\n\n# Contributing to the library\n\nContributions are welcome and appreciated. See the [Contribution Page](http://bluebirdjs.com/docs/contribute.html) on bluebirdjs.com\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013-2018 Petka Antonov\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<a href=\"http://promisesaplus.com/\">\n    <img src=\"http://promisesaplus.com/assets/logo-small.png\" alt=\"Promises/A+ logo\"\n         title=\"Promises/A+ 1.1 compliant\" align=\"right\" />\n</a>\n\n\n[![Build Status](https://travis-ci.org/petkaantonov/bluebird.svg?branch=master)](https://travis-ci.org/petkaantonov/bluebird)\n[![coverage-98%](https://img.shields.io/badge/coverage-98%25-brightgreen.svg?style=flat)](http://petkaantonov.github.io/bluebird/coverage/debug/index.html)\n\n**Got a question?** Join us on [stackoverflow](http://stackoverflow.com/questions/tagged/bluebird), the [mailing list](https://groups.google.com/forum/#!forum/bluebird-js) or chat on [IRC](https://webchat.freenode.net/?channels=#promises)\n\n# Introduction\n\nBluebird is a fully featured promise library with focus on innovative features and performance\n\nSee the [**bluebird website**](http://bluebirdjs.com/docs/getting-started.html) for further documentation, references and instructions. See the [**API reference**](http://bluebirdjs.com/docs/api-reference.html) here.\n\nFor bluebird 2.x documentation and files, see the [2.x tree](https://github.com/petkaantonov/bluebird/tree/2.x).\n\n## ⚠️Note⚠️ \n\n**Please use native promises instead if at all possible**. Native Promises have been stable in Node.js and browsers for around 10 years now and they have been fast for around 7. Any utility bluebird has like `.map` has native equivalents (like Node streams' `.map`).\n\nThis is a good thing, the people working on Bluebird and promises have been able to help incorporate most of the useful things from Bluebird into JavaScript itself and platforms/engines.\n\nIf there is a feature that keeps you using bluebird. Please let us know so we can try and upstream it :)\n\nCurrently - it is only recommended to use Bluebird if you need to support _really old_ browsers or EoL Node.js or as an intermediate step to use warnings/monitoring to find bugs.\n\n# Questions and issues\n\nThe [github issue tracker](https://github.com/petkaantonov/bluebird/issues) is **_only_** for bug reports and feature requests. Anything else, such as questions for help in using the library, should be posted in [StackOverflow](http://stackoverflow.com/questions/tagged/bluebird) under tags `promise` and `bluebird`.\n\n\n## Thanks\n\nThanks to BrowserStack for providing us with a free account which lets us support old browsers like IE8. \n\n# License\n\nThe MIT License (MIT)\n\nCopyright (c) 2013-2021 Petka Antonov\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n"
  },
  {
    "path": "bench",
    "content": "#!/usr/bin/env bash\n./build --release --no-debug\nbenchmark=$1\nnodepath=${2:-node}\nshift 2;\ncwd=${PWD}\n\nexport NODE_ENV=production\n\ntrap 'cd \"$cwd\"' EXIT\n\nif [ \"$benchmark\" = \"doxbee\" ]; then\n    cd \"$cwd/benchmark\"\n    npm install\n    echo \"Doxbee sequential\"\n    $nodepath performance.js --n 10000 --t 1 ./doxbee-sequential/*.js --harmony \"$@\"\n    exit 0\nelif [ \"$benchmark\" = \"doxbee-errors\" ]; then\n    cd \"$cwd/benchmark\"\n    npm install\n    echo \"Doxbee sequential with 10% errors\"\n    $nodepath performance.js --n 10000 --t 1 --e 0.1 ./doxbee-sequential-errors/*.js --harmony \"$@\"\n    exit 0\nelif [ \"$benchmark\" = \"parallel\" ]; then\n    cd \"$cwd/benchmark\"\n    npm install\n    echo \"Madeup parallel\"\n    $nodepath performance.js --n 10000 --t 1 --p 25 ./madeup-parallel/*.js --harmony \"$@\"\n    exit 0\nelif [ \"$benchmark\" = \"analysis\" ]; then\n    cd \"$cwd/benchmark\"\n    npm install\n    echo \"analysis\"\n    $nodepath performance.js --n 10000 --t 1 ./analysis/*.js --harmony \"$@\"\n    exit 0\nelse\n    echo \"Invalid benchmark name $benchmark\"\n    exit -1\nfi\n"
  },
  {
    "path": "benchmark/README.md",
    "content": "**2018-07-16** Latest results, using latest versions of modules:\n\n    ├── async@2.6.1\n    ├── davy@1.3.0\n    ├── deferred@0.7.9\n    ├── kew@0.7.0\n    ├── lie@3.3.0\n    ├── optimist@0.6.1\n    ├── promise@8.0.1\n    ├── q@1.5.1\n    ├── rsvp@4.8.3\n    ├── vow@0.4.17\n    ├── when@3.7.8\n\nbench doxbee-sequential `ls ./doxbee-sequential/*.js | sed -e 's|\\.js||' | xargs node ./performance.js --p 1 --t 1 --n 10000`\n\n    file                                    time(ms)  memory(MB)\n    callbacks-baseline                           162       28.12\n    callbacks-suguru03-neo-async-waterfall       195       42.39\n    promises-bluebird-generator                  199       40.23\n    callbacks-caolan-async-waterfall             225       46.36\n    promises-native-async-await                  245       57.39\n    promises-bluebird                            257       47.03\n    promises-lvivski-davy                        313       87.59\n    promises-cujojs-when                         318       64.34\n    promises-then-promise                        323       64.49\n    generators-tj-co                             334       58.03\n    promises-ecmascript6-native                  335       65.40\n    promises-tildeio-rsvp                        420       86.79\n    promises-calvinmetcalf-lie                   514      138.58\n    promises-dfilatov-vow                        629      135.28\n    promises-obvious-kew                         693      190.43\n    streamline-generators                        762       90.18\n    promises-medikoo-deferred                    781      149.33\n    observables-pozadi-kefir                     824      180.54\n    streamline-callbacks                        1088      114.73\n    observables-Reactive-Extensions-RxJS        1208      243.74\n    observables-caolan-highland                 3094      424.63\n    promises-kriskowal-q                        3505      367.13\n    observables-baconjs-bacon.js                5224      660.07\n\n    Platform info:\n    Darwin 17.7.0 x64\n    Node.JS 10.6.0\n    V8 6.7.288.46-node.13\n    Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz × 4\n\nbench parallel (`--p 25`)\n\nresults for 10000 parallel executions, 1 ms per I/O op `ls ./madeup-parallel/*.js | sed -e 's|\\.js||' | xargs node ./performance.js --p 25 --t 1 --n 10000`\n\n    results for 10000 parallel executions, 1 ms per I/O op\n\n    file                                   time(ms)  memory(MB)\n    callbacks-baseline                          309       74.47\n    callbacks-suguru03-neo-async-parallel       374       84.18\n    promises-bluebird-generator                 455      106.49\n    promises-bluebird                           472       98.00\n    callbacks-caolan-async-parallel             510      119.34\n    promises-lvivski-davy                       671      163.84\n    promises-cujojs-when                        701      168.99\n    promises-native-async-await                1087      242.02\n    promises-tildeio-rsvp                      1237      344.17\n    promises-calvinmetcalf-lie                 1401      370.65\n    promises-ecmascript6-native                1509      242.91\n    promises-then-promise                      1533      303.89\n    promises-medikoo-deferred                  1923      334.75\n    promises-dfilatov-vow                      2534      534.80\n    promises-obvious-kew                       2623      306.68\n\n    Platform info:\n    Darwin 17.7.0 x64\n    Node.JS 10.6.0\n    V8 6.7.288.46-node.13\n    Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz × 4\n"
  },
  {
    "path": "benchmark/analysis/promises-bluebird-parallel.js",
    "content": "global.useBluebird = true;\nglobal.useQ = false;\nglobal.parallelQueries = 25;\nvar Promise = require('../../js/release/bluebird.js');\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    Promise.all(queries).then().then(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/analysis/promises-bluebird.js",
    "content": "global.useBluebird = true;\nglobal.useQ = false;\nvar bluebird = require('../../js/release/bluebird.js');\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n    bluebird.join(blobIdP, fileP, function(blobId, fileV) {\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/callbacks-baseline.js",
    "content": "require('../lib/fakes');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    function backoff(err) {\n        tx.rollback();\n        return done(err);\n    }\n    blob.put(stream, function (err, blobId) {\n        if (err) return done(err);\n        self.byUuidOrPath(idOrPath).get(function (err, file) {\n            if (err) return done(err);\n            var previousId = file ? file.version : null;\n            var version = {\n                userAccountId: userAccount.id,\n                date: new Date(),\n                blobId: blobId,\n                creatorId: userAccount.id,\n                previousId: previousId,\n            };\n            version.id = Version.createHash(version);\n            Version.insert(version).execWithin(tx, function (err) {\n                if (err) return backoff(err);\n                if (!file) {\n                    var splitPath = idOrPath.split('/');\n                    var fileName = splitPath[splitPath.length - 1];\n                    var newId = uuid.v1();\n                    self.createQuery(idOrPath, {\n                        id: newId,\n                        userAccountId: userAccount.id,\n                        name: fileName,\n                        version: version.id\n                    }, function (err, q) {\n                        if (err) return backoff(err);\n                        q.execWithin(tx, function (err) {\n                            afterFileExists(err, newId);\n                        });\n\n                    })\n                }\n                else return afterFileExists(null, file.id);\n            });\n            function afterFileExists(err, fileId) {\n                if (err) return backoff(err);\n                FileVersion.insert({fileId: fileId,versionId: version.id})\n                    .execWithin(tx, function (err) {\n                        if (err) return backoff(err);\n                        File.whereUpdate({id: fileId}, {\n                            version: version.id\n                        }).execWithin(tx, function (err) {\n                            if (err) return backoff(err);\n                            tx.commit(done);\n                        });\n                })\n            }\n        });\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/callbacks-caolan-async-waterfall.js",
    "content": "require('../lib/fakes');\nvar async = require('async');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobId, file, version, fileId;\n    async.waterfall([\n        function writeBlob(callback) {\n            blob.put(stream, callback);\n        },\n        function afterBlobWritten(callback) {\n            blobId = undefined // iBlobId;\n            self.byUuidOrPath(idOrPath).get(callback);\n        },\n        function afterFileFetched(callback) {\n            file = undefined; //iFile;\n            var previousId = file ? file.version : null;\n            version = {\n                userAccountId: userAccount.id,\n                date: new Date(),\n                blobId: blobId,\n                creatorId: userAccount.id,\n                previousId: previousId,\n                mergedId: null,\n                mergeType: 'mine',\n                comment: '',\n                tag: tag\n            };\n            version.id = Version.createHash(version);\n            Version.insert(version).execWithin(tx, callback);\n        },\n        function afterVersionInserted(callback) {\n            if (!file) {\n                var splitPath = idOrPath.split('/');\n                var fileName = splitPath[splitPath.length - 1];\n                var newId = uuid.v1();\n                self.createQuery(idOrPath, {\n                    id: newId,\n                    userAccountId: userAccount.id,\n                    type: 'file',\n                    name: fileName,\n                    version: version.id\n                }, function (err, q) {\n                    if (err) return backoff(err);\n                    q.execWithin(tx, function (err) {\n                        callback(err, newId);\n                    });\n\n                })\n            }\n            else return callback(null, file.id);\n        },\n        function afterFileExists(iFileId, callback) {\n            fileId = iFileId; \n            FileVersion.insert({fileId: fileId, versionId: version.id})\n                .execWithin(tx, callback);\n        },\n        function afterFileVersionInserted(callback) {\n            File.whereUpdate({id: fileId}, { version: version.id })\n                .execWithin(tx, callback);\n        },\n        function afterFileUpdated(callback) {\n            tx.commit(callback);\n        }\n    ],\n    function (err) {\n        if (err) tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/callbacks-suguru03-neo-async-waterfall.js",
    "content": "require('../lib/fakes');\nvar async = require('neo-async');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobId, file, version, fileId;\n    async.waterfall([\n        function writeBlob(callback) {\n            blob.put(stream, callback);\n        },\n        function afterBlobWritten(callback) {\n            blobId = undefined // iBlobId;\n            self.byUuidOrPath(idOrPath).get(callback);\n        },\n        function afterFileFetched(callback) {\n            file = undefined; //iFile;\n            var previousId = file ? file.version : null;\n            version = {\n                userAccountId: userAccount.id,\n                date: new Date(),\n                blobId: blobId,\n                creatorId: userAccount.id,\n                previousId: previousId,\n                mergedId: null,\n                mergeType: 'mine',\n                comment: '',\n                tag: tag\n            };\n            version.id = Version.createHash(version);\n            Version.insert(version).execWithin(tx, callback);\n        },\n        function afterVersionInserted(callback) {\n            if (!file) {\n                var splitPath = idOrPath.split('/');\n                var fileName = splitPath[splitPath.length - 1];\n                var newId = uuid.v1();\n                self.createQuery(idOrPath, {\n                    id: newId,\n                    userAccountId: userAccount.id,\n                    type: 'file',\n                    name: fileName,\n                    version: version.id\n                }, function (err, q) {\n                    if (err) return backoff(err);\n                    q.execWithin(tx, function (err) {\n                        callback(err, newId);\n                    });\n\n                })\n            }\n            else return callback(null, file.id);\n        },\n        function afterFileExists(iFileId, callback) {\n            fileId = iFileId;\n            FileVersion.insert({fileId: fileId, versionId: version.id})\n                .execWithin(tx, callback);\n        },\n        function afterFileVersionInserted(callback) {\n            File.whereUpdate({id: fileId}, { version: version.id })\n                .execWithin(tx, callback);\n        },\n        function afterFileUpdated(callback) {\n            tx.commit(callback);\n        }\n    ],\n    function (err) {\n        if (err) tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/generators-tj-co.js",
    "content": "global.useNative = true;\n\ntry {\n    if (Promise.race.toString() !== 'function race() { [native code] }')\n        throw 0;\n} catch (e) {\n    throw new Error(\"No ES6 promises available\");\n}\nvar co = require(\"co\");\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    co(function* () {\n        try {\n            var blob = blobManager.create(account);\n            var tx = db.begin();\n            var blobId = yield blob.put(stream);\n            var file = yield self.byUuidOrPath(idOrPath).get();\n\n            var previousId = file ? file.version : null;\n            version = {\n                userAccountId: userAccount.id,\n                date: new Date(),\n                blobId: blobId,\n                creatorId: userAccount.id,\n                previousId: previousId,\n            };\n            version.id = Version.createHash(version);\n            yield Version.insert(version).execWithin(tx);\n            if (!file) {\n                var splitPath = idOrPath.split('/');\n                var fileName = splitPath[splitPath.length - 1];\n                file = {\n                    id: uuid.v1(),\n                    userAccountId: userAccount.id,\n                    name: fileName,\n                    version: version.id\n                }\n                var query = yield self.createQuery(idOrPath, file);\n                yield query.execWithin(tx);\n            }\n            yield FileVersion.insert({fileId: file.id, versionId: version.id})\n                .execWithin(tx);\n            yield File.whereUpdate({id: file.id}, {version: version.id})\n                .execWithin(tx);\n            tx.commit();\n            done();\n        } catch (err) {\n            tx.rollback();\n            done(err);\n        }\n    });\n};\n"
  },
  {
    "path": "benchmark/doxbee-sequential/observables-Reactive-Extensions-RxJS.js",
    "content": "global.useRx = true;\nvar Rx = require('rx');\nrequire('../lib/fakesObservable');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n\n    Rx.Observable.forkJoin(blobIdP, fileP).flatMap(function(v) {\n        file = v[1];\n        var blobId = v[0];\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).flatMap(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).flatMap(function(q) {\n                return q.execWithin(tx);\n            }).map(function() {\n                return newId;\n            });\n        } else {\n            return Rx.Observable.return(file.id);\n        }\n    }).flatMap(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).flatMap(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).subscribe(function() {\n\n    }, function() {\n        tx.rollback();\n        done(err);\n    }, function() {\n        tx.commit();\n        done();\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/observables-baconjs-bacon.js.js",
    "content": "global.useBacon = true;\nvar Bacon = require('baconjs').Bacon;\nrequire('../lib/fakesObservable');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n\n    var stream = Bacon.combineAsArray(blobIdP, fileP).flatMap(function(v) {\n        file = v[1];\n        var blobId = v[0];\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).flatMap(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).flatMap(function(q) {\n                return q.execWithin(tx);\n            }).map(function() {\n                return newId;\n            });\n        } else {\n            return Bacon.constant(file.id);\n        }\n    }).flatMap(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).flatMap(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    });\n    stream.onError(function() {\n        tx.rollback();\n        done(err);\n    });\n    stream.onValue(function() {\n        tx.commit();\n        done();\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/observables-caolan-highland.js",
    "content": "global.useHighland = true;\nvar _ = require(\"highland\");\nrequire('../lib/fakesObservable');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n    _([blobIdP, fileP]).merge().apply(function(blobId, file) {\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        Version.insert(version).execWithin(tx).flatMap(function() {\n            if (!file) {\n                var splitPath = idOrPath.split('/');\n                var fileName = splitPath[splitPath.length - 1];\n                var newId = uuid.v1();\n                return self.createQuery(idOrPath, {\n                    id: newId,\n                    userAccountId: userAccount.id,\n                    name: fileName,\n                    version: version.id\n                }).flatMap(function(q) {\n                    return q.execWithin(tx);\n                }).map(function() {\n                    return newId;\n                });\n            } else {\n                return _([file.id]);\n            }\n        }).flatMap(function(fileIdV) {\n            fileId = fileIdV;\n            return FileVersion.insert({\n                fileId: fileId,\n                versionId: version.id\n            }).execWithin(tx);\n        }).flatMap(function() {\n            return File.whereUpdate({id: fileId}, {version: version.id})\n                .execWithin(tx);\n        }).stopOnError(function(err) {\n            tx.rollback();\n            done(err);\n        }).apply(function(v) {\n            tx.commit();\n            done();\n        });\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/observables-pozadi-kefir.js",
    "content": "global.useKefir = true;\nvar Kefir = require('kefir').Kefir;\nrequire('../lib/fakesObservable');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n\n    var stream = Kefir.zip([blobIdP, fileP]).flatMap(function(v) {\n        file = v[1];\n        var blobId = v[0];\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).flatMap(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).flatMap(function(q) {\n                return q.execWithin(tx);\n            }).map(function() {\n                return newId;\n            });\n        } else {\n            return Kefir.constant(file.id);\n        }\n    }).flatMap(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).flatMap(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    });\n    stream.onError(function() {\n        tx.rollback();\n        done(err);\n    });\n    stream.onValue(function() {\n        tx.commit();\n        done();\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-bluebird-generator.js",
    "content": "global.useBluebird = true;\nglobal.useQ = false;\nvar bluebird = require('../../js/release/bluebird.js');\nrequire('../lib/fakesP');\n\nmodule.exports = bluebird.coroutine(function* upload(stream, idOrPath, tag, done) {\n    try {\n        var blob = blobManager.create(account);\n        var tx = db.begin();\n        var blobId = yield blob.put(stream);\n        var file = yield self.byUuidOrPath(idOrPath).get();\n\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        yield Version.insert(version).execWithin(tx);\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            file = {\n                id: uuid.v1(),\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }\n            var query = yield self.createQuery(idOrPath, file);\n            yield query.execWithin(tx);\n        }\n        yield FileVersion.insert({fileId: file.id, versionId: version.id})\n            .execWithin(tx);\n        yield File.whereUpdate({id: file.id}, {version: version.id})\n            .execWithin(tx);\n        tx.commit();\n        done();\n    } catch (err) {\n        tx.rollback();\n        done(err);\n    }\n});\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-bluebird.js",
    "content": "global.useBluebird = true;\nglobal.useQ = false;\nvar bluebird = require('../../js/release/bluebird.js');\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n    bluebird.join(blobIdP, fileP, function(blobId, fileV) {\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-calvinmetcalf-lie.js",
    "content": "global.useLie = true;\n\nvar promise = require(\"lie\");\n\nrequire('../lib/fakesP');\n\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    promise.all([blobIdP, fileP]).then(function(all) {\n        var blobId = all[0], fileV = all[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQueryCtxless(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-cujojs-when.js",
    "content": "var when = require('when'), \n    fn = require('when/function'), \n    p = require('../lib/promiseSupport.js');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream); \n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    when([blobIdP, fileP]).spread(function(blobId, fileV) {        \n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-dfilatov-vow.js",
    "content": "var vow = require('vow'),\n    p = require('../lib/promiseSupport.js');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n    vow.all([blobIdP, fileP]).spread(function(blobId, fileV) {\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-ecmascript6-native.js",
    "content": "global.useNative = true;\n\ntry {\n    if (Promise.race.toString() !== 'function race() { [native code] }')\n        throw 0;\n} catch (e) {\n    throw new Error(\"No ES6 promises available\");\n}\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n    Promise.all([blobIdP, fileP]).then(function(result) {\n        var blobId = result[0];\n        var fileV = result[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-kriskowal-q.js",
    "content": "global.useQ = true;\n\nvar q = require('q');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream); \n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    q.spread([blobIdP, fileP], function(blobId, fileV) {        \n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-lvivski-davy.js",
    "content": "global.useDavy = true;\nvar davy = require('davy');\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n    davy.all([blobIdP, fileP]).spread(function(blobId, fileV) {\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-medikoo-deferred.js",
    "content": "global.useDeferred = true;\n\nvar deferred = require('deferred');\n\nrequire('../lib/fakesP');\n\nfunction identity(v) {\n    return v;\n}\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    //Couldn't find .all in docs, this seems closest\n    deferred.map([blobIdP, fileP], identity)(function(all) {\n        var blobId = all[0], fileV = all[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    })(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQueryCtxless(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            })(function(q) {\n                return q.execWithin(tx);\n            })(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    })(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    })(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    })(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-native-async-await.js",
    "content": "global.useNative = true;\n\ntry {\n    if (Promise.race.toString() !== 'function race() { [native code] }')\n        throw 0;\n} catch (e) {\n    throw new Error(\"No ES6 promises available\");\n}\n\nrequire('../lib/fakesP');\n\nmodule.exports = async function upload(stream, idOrPath, tag, done) {\n    try {\n        var blob = blobManager.create(account);\n        var tx = db.begin();\n        var blobId = await blob.put(stream);\n        var file = await self.byUuidOrPath(idOrPath).get();\n\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        await Version.insert(version).execWithin(tx);\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            file = {\n                id: uuid.v1(),\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }\n            var query = await self.createQuery(idOrPath, file);\n            await query.execWithin(tx);\n        }\n        await FileVersion.insert({fileId: file.id, versionId: version.id})\n            .execWithin(tx);\n        await File.whereUpdate({id: file.id}, {version: version.id})\n            .execWithin(tx);\n        tx.commit();\n        done();\n    } catch (err) {\n        tx.rollback();\n        done(err);\n    }\n};\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-obvious-kew.js",
    "content": "global.useKew = true;\n\nvar q = require('kew');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream); \n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    q.all([blobIdP, fileP]).then(function(all) {        \n        var blobId = all[0], fileV = all[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQueryCtxless(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-then-promise.js",
    "content": "global.useThenPromise = true;\n\nvar promise = require(\"promise\");\n\nrequire('../lib/fakesP');\n\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    promise.all([blobIdP, fileP]).then(function(all) {\n        var blobId = all[0], fileV = all[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQueryCtxless(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/promises-tildeio-rsvp.js",
    "content": "global.useRSVP = true;\n\nvar rsvp = require('rsvp');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    rsvp.all([blobIdP, fileP]).then(function(all) {\n        var blobId = all[0], fileV = all[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQueryCtxless(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential/streamline-callbacks.js",
    "content": "'use strict';\n\nvar regeneratorRuntime = typeof require === 'function' ? require('streamline-runtime/lib/callbacks/regenerator') : Streamline.require('streamline-runtime/lib/callbacks/regenerator');\n\nvar _streamline = typeof require === 'function' ? require('streamline-runtime/lib/callbacks/runtime') : Streamline.require('streamline-runtime/lib/callbacks/runtime');\n\nvar _filename = '/Users/bruno/dev/bluebird/benchmark/doxbee-sequential/streamline._js';\nrequire('../lib/fakes');\n\nmodule.exports = _streamline.async(regeneratorRuntime.mark(function _$$upload$$(stream, idOrPath, tag, _2) {\n    var blob, tx, blobId, file, previousId, version, splitPath, fileName, query;\n    return regeneratorRuntime.wrap(function _$$upload$$$(_context) {\n        while (1) {\n            switch (_context.prev = _context.next) {\n                case 0:\n                    _context.prev = 0;\n                    blob = blobManager.create(account);\n                    tx = db.begin();\n                    _context.next = 5;\n                    return _streamline.await(_filename, 7, blob, 'put', 1, null, false, [stream, true]);\n\n                case 5:\n                    blobId = _context.sent;\n                    _context.next = 8;\n                    return _streamline.await(_filename, 8, self.byUuidOrPath(idOrPath), 'get', 0, null, false, [true]);\n\n                case 8:\n                    file = _context.sent;\n                    previousId = file ? file.version : null;\n                    version = {\n                        userAccountId: userAccount.id,\n                        date: new Date(),\n                        blobId: blobId,\n                        creatorId: userAccount.id,\n                        previousId: previousId\n                    };\n\n                    version.id = Version.createHash(version);\n                    _context.next = 14;\n                    return _streamline.await(_filename, 19, Version.insert(version), 'execWithin', 1, null, false, [tx, true]);\n\n                case 14:\n                    if (file) {\n                            _context.next = 23;\n                            break;\n                        }\n\n                    splitPath = idOrPath.split('/');\n                    fileName = splitPath[splitPath.length - 1];\n\n                    file = {\n                        id: uuid.v1(),\n                        userAccountId: userAccount.id,\n                        name: fileName,\n                        version: version.id\n                    };\n                    _context.next = 20;\n                    return _streamline.await(_filename, 29, self, 'createQuery', 2, null, false, [idOrPath, file, true]);\n\n                case 20:\n                    query = _context.sent;\n                    _context.next = 23;\n                    return _streamline.await(_filename, 30, query, 'execWithin', 1, null, false, [tx, true]);\n\n                case 23:\n                    _context.next = 25;\n                    return _streamline.await(_filename, 32, FileVersion.insert({ fileId: file.id, versionId: version.id }), 'execWithin', 1, null, false, [tx, true]);\n\n                case 25:\n                    _context.next = 27;\n                    return _streamline.await(_filename, 34, File.whereUpdate({ id: file.id }, { version: version.id }), 'execWithin', 1, null, false, [tx, true]);\n\n                case 27:\n                    tx.commit();\n                    _context.next = 34;\n                    break;\n\n                case 30:\n                    _context.prev = 30;\n                    _context.t0 = _context['catch'](0);\n\n                    tx.rollback();\n                    throw _context.t0;\n\n                case 34:\n                case 'end':\n                    return _context.stop();\n            }\n        }\n    }, _$$upload$$, this, [[0, 30]]);\n}), 3, 4);"
  },
  {
    "path": "benchmark/doxbee-sequential/streamline-generators.js",
    "content": "'use strict';\n\nvar _streamline = typeof require === 'function' ? require('streamline-runtime/lib/generators/runtime') : Streamline.require('streamline-runtime/lib/generators/runtime');\n\nvar _filename = '/Users/bruno/dev/bluebird/benchmark/doxbee-sequential/streamline._js';\nrequire('../lib/fakes');\n\nmodule.exports = _streamline.async(function* _$$upload$$(stream, idOrPath, tag, _2) {\n    {\n        try {\n            var blob = blobManager.create(account);\n            var tx = db.begin();\n            var blobId = yield _streamline.await(_filename, 7, blob, 'put', 1, null, false, [stream, true]);\n            var file = yield _streamline.await(_filename, 8, self.byUuidOrPath(idOrPath), 'get', 0, null, false, [true]);\n\n            var previousId = file ? file.version : null;\n            var version = {\n                userAccountId: userAccount.id,\n                date: new Date(),\n                blobId: blobId,\n                creatorId: userAccount.id,\n                previousId: previousId\n            };\n            version.id = Version.createHash(version);\n            yield _streamline.await(_filename, 19, Version.insert(version), 'execWithin', 1, null, false, [tx, true]);\n            if (!file) {\n                    var splitPath = idOrPath.split('/');\n                    var fileName = splitPath[splitPath.length - 1];\n                    file = {\n                        id: uuid.v1(),\n                        userAccountId: userAccount.id,\n                        name: fileName,\n                        version: version.id\n                    };\n                    var query = yield _streamline.await(_filename, 29, self, 'createQuery', 2, null, false, [idOrPath, file, true]);\n                    yield _streamline.await(_filename, 30, query, 'execWithin', 1, null, false, [tx, true]);\n                }\n            yield _streamline.await(_filename, 32, FileVersion.insert({ fileId: file.id, versionId: version.id }), 'execWithin', 1, null, false, [tx, true]);\n            yield _streamline.await(_filename, 34, File.whereUpdate({ id: file.id }, { version: version.id }), 'execWithin', 1, null, false, [tx, true]);\n            tx.commit();\n        } catch (err) {\n            tx.rollback();\n            throw err;\n        }\n    }\n}, 3, 4);"
  },
  {
    "path": "benchmark/doxbee-sequential/streamline._js",
    "content": "require('../lib/fakes');\n\nmodule.exports = function upload(stream, idOrPath, tag, _) {\n    try {\n        var blob = blobManager.create(account);\n        var tx = db.begin();\n        var blobId = blob.put(stream, _);\n        var file = self.byUuidOrPath(idOrPath).get(_);\n\n        var previousId = file ? file.version : null;\n        var version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        Version.insert(version).execWithin(tx, _);\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            file = {\n                id: uuid.v1(),\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }\n            var query = self.createQuery(idOrPath, file, _);\n            query.execWithin(tx, _);\n        }\n        FileVersion.insert({fileId: file.id, versionId: version.id})\n            .execWithin(tx, _);\n        File.whereUpdate({id: file.id}, {version: version.id})\n            .execWithin(tx, _);\n        tx.commit();\n    } catch (err) {\n        tx.rollback();\n        throw err;\n    }\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/callbacks-baseline.js",
    "content": "require('../lib/fakes');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    function backoff(err) {\n        tx.rollback();\n        return done(err);\n    }\n    var intentionalErrorShouldBeTriggered = function(){\n        return LIKELIHOOD_OF_REJECTION && Math.random() <= LIKELIHOOD_OF_REJECTION;\n    }\n\n    blob.put(stream, function (err, blobId) {\n        if (err) return done(err);\n        self.byUuidOrPath(idOrPath).get(function (err, file) {\n            if (err) return done(err);\n            var previousId = file ? file.version : null;\n            var version = {\n                userAccountId: userAccount.id,\n                date: new Date(),\n                blobId: blobId,\n                creatorId: userAccount.id,\n                previousId: previousId,\n            };\n            version.id = Version.createHash(version);\n            Version.insert(version).execWithin(tx, function (err) {\n                if (err) return backoff(err);\n                if(intentionalErrorShouldBeTriggered()) return done(new Error(\"intentional failure\"));\n                if (!file) {\n                    var splitPath = idOrPath.split('/');\n                    var fileName = splitPath[splitPath.length - 1];\n                    var newId = uuid.v1();\n                    self.createQuery(idOrPath, {\n                        id: newId,\n                        userAccountId: userAccount.id,\n                        name: fileName,\n                        version: version.id\n                    }, function (err, q) {\n                        if (err) return backoff(err);\n                        if(intentionalErrorShouldBeTriggered()) return done(new Error(\"intentional failure\"));\n                        q.execWithin(tx, function (err) {\n                            afterFileExists(err, newId);\n                        });\n\n                    })\n                }\n                else return afterFileExists(null, file.id);\n            });\n            function afterFileExists(err, fileId) {\n                if (err) return backoff(err);\n                if(intentionalErrorShouldBeTriggered()) return done(new Error(\"intentional failure\"));\n                FileVersion.insert({fileId: fileId,versionId: version.id})\n                    .execWithin(tx, function (err) {\n                        if (err) return backoff(err);\n                        if(intentionalErrorShouldBeTriggered()) return done(new Error(\"intentional failure\"));\n                        File.whereUpdate({id: fileId}, {\n                            version: version.id\n                        }).execWithin(tx, function (err) {\n                            if (err) return backoff(err);\n                            if(intentionalErrorShouldBeTriggered()) return done(new Error(\"intentional failure\"));\n                            tx.commit(done);\n                        });\n                })\n            }\n        });\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/callbacks-caolan-async-waterfall.js",
    "content": "require('../lib/fakes');\nvar async = require('async');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobId, file, version, fileId;\n    async.waterfall([\n        function writeBlob(callback) {\n            blob.put(stream, callback);\n        },\n        function afterBlobWritten(callback) {\n            blobId = undefined // iBlobId;\n            self.byUuidOrPath(idOrPath).get(callback);\n        },\n        function afterFileFetched(callback) {\n            file = undefined; //iFile;\n            var previousId = file ? file.version : null;\n            version = {\n                userAccountId: userAccount.id,\n                date: new Date(),\n                blobId: blobId,\n                creatorId: userAccount.id,\n                previousId: previousId,\n                mergedId: null,\n                mergeType: 'mine',\n                comment: '',\n                tag: tag\n            };\n            version.id = Version.createHash(version);\n            Version.insert(version).execWithin(tx, callback);\n        },\n        function afterVersionInserted(callback) {\n            if (!file) {\n                var splitPath = idOrPath.split('/');\n                var fileName = splitPath[splitPath.length - 1];\n                var newId = uuid.v1();\n                self.createQuery(idOrPath, {\n                    id: newId,\n                    userAccountId: userAccount.id,\n                    type: 'file',\n                    name: fileName,\n                    version: version.id\n                }, function (err, q) {\n                    if (err) return backoff(err);\n                    q.execWithin(tx, function (err) {\n                        callback(err, newId);\n                    });\n\n                })\n            }\n            else return callback(null, file.id);\n        },\n        function afterFileExists(iFileId, callback) {\n            fileId = iFileId; \n            FileVersion.insert({fileId: fileId, versionId: version.id})\n                .execWithin(tx, callback);\n        },\n        function afterFileVersionInserted(callback) {\n            File.whereUpdate({id: fileId}, { version: version.id })\n                .execWithin(tx, callback);\n        },\n        function afterFileUpdated(callback) {\n            tx.commit(callback);\n        }\n    ],\n    function (err) {\n        if (err) tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/callbacks-suguru03-neo-async-waterfall.js",
    "content": "require('../lib/fakes');\nvar async = require('neo-async');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobId, file, version, fileId;\n    async.waterfall([\n        function writeBlob(callback) {\n            blob.put(stream, callback);\n        },\n        function afterBlobWritten(callback) {\n            blobId = undefined // iBlobId;\n            self.byUuidOrPath(idOrPath).get(callback);\n        },\n        function afterFileFetched(callback) {\n            file = undefined; //iFile;\n            var previousId = file ? file.version : null;\n            version = {\n                userAccountId: userAccount.id,\n                date: new Date(),\n                blobId: blobId,\n                creatorId: userAccount.id,\n                previousId: previousId,\n                mergedId: null,\n                mergeType: 'mine',\n                comment: '',\n                tag: tag\n            };\n            version.id = Version.createHash(version);\n            Version.insert(version).execWithin(tx, callback);\n        },\n        function afterVersionInserted(callback) {\n            if (!file) {\n                var splitPath = idOrPath.split('/');\n                var fileName = splitPath[splitPath.length - 1];\n                var newId = uuid.v1();\n                self.createQuery(idOrPath, {\n                    id: newId,\n                    userAccountId: userAccount.id,\n                    type: 'file',\n                    name: fileName,\n                    version: version.id\n                }, function (err, q) {\n                    if (err) return backoff(err);\n                    q.execWithin(tx, function (err) {\n                        callback(err, newId);\n                    });\n\n                })\n            }\n            else return callback(null, file.id);\n        },\n        function afterFileExists(iFileId, callback) {\n            fileId = iFileId;\n            FileVersion.insert({fileId: fileId, versionId: version.id})\n                .execWithin(tx, callback);\n        },\n        function afterFileVersionInserted(callback) {\n            File.whereUpdate({id: fileId}, { version: version.id })\n                .execWithin(tx, callback);\n        },\n        function afterFileUpdated(callback) {\n            tx.commit(callback);\n        }\n    ],\n    function (err) {\n        if (err) tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-bluebird-generator.js",
    "content": "global.useBluebird = true;\nglobal.useQ = false;\nvar bluebird = require('../../js/release/bluebird.js');\nrequire('../lib/fakesP');\n\nmodule.exports = bluebird.coroutine(function* upload(stream, idOrPath, tag, done) {\n    try {\n        var blob = blobManager.create(account);\n        var tx = db.begin();\n        var blobId = yield blob.put(stream);\n        var file = yield self.byUuidOrPath(idOrPath).get();\n\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        yield Version.insert(version).execWithin(tx);\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            file = {\n                id: uuid.v1(),\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }\n            var query = yield self.createQuery(idOrPath, file);\n            yield query.execWithin(tx);\n            triggerIntentionalError();\n        }\n        yield FileVersion.insert({fileId: file.id, versionId: version.id})\n            .execWithin(tx);\n        triggerIntentionalError();\n        yield File.whereUpdate({id: file.id}, {version: version.id})\n            .execWithin(tx);\n        triggerIntentionalError();\n        tx.commit();\n        done();\n    } catch (err) {\n        tx.rollback();\n        done(err);\n    }\n});\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-bluebird.js",
    "content": "global.useBluebird = true;\nglobal.useQ = false;\nvar bluebird = require('../../js/release/bluebird.js');\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n    bluebird.all([blobIdP, fileP]).spread(function(blobId, fileV) {\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        triggerIntentionalError();\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        tx.commit();\n        return done();\n    }).then(null, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-calvinmetcalf-lie.js",
    "content": "global.useLie = true;\n\nvar promise = require(\"lie\");\n\nrequire('../lib/fakesP');\n\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    promise.all([blobIdP, fileP]).then(function(all) {\n        var blobId = all[0], fileV = all[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQueryCtxless(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        triggerIntentionalError();\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        tx.commit();\n        return done();\n    }).then(null, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-cujojs-when.js",
    "content": "var when = require('when'),\n    fn = require('when/function'),\n    p = require('../lib/promiseSupport.js');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    when([blobIdP, fileP]).spread(function(blobId, fileV) {\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        triggerIntentionalError();\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        tx.commit();\n        return done();\n    }).then(null, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-dfilatov-vow.js",
    "content": "var vow = require('vow'),\n    p = require('../lib/promiseSupport.js');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n    vow.all([blobIdP, fileP]).spread(function(blobId, fileV) {\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        triggerIntentionalError();\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        tx.commit();\n        return done();\n    }).then(null, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-kriskowal-q.js",
    "content": "global.useQ = true;\n\nvar q = require('q');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    q.spread([blobIdP, fileP], function(blobId, fileV) {\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        triggerIntentionalError();\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        tx.commit();\n        return done();\n    }).then(null, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-lvivski-davy.js",
    "content": "global.useDavy = true;\nvar davy = require('davy');\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n\n    davy.all([blobIdP, fileP]).spread(function(blobId, fileV) {\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQuery(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        triggerIntentionalError();\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        tx.commit();\n        return done();\n    }).then(null, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-medikoo-deferred.js",
    "content": "global.useDeferred = true;\n\nvar deferred = require('deferred');\n\nrequire('../lib/fakesP');\n\nfunction identity(v) {\n    return v;\n}\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    //Couldn't find .all in docs, this seems closest\n    deferred.map([blobIdP, fileP], identity)(function(all) {\n        var blobId = all[0], fileV = all[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    })(function() {\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQueryCtxless(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            })(function(q) {\n                return q.execWithin(tx);\n            })(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    })(function(fileIdV) {\n        triggerIntentionalError();\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    })(function() {\n        triggerIntentionalError();\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    })(function() {\n        triggerIntentionalError();\n        tx.commit();\n        return done();\n    }, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-obvious-kew.js",
    "content": "global.useKew = true;\n\nvar q = require('kew');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    q.all([blobIdP, fileP]).then(function(all) {\n        var blobId = all[0], fileV = all[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQueryCtxless(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        triggerIntentionalError();\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        tx.commit();\n        return done();\n    }).then(null, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-then-promise.js",
    "content": "global.useThenPromise = true;\n\nvar promise = require(\"promise\");\n\nrequire('../lib/fakesP');\n\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    promise.all([blobIdP, fileP]).then(function(all) {\n        var blobId = all[0], fileV = all[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQueryCtxless(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        triggerIntentionalError();\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        tx.commit();\n        return done();\n    }).then(null, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/promises-tildeio-rsvp.js",
    "content": "global.useRSVP = true;\n\nvar rsvp = require('rsvp');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var blob = blobManager.create(account);\n    var tx = db.begin();\n    var blobIdP = blob.put(stream);\n    var fileP = self.byUuidOrPath(idOrPath).get();\n    var version, fileId, file;\n    rsvp.all([blobIdP, fileP]).then(function(all) {\n        var blobId = all[0], fileV = all[1];\n        file = fileV;\n        var previousId = file ? file.version : null;\n        version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        return Version.insert(version).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            var newId = uuid.v1();\n            return self.createQueryCtxless(idOrPath, {\n                id: newId,\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }).then(function(q) {\n                return q.execWithin(tx);\n            }).then(function() {\n                return newId;\n            });\n        } else {\n            return file.id;\n        }\n    }).then(function(fileIdV) {\n        triggerIntentionalError();\n        fileId = fileIdV;\n        return FileVersion.insert({\n            fileId: fileId,\n            versionId: version.id\n        }).execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        return File.whereUpdate({id: fileId}, {version: version.id})\n            .execWithin(tx);\n    }).then(function() {\n        triggerIntentionalError();\n        tx.commit();\n        return done();\n    }).then(null, function(err) {\n        tx.rollback();\n        return done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/streamline-callbacks.js",
    "content": "'use strict';\n\nvar regeneratorRuntime = typeof require === 'function' ? require('streamline-runtime/lib/callbacks/regenerator') : Streamline.require('streamline-runtime/lib/callbacks/regenerator');\n\nvar _streamline = typeof require === 'function' ? require('streamline-runtime/lib/callbacks/runtime') : Streamline.require('streamline-runtime/lib/callbacks/runtime');\n\nvar _filename = '/Users/bruno/dev/bluebird/benchmark/doxbee-sequential-errors/streamline._js';\nrequire('../lib/fakes');\n\nmodule.exports = _streamline.async(regeneratorRuntime.mark(function _$$upload$$(stream, idOrPath, tag, _2) {\n    var blob, tx, blobId, file, previousId, version, splitPath, fileName, query;\n    return regeneratorRuntime.wrap(function _$$upload$$$(_context) {\n        while (1) {\n            switch (_context.prev = _context.next) {\n                case 0:\n                    _context.prev = 0;\n                    blob = blobManager.create(account);\n                    tx = db.begin();\n                    _context.next = 5;\n                    return _streamline.await(_filename, 7, blob, 'put', 1, null, false, [stream, true]);\n\n                case 5:\n                    blobId = _context.sent;\n                    _context.next = 8;\n                    return _streamline.await(_filename, 8, self.byUuidOrPath(idOrPath), 'get', 0, null, false, [true]);\n\n                case 8:\n                    file = _context.sent;\n                    previousId = file ? file.version : null;\n                    version = {\n                        userAccountId: userAccount.id,\n                        date: new Date(),\n                        blobId: blobId,\n                        creatorId: userAccount.id,\n                        previousId: previousId\n                    };\n\n                    version.id = Version.createHash(version);\n                    _context.next = 14;\n                    return _streamline.await(_filename, 19, Version.insert(version), 'execWithin', 1, null, false, [tx, true]);\n\n                case 14:\n                    triggerIntentionalError();\n\n                    if (file) {\n                            _context.next = 25;\n                            break;\n                        }\n\n                    splitPath = idOrPath.split('/');\n                    fileName = splitPath[splitPath.length - 1];\n\n                    file = {\n                        id: uuid.v1(),\n                        userAccountId: userAccount.id,\n                        name: fileName,\n                        version: version.id\n                    };\n                    _context.next = 21;\n                    return _streamline.await(_filename, 30, self, 'createQuery', 2, null, false, [idOrPath, file, true]);\n\n                case 21:\n                    query = _context.sent;\n                    _context.next = 24;\n                    return _streamline.await(_filename, 31, query, 'execWithin', 1, null, false, [tx, true]);\n\n                case 24:\n                    triggerIntentionalError();\n\n                case 25:\n                    _context.next = 27;\n                    return _streamline.await(_filename, 34, FileVersion.insert({ fileId: file.id, versionId: version.id }), 'execWithin', 1, null, false, [tx, true]);\n\n                case 27:\n                    triggerIntentionalError();\n                    _context.next = 30;\n                    return _streamline.await(_filename, 37, File.whereUpdate({ id: file.id }, { version: version.id }), 'execWithin', 1, null, false, [tx, true]);\n\n                case 30:\n                    triggerIntentionalError();\n                    tx.commit();\n                    _context.next = 38;\n                    break;\n\n                case 34:\n                    _context.prev = 34;\n                    _context.t0 = _context['catch'](0);\n\n                    tx.rollback();\n                    throw _context.t0;\n\n                case 38:\n                case 'end':\n                    return _context.stop();\n            }\n        }\n    }, _$$upload$$, this, [[0, 34]]);\n}), 3, 4);"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/streamline-generators.js",
    "content": "'use strict';\n\nvar _streamline = typeof require === 'function' ? require('streamline-runtime/lib/generators/runtime') : Streamline.require('streamline-runtime/lib/generators/runtime');\n\nvar _filename = '/Users/bruno/dev/bluebird/benchmark/doxbee-sequential-errors/streamline._js';\nrequire('../lib/fakes');\n\nmodule.exports = _streamline.async(function* _$$upload$$(stream, idOrPath, tag, _2) {\n    {\n        try {\n            var blob = blobManager.create(account);\n            var tx = db.begin();\n            var blobId = yield _streamline.await(_filename, 7, blob, 'put', 1, null, false, [stream, true]);\n            var file = yield _streamline.await(_filename, 8, self.byUuidOrPath(idOrPath), 'get', 0, null, false, [true]);\n\n            var previousId = file ? file.version : null;\n            var version = {\n                userAccountId: userAccount.id,\n                date: new Date(),\n                blobId: blobId,\n                creatorId: userAccount.id,\n                previousId: previousId\n            };\n            version.id = Version.createHash(version);\n            yield _streamline.await(_filename, 19, Version.insert(version), 'execWithin', 1, null, false, [tx, true]);\n            triggerIntentionalError();\n            if (!file) {\n                    var splitPath = idOrPath.split('/');\n                    var fileName = splitPath[splitPath.length - 1];\n                    file = {\n                        id: uuid.v1(),\n                        userAccountId: userAccount.id,\n                        name: fileName,\n                        version: version.id\n                    };\n                    var query = yield _streamline.await(_filename, 30, self, 'createQuery', 2, null, false, [idOrPath, file, true]);\n                    yield _streamline.await(_filename, 31, query, 'execWithin', 1, null, false, [tx, true]);\n                    triggerIntentionalError();\n                }\n            yield _streamline.await(_filename, 34, FileVersion.insert({ fileId: file.id, versionId: version.id }), 'execWithin', 1, null, false, [tx, true]);\n            triggerIntentionalError();\n            yield _streamline.await(_filename, 37, File.whereUpdate({ id: file.id }, { version: version.id }), 'execWithin', 1, null, false, [tx, true]);\n            triggerIntentionalError();\n            tx.commit();\n        } catch (err) {\n            tx.rollback();\n            throw err;\n        }\n    }\n}, 3, 4);"
  },
  {
    "path": "benchmark/doxbee-sequential-errors/streamline._js",
    "content": "require('../lib/fakes');\n\nmodule.exports = function upload(stream, idOrPath, tag, _) {\n    try {\n        var blob = blobManager.create(account);\n        var tx = db.begin();\n        var blobId = blob.put(stream, _);\n        var file = self.byUuidOrPath(idOrPath).get(_);\n\n        var previousId = file ? file.version : null;\n        var version = {\n            userAccountId: userAccount.id,\n            date: new Date(),\n            blobId: blobId,\n            creatorId: userAccount.id,\n            previousId: previousId,\n        };\n        version.id = Version.createHash(version);\n        Version.insert(version).execWithin(tx, _);\n        triggerIntentionalError();\n        if (!file) {\n            var splitPath = idOrPath.split('/');\n            var fileName = splitPath[splitPath.length - 1];\n            file = {\n                id: uuid.v1(),\n                userAccountId: userAccount.id,\n                name: fileName,\n                version: version.id\n            }\n            var query = self.createQuery(idOrPath, file, _);\n            query.execWithin(tx, _);\n            triggerIntentionalError();\n        }\n        FileVersion.insert({fileId: file.id, versionId: version.id})\n            .execWithin(tx, _);\n        triggerIntentionalError();\n        File.whereUpdate({id: file.id}, {version: version.id})\n            .execWithin(tx, _);\n        triggerIntentionalError();\n        tx.commit();\n    } catch (err) {\n        tx.rollback();\n        throw err;\n    }\n};"
  },
  {
    "path": "benchmark/lib/catcher.js",
    "content": "\nexports.longStackSupport = global.longStackSupport;\n\n\nfunction invoke(ctx, cb, value, myhandler) {            \n    try {\n        cb.call(ctx, value); // no error\n    } catch (e) {\n        if (myhandler)\n            myhandler.call(ctx, e);\n        else\n            console.error(e);\n    }\n}\n\nmodule.exports = function() {\n    var self = {};\n    var notCaught = true, myhandler;\n    self.try = function $try(cb) {\n        if (exports.longStackSupport) {\n            var ex = {};\n            Error.captureStackTrace(ex);\n        }\n        return function wrapper(err, value) {\n            if (err) {\n               if (notCaught) {\n                   notCaught = false;\n                   if (err.stack && ex) {\n                       var asyncStackRaw =\n                           ex.stack.substr(ex.stack.indexOf('\\n'));\n                       err.stack += '\\nFrom previous event:' \n                           + asyncStackRaw;\n                   }\n                   if (myhandler) myhandler(err);\n                   else console.error(err);\n               }\n            }\n            else if (myhandler) \n                invoke(this, cb, value, myhandler);\n            else cb(value);\n        }\n    }\n    self.catch = function $catch(handler) {\n        myhandler = handler\n    };\n    return self;\n};\n\n"
  },
  {
    "path": "benchmark/lib/dummy.js",
    "content": "// A typical node callback function\n// with the callback at the Nth position\nexports.dummy = function dummy(n) {\n    return function dummy_n() {\n        var cb = arguments[n - 1] || function(){};\n        if (global.asyncTime)\n            setTimeout(cb, global.asyncTime || 100);\n        else\n            process.nextTick(cb);\n    }\n}\n\n// A throwing callback function\nexports.dummyt = function dummyt(n) {\n    return function dummy_throwing_n() {\n        var cb = arguments[n - 1];\n        if (global.testThrow) \n            throw(new Error(\"Exception happened\"));\n        setTimeout(function throwTimeout() {\n            if (global.testThrowAsync) {\n                throw(new Error(\"Exception happened\"));\n            } else if (global.testError) {\n                return cb(new Error(\"Error happened\"));\n            }\n            else cb();\n        }, global.asyncTime || 100);\n    }\n}\n\n\n"
  },
  {
    "path": "benchmark/lib/fakemaker.js",
    "content": "\nmodule.exports = function fakemaker(dummy, dummyt, wrap) {\n\n    var dummy_2 = dummy(2), \n        dummy_1 = dummy(1);\n\n    var dummyt_2, dummyt_1;\n\n    if (global.testError || global.testThrow \n        || global.testThrowAsync) {\n        dummyt_2 = dummyt(2);\n        dummyt_1 = dummyt(1);\n    } else {\n        dummyt_2 = dummy_2;\n        dummyt_1 = dummy_1;\n    }\n\n    // a queryish object with all\n    // kinds of functions\n    function queryish() {\n        return {\n            execWithin: dummy_2,\n            exec: dummy_1,\n            get: dummy_1,\n            all: dummy_1,\n        };\n    }\n\n    // a queryish object with functions\n    // that throw\n    function queryisht() {\n        return {\n            execWithin: dummyt_2,\n            exec: dummyt_1,\n            get: dummyt_1,\n            all: dummyt_1,\n        };\n    }\n\n    global.uuid = { v1: function v1() {} };\n\n    global.userAccount = { };\n\n    global.account = { };\n\n    global.blobManager = {\n        create: function create() {\n            return { \n                put: dummy_2, \n            }\n        }\n    };\n\n    var cqQueryish = queryish();\n\n    global.self = {\n        byUuidOrPath: queryish,\n        createQuery: wrap(function createQuery(x, y, cb, ctx) {\n            cb.call(ctx, null, cqQueryish);\n        }),\n        createQueryCtxless: wrap(function createQuery(x, y, cb) {\n            cb.call(this, null, cqQueryish);\n        })\n    };\n\n\n    global.File = {\n        insert: queryish,\n        whereUpdate: queryish\n    };\n\n    global.FileVersion = {\n        insert: queryisht\n    };\n\n    global.Version  = {\n        createHash: function createHash(v) { return 1; },\n        insert: queryish\n    };\n\n    global.db = {\n        begin: function begin() {\n            return { \n                commit: dummy_1,\n                rollback: dummy_1,\n            };\n        }\n    };\n\n};\n\n\n"
  },
  {
    "path": "benchmark/lib/fakes-ctx.js",
    "content": "var timers = require('./timers-ctx');\n\nvar fakemaker = require('./fakemaker');\n\nvar f = {};\nf.dummy = function dummy(n) {\n    return function dummy_n() {\n        var cb = arguments[n - 1],\n            ctx = arguments[n];\n        //console.log(cb, ctx);\n\n        timers.setTimeout(cb, ctx, global.asyncTime || 100);\n    }\n}\n\n// A throwing callback function\nf.dummyt = function dummyt(n) {\n    return function dummy_throwing_n() {\n        var cb = arguments[n - 1],\n            ctx = arguments[n];\n        if (global.testThrow) \n            throw(new Error(\"Exception happened\"));\n        setTimeout(function throwTimeout() {\n            if (global.testThrowAsync) {\n                throw(new Error(\"Exception happened\"));\n            } else if (global.testError) {\n                return cb.call(ctx, new Error(\"Error happened\"));\n            }\n            else cb.call(ctx);\n        }, global.asyncTime || 100);\n    }\n}\n\n\n\n\nfakemaker(f.dummy, f.dummyt, function wrap_identity(f) { return f; });\n\n\n"
  },
  {
    "path": "benchmark/lib/fakes.js",
    "content": "\n\nvar fakemaker = require('./fakemaker'),\n    f = require('./dummy');\n\nfakemaker(f.dummy, f.dummyt, function wrap_identity(f) { return f; });\n\n\n"
  },
  {
    "path": "benchmark/lib/fakesC.js",
    "content": "\nvar co = require('co');\n\nvar f = require('./dummy');\n\nvar makefakes = require('./fakemaker');\n\n// Continuable versions made with co.wrap\nfunction dummyC(n) {\n    return co.wrap(f.dummy(n));\n}\nfunction dummytC(n) {\n    return co.wrap(f.dummyt(n));\n}\n\nmakefakes(dummyC, dummytC, co.wrap);\n\n\n"
  },
  {
    "path": "benchmark/lib/fakesO.js",
    "content": "\nvar Rx = require('rx');\nvar f = require('./dummy');\n\nvar dummy1 = f.dummy(1),\n    dummyt1 = f.dummyt(1);\n\n// Observable wrapper\nfunction dummyObsWrap(fn) {\n    return function() {\n        return Rx.Observable.create(function(observer) {\n            fn(function(err, res) {\n                if(err) \n                    return observer.onError(err);\n                observer.onNext(res);\n                observer.onCompleted();\n            });\n        });\n    }\n}\nfunction dummyO() {\n    return dummyObsWrap(dummy(1)); \n}\nfunction dummytO() {\n    return dummyObsWrap(dummyt(1));\n}\n\nmakefakes(dummyO, dummytO, dummyObsWrap);\n\n"
  },
  {
    "path": "benchmark/lib/fakesObservable.js",
    "content": "var lifter, fromNodeCallback;\nif (global.useRx) {\n    lifter = require(\"rx\").Observable.fromNodeCallback;\n} else if (global.useBacon) {\n    fromNodeCallback = require(\"baconjs\").fromNodeCallback;\n} else if (global.useKefir) {\n    fromNodeCallback = require(\"kefir\").Kefir.fromNodeCallback;\n    lifter = function(nodeFn) {\n        return function() {\n            var args = [].slice.call(arguments);            \n            function thunk(callback) {\n                args.push(callback);\n                nodeFn.apply(null, args);\n                args.pop();\n            }\n            return fromNodeCallback(thunk);\n        }\n    };\n} else if (global.useHighland) {\n    lifter = require(\"highland\").wrapCallback;\n}\n\nif (!lifter) {\n    lifter = function(nodeFn) {\n        return function() {\n            var args = [].slice.call(arguments);\n            args.unshift(nodeFn);\n            return fromNodeCallback.apply(undefined, args);\n        };\n    };\n}\n\nvar f = require('./dummy');\n\nvar makefakes = require('./fakemaker');\n\n// A function taking n values or promises and returning\n// a promise\nfunction dummyP(n) {\n    return lifter(f.dummy(n));\n}\n\n// Throwing version of above\nfunction dummytP(n) {\n    return lifter(f.dummyt(n));\n}\n\nmakefakes(dummyP, dummytP, lifter);\n"
  },
  {
    "path": "benchmark/lib/fakesP-ctx.js",
    "content": "var timers = require('./timers-ctx');\n\nvar fakemaker = require('./fakemaker');\n\nvar f = {};\nf.dummy = function dummy(n) {\n    return function dummy_n() {\n        var cb = arguments[n - 1],\n            ctx = arguments[n];\n        timers.setTimeout(cb, ctx, global.asyncTime || 100);\n    }\n}\n\n// A throwing callback function\nf.dummyt = function dummyt(n) {\n    return function dummy_throwing_n() {\n        var cb = arguments[n - 1],\n            ctx = arguments[n];\n        if (global.testThrow) \n            throw(new Error(\"Exception happened\"));\n        setTimeout(function throwTimeout() {\n            if (global.testThrowAsync) {\n                throw(new Error(\"Exception happened\"));\n            } else if (global.testError) {\n                return cb.call(ctx, new Error(\"Error happened\"));\n            }\n            else cb.call(ctx);\n        }, global.asyncTime || 100);\n    }\n}\n\n\n\n//Currently promisifies only Node style callbacks\n//var lifter = require('bluebird').promisify;\n\nvar Promise = require('bluebird');\n\nfunction nodeback(err, result) {\n    if (err == null) this.fulfill(result);\n    else this.reject(err);\n}\n\nfunction lifter(f) {\n    return function lifted(a1, a2, a3, a4, a5) {\n        \"use strict\";\n        var len = arguments.length;\n        var deferred = Promise.pending();\n        try {\n            switch(len) {\n                case 1: f(a1, nodeback, deferred); break;\n                case 2: f(a1, a2, nodeback, deferred); break;\n                case 0: f(nodeback, deferred); break;\n                case 3: f(a1, a2, a3, nodeback, deferred); break;\n                case 4: f(a1, a2, a3, a4, nodeback, deferred); break;\n                case 5: f(a1, a2, a3, a4, a5, nodeback, deferred); break;\n            }\n        } catch (err) { deferred.reject(err); }\n        return deferred.promise;\n    }\n}\n\n// A function taking n values or promises and returning \n// a promise\nfunction dummyP(n) {    \n    return function lifted() {\n        var deferred = Promise.pending();\n        timers.setTimeout(nodeback, deferred, global.asyncTime || 100);\n        return deferred.promise;\n    }\n}\n\n// Throwing version of above\nfunction dummytP(n) {\n    return lifter(f.dummyt(n));\n}\n\nfakemaker(dummyP, dummytP, lifter);\n\n"
  },
  {
    "path": "benchmark/lib/fakesP.js",
    "content": "\n\nif (global.useQ)\n    var lifter = require('q').denodeify;\nelse if (global.useBluebird)\n    //Currently promisifies only Node style callbacks\n    var lifter = require('../../js/release/bluebird.js').promisify;\nelse if (global.useKew) {\n    var q = require('kew');\n    var slicer = [].slice;\n    var lifter = function lifter(nodefn) {\n        return function() {\n            var p = q.defer();\n            arguments[arguments.length++] = function(err, res) {\n                if (err) p.reject(err);\n                else p.resolve(res)\n            };\n            try {\n                nodefn.apply(this, arguments);\n            }\n            catch (e) {\n                p.reject(e);\n            }\n            return p;\n        }\n    }\n}\nelse if(global.useLie) {\n    var Lie = require('lie');\n    var lifter = function(nodefn) {\n        return function() {\n            var self = this;\n            var l = arguments.length;\n            var args = new Array(l + 1);\n            for (var i = 0; i < l; ++i) {\n                args[i] = arguments[i];\n            }\n            return new Lie(function(resolve, reject) {\n                args[l] = function(err, val) {\n                    if (err) reject(err);\n                    else resolve(val);\n                };\n                nodefn.apply(self, args);\n            });\n        };\n    };\n}\nelse if(global.useThenPromise) {\n    var lifter = require(\"promise\").denodeify;\n}\nelse if( global.useRSVP ) {\n    var lifter = require(\"rsvp\").denodeify;\n}\nelse if( global.useDeferred) {\n    var lifter = require(\"deferred\").promisify;\n}\nelse if( global.useDavy) {\n    var lifter = require(\"davy\").wrap;\n}\nelse if (global.useNative) {\n    try {\n        if (Promise.race.toString() !== 'function race() { [native code] }')\n            throw 0;\n    } catch (e) {\n        throw new Error(\"No ES6 promises available\");\n    }\n    var lifter = function(nodefn) {\n        return function() {\n            var self = this;\n            var l = arguments.length;\n            var args = new Array(l + 1);\n            for (var i = 0; i < l; ++i) {\n                args[i] = arguments[i];\n            }\n            return new Promise(function(resolve, reject) {\n                args[l] = function(err, val) {\n                    if (err) reject(err);\n                    else resolve(val);\n                };\n                nodefn.apply(self, args);\n            });\n        };\n    };\n}\nelse {\n    var lifter = require('when/node').lift;\n}\n\nvar f = require('./dummy');\n\nvar makefakes = require('./fakemaker');\n\n// A function taking n values or promises and returning\n// a promise\nfunction dummyP(n) {\n    return lifter(f.dummy(n));\n}\n\n// Throwing version of above\nfunction dummytP(n) {\n    return lifter(f.dummyt(n));\n}\n\nmakefakes(dummyP, dummytP, lifter);\n\n"
  },
  {
    "path": "benchmark/lib/fakesSJS-dst.js",
    "content": "\n\nvar f,makefakes;function wrap(f){return __oni_rt.exseq(arguments,this,'lib/fakesSJS-src.sjs',[1,__oni_rt.Nb(function(){return __oni_rt.Return(function (x,y){var err,val;return __oni_rt.exseq(arguments,this,'lib/fakesSJS-src.sjs',[1,__oni_rt.Suspend(function(__oni_env,resume){return __oni_rt.ex(__oni_rt.Nb(function(){return f(x,y,resume);},8),__oni_env)}, function() {err=arguments[0];val=arguments[1];}),__oni_rt.Nb(function(){if(err){throw err;}return __oni_rt.Return(val);},10)])});},12)])}function dummySJS0(){var inner;return __oni_rt.exseq(arguments,this,'lib/fakesSJS-src.sjs',[1,__oni_rt.Nb(function(){inner=f.dummy(1);return __oni_rt.Return(function (){var err,val;return __oni_rt.exseq(arguments,this,'lib/fakesSJS-src.sjs',[1,__oni_rt.Suspend(function(__oni_env,resume){return __oni_rt.ex(__oni_rt.Nb(function(){return inner(resume);},19),__oni_env)}, function() {err=arguments[0];val=arguments[1];}),__oni_rt.Nb(function(){if(err){throw err;}return __oni_rt.Return(val);},21)])});},17)])}function dummySJS1(){var inner;return __oni_rt.exseq(arguments,this,'lib/fakesSJS-src.sjs',[1,__oni_rt.Nb(function(){inner=f.dummy(2);return __oni_rt.Return(function (x){var err,val;return __oni_rt.exseq(arguments,this,'lib/fakesSJS-src.sjs',[1,__oni_rt.Suspend(function(__oni_env,resume){return __oni_rt.ex(__oni_rt.Nb(function(){return inner(x,resume);},30),__oni_env)}, function() {err=arguments[0];val=arguments[1];}),__oni_rt.Nb(function(){if(err){throw err;}return __oni_rt.Return(val);},32)])});},28)])}function dummySJS(n){if(n === 1){return dummySJS0();}if(n === 2){return dummySJS1();}}function dummytSJS(n){var inner;return __oni_rt.exseq(arguments,this,'lib/fakesSJS-src.sjs',[1,__oni_rt.Nb(function(){inner=f.dummyt(n);return __oni_rt.Return(function (){var args,err,val;return __oni_rt.exseq(arguments,this,'lib/fakesSJS-src.sjs',[1,__oni_rt.Suspend(function(__oni_env,resume){return __oni_rt.ex(__oni_rt.Nb(function(){args=Array.prototype.slice.apply(this.aobj);args.push(resume);inner.apply(this,args);},0),__oni_env)}, function() {err=arguments[0];val=arguments[1];}),__oni_rt.Nb(function(){if(err){throw err;}return __oni_rt.Return(val);},51)])});},44)])}__oni_rt.exseq(this.arguments,this,'lib/fakesSJS-src.sjs',[24,__oni_rt.Sc(3,function(_oniX){return f=_oniX;},__oni_rt.C(function(){return require('./dummy.js')},1)),__oni_rt.Sc(5,function(_oniX){return makefakes=_oniX;},__oni_rt.C(function(){return require('./fakemaker.js')},3)),__oni_rt.Nb(function(){return makefakes(dummySJS,dummytSJS,wrap,global);},56)])\n\n"
  },
  {
    "path": "benchmark/lib/fakesSJS-src.sjs",
    "content": "var f = require('./dummy.js');\n\nvar makefakes = require('./fakemaker.js');\n\nfunction wrap(f) {\n  return function(x, y) {\n    waitfor(var err, val) {\n      f(x, y, resume);\n    }\n    if (err) throw err;\n    return val;\n  };\n}\n\nfunction dummySJS0() {\n  var inner = f.dummy(1);\n  return function() {\n    waitfor (var err, val) {\n      inner(resume);\n    }\n    if (err) throw err;\n    return val;\n  }\n}\n\nfunction dummySJS1() {\n  var inner = f.dummy(2);\n  return function(x) {\n    waitfor (var err, val) {\n      inner(x, resume);\n    }\n    if (err) throw err;\n    return val;\n  }\n}\n\nfunction dummySJS(n) {\n  if (n === 1) return dummySJS0();\n  if (n === 2) return dummySJS1();\n}\n\nfunction dummytSJS(n) {\n  var inner = f.dummyt(n);\n  return function() {\n    waitfor(var err, val) {\n      var args = Array.prototype.slice.apply(arguments);\n      args.push(resume);\n      inner.apply(this, args);\n    }\n    \n    if (err) throw err;\n    return val;\n  }\n}\n\nmakefakes(dummySJS, dummytSJS, wrap, global);\n"
  },
  {
    "path": "benchmark/lib/promiseSupport.js",
    "content": "var when = require('when');\nvar fn = require('when/function');\n\n\n\nexports.ternary = fn.lift(function(truthy, iftrue, iffalse) {\n    return truthy ? iftrue: iffalse;\n})\n\nexports.not = function not(truthyP) {\n    return when(truthyP).then(function(truthyVal) {\n        return !truthyVal;\n    });\n}\n\nexports.allObject = function allObject(objWithPromises) {\n    return when(objWithPromises).then(function(objWithPromises) {\n        var keys = Object.keys(objWithPromises);\n        return when.all(keys.map(function(key) { \n            return objWithPromise; \n        })).then(function(vals) {\n            var init = {};\n            for (var k = 0; k < keys.length; ++k) {\n                init[keys[k]] = vals[k];\n            }\n            return init;\n        });\n    });\n}\n\nexports.set = fn.lift(function(obj, values) {\n    for (var key in values)\n        obj[key] = values[key];\n    return obj;\n});\n\nexports.if = function ifP (truthyP, fnTrue, fnFalse) {\n    return truthyP.then(function(truthy) {\n        if (truthy) return fnTrue();\n        else return fnFalse();\n    });\n}\n\nexports.get = fn.lift(function (obj, key) {\n    return obj[key];\n});\n\nexports.eventuallyCall = fn.lift(function(obj, fnkey) {\n    var args = [].slice.call(arguments, 2);\n    obj[fnkey].apply(obj, args);\n});\n"
  },
  {
    "path": "benchmark/lib/timers-ctx.js",
    "content": "// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar Timer = process.binding('timer_wrap').Timer;\nvar L = require('_linklist');\nvar assert = require('assert').ok;\n\nvar kOnTimeout = Timer.kOnTimeout | 0;\n\n// Timeout values > TIMEOUT_MAX are set to 1.\nvar TIMEOUT_MAX = 2147483647; // 2^31-1\n\n\nvar debug = require('util').debuglog('timer');\n\n\n// IDLE TIMEOUTS\n//\n// Because often many sockets will have the same idle timeout we will not\n// use one timeout watcher per item. It is too much overhead.  Instead\n// we'll use a single watcher for all sockets with the same timeout value\n// and a linked list. This technique is described in the libev manual:\n// http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#Be_smart_about_timeouts\n\n// Object containing all lists, timers\n// key = time in milliseconds\n// value = list\nvar lists = {};\n\n// the main function - creates lists on demand and the watchers associated\n// with them.\nfunction insert(item, msecs) {\n  item._idleStart = Timer.now();\n  item._idleTimeout = msecs;\n\n  if (msecs < 0) return;\n\n  var list;\n\n  if (lists[msecs]) {\n    list = lists[msecs];\n  } else {\n    list = new Timer();\n    list.start(msecs, 0);\n\n    L.init(list);\n\n    lists[msecs] = list;\n    list.msecs = msecs;\n    list[kOnTimeout] = listOnTimeout;\n  }\n\n  L.append(list, item);\n  assert(!L.isEmpty(list)); // list is not empty\n}\n\nfunction listOnTimeout() {\n  var msecs = this.msecs;\n  var list = this;\n\n  debug('timeout callback %d', msecs);\n\n  var now = Timer.now();\n  debug('now: %s', now);\n\n  var first;\n  while (first = L.peek(list)) {\n    var diff = now - first._idleStart;\n    if (diff < msecs) {\n      list.start(msecs - diff, 0);\n      debug('%d list wait because diff is %d', msecs, diff);\n      return;\n    } else {\n      L.remove(first);\n      assert(first !== L.peek(list));\n\n      if (!first._onTimeout) continue;\n\n      // v0.4 compatibility: if the timer callback throws and the\n      // domain or uncaughtException handler ignore the exception,\n      // other timers that expire on this tick should still run.\n      //\n      // https://github.com/joyent/node/issues/2631\n      var domain = first.domain;\n      if (domain && domain._disposed) continue;\n      try {\n        if (domain)\n          domain.enter();\n        var threw = true;\n        if (!first._ctx || first._ctx === first)\n          first._onTimeout();     \n        else\n          first._onTimeout.call(first._ctx);\n \n        if (domain)\n          domain.exit();\n        threw = false;\n      } finally {\n        if (threw) {\n          process.nextTick(function() {\n            list[kOnTimeout]();\n          });\n        }\n      }\n    }\n  }\n\n  debug('%d list empty', msecs);\n  assert(L.isEmpty(list));\n  list.close();\n  delete lists[msecs];\n}\n\n\nvar unenroll = exports.unenroll = function(item) {\n  L.remove(item);\n\n  var list = lists[item._idleTimeout];\n  // if empty then stop the watcher\n  debug('unenroll');\n  if (list && L.isEmpty(list)) {\n    debug('unenroll: list empty');\n    list.close();\n    delete lists[item._idleTimeout];\n  }\n  // if active is called later, then we want to make sure not to insert again\n  item._idleTimeout = -1;\n};\n\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n  // if this item was already in a list somewhere\n  // then we should unenroll it from that\n  if (item._idleNext) unenroll(item);\n\n  // Ensure that msecs fits into signed int32\n  if (msecs > 0x7fffffff) {\n    msecs = 0x7fffffff;\n  }\n\n  item._idleTimeout = msecs;\n  L.init(item);\n};\n\n\n// call this whenever the item is active (not idle)\n// it will reset its timeout.\nexports.active = function(item) {\n  var msecs = item._idleTimeout;\n  if (msecs >= 0) {\n\n    var list = lists[msecs];\n    if (!list || L.isEmpty(list)) {\n      insert(item, msecs);\n    } else {\n      item._idleStart = Timer.now();\n      L.append(list, item);\n    }\n  }\n};\n\n\n/*\n * DOM-style timers\n */\n\n\nexports.setTimeout = function(callback, ctx, after) {\n  var timer;\n\n  after *= 1; // coalesce to number or NaN\n\n  if (!(after >= 1 && after <= TIMEOUT_MAX)) {\n    after = 1; // schedule on next tick, follows browser behaviour\n  }\n\n  timer = new Timeout(after);\n  timer._ctx = ctx;\n  timer._onTimeout = callback;\n\n  if (process.domain) timer.domain = process.domain;\n\n  exports.active(timer);\n\n  return timer;\n};\n\n\nexports.clearTimeout = function(timer) {\n  if (timer && (timer[kOnTimeout] || timer._onTimeout)) {\n    timer[kOnTimeout] = timer._onTimeout = null;\n    if (timer instanceof Timeout) {\n      timer.close(); // for after === 0\n    } else {\n      exports.unenroll(timer);\n    }\n  }\n};\n\n\nexports.setInterval = function(callback, repeat) {\n  repeat *= 1; // coalesce to number or NaN\n\n  if (!(repeat >= 1 && repeat <= TIMEOUT_MAX)) {\n    repeat = 1; // schedule on next tick, follows browser behaviour\n  }\n\n  var timer = new Timeout(repeat);\n  var args = Array.prototype.slice.call(arguments, 2);\n  timer._onTimeout = wrapper;\n  timer._repeat = true;\n\n  if (process.domain) timer.domain = process.domain;\n  exports.active(timer);\n\n  return timer;\n\n  function wrapper() {\n    callback.apply(this, args);\n    // If callback called clearInterval().\n    if (timer._repeat === false) return;\n    // If timer is unref'd (or was - it's permanently removed from the list.)\n    if (this._handle) {\n      this._handle.start(repeat, 0);\n    } else {\n      timer._idleTimeout = repeat;\n      exports.active(timer);\n    }\n  }\n};\n\n\nexports.clearInterval = function(timer) {\n  if (timer && timer._repeat) {\n    timer._repeat = false;\n    clearTimeout(timer);\n  }\n};\n\n\nvar Timeout = function(after) {\n  this._idleTimeout = after;\n  this._idlePrev = this;\n  this._idleNext = this;\n  this._idleStart = null;\n  this._onTimeout = null;\n  this._repeat = false;\n  this._ctx = this;\n};\n\nTimeout.prototype.unref = function() {\n  if (!this._handle) {\n    var now = Timer.now();\n    if (!this._idleStart) this._idleStart = now;\n    var delay = this._idleStart + this._idleTimeout - now;\n    if (delay < 0) delay = 0;\n    exports.unenroll(this);\n    this._handle = new Timer();\n    this._handle[kOnTimeout] = this._onTimeout;\n    this._handle.start(delay, 0);\n    this._handle.domain = this.domain;\n    this._handle.unref();\n  } else {\n    this._handle.unref();\n  }\n};\n\nTimeout.prototype.ref = function() {\n  if (this._handle)\n    this._handle.ref();\n};\n\nTimeout.prototype.close = function() {\n  this._onTimeout = this._ctx = null;\n  if (this._handle) {\n    this._handle[kOnTimeout] = null;\n    this._handle.close();\n  } else {\n    exports.unenroll(this);\n  }\n};\n\n\nvar immediateQueue = {};\nL.init(immediateQueue);\n\n\nfunction processImmediate() {\n  var queue = immediateQueue;\n\n  immediateQueue = {};\n  L.init(immediateQueue);\n\n  while (L.isEmpty(queue) === false) {\n    var immediate = L.shift(queue);\n    var domain = immediate.domain;\n    if (domain) domain.enter();\n    immediate._onImmediate();\n    if (domain) domain.exit();\n  }\n\n  // Only round-trip to C++ land if we have to. Calling clearImmediate() on an\n  // immediate that's in |queue| is okay. Worst case is we make a superfluous\n  // call to NeedImmediateCallbackSetter().\n  if (L.isEmpty(immediateQueue)) {\n    process._needImmediateCallback = false;\n  }\n}\n\n\nexports.setImmediate = function(callback) {\n  var immediate = {}, args;\n\n  L.init(immediate);\n\n  immediate._onImmediate = callback;\n\n  if (arguments.length > 1) {\n    args = Array.prototype.slice.call(arguments, 1);\n\n    immediate._onImmediate = function() {\n      callback.apply(immediate, args);\n    };\n  }\n\n  if (!process._needImmediateCallback) {\n    process._needImmediateCallback = true;\n    process._immediateCallback = processImmediate;\n  }\n\n  if (process.domain) immediate.domain = process.domain;\n\n  L.append(immediateQueue, immediate);\n\n  return immediate;\n};\n\n\nexports.clearImmediate = function(immediate) {\n  if (!immediate) return;\n\n  immediate._onImmediate = undefined;\n\n  L.remove(immediate);\n\n  if (L.isEmpty(immediateQueue)) {\n    process._needImmediateCallback = false;\n  }\n};\n\n\n// Internal APIs that need timeouts should use timers._unrefActive isntead of\n// timers.active as internal timeouts shouldn't hold the loop open\n\nvar unrefList, unrefTimer;\n\n\nfunction unrefTimeout() {\n  var now = Timer.now();\n\n  debug('unrefTimer fired');\n\n  var first;\n  while (first = L.peek(unrefList)) {\n    var diff = now - first._idleStart;\n\n    if (diff < first._idleTimeout) {\n      diff = first._idleTimeout - diff;\n      unrefTimer.start(diff, 0);\n      unrefTimer.when = now + diff;\n      debug('unrefTimer rescheudling for later');\n      return;\n    }\n\n    L.remove(first);\n\n    var domain = first.domain;\n\n    if (!first._onTimeout) continue;\n    if (domain && domain._disposed) continue;\n\n    try {\n      if (domain) domain.enter();\n      var threw = true;\n      debug('unreftimer firing timeout');\n      if (!first._ctx || first._ctx === first)\n          first._onTimeout();     \n      else\n          first._onTimeout.call(first._ctx);\n      threw = false;\n      if (domain) domain.exit();\n    } finally {\n      if (threw) process.nextTick(unrefTimeout);\n    }\n  }\n\n  debug('unrefList is empty');\n  unrefTimer.when = -1;\n}\n\n\nexports._unrefActive = function(item) {\n  var msecs = item._idleTimeout;\n  if (!msecs || msecs < 0) return;\n  assert(msecs >= 0);\n\n  L.remove(item);\n\n  if (!unrefList) {\n    debug('unrefList initialized');\n    unrefList = {};\n    L.init(unrefList);\n\n    debug('unrefTimer initialized');\n    unrefTimer = new Timer();\n    unrefTimer.unref();\n    unrefTimer.when = -1;\n    unrefTimer[kOnTimeout] = unrefTimeout;\n  }\n\n  var now = Timer.now();\n  item._idleStart = now;\n\n  if (L.isEmpty(unrefList)) {\n    debug('unrefList empty');\n    L.append(unrefList, item);\n\n    unrefTimer.start(msecs, 0);\n    unrefTimer.when = now + msecs;\n    debug('unrefTimer scheduled');\n    return;\n  }\n\n  var when = now + msecs;\n\n  debug('unrefList find where we can insert');\n\n  var cur, them;\n\n  for (cur = unrefList._idlePrev; cur != unrefList; cur = cur._idlePrev) {\n    them = cur._idleStart + cur._idleTimeout;\n\n    if (when < them) {\n      debug('unrefList inserting into middle of list');\n\n      L.append(cur, item);\n\n      if (unrefTimer.when > when) {\n        debug('unrefTimer is scheduled to fire too late, reschedule');\n        unrefTimer.start(msecs, 0);\n        unrefTimer.when = when;\n      }\n\n      return;\n    }\n  }\n\n  debug('unrefList append to end');\n  L.append(unrefList, item);\n};\n"
  },
  {
    "path": "benchmark/madeup-parallel/callbacks-baseline.js",
    "content": "require('../lib/fakes');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var tx = db.begin();\n    var current = 0;\n    var total = global.parallelQueries;\n\n\n\n    for( var i = 0; i < total; ++i ) {\n        FileVersion.insert({index: i}).execWithin(tx, function onComplete(err) {\n            if (onComplete.called) return;\n            onComplete.called = true;\n            if( err ) {\n                tx.rollback();\n                done(err);\n            }\n            else {\n                current++;\n                if( current === total ) {\n                    tx.commit();\n                    done();\n                }\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/callbacks-caolan-async-parallel.js",
    "content": "require('../lib/fakes');\nvar async = require('async');\n\nfunction fileInsertFor(i, tx) {\n    return function(callback) {\n        FileVersion.insert({index: i})\n            .execWithin(tx, callback);\n    };\n}\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = fileInsertFor(i, tx);\n    }\n\n    async.parallel(queries, function(err, callback) {\n        if (err) {\n            tx.rollback();\n            done(err);\n        }\n        else {\n            tx.commit();\n            done();\n        }\n    });\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/callbacks-suguru03-neo-async-parallel.js",
    "content": "require('../lib/fakes');\nvar async = require('neo-async');\n\nfunction fileInsertFor(i, tx) {\n    return function(callback) {\n        FileVersion.insert({index: i})\n            .execWithin(tx, callback);\n    };\n}\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = fileInsertFor(i, tx);\n    }\n\n    async.parallel(queries, function(err, callback) {\n        if (err) {\n            tx.rollback();\n            done(err);\n        }\n        else {\n            tx.commit();\n            done();\n        }\n    });\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/generators-tj-co.js",
    "content": "global.useNative = true;\n\ntry {\n    if (Promise.race.toString() !== 'function race() { [native code] }')\n        throw 0;\n} catch (e) {\n    throw new Error(\"No ES6 promises available\");\n}\n\nvar co = require('co');\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    return co(function* () {\n        var queries = new Array(global.parallelQueries);\n        var tx = db.begin();\n\n        for( var i = 0, len = queries.length; i < len; ++i ) {\n            queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n        }\n\n        try {\n            yield Promise.all(queries);\n            tx.commit();\n            done();\n        }\n        catch(e) {\n            tx.rollback();\n            done(e);\n        }\n    });\n};\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-bluebird-generator.js",
    "content": "global.useBluebird = true;\nglobal.useQ = false;\nvar bluebird = require('../../js/release/bluebird.js');\nrequire('../lib/fakesP');\n\nmodule.exports = bluebird.coroutine(function* upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    try {\n        yield bluebird.all(queries);\n        tx.commit();\n        done();\n    }\n    catch(e) {\n        tx.rollback();\n        done(e);\n    }\n});\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-bluebird.js",
    "content": "global.useBluebird = true;\nglobal.useQ = false;\nvar Promise = require('../../js/release/bluebird.js');\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    Promise.all(queries).then(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-calvinmetcalf-lie.js",
    "content": "global.useLie = true;\n\nvar Promise = require(\"lie\");\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    Promise.all(queries).then(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-cujojs-when.js",
    "content": "global.useWhen = true;\n\nvar when = require('when');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    when.all(queries).then(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n};\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-dfilatov-vow.js",
    "content": "var vow = require('vow'),\n    p = require('../lib/promiseSupport.js');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    vow.all(queries).then(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-ecmascript6-native.js",
    "content": "global.useNative = true;\n\ntry {\n    if (Promise.race.toString() !== 'function race() { [native code] }')\n        throw 0;\n} catch (e) {\n    throw new Error(\"No ES6 promises available\");\n}\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    Promise.all(queries).then(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-lvivski-davy.js",
    "content": "global.useDavy = true;\n\nvar davy = require('davy');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    davy.all(queries).then(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-medikoo-deferred.js",
    "content": "global.useDeferred = true;\n\nvar deferred = require('deferred');\n\nrequire('../lib/fakesP');\n\nfunction identity(v) {\n    return v;\n}\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    //Couldn't find .all in docs, this seems closest\n    deferred.map(queries, identity)(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-native-async-await.js",
    "content": "global.useNative = true;\n\ntry {\n    if (Promise.race.toString() !== 'function race() { [native code] }')\n        throw 0;\n} catch (e) {\n    throw new Error(\"No ES6 promises available\");\n}\n\nrequire('../lib/fakesP');\n\nmodule.exports = async function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    try {\n        await Promise.all(queries);\n        tx.commit();\n        done();\n    }\n    catch(e) {\n        tx.rollback();\n        done(e);\n    }\n};\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-obvious-kew.js",
    "content": "global.useKew = true;\n\nvar q = require('kew');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    q.all(queries).then(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-then-promise.js",
    "content": "global.useThenPromise = true;\n\nvar Promise = require(\"promise\");\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    Promise.all(queries).then(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n}\n"
  },
  {
    "path": "benchmark/madeup-parallel/promises-tildeio-rsvp.js",
    "content": "global.useRSVP = true;\n\nvar RSVP = require('rsvp');\n\nrequire('../lib/fakesP');\n\nmodule.exports = function upload(stream, idOrPath, tag, done) {\n    var queries = new Array(global.parallelQueries);\n    var tx = db.begin();\n\n    for( var i = 0, len = queries.length; i < len; ++i ) {\n        queries[i] = FileVersion.insert({index: i}).execWithin(tx);\n    }\n\n    RSVP.all(queries).then(function() {\n        tx.commit();\n        done();\n    }, function(err) {\n        tx.rollback();\n        done(err);\n    });\n};\n"
  },
  {
    "path": "benchmark/madeup-parallel/streamline-callbacks.js",
    "content": "'use strict';\n\nvar regeneratorRuntime = typeof require === 'function' ? require('streamline-runtime/lib/callbacks/regenerator') : Streamline.require('streamline-runtime/lib/callbacks/regenerator');\n\nvar _streamline = typeof require === 'function' ? require('streamline-runtime/lib/callbacks/runtime') : Streamline.require('streamline-runtime/lib/callbacks/runtime');\n\nvar _filename = '/Users/bruno/dev/bluebird/benchmark/madeup-parallel/streamline._js';\n\nvar execWithin = _streamline.async(regeneratorRuntime.mark(function _$$execWithin$$(query, tx, _2) {\n    return regeneratorRuntime.wrap(function _$$execWithin$$$(_context) {\n        while (1) {\n            switch (_context.prev = _context.next) {\n                case 0:\n                    _context.next = 2;\n                    return _streamline.await(_filename, 5, query, 'execWithin', 1, null, false, [tx, true]);\n\n                case 2:\n                    return _context.abrupt('return', _context.sent);\n\n                case 3:\n                case 'end':\n                    return _context.stop();\n            }\n        }\n    }, _$$execWithin$$, this);\n}), 2, 3);\n\nrequire('../lib/fakes');\n\n// Futures work on streamlined function so we need to wrap execWithin\n\n\nmodule.exports = _streamline.async(regeneratorRuntime.mark(function _$$upload$$(stream, idOrPath, tag, _3) {\n    var queries, tx, i, len;\n    return regeneratorRuntime.wrap(function _$$upload$$$(_context2) {\n        while (1) {\n            switch (_context2.prev = _context2.next) {\n                case 0:\n                    _context2.prev = 0;\n                    queries = new Array(global.parallelQueries);\n                    tx = db.begin();\n\n\n                    for (i = 0, len = queries.length; i < len; ++i) {\n                        queries[i] = _streamline.future(_filename, 14, null, execWithin, 2, null, false, [FileVersion.insert({ index: i }), tx, false]);\n                    }\n\n                    i = 0, len = queries.length;\n\n                case 5:\n                    if (!(i < len)) {\n                            _context2.next = 11;\n                            break;\n                        }\n\n                    _context2.next = 8;\n                    return _streamline.await(_filename, 18, queries, i, 0, null, false, [true]);\n\n                case 8:\n                    ++i;\n                    _context2.next = 5;\n                    break;\n\n                case 11:\n\n                    tx.commit();\n                    _context2.next = 18;\n                    break;\n\n                case 14:\n                    _context2.prev = 14;\n                    _context2.t0 = _context2['catch'](0);\n\n                    tx.rollback();\n                    throw _context2.t0;\n\n                case 18:\n                case 'end':\n                    return _context2.stop();\n            }\n        }\n    }, _$$upload$$, this, [[0, 14]]);\n}), 3, 4);"
  },
  {
    "path": "benchmark/madeup-parallel/streamline-generators.js",
    "content": "'use strict';\n\nvar _streamline = typeof require === 'function' ? require('streamline-runtime/lib/generators/runtime') : Streamline.require('streamline-runtime/lib/generators/runtime');\n\nvar _filename = '/Users/bruno/dev/bluebird/benchmark/madeup-parallel/streamline._js';\n\nvar execWithin = _streamline.async(function* _$$execWithin$$(query, tx, _2) {\n    {\n        return yield _streamline.await(_filename, 5, query, 'execWithin', 1, null, false, [tx, true]);\n    }\n}, 2, 3);\n\nrequire('../lib/fakes');\n\n// Futures work on streamlined function so we need to wrap execWithin\n\n\nmodule.exports = _streamline.async(function* _$$upload$$(stream, idOrPath, tag, _3) {\n    {\n        try {\n            var queries = new Array(global.parallelQueries);\n            var tx = db.begin();\n\n            for (var i = 0, len = queries.length; i < len; ++i) {\n                queries[i] = _streamline.future(_filename, 14, null, execWithin, 2, null, false, [FileVersion.insert({ index: i }), tx, false]);\n            }\n\n            for (var i = 0, len = queries.length; i < len; ++i) {\n                yield _streamline.await(_filename, 18, queries, i, 0, null, false, [true]);\n            }\n\n            tx.commit();\n        } catch (err) {\n            tx.rollback();\n            throw err;\n        }\n    }\n}, 3, 4);"
  },
  {
    "path": "benchmark/madeup-parallel/streamline._js",
    "content": "require('../lib/fakes');\n\n// Futures work on streamlined function so we need to wrap execWithin\nfunction execWithin(query, tx, _) {\n    return query.execWithin(tx, _);\n}\n\nmodule.exports = function upload(stream, idOrPath, tag, _) {\n    try {\n        var queries = new Array(global.parallelQueries);\n        var tx = db.begin();\n\n        for (var i = 0, len = queries.length; i < len; ++i ) {\n            queries[i] = execWithin(FileVersion.insert({index: i}), tx, !_);\n        }\n\n        for (var i = 0, len = queries.length; i < len; ++i ) {\n            queries[i](_);\n        }\n\n        tx.commit();\n    } catch (err) {\n        tx.rollback();\n        throw err;\n    }\n};\n"
  },
  {
    "path": "benchmark/package.json",
    "content": "{\n  \"name\": \"async-compare\",\n  \"version\": \"0.1.1\",\n  \"description\": \"Compare the performance and code of multiple async patterns\",\n  \"main\": \"perf.js\",\n  \"dependencies\": {\n    \"async\": \"^2.6.1\",\n    \"davy\": \"^1.3.0\",\n    \"deferred\": \"^0.7.9\",\n    \"kew\": \"^0.7.0\",\n    \"lie\": \"^3.3.0\",\n    \"neo-async\": \"^2.5.1\",\n    \"optimist\": \"^0.6.1\",\n    \"promise\": \"^8.0.1\",\n    \"q\": \"^1.5.1\",\n    \"rsvp\": \"^4.8.3\",\n    \"streamline\": \"^2.1.3\",\n    \"streamline-runtime\": \"^1.1.15\",\n    \"text-table\": \"^0.2.0\",\n    \"vow\": \"^0.4.17\",\n    \"when\": \"^3.7.8\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"generators\",\n    \"fibers\",\n    \"promises\",\n    \"callbacks\",\n    \"comparison\",\n    \"compare\",\n    \"async\"\n  ],\n  \"author\": \"spion\",\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">8.11.0 <9\"\n  }\n}\n"
  },
  {
    "path": "benchmark/performance.js",
    "content": "\nvar args = require('optimist').argv;\n\nvar path = require('path');\n\nglobal.LIKELIHOOD_OF_REJECTION = args.e || 0.1;\nglobal.triggerIntentionalError = function(){\n    if(LIKELIHOOD_OF_REJECTION && Math.random() <= LIKELIHOOD_OF_REJECTION) throw new Error(\"intentional failure\");\n}\n\nfunction printPlatform() {\n    console.log(\"\\nPlatform info:\");\n    var os = require(\"os\");\n    var v8 = process.versions.v8;\n    var node = process.versions.node;\n    var plat = os.type() + \" \" + os.release() + \" \" + os.arch() + \"\\nNode.JS \" + node + \"\\nV8 \" + v8;\n    var cpus = os.cpus().map(function(cpu){\n        return cpu.model;\n    }).reduce(function(o, model){\n        if( !o[model] ) o[model] = 0;\n        o[model]++;\n        return o;\n    }, {});\n    cpus = Object.keys(cpus).map(function( key ){\n        return key + \" \\u00d7 \" + cpus[key];\n    }).join(\"\\n\");\n    console.log(plat + \"\\n\" + cpus + \"\\n\");\n}\n\nvar perf = module.exports = function(args, done) {\n\n    var errs = 0;\n    var lastErr;\n    var times = args.n;\n\n    global.asyncTime = args.t;\n    global.parallelQueries = args.p || 10;\n\n    if (args.longStackSupport) {\n        global.longStackSupport = require('q').longStackSupport\n            = args.longStackSupport;\n        require('bluebird').longStackTraces();\n    }\n\n    var fn = require(args.file);\n\n    var start = Date.now();\n\n\n    var warmedUp = 0;\n    var tot =  Math.min( 350, times );\n    for (var k = 0, kn = tot; k < kn; ++k)\n        fn(k,'b','c', warmup);\n\n    var memMax; var memStart; var start;\n    function warmup() {\n        warmedUp++\n        if( warmedUp === tot ) {\n            start = Date.now();\n\n            memStart = process.memoryUsage().rss;\n            for (var k = 0, kn = args.n; k < kn; ++k)\n                fn(k, 'b', 'c', cb);\n            memMax = process.memoryUsage().rss;\n        }\n    }\n\n    function cb (err) {\n        if (err && err.message !== \"intentional failure\") {\n            ++errs;\n            lastErr = err;\n        }\n        memMax = Math.max(memMax, process.memoryUsage().rss);\n        if (!--times) {\n            fn.end && fn.end();\n            done(null, {\n                time: Date.now() - start,\n                mem: (memMax - memStart)/1024/1024,\n                errors: errs,\n                lastErr: lastErr ? lastErr.stack : null\n            });\n        }\n    }\n}\n\n\nfunction report(err, res) {\n    console.log(JSON.stringify(res));\n}\n\nif (args.file) {\n    perf(args, function(err, res) {\n        report(err, res);\n        if (res.lastErr)\n            console.error(res.lastErr);\n    });\n} else {\n    var cp    = require('child_process')\n    var async = require('async');\n    var table = require('text-table');\n\n    var files = args._.filter(function(f) {\n        return !/^src-/.test(path.basename(f));\n    });\n\n    measure(files, args.n, args.t, args.p, function(err, res) {\n        console.log(\"\");\n        console.log(\"results for\", args.n, \"parallel executions,\",\n                    args.t, \"ms per I/O op\");\n        if(args.e) console.log(\"Likelihood of rejection:\", args.e);\n\n        res.sort(function(r1, r2) {\n            return parseFloat(r1.data.time) - parseFloat(r2.data.time)\n        });\n        console.log(\"\");\n        res = res.map(function(r) {\n            var failText = 'OOM';\n            if (r.data.timeout) failText = 'T/O';\n            return [path.basename(r.file),\n                r.data.mem != null ? r.data.time: failText,\n                r.data.mem != null ? r.data.mem.toFixed(2) : failText]\n        });\n\n        res = [['file', 'time(ms)', 'memory(MB)']].concat(res)\n\n        console.log(table(res, {align: ['l', 'r', 'r']}));\n        printPlatform();\n\n    });\n}\n\n\nfunction measure(files, requests, time, parg, callback) {\n    async.mapSeries(files, function(f, done) {\n        console.log(\"benchmarking\", f);\n        var logFile = path.basename(f) + \".log\";\n        var profileFlags = [\"--prof\", \"--logfile=C:/etc/v8/\" + logFile];\n\n        var argsFork = [__filename,\n            '--n', requests,\n            '--t', time,\n            '--p', parg,\n            '--file', f];\n        if (args.profile) argsFork = profileFlags.concat(argsFork);\n        if (args.harmony) argsFork.unshift('--harmony');\n        if (args.longStackSupport) argsFork.push('--longStackSupport');\n        var p = cp.spawn(process.execPath, argsFork);\n\n        var complete = false, timedout = false;\n        if (args.timeout) setTimeout(function() {\n            if (complete) return;\n            timedout = true;\n            p.kill();\n        }, args.timeout);\n\n        var r = { file: f, data: [] };\n        p.stdout.on('data', function(d) { r.data.push(d.toString()); });\n        p.stdout.pipe(process.stdout);\n        p.stderr.pipe(process.stderr);\n        p.stdout.on('end', function(code) {\n            complete = true;\n            try {\n                r.data = JSON.parse(r.data.join(''));\n            } catch(e) {\n                r.data = {time: Number.POSITIVE_INFINITY, mem: null,\n                    missing: true, timeout: timedout};\n            }\n            done(null, r);\n        });\n    }, callback);\n}\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"bluebird\",\n  \"version\": \"3.7.2\",\n  \"homepage\": \"https://github.com/petkaantonov/bluebird\",\n  \"authors\": [\n    \"Petka Antonov <petka_antonov@hotmail.com>\"\n  ],\n  \"description\": \"Bluebird is a full featured promise library with unmatched performance.\",\n  \"main\": \"js/browser/bluebird.js\",\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"benchmark\",\n    \"bower_components\",\n    \"./browser\",\n    \"node_modules\",\n    \"test\"\n  ],\n  \"keywords\": [\n    \"promise\",\n    \"performance\",\n    \"promises\",\n    \"promises-a\",\n    \"promises-aplus\",\n    \"async\",\n    \"await\",\n    \"deferred\",\n    \"deferreds\",\n    \"future\",\n    \"flow control\",\n    \"dsl\",\n    \"fluent interface\"\n  ]\n}\n"
  },
  {
    "path": "build",
    "content": "#!/usr/bin/env bash\nnode tools/build.js \"$@\"\n"
  },
  {
    "path": "changelog.md",
    "content": "[http://bluebirdjs.com/docs/changelog.html](http://bluebirdjs.com/docs/changelog.html)\n"
  },
  {
    "path": "deprecated_apis.md",
    "content": "[http://bluebirdjs.com/docs/deprecated-apis.html](http://bluebirdjs.com/docs/deprecated-apis.html)\n"
  },
  {
    "path": "docs/.gitignore",
    "content": "_site\n.sass-cache\nGemfile.lock\n"
  },
  {
    "path": "docs/Gemfile",
    "content": "source \"https://rubygems.org\"\n\ngem \"jekyll\", '3.9.0'\ngem \"jekyll-redirect-from\"\ngem \"sanitize\", '4.0.1'\ngem \"redcarpet\"\ngem \"pygments.rb\"\ngem 'wdm', '>= 0.1.0' if Gem.win_platform?\n"
  },
  {
    "path": "docs/README.md",
    "content": "Requires ruby and [jekyll](http://jekyllrb.com/). See the gem file for dependencies.\n\nChange directory to `bluebird/docs` and run `jekyll serve`. The docs will be hosted under `/docs` directory in relation to the web root. Typically something like `http://localhost:4000/docs/`\n\n\n"
  },
  {
    "path": "docs/_config.yml",
    "content": "name: bluebird\ndescription: Bluebird is a fully featured JavaScript promises library with unmatched performance.\nurl: \"http://bluebirdjs.com\"\nbaseurl: \"\"\ntitle: bluebird\ntimezone: Helsinki/Finland\nhighlighter: pygments\nexclude:\n  - Gemfile\n  - Gemfile.lock\n  - helpers.rb\ndefaults:\n  - scope:\n      path: docs\n      type: pages\n    values:\n      layout: page\nmarkdown: redcarpet\nredcarpet:\n  extensions:\n    - fenced_code_blocks\nversion: 3.7.2\ngems:\n  - jekyll-redirect-from\ndestination: ../gh-pages/\nkeep_files:\n  - .git\n  - .gitignore\n  - logo.png\n  - CNAME\n  - coverage\nsafe: false\nencoding: utf-8\nhost: 0.0.0.0\n\n"
  },
  {
    "path": "docs/_layouts/api.html",
    "content": "---\nlayout: default\n---\n\n<div class=\"post\">\n  <article class=\"post-content\">\n    {{ content }}\n  </article>\n</div>\n"
  },
  {
    "path": "docs/_layouts/default.html",
    "content": "<!DOCTYPE html>\n<!--[if lt IE 7]>      <html class=\"no-js lt-ie9 lt-ie8 lt-ie7\"> <![endif]-->\n<!--[if IE 7]>         <html class=\"no-js lt-ie9 lt-ie8\"> <![endif]-->\n<!--[if IE 8]>         <html class=\"no-js lt-ie9\"> <![endif]-->\n<!--[if gt IE 8]><!-->\n<html class=\"no-js\">\n <!--<![endif]-->\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <link href='http://fonts.googleapis.com/css?family=Raleway:400,300,200,700,500,100,800,600,900' rel='stylesheet' type='text/css'>\n    <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css\" />\n    <title>{% if page.title %}{{ page.title }} | {{ site.title }}{% else %}{{ site.title }}{% endif %}</title>\n    <meta name=\"description\" content=\"{% if page.excerpt %}{{ page.excerpt | strip_html | strip_newlines | truncate: 160 }}{% else %}{{ site.description }}{% endif %}\">\n    <link href=\"//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css\" rel=\"stylesheet\">\n    <link rel=\"stylesheet\" href=\"{{ \"/css/mono-blue.css\" | prepend: site.baseurl }}\" type='text/css' />\n    <link rel=\"stylesheet\" href=\"{{ \"/css/hover-min.css\" | prepend: site.baseurl }}\" media=\"all\">\n    <link rel=\"stylesheet\" href=\"{{ \"/css/main.css\" | prepend: site.baseurl }}\">\n    <link rel=\"canonical\" href=\"{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}\">\n    <link rel=\"icon\" href=\"{{ \"/img/favicon.png\" | prepend: site.baseurl }}\" type=\"image/png\" />\n  </head>\n\n  <body>\n\n    <nav class=\"navbar\" role=\"navigation\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#navbar\" aria-expanded=\"false\" aria-controls=\"navbar\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n\n                <a href=\"/\" class=\"title\">\n                    <img src=\"{{ \"/img/libbblog_v3.png\" | prepend: site.baseurl }}\" class=\"hidden-xs\" alt=\"bluebird logo\" />\n\n                    <span class=\"tagline\">bluebird</span>\n                </a>\n            </div>\n            <div id=\"navbar\" class=\"navbar-collapse navbar-bluebird navbar-right collapse\">\n                <ul class=\"nav navbar-nav bb-nav\">\n                    {% if page.path == 'docs/api-reference.md' %}\n                        {% assign name = 'api' %}\n                    {% elsif page.path == 'docs/support.md' %}\n                        {% assign name = 'support' %}\n                    {% elsif page.path == 'docs/install.md' %}\n                        {% assign name = 'install' %}\n                    {% else %}\n                        {% assign name = 'docs' %}\n                    {% endif %}\n\n                    <li class=\"{% if name == 'api' %}active{% endif %}\"><a href=\"{{ \"/docs/api-reference.html\" | prepend: site.baseurl }}\">API</a></li>\n                    <li class=\"{% if name == 'docs' %}active{% endif %}\"><a href=\"{{ \"/docs/getting-started.html\" | prepend: site.baseurl }}\">Docs</a></li>\n                    <li class=\"{% if name == 'support' %}active{% endif %}\"><a href=\"{{ \"/docs/support.html\" | prepend: site.baseurl }}\">Support</a></li>\n                    <li class=\"{% if name == 'install' %}active{% endif %}\"><a href=\"{{ \"/docs/install.html\" | prepend: site.baseurl }}\">Install</a></li>\n                    <li><a href=\"https://github.com/petkaantonov/bluebird/\">Github</a></li>\n                </ul>\n            </div><!--/.navbar-collapse -->\n        </div>\n    </nav>\n\n   <div class=\"container\">\n      <div class=\"row\">\n        <div class=\"col-sm-3\">\n            <ul class=\"nav left-nav\">\n                <li><a href=\"{{ \"/docs/getting-started.html\" | prepend: site.baseurl }}\">Getting Started</a></li>\n                <li><a href=\"{{ \"/docs/features.html\" | prepend: site.baseurl }}\">Features</a></li>\n                <li><a href=\"{{ \"/docs/changelog.html\" | prepend: site.baseurl }}\">Changelog</a></li>\n                <li><a href=\"{{ \"/docs/api-reference.html\" | prepend: site.baseurl }}\"><strong>API Reference</strong></a></li>\n                <li><a href=\"{{ \"/docs/new-in-bluebird-3.html\" | prepend: site.baseurl }}\"><strong>New in 3.0</strong></a></li>\n                <li><a href=\"{{ \"/docs/warning-explanations.html\" | prepend: site.baseurl }}\">Warning Explanations</a></li>\n                <li><a href=\"{{ \"/docs/error-explanations.html\" | prepend: site.baseurl }}\">Error Explanations</a></li>\n                <li><a href=\"{{ \"/docs/contribute.html\" | prepend: site.baseurl }}\">Contribute</a></li>\n                <li><a href=\"{{ \"/docs/benchmarks.html\" | prepend: site.baseurl }}\">Benchmarks</a></li>\n                <li><a href=\"{{ \"/docs/deprecated-apis.html\" | prepend: site.baseurl }}\">Deprecated APIs</a></li>\n                <li><a href=\"{{ \"/docs/download-api-reference.html\" | prepend: site.baseurl }}\">Download API Reference</a></li>\n                <li><hr></li>\n                <li>Why?\n                    <ul class=\"nav nav-child\">\n                        <li><a href=\"{{ \"/docs/why-promises.html\" | prepend: site.baseurl }}\">Why Promises?</a></li>\n                        <li><a href=\"{{ \"/docs/why-bluebird.html\" | prepend: site.baseurl }}\">Why bluebird?</a></li>\n                        <li><a href=\"{{ \"/docs/why-performance.html\" | prepend: site.baseurl }}\">Why Performance?</a></li>\n                        <li><a href=\"{{ \"/docs/what-about-generators.html\" | prepend: site.baseurl }}\">What About Generators?</a></li>\n                    </ul>\n                </li>\n                <li><hr></li>\n                <li>\n                    Tutorials\n                    <ul class=\"nav nav-child\">\n                        <li><a href=\"{{ \"/docs/async-dialogs.html\" | prepend: site.baseurl }}\">Async Dialogs</a></li>\n                    </ul>\n                </li>\n                <li><hr></li>\n                <li>\n                    Guides\n                    <ul class=\"nav nav-child\">\n                        <li><a href=\"{{ \"/docs/beginners-guide.html\" | prepend: site.baseurl }}\">Beginner's Guide</a></li>\n                        <li><a href=\"{{ \"/docs/anti-patterns.html\" | prepend: site.baseurl }}\">Anti-patterns</a></li>\n                        <li><a href=\"{{ \"/docs/working-with-callbacks.html\" | prepend: site.baseurl }}\">Working with Callbacks</a></li>\n                        <li><a href=\"{{ \"/docs/coming-from-other-languages.html\" | prepend: site.baseurl }}\">Coming from Other Languages</a></li>\n                        <li><a href=\"{{ \"/docs/coming-from-other-libraries.html\" | prepend: site.baseurl }}\">Coming from Other Libraries</a></li>\n                    </ul>\n                </li>\n                <li><hr></li>\n\n            </ul>\n        </div>\n        <div class=\"col-sm-9\">\n            {% if page.path %}\n            <div class=\"post-info\">\n                <a href=\"{{ page.path | prepend: \"https://github.com/petkaantonov/bluebird/edit/master/docs/\" }}\">\n                    <i class=\"fa fa-edit\"></i>\n                    Edit on Github</a>\n                <br>\n                <i>Updated {{ page.path | file_date | date_to_string }}</i>\n            </div>\n            <div class=\"clearfix\"></div>\n            {% endif %}\n            {{ content }}\n        </div>\n      </div>\n    </div>\n    <footer></footer>\n    <script src=\"https://code.jquery.com/jquery-2.1.3.min.js\"></script>\n    <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js\"></script>\n    <script src=\"//cdn.jsdelivr.net/npm/bluebird@{{ site.version }}/js/browser/bluebird.js\"></script>\n    <script>\n      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n      })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n      ga('create', 'UA-46253177-1', 'auto');\n      ga('send', 'pageview');\n\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "docs/_layouts/page.html",
    "content": "---\nlayout: default\n---\n<div class=\"post\">\n\n  <header class=\"post-header\">\n    <h1 class=\"post-title\">{{ page.title }}</h1>\n  </header>\n\n  <article class=\"post-content\">\n    {{ content }}\n  </article>\n\n</div>\n"
  },
  {
    "path": "docs/_plugins/mdate.rb",
    "content": "module Jekyll\n  module MyFilters\n    def file_date(input)\n      File.mtime(input)\n    end\n\n    def check_active(page_path, link_type)\n        if (link_type == \"support\" and page_path =~ /support/) or\n            (link_type == \"install\" and page_path =~ /install/) or\n            (link_type == \"docs\")\n            \"active\"\n        else\n            \"\"\n        end\n    end\n  end\nend\n\nLiquid::Template.register_filter(Jekyll::MyFilters)\n"
  },
  {
    "path": "docs/_plugins/plugin.rb",
    "content": "require \"redcarpet\"\nrequire \"pygments\"\nrequire_relative \"../helpers\"\n\n\nclass Redcarpet::Render::HTML\n    def header(title, level)\n        anchor = Helpers.clean(title)\n\n        return <<-eos\n            <h#{level}>\n                <a class=\"header-anchor\"\n                    name=\"#{anchor}\"\n                    aria-hidden=\"true\"\n                    href=\"##{anchor}\"><i class=\"fa fa-link\"></i></a>\n                #{title}\n            </h#{level}>\n        eos\n    end\n    # Hacks to get markdown working inside html blocks ....\n    def block_html(html)\n        html.gsub(/<markdown>([\\d\\D]+?)<\\/markdown>/) {|_|\n            extensions = {fenced_code_blocks: true}\n            renderer = Redcarpet::Markdown.new(WithHighlights, extensions)\n            renderer.render(Regexp.last_match[1])\n        }\n    end\n\n    def link(link, title, content)\n        if link == \"unfinished-article\"\n            return <<-eos\n            <div class=\"info-box\">\n                This article is partially or completely unfinished.\n                You are welcome to create <a href=\"https://github.com/petkaantonov/bluebird/edit/master/docs/docs/#{content}.md\">pull requests</a>\n                to help completing this article.\n            </div>\n            eos\n        elsif link == \".\"\n            if content =~ /#\\d+/\n                url = \"https://github.com/petkaantonov/bluebird/issues/\" + content[1..-1]\n            else\n                url = \"/docs/api/\" + Helpers.clean(content) + \".html\"\n            end\n            return \"<a href='#{url}'><code>#{content}</code></a>\"\n        else\n            return \"<a href='#{link}' title='#{title}'>#{content}</a>\"\n        end\n    end\nend\n\nclass WithHighlights < Redcarpet::Render::HTML\n    def block_code(code, language)\n        Pygments.highlight(code, :lexer => language)\n    end\nend\n"
  },
  {
    "path": "docs/css/main.css",
    "content": "body {\n    font-size: 16px;\n}\n\nbody > .container {\n    padding-bottom: 50px;\n}\n\n.navbar-bluebird {\n    font-family: 'Raleway', sans-serif;\n    font-size: 18px;\n    margin-top: 50px;\n    text-transform:uppercase;\n}\n\n.nav {\n    font-family: 'Raleway', sans-serif;\n}\n\n.nav.bb-nav > li > a{\n    transition: all 0.3s ease-in-out;\n    border-bottom: 1px solid rgba(0,0,0,0);\n}\n.nav.bb-nav > li > a:focus, .nav.bb-nav > li > a:hover,\n.nav.bb-nav > li.active > a {\n    background-color:initial;\n    border-bottom:1px solid #BE7306;\n}\n\n.nav a {\n    color: #BE7306;\n}\n\n.nav.left-nav li a {\n    padding: 2px 0px;\n    font-size: 14px;\n    font-family: 'Raleway', sans-serif;\n}\n\n.nav.left-nav li a:focus, .nav.left-nav li a:hover {\n    background: none;\n    text-decoration: underline;\n}\n\n.navbar-bluebird li {\n    text-align:center;\n}\nh1,h2,h3,h4,h5,h6{\n    font-family: 'Raleway', sans-serif;\n    /*color:#5275B4;*/\n    color: #1B4288;\n}\n.api-code-section h2, code, pre {\n    font-family: 'Consolas', 'Lucida Console', 'Courier New', 'monospace'\n}\nbody {\n    margin-top:10px;\n}\n\n.icon-bar {\n    background-color:#5275B4;\n}\n.promises-showroom .arrow {\n    text-align: center;\n    margin-top: 100px;\n    color:#EC9313;\n}\n\npre{\n    background-color: initial;\n    border: none;\n    margin:0px;\n    padding:0px;\n}\n.promises-showroom .hljs{\n    border-radius: 6px;\n    padding-left: 30px;\n    padding-bottom: 15px;\n}\n.take-action{\n    position:relative;\n    min-height:300px;\n\n}\n\n.take-action .cloud-bg{\n    width: 100%;\n    height: 300px;\n    border: none;\n}\n\n.take-action .action-buttons{\n    position:absolute;\n    top:50%;\n    text-align:center;\n    width:100%;\n}\n.btn-bb {\n    font-family: 'Raleway', sans-serif;\n    color: white;\n}\n.btn-beak{\n    background-color: #EC9313;\n    border-bottom: 4px solid #BE7306;\n}\n.btn-wings {\n    background-color: #265584;\n    border-bottom: 4px solid #1A3A59;\n}\n.btn-bb:hover{\n    color:white;\n}\n.undo-margin{\n    margin-left:-15px;\n}\n\n.main-line{\n    font-family: 'Raleway', sans-serif;\n    margin-bottom: 59px;\n    margin-top: -74px;\n    font-size: 20px;\n    color:white;\n}\n\n.tagline {\n    font-family: 'Raleway', sans-serif;\n    font-size:26px;\n    color:#5275B4;\n    font-weight:200;\n}\n\n.nav-child {\n    margin-left:20px;\n}\n.title:hover{\n    text-decoration:none;\n}\n\n.header-anchor {\n  opacity: 0;\n\n  -webkit-transition: opacity 0.2s ease-in-out 0.1s;\n  -moz-transition: opacity 0.2s ease-in-out 0.1s;\n  -ms-transition: opacity 0.2s ease-in-out 0.1s;\n  outline: none;\n}\n\n.header-anchor:active, .header-anchor:focus  {\n    outline: none;\n}\n\nh1:hover .header-anchor,\nh2:hover .header-anchor,\nh3:hover .header-anchor,\nh4:hover .header-anchor,\nh5:hover .header-anchor,\nh6:hover .header-anchor {\n  opacity: 1;\n}\n\n.api-reference-menu {\n    -moz-column-count: 2;\n    -webkit-column-count: 2;\n    columns: 2;\n    margin-bottom: 50px;\n}\n\n.post-info {\n    float: right;\n}\n\n.info-box {\n    margin-top: 20px;\n    color: #8a6d3b;\n    background-color: #fcf8e3;\n    border-color: #faebcc;\n    padding: 15px;\n    margin-bottom: 20px;\n    border: 1px dashed #8a6d3b;\n    border-radius: 4px;\n}\n\n.supporter.reaktor {\n    width: 200px;\n    margin: 0px auto;\n}\n"
  },
  {
    "path": "docs/css/mono-blue.css",
    "content": ".highlight {\n    display: block;\n    overflow-x: auto;\n    padding: 0.5em;\n    margin: 15px 0px;\n    background: #eaeef3;\n    -webkit-text-size-adjust: none;\n    color: #00193a;\n}\n\ncode {\n  color: #00193a;\n  background: #eaeef3;\n}\n\na code {\n  color: #337AB7;\n}\n\n.highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #738191; font-style: italic } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { color: #4c81c9; font-weight: bold } /* Keyword */\n.highlight .o { color: #666666 } /* Operator */\n.highlight .cm { color: #738191; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n.highlight .c1 { color: #738191; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #738191; font-style: italic } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #808080 } /* Generic.Output */\n.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0040D0 } /* Generic.Traceback */\n.highlight .kc { color: #4c81c9; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #4c81c9; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #4c81c9; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #4c81c9 } /* Keyword.Pseudo */\n.highlight .kr { color: #4c81c9; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #B00040 } /* Keyword.Type */\n.highlight .m { color: #666666 } /* Literal.Number */\n.highlight .s { color: #BE7306;} /* Literal.String */\n.highlight .na { color: #7D9029 } /* Name.Attribute */\n.highlight .nb { color: #4c81c9 } /* Name.Builtin */\n.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n.highlight .no { color: #880000 } /* Name.Constant */\n.highlight .nd { color: #AA22FF } /* Name.Decorator */\n.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #0000FF } /* Name.Function */\n.highlight .nl { color: #A0A000 } /* Name.Label */\n.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #4c81c9; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #19177C } /* Name.Variable */\n.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mf { color: #666666 } /* Literal.Number.Float */\n.highlight .mh { color: #666666 } /* Literal.Number.Hex */\n.highlight .mi { color: #666666 } /* Literal.Number.Integer */\n.highlight .mo { color: #666666 } /* Literal.Number.Oct */\n.highlight .sb { color: #BE7306 } /* Literal.String.Backtick */\n.highlight .sc { color: #BE7306 } /* Literal.String.Char */\n.highlight .sd { color: #BE7306; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #BE7306 } /* Literal.String.Double */\n.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n.highlight .sh { color: #BE7306 } /* Literal.String.Heredoc */\n.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n.highlight .sx { color: #BE7306 } /* Literal.String.Other */\n.highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n.highlight .s1 { color: #BE7306 } /* Literal.String.Single */\n.highlight .ss { color: #19177C } /* Literal.String.Symbol */\n.highlight .bp { color: #4c81c9 } /* Name.Builtin.Pseudo */\n.highlight .vc { color: #19177C } /* Name.Variable.Class */\n.highlight .vg { color: #19177C } /* Name.Variable.Global */\n.highlight .vi { color: #19177C } /* Name.Variable.Instance */\n.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */\n"
  },
  {
    "path": "docs/docs/anti-patterns.md",
    "content": "---\nid: anti-patterns\ntitle: Anti-patterns\n---\n\nThis page will contain common promise anti-patterns that are exercised in the wild.\n\n\n- [The explicit construction anti-pattern](#the-explicit-construction-anti-pattern)\n- [The `.then(success, fail)` anti-pattern](#the-.then)\n\n##The Explicit Construction Anti-Pattern\n\nThis is the most common anti-pattern. It is easy to fall into this when you don't really understand promises and think of them as glorified event emitters or callback utility. It's also sometimes called the promise constructor anti-pattern. Let's recap: promises are about making asynchronous code retain most of the lost properties of synchronous code such as flat indentation and one exception channel. This pattern is also called the deferred anti-pattern.\n\nIn the explicit construction anti-pattern, promise objects are created for no reason, complicating code.\n\nFirst example is creating deferred object when you already have a promise or thenable:\n\n```js\n//Code copyright by Twisternha http://stackoverflow.com/a/19486699/995876 CC BY-SA 2.5\nmyApp.factory('Configurations', function (Restangular, MotorRestangular, $q) {\n    var getConfigurations = function () {\n        var deferred = $q.defer();\n\n        MotorRestangular.all('Motors').getList().then(function (Motors) {\n            //Group by Config\n            var g = _.groupBy(Motors, 'configuration');\n            //Map values\n            var mapped = _.map(g, function (m) {\n                return {\n                    id: m[0].configuration,\n                    configuration: m[0].configuration,\n                    sizes: _.map(m, function (a) {\n                        return a.sizeMm\n                    })\n                }\n            });\n            deferred.resolve(mapped);\n        });\n        return deferred.promise;\n    };\n\n    return {\n        config: getConfigurations()\n    }\n\n});\n```\n\nThis superfluous wrapping is also dangerous, any kind of errors and rejections are swallowed and not propagated to the caller of this function.\n\nInstead of using the Deferred anti-pattern, the code should simply return the promise it already has and propagate values using `return`:\n\n```js\nmyApp.factory('Configurations', function (Restangular, MotorRestangular, $q) {\n    var getConfigurations = function () {\n        //Just return the promise we already have!\n        return MotorRestangular.all('Motors').getList().then(function (Motors) {\n            //Group by Cofig\n            var g = _.groupBy(Motors, 'configuration');\n            //Return the mapped array as the value of this promise\n            return _.map(g, function (m) {\n                return {\n                    id: m[0].configuration,\n                    configuration: m[0].configuration,\n                    sizes: _.map(m, function (a) {\n                        return a.sizeMm\n                    })\n                }\n            });\n        });\n    };\n\n    return {\n        config: getConfigurations()\n    }\n\n});\n```\n\nNot only is the code shorter but more importantly, if there is any error it will propagate properly to the final consumer.\n\nSecond example is creating a function that does nothing but manually wrap a callback API and doing a poor job at that:\n\n```js\nfunction applicationFunction(arg1) {\n    return new Promise(function(resolve, reject){ //Or Q.defer() in Q\n      libraryFunction(arg1, function (err, value) {\n        if (err) {\n          reject(err);\n        } else {\n          resolve(value);\n        }\n    });\n}\n```\n\nThis is reinventing the square wheel because any callback API wrapping can and should be done immediately using the promise library's promisification methods:\n\n```js\nvar applicationFunction = Promise.promisify(libraryFunction);\n```\n\nThe generic promisification is likely to be faster because it can use internals directly but also handles edge cases like `libraryFunction` throwing synchronously or using multiple success values.\n\n\n**So when should deferred be used?**\n\nWell simply, when you have to.\n\nYou might have to use a deferred object when wrapping a callback API that doesn't follow the standard convention. Like `setTimeout`:\n\n```js\n//setTimeout that returns a promise\nfunction delay(ms) {\n    var deferred = Promise.defer(); // warning, defer is deprecated, use the promise constructor\n    setTimeout(function(){\n        deferred.fulfill();\n    }, ms);\n    return deferred.promise;\n}\n```\n\nSuch wrappers should be rare, if they're common for the reason that the promise library cannot generically promisify them, you should file an issue.\n\nIf you cannot do static promisification (promisify and promisifyAll perform too slowly to use at runtime), you may use [Promise.fromCallback](.).\n\nAlso see [this StackOverflow question](http://stackoverflow.com/questions/23803743/what-is-the-deferred-antipattern-and-how-do-i-avoid-it) for more examples and a debate around it.\n\n##The `.then(success, fail)` anti-pattern\n\n*Almost* a sure sign of using promises as glorified callbacks. Instead of `doThat(function(err, success))` you do `doThat().then(success, err)` and rationalize to yourself that at least the code is \"less coupled\" or something.\n\nThe `.then` signature is mostly about interop, there is *almost* never a reason to use `.then(success, fail)` in application code. It is even awkward to express it in the sync parallel:\n\n```js\nvar t0;\ntry {\n    t0 = doThat();\n}\ncatch(e) {\n\n}\n//deal with t0 here and waste the try-catch\nvar stuff = JSON.parse(t0);\n```\n\nIt is more likely that you would write this instead in the sync world:\n\n```js\ntry {\n    var stuff = JSON.parse(doThat());\n}\ncatch(e) {\n\n}\n```\n\nSo please write the same when using promises too:\n\n```js\ndoThat()\n.then(function(v) {\n    return JSON.parse(v);\n})\n.catch(function(e) {\n\n});\n```\n\n`.catch` is specified for built-in Javascript promises and is \"sugar\" for `.then(null, function(){})`. Since the way errors work in promises is almost the entire point (and the only thing jQuery never got right, even if it used `.pipe` as a `.then`), I really hope the implementation you are using provides this method for readability.\n"
  },
  {
    "path": "docs/docs/api/aggregateerror.md",
    "content": "---\nlayout: api\nid: aggregateerror\ntitle: AggregateError\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##AggregateError\n\n```js\nnew AggregateError() extends Array -> AggregateError\n```\n\n\nA collection of errors. `AggregateError` is an array-like object, with numeric indices and a `.length` property. It supports all generic array methods such as `.forEach` directly.\n\n`AggregateError`s are caught in [`.error`](.) handlers, even if the contained errors are not operational.\n\n[Promise.some](.) and [Promise.any](.)  use `AggregateError` as rejection reason when they fail.\n\n\nExample:\n\n```js\n//Assumes AggregateError has been made global\nvar err = new AggregateError();\nerr.push(new Error(\"first error\"));\nerr.push(new Error(\"second error\"));\nthrow err;\n```\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"AggregateError\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-aggregateerror\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/all.md",
    "content": "---\nlayout: api\nid: all\ntitle: .all\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.all\n\n```js\n.all() -> Promise\n```\n\nConsume the resolved [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) and wait for all items to fulfill similar to [Promise.all()](.).\n\n[Promise.resolve(iterable).all()](.) is the same as [Promise.all(iterable)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".all\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-all\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/any.md",
    "content": "---\nlayout: api\nid: any\ntitle: .any\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.any\n\n```js\n.any() -> Promise\n```\n\nSame as [Promise.any(this)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".any\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-any\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/ascallback.md",
    "content": "---\nlayout: api\nid: ascallback\ntitle: .asCallback\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.asCallback\n\n```js\n.asCallback(\n    [function(any error, any value) callback],\n    [Object {spread: boolean=false} options]\n) -> this\n```\n```js\n.nodeify(\n    [function(any error, any value) callback],\n    [Object {spread: boolean=false} options]\n) -> this\n```\n\nRegister a node-style callback on this promise. When this promise is either fulfilled or rejected, the node callback will be called back with the node.js convention where error reason is the first argument and success value is the second argument. The error argument will be `null` in case of success.\n\nReturns back this promise instead of creating a new one. If the `callback` argument is not a function, this method does not do anything.\n\nThis can be used to create APIs that both accept node-style callbacks and return promises:\n\n```js\nfunction getDataFor(input, callback) {\n    return dataFromDataBase(input).asCallback(callback);\n}\n```\n\nThe above function can then make everyone happy.\n\nPromises:\n\n```js\ngetDataFor(\"me\").then(function(dataForMe) {\n    console.log(dataForMe);\n});\n```\n\nNormal callbacks:\n\n```js\ngetDataFor(\"me\", function(err, dataForMe) {\n    if( err ) {\n        console.error( err );\n    }\n    console.log(dataForMe);\n});\n```\n\nPromises can be rejected with falsy values (or no value at all, equal to rejecting with `undefined`), however `.asCallback` will call the callback with an `Error` object if the promise's rejection reason is a falsy value. You can retrieve the original falsy value from the error's `.cause` property.\n\nExample:\n\n```js\nPromise.reject(null).asCallback(function(err, result) {\n    // If is executed\n    if (err) {\n        // Logs 'null'\n        console.log(err.cause);\n    }\n});\n```\n\nThere is no effect on performance if the user doesn't actually pass a node-style callback function.\n\n####Option: spread\n\nSome nodebacks expect more than 1 success value but there is no mapping for this in the promise world. You may specify the option `spread` to call the nodeback with multiple values when the fulfillment value is an array:\n\n```js\nPromise.resolve([1,2,3]).asCallback(function(err, result) {\n    // err == null\n    // result is the array [1,2,3]\n});\n\nPromise.resolve([1,2,3]).asCallback(function(err, a, b, c) {\n    // err == null\n    // a == 1\n    // b == 2\n    // c == 3\n}, {spread: true});\n\nPromise.resolve(123).asCallback(function(err, a, b, c) {\n    // err == null\n    // a == 123\n    // b == undefined\n    // c == undefined\n}, {spread: true});\n```\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".asCallback\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-ascallback\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/bind.md",
    "content": "---\nlayout: api\nid: bind\ntitle: .bind\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.bind\n\n```js\n.bind(any|Promise<any> thisArg) -> BoundPromise\n```\n\nSame as calling [Promise.bind(thisArg, thisPromise)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".bind\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-bind\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/built-in-error-types.md",
    "content": "---\nlayout: api\nid: built-in-error-types\ntitle: Built-in error types\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Built-in error types\n\nBluebird includes a few built-in error types for common usage. All error types have the same identity across different copies of bluebird\nmodule so that pattern matching works in [`.catch`](.). All error types have a constructor taking a message string as their first argument, with that message\nbecoming the `.message` property of the error object.\n\nBy default the error types need to be referenced from the Promise constructor, e.g. to get a reference to [TimeoutError](.), do `var TimeoutError = Promise.TimeoutError`. However, for convenience you will probably want to just make the references global.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Built-in error types\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-built-in-error-types\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/call.md",
    "content": "---\nlayout: api\nid: call\ntitle: .call\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.call\n\n```js\n.call(\n    String methodName,\n    [any args...]\n)\n```\n\nThis is a convenience method for doing:\n\n```js\npromise.then(function(obj) {\n    return obj[methodName].call(obj, arg...);\n});\n```\n\nFor example ([`some` is a built-in array method](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some)):\n\n```js\nvar Promise = require(\"bluebird\");\nvar fs = Promise.promisifyAll(require(\"fs\"));\nvar path = require(\"path\");\nvar thisPath = process.argv[2] || \".\";\nvar now = Date.now();\n\nfs.readdirAsync(thisPath)\n    .map(function(fileName) {\n        return fs.statAsync(path.join(thisPath, fileName));\n    })\n    .call(\"some\", function(stat) {\n        return (now - new Date(stat.mtime)) < 10000;\n    })\n    .then(function(someFilesHaveBeenModifiedLessThanTenSecondsAgo) {\n        console.log(someFilesHaveBeenModifiedLessThanTenSecondsAgo) ;\n    });\n```\n\nChaining lo-dash or underscore methods (Copy-pasteable example):\n\n```js\nvar Promise = require(\"bluebird\");\nvar pmap = Promise.map;\nvar props = Promise.props;\nvar _ = require(\"lodash\");\nvar fs = Promise.promisifyAll(require(\"fs\"));\n\nfunction getTotalSize(paths) {\n    return pmap(paths, function(path) {\n        return fs.statAsync(path).get(\"size\");\n    }).reduce(function(a, b) {\n        return a + b;\n    }, 0);\n}\n\nfs.readdirAsync(\".\").then(_)\n    .call(\"groupBy\", function(fileName) {\n        return fileName.charAt(0);\n    })\n    .call(\"map\", function(fileNames, firstCh) {\n        return props({\n            firstCh: firstCh,\n            count: fileNames.length,\n            totalSize: getTotalSize(fileNames)\n        });\n    })\n    // Since the currently wrapped array contains promises we need to unwrap it and call .all() before continuing the chain\n    // If the currently wrapped thing was an object with properties that might be promises, we would call .props() instead\n    .call(\"value\").all().then(_)\n    .call(\"sortBy\", \"count\")\n    .call(\"reverse\")\n    .call(\"map\", function(data) {\n        return data.count + \" total files beginning with \" + data.firstCh + \" with total size of \" + data.totalSize + \" bytes\";\n    })\n    .call(\"join\", \"\\n\")\n    .then(console.log)\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".call\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-call\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/cancel.md",
    "content": "---\nlayout: api\nid: cancel\ntitle: .cancel\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.cancel\n\n```js\n.cancel() -> undefined\n```\n\nCancel this promise. Will not do anything if this promise is already settled or if the [Cancellation](.) feature has not been enabled. See [Cancellation](.) for how to use cancellation.\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".cancel\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-cancel\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/cancellation.md",
    "content": "---\nlayout: api\nid: cancellation\ntitle: Cancellation\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Cancellation\n\nCancellation has been redesigned for bluebird 3.x, any code that relies on 2.x cancellation semantics won't work in 3.x.\n\nThe cancellation feature is **by default turned off**, you can enable it using [Promise.config](.).\n\nThe new cancellation has \"don't care\" semantics while the old cancellation had abort semantics. Cancelling a promise simply means that its handler callbacks will not be called.\n\nThe advantages of the new cancellation compared to the old cancellation are:\n\n- [.cancel()](.) is synchronous.\n- no setup code required to make cancellation work\n- composes with other bluebird features, like [Promise.all](.).\n- [reasonable semantics for multiple consumer cancellation](#what-about-promises-that-have-multiple-consumers)\n\nAs an optimization, the cancellation signal propagates upwards the promise chain so that an ongoing operation e.g. network request can be aborted. However, *not* aborting the network request still doesn't make any operational difference as the callbacks are still not called either way.\n\nYou may register an optional cancellation hook at a root promise by using the `onCancel` argument that is passed to the executor function when cancellation is enabled:\n\n```js\nfunction makeCancellableRequest(url) {\n    return new Promise(function(resolve, reject, onCancel) {\n        var xhr = new XMLHttpRequest();\n        xhr.on(\"load\", resolve);\n        xhr.on(\"error\", reject);\n        xhr.open(\"GET\", url, true);\n        xhr.send(null);\n        // Note the onCancel argument only exists if cancellation has been enabled!\n        onCancel(function() {\n            xhr.abort();\n        });\n    });\n}\n```\n\nNote that the `onCancel` hook is really an optional disconnected optimization, there is no real requirement to register any cancellation hooks for cancellation to work. As such, any errors that may occur while inside the `onCancel` callback are not caught and turned into rejections.\n\nWhile `cancel().` is synchronous - `onCancel()` is called asynchronously (in the next turn) just like `then` handlers.\n\nExample:\n\n```js\nvar searchPromise = Promise.resolve();  // Dummy promise to avoid null check.\ndocument.querySelector(\"#search-input\").addEventListener(\"input\", function() {\n    // The handlers of the previous request must not be called\n    searchPromise.cancel();\n    var url = \"/search?term=\" + encodeURIComponent(this.value.trim());\n    showSpinner();\n    searchPromise = makeCancellableRequest(url)\n        .then(function(results) {\n            return transformData(results);\n        })\n        .then(function(transformedData) {\n            document.querySelector(\"#search-results\").innerHTML = transformedData;\n        })\n        .catch(function(e) {\n            document.querySelector(\"#search-results\").innerHTML = renderErrorBox(e);\n        })\n        .finally(function() {\n            // This check is necessary because `.finally` handlers are always called.\n            if (!searchPromise.isCancelled()) {\n                hideSpinner();\n            }\n        });\n});\n\n```\n\nAs shown in the example the handlers registered with `.finally` are called even if the promise is cancelled. Another such exception is [.reflect()](.). No other types of handlers will be called in case of cancellation. This means that in `.then(onSuccess, onFailure)` neither `onSuccess` or `onFailure` handler is called. This is similar to how [`Generator#return`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/return) works - only active `finally` blocks are executed and then the generator exits.\n\n###What about promises that have multiple consumers?\n\nIt is often said that promises cannot be cancellable because they can have multiple consumers.\n\nFor instance:\n\n```js\nvar result = makeCancellableRequest(...);\n\nvar firstConsumer = result.then(...);\nvar secondConsumer = result.then(...);\n```\n\nEven though in practice most users of promises will never have any need to take advantage of the fact that you can attach multiple consumers to a promise, it is nevertheless possible. The problem: \"what should happen if [.cancel()](.) is called on `firstConsumer`?\" Propagating the cancellation signal (and therefore making it abort the request) would be very bad as the second consumer might still be interested in the result despite the first consumer's disinterest.\n\nWhat actually happens is that `result` keeps track of how many consumers it has, in this case 2, and only if all the consumers signal cancel will the request be aborted. However, as far as `firstConsumer` can tell, the promise was successfully cancelled and its handlers will not be called.\n\nNote that it is an error to consume an already cancelled promise, doing such a thing will give you a promise that is rejected with `new CancellationError(\"late cancellation observer\")` as the rejection reason.\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Cancellation\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-cancellation\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/cancellationerror.md",
    "content": "---\nlayout: api\nid: cancellationerror\ntitle: CancellationError\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##CancellationError\n\n```js\nnew CancellationError(String message) -> CancellationError\n```\n\n\nSignals that an operation has been aborted or cancelled. The default reason used by [`.cancel`](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"CancellationError\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-cancellationerror\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/catch.md",
    "content": "---\nlayout: api\nid: catch\ntitle: .catch\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.catch\n\n`.catch` is a convenience method for handling errors in promise chains. \nIt comes in two variants \n - A catch-all variant similar to the synchronous `catch(e) {` block. This variant is compatible with native promises. \n - A filtered variant (like other non-JS languages typically have) that lets you only handle specific errors. **This variant is usually preferable and is significantly safer**. \n\n### A note on promise exception handling.\n\nPromise exception handling mirrors native exception handling in JavaScript. A synchronous function `throw`ing is similar to a promise rejecting. Here is an example to illustrate it:\n\n```js\nfunction getItems(param) {\n    try { \n        var items = getItemsSync();\n        if(!items) throw new InvalidItemsError();  \n    } catch(e) { \n        // can address the error here, either from getItemsSync returning a falsey value or throwing itself\n        throw e; // need to re-throw the error unless I want it to be considered handled. \n    }\n    return process(items);\n}\n```\n\nSimilarly, with promises:\n\n```js\nfunction getItems(param) {\n    return getItemsAsync().then(items => {\n        if(!items) throw new InvalidItemsError(); \n        return items;\n    }).catch(e => {\n        // can address the error here and recover from it, from getItemsAsync rejects or returns a falsey value\n        throw e; // Need to rethrow unless we actually recovered, just like in the synchronous version\n    }).then(process);\n}\n```\n\n### Catch-all\n\n```js\n.catch(function(any error) handler) -> Promise\n```\n```js\n.caught(function(any error) handler) -> Promise\n```\n\nThis is a catch-all exception handler, shortcut for calling [`.then(null, handler)`](.) on this promise. Any exception happening in a `.then`-chain will propagate to nearest `.catch` handler.\n\n*For compatibility with earlier ECMAScript versions, an alias `.caught` is provided for [`.catch`](.).*\n\n### Filtered Catch \n\n```js\n.catch(\n    class ErrorClass|function(any error)|Object predicate...,\n    function(any error) handler\n) -> Promise\n```\n```js\n.caught(\n    class ErrorClass|function(any error)|Object predicate...,\n    function(any error) handler\n) -> Promise\n```\nThis is an extension to [`.catch`](.) to work more like catch-clauses in languages like Java or C#. Instead of manually checking `instanceof` or `.name === \"SomeError\"`, you may specify a number of error constructors which are eligible for this catch handler. The catch handler that is first met that has eligible constructors specified, is the one that will be called.\n\nExample:\n\n```js\nsomePromise.then(function() {\n    return a.b.c.d();\n}).catch(TypeError, function(e) {\n    //If it is a TypeError, will end up here because\n    //it is a type error to reference property of undefined\n}).catch(ReferenceError, function(e) {\n    //Will end up here if a was never declared at all\n}).catch(function(e) {\n    //Generic catch-the rest, error wasn't TypeError nor\n    //ReferenceError\n});\n ```\n\nYou may also add multiple filters for a catch handler:\n\n```js\nsomePromise.then(function() {\n    return a.b.c.d();\n}).catch(TypeError, ReferenceError, function(e) {\n    //Will end up here on programmer error\n}).catch(NetworkError, TimeoutError, function(e) {\n    //Will end up here on expected everyday network errors\n}).catch(function(e) {\n    //Catch any unexpected errors\n});\n```\n\nFor a parameter to be considered a type of error that you want to filter, you need the constructor to have its `.prototype` property be `instanceof Error`.\n\nSuch a constructor can be minimally created like so:\n\n```js\nfunction MyCustomError() {}\nMyCustomError.prototype = Object.create(Error.prototype);\n```\n\nUsing it:\n\n```js\nPromise.resolve().then(function() {\n    throw new MyCustomError();\n}).catch(MyCustomError, function(e) {\n    //will end up here now\n});\n```\n\nHowever if you  want stack traces and cleaner string output, then you should do:\n\n*in Node.js and other V8 environments, with support for `Error.captureStackTrace`*\n\n```js\nfunction MyCustomError(message) {\n    this.message = message;\n    this.name = \"MyCustomError\";\n    Error.captureStackTrace(this, MyCustomError);\n}\nMyCustomError.prototype = Object.create(Error.prototype);\nMyCustomError.prototype.constructor = MyCustomError;\n```\n\nUsing CoffeeScript's `class` for the same:\n\n```coffee\nclass MyCustomError extends Error\n  constructor: (@message) ->\n    @name = \"MyCustomError\"\n    Error.captureStackTrace(this, MyCustomError)\n```\n\nThis method also supports predicate-based filters. If you pass a\npredicate function instead of an error constructor, the predicate will receive\nthe error as an argument. The return result of the predicate will be used\ndetermine whether the error handler should be called.\n\nPredicates should allow for very fine grained control over caught errors:\npattern matching, error-type sets with set operations and many other techniques\ncan be implemented on top of them.\n\nExample of using a predicate-based filter:\n\n```js\nvar Promise = require(\"bluebird\");\nvar request = Promise.promisify(require(\"request\"));\n\nfunction ClientError(e) {\n    return e.code >= 400 && e.code < 500;\n}\n\nrequest(\"http://www.google.com\").then(function(contents) {\n    console.log(contents);\n}).catch(ClientError, function(e) {\n   //A client error like 400 Bad Request happened\n});\n```\n\nPredicate functions that only check properties have a handy shorthand. In place of a predicate function, you can pass an object, and its properties will be checked against the error object for a match:\n\n```js\nfs.readFileAsync(...)\n    .then(...)\n    .catch({code: 'ENOENT'}, function(e) {\n        console.log(\"file not found: \" + e.path);\n    });\n```\n\nThe object predicate passed to `.catch` in the above code (`{code: 'ENOENT'}`) is shorthand for a predicate function `function predicate(e) { return isObject(e) && e.code == 'ENOENT' }`, I.E. loose equality is used.\n\n*For compatibility with earlier ECMAScript version, an alias `.caught` is provided for [`.catch`](.).*\n</markdown></div>\n\nBy not returning a rejected value or `throw`ing from a catch, you \"recover from failure\" and continue the chain:\n\n```js\nPromise.reject(Error('fail!'))\n  .catch(function(e) {\n    // fallback with \"recover from failure\"\n    return Promise.resolve('success!'); // promise or value\n  })\n  .then(function(result) {\n    console.log(result); // will print \"success!\"\n  });\n```\n\nThis is exactly like the synchronous code:\n\n```js\nvar result;\ntry {\n  throw Error('fail');\n} catch(e) {\n  result = 'success!';\n}\nconsole.log(result);\n```\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".catch\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-catch\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/catchreturn.md",
    "content": "---\nlayout: api\nid: catchreturn\ntitle: .catchReturn\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.catchReturn\n\n```js\n.catchReturn(\n    [class ErrorClass|function(any error) predicate],\n    any value\n) -> Promise\n```\n\nConvenience method for:\n\n```js\n.catch(function() {\n   return value;\n});\n```\nYou may optionally prepend one predicate function or ErrorClass to pattern match the error (the generic [.catch](.) methods accepts multiple)\n\nSame limitations regarding to the binding time of `value` to apply as with [`.return`](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".catchReturn\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-catchreturn\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/catchthrow.md",
    "content": "---\nlayout: api\nid: catchthrow\ntitle: .catchThrow\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.catchThrow\n\n```js\n.catchThrow(\n    [class ErrorClass|function(any error) predicate],\n    any reason\n) -> Promise\n```\n\nConvenience method for:\n\n```js\n.catch(function() {\n   throw reason;\n});\n```\nYou may optionally prepend one predicate function or ErrorClass to pattern match the error (the generic [.catch](.) methods accepts multiple)\n\nSame limitations regarding to the binding time of `reason` to apply as with [`.return`](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".catchThrow\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-catchthrow\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/collections.md",
    "content": "---\nlayout: api\nid: collections\ntitle: Collections\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Collections\n\nMethods of `Promise` instances and core static methods of the Promise class to deal with collections of promises or mixed promises and values.\n\nAll collection methods have a static equivalent on the Promise object, e.g. `somePromise.map(...)...` is same as `Promise.map(somePromise, ...)...`,\n`somePromise.all` is same as [`Promise.all`](.) and so on.\n\nNone of the collection methods modify the original input. Holes in arrays are treated as if they were defined with the value `undefined`.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Collections\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-collections\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/core.md",
    "content": "---\nlayout: api\nid: core\ntitle: Core\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Core\n\nCore methods of `Promise` instances and core static methods of the Promise class.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Core\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-core\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/deferred-migration.md",
    "content": "---\nlayout: api\nid: deferred-migration\ntitle: Deferred migration\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Deferred migration\n\nDeferreds are deprecated in favor of the promise constructor. If you need deferreds for some reason, you can create them trivially using the constructor:\n\n```js\nfunction defer() {\n    var resolve, reject;\n    var promise = new Promise(function() {\n        resolve = arguments[0];\n        reject = arguments[1];\n    });\n    return {\n        resolve: resolve,\n        reject: reject,\n        promise: promise\n    };\n}\n```\n\nFor old code that still uses deferred objects, see [the deprecated API docs ](//bluebirdjs.com/docs/deprecated-apis.html#promise-resolution).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Deferred migration\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-deferred-migration\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/delay.md",
    "content": "---\nlayout: api\nid: delay\ntitle: .delay\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.delay\n\n```js\n.delay(int ms) -> Promise\n```\n\nSame as calling [Promise.delay(ms, this)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".delay\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-delay\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/disposer.md",
    "content": "---\nlayout: api\nid: disposer\ntitle: .disposer\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.disposer\n\n```js\n.disposer(function(any resource, Promise usingOutcomePromise) disposer) -> Disposer\n```\n\nA meta method used to specify the disposer method that cleans up a resource when using [`Promise.using`](/docs/api/promise.using.html).\n\nReturns a Disposer object which encapsulates both the resource as well as the method to clean it up. The user can pass this object to `Promise.using` to get access to the resource when it becomes available, as well as to ensure it's automatically cleaned up.\n\nThe second argument passed to a disposer is the result promise of the using block, which you can inspect synchronously.\n\nExample:\n\n```js\n// This function doesn't return a promise but a Disposer\n// so it's very hard to use it wrong (not passing it to `using`)\nfunction getConnection() {\n    return db.connect().disposer(function(connection, promise) {\n        connection.close();\n    });\n}\n```\n\nIn the above example, the connection returned by `getConnection` can only be \nused via `Promise.using`, like so:\n\n```js\nfunction useConnection(query) {\n  return Promise.using(getConnection(), function(connection) {\n    return connection.sendQuery(query).then(function(results) {\n      return process(results);\n    })\n  });\n}\n```\n\nThis will ensure that `connection.close()` will be called once the promise returned\nfrom the `Promise.using` closure is resolved or if an exception was thrown in the closure\nbody.\n\nReal example:\n\n```js\nvar pg = require(\"pg\");\n// Uncomment if pg has not been properly promisified yet\n//var Promise = require(\"bluebird\");\n//Promise.promisifyAll(pg, {\n//    filter: function(methodName) {\n//        return methodName === \"connect\"\n//    },\n//    multiArgs: true\n//});\n// Promisify rest of pg normally\n//Promise.promisifyAll(pg);\n\nfunction getSqlConnection(connectionString) {\n    var close;\n    return pg.connectAsync(connectionString).spread(function(client, done) {\n        close = done;\n        return client;\n    }).disposer(function() {\n        if (close) close();\n    });\n}\n\nmodule.exports = getSqlConnection;\n```\n\nReal example 2:\n\n```js\nvar mysql = require(\"mysql\");\n// Uncomment if mysql has not been properly promisified yet\n// var Promise = require(\"bluebird\");\n// Promise.promisifyAll(mysql);\n// Promise.promisifyAll(require(\"mysql/lib/Connection\").prototype);\n// Promise.promisifyAll(require(\"mysql/lib/Pool\").prototype);\nvar pool  = mysql.createPool({\n    connectionLimit: 10,\n    host: 'example.org',\n    user: 'bob',\n    password: 'secret'\n});\n\nfunction getSqlConnection() {\n    return pool.getConnectionAsync().disposer(function(connection) {\n        connection.release();\n    });\n}\n\nmodule.exports = getSqlConnection;\n```\n\n#### Note about disposers in node\n\nIf a disposer method throws or returns a rejected promise, it's highly likely that it failed to dispose of the resource. In that case, Bluebird has two options - it can either ignore the error and continue with program execution or throw an exception (crashing the process in node.js).\n\nIn bluebird we've chosen to do the latter because resources are typically scarce. For example, if a database connection cannot be disposed of and Bluebird ignores that, the connection pool will be quickly depleted and the process will become unusable (all requests that query the database will wait forever). Since Bluebird doesn't know how to handle that, the only sensible default is to crash the process. That way, rather than getting a useless process that cannot fulfill more requests, we can swap the faulty worker with a new one letting the OS clean up the resources for us.\n\nAs a result, if you anticipate thrown errors or promise rejections while disposing of the resource you should use a `try..catch` block (or Promise.try) and write the appropriate catch code to handle the errors. If it's not possible to sensibly handle the error, letting the process crash is the next best option.\n\nThis also means that disposers should not contain code that does anything other than resource disposal. For example, you cannot write code inside a disposer to commit or rollback a transaction, because there is no mechanism for the disposer to signal a failure of the commit or rollback action without crashing the process.\n\nFor transactions, you can use the following similar pattern instead:\n\n```js\nfunction withTransaction(fn) {\n  return Promise.using(pool.acquireConnection(), function(connection) {\n    var tx = connection.beginTransaction()\n    return Promise\n      .try(fn, tx)\n      .then(function(res) { return connection.commit().thenReturn(res) },\n            function(err) {\n              return connection.rollback()\n                     .catch(function(e) {/* maybe add the rollback error to err */})\n                     .thenThrow(err);\n            });\n  });\n}\n\n// If the withTransaction block completes successfully, the transaction is automatically committed\n// Any error or rejection will automatically roll it back\n\nwithTransaction(function(tx) {\n    return tx.queryAsync(...).then(function() {\n        return tx.queryAsync(...)\n    }).then(function() {\n        return tx.queryAsync(...)\n    });\n});\n```\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".disposer\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-disposer\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/done.md",
    "content": "---\nlayout: api\nid: done\ntitle: .done\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.done\n\n```js\n.done(\n    [function(any value) fulfilledHandler],\n    [function(any error) rejectedHandler]\n) -> undefined\n```\n\n\nLike [`.then`](.), but any unhandled rejection that ends up here will crash the process (in node) or be thrown as an error (in browsers). The use of this method is heavily discouraged and it only exists for historical reasons.\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".done\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-done\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/each.md",
    "content": "---\nlayout: api\nid: each\ntitle: .each\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.each\n\n```js\n.each(function(any item, int index, int length) iterator) -> Promise\n```\n\nIterate over an array, or a promise of an array, which contains promises (or a mix of promises and values) with the given `iterator` function with the signature `(value, index, length)` where `value` is the resolved value of a respective promise in the input array. Iteration happens serially. If any promise in the input array is rejected the returned promise is rejected as well.\n\nResolves to the original array unmodified, this method is meant to be used for side effects. If the iterator function returns a promise or a thenable, then the result of the promise is awaited, before continuing with next iteration.\n\nExample where you might want to utilize `.each`:\n\n```js\n// Source: http://jakearchibald.com/2014/es7-async-functions/\nfunction loadStory() {\n  return getJSON('story.json')\n    .then(function(story) {\n      addHtmlToPage(story.heading);\n      return story.chapterURLs.map(getJSON);\n    })\n    .each(function(chapter) { addHtmlToPage(chapter.html); })\n    .then(function() { addTextToPage(\"All done\"); })\n    .catch(function(err) { addTextToPage(\"Argh, broken: \" + err.message); })\n    .then(function() { document.querySelector('.spinner').style.display = 'none'; });\n}\n```\n\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".each\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-each\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/environment-variables.md",
    "content": "---\nlayout: api\nid: environment-variables\ntitle: Environment variables\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Environment variables\n\nThis section only applies to node.js or io.js.\n\nYou can change bluebird behavior globally with various environment variables. These global variables affect all instances of bluebird that are running in your environment, rather than just the one you have `require`d in your application. The effect an environment variable has depends on the bluebird version.\n\nEnvironment variables supported by 2.x:\n\n- `BLUEBIRD_DEBUG` - Set to any truthy value this will enable long stack traces and warnings\n- `NODE_ENV` - If set exactly to `development` it will have the same effect as if the `BLUEBIRD_DEBUG` variable was set.\n\nEnvironment variables supported by 3.x:\n\n- `BLUEBIRD_DEBUG` - If set this will enable long stack traces and warnings, unless those are explicitly disabled. Setting this to exactly `0` can be used to override `NODE_ENV=development` enabling long stack traces and warnings.\n- `NODE_ENV` - If set exactly to `development` it will have the same effect as if the `BLUEBIRD_DEBUG` variable was set.\n- `BLUEBIRD_WARNINGS` - if set exactly to `0` it will explicitly disable warnings and this overrides any other setting that might enable warnings. If set to any truthy value, it will explicitly enable warnings.\n- `BLUEBIRD_LONG_STACK_TRACES` - if set exactly to `0` it will explicitly disable long stack traces and this overrides any other setting that might enable long stack traces. If set to any truthy value, it will explicitly enable long stack traces.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Environment variables\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-environment-variables\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/error-management-configuration.md",
    "content": "---\nlayout: api\nid: error-management-configuration\ntitle: Error management configuration\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Error management configuration\n\nThe default approach of bluebird is to immediately log the stack trace when there is an unhandled rejection. This is similar to how uncaught exceptions cause the stack trace to be logged so that you have something to work with when something is not working as expected.\n\nHowever because it is possible to handle a rejected promise at any time in the indeterminate future, some programming patterns will result in false positives. Because such programming patterns are not necessary and can always be refactored to never cause false positives, we recommend doing that to keep debugging as easy as possible . You may however feel differently so bluebird provides hooks to implement more complex failure policies.\n\nSuch policies could include:\n\n- Logging after the promise became GCd (requires a native node.js module)\n- Showing a live list of rejected promises\n- Using no hooks and using [`.done`](.) to manually to mark end points where rejections will not be handled\n- Swallowing all errors (challenge your debugging skills)\n- ...\n\n<hr>\n\n###Global rejection events\n\nStarting from 2.7.0 all bluebird instances also fire rejection events globally so that applications can register one universal hook for them.\n\nThe global events are:\n\n - `\"unhandledRejection\"` (corresponds to the local [`Promise.onPossiblyUnhandledRejection`](.))\n - `\"rejectionHandled\"` (corresponds to the local [`Promise.onUnhandledRejectionHandled`](.))\n\n\nAttaching global rejection event handlers in **node.js**:\n\n```js\n// NOTE: event name is camelCase as per node convention\nprocess.on(\"unhandledRejection\", function(reason, promise) {\n    // See Promise.onPossiblyUnhandledRejection for parameter documentation\n});\n\n// NOTE: event name is camelCase as per node convention\nprocess.on(\"rejectionHandled\", function(promise) {\n    // See Promise.onUnhandledRejectionHandled for parameter documentation\n});\n```\n\nAttaching global rejection event handlers in **browsers**:\n\nUsing DOM3 `addEventListener` APIs (support starting from IE9+):\n\n```js\n// NOTE: event name is all lower case as per DOM convention\nwindow.addEventListener(\"unhandledrejection\", function(e) {\n    // NOTE: e.preventDefault() must be manually called to prevent the default\n    // action which is currently to log the stack trace to console.warn\n    e.preventDefault();\n    // NOTE: parameters are properties of the event detail property\n    var reason = e.detail.reason;\n    var promise = e.detail.promise;\n    // See Promise.onPossiblyUnhandledRejection for parameter documentation\n});\n\n// NOTE: event name is all lower case as per DOM convention\nwindow.addEventListener(\"rejectionhandled\", function(e) {\n    // NOTE: e.preventDefault() must be manually called prevent the default\n    // action which is currently unset (but might be set to something in the future)\n    e.preventDefault();\n    // NOTE: parameters are properties of the event detail property\n    var promise = e.detail.promise;\n    // See Promise.onUnhandledRejectionHandled for parameter documentation\n});\n```\n\nIn Web Workers you may use `self.addEventListener`.\n\nUsing legacy APIs (support starting from IE6+):\n\n```js\n// NOTE: event name is all lower case as per legacy convention\nwindow.onunhandledrejection = function(reason, promise) {\n    // See Promise.onPossiblyUnhandledRejection for parameter documentation\n};\n\n// NOTE: event name is all lower case as per legacy convention\nwindow.onrejectionhandled = function(promise) {\n    // See Promise.onUnhandledRejectionHandled for parameter documentation\n};\n```\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Error management configuration\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-error-management-configuration\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/error.md",
    "content": "---\nlayout: api\nid: error\ntitle: .error\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.error\n\n```js\n.error([function(any error) rejectedHandler]) -> Promise\n```\n\n\nLike [`.catch`](.) but instead of catching all types of exceptions, it only catches operational errors.\n\n*Note, \"errors\" mean errors, as in objects that are `instanceof Error` - not strings, numbers and so on. See [a string is not an error](http://www.devthought.com/2011/12/22/a-string-is-not-an-error/).*\n\nIt is equivalent to the following [`.catch`](.) pattern:\n\n```js\n// Assumes OperationalError has been made global\nfunction isOperationalError(e) {\n    if (e == null) return false;\n    return (e instanceof OperationalError) || (e.isOperational === true);\n}\n\n// Now this bit:\n.catch(isOperationalError, function(e) {\n    // ...\n})\n\n// Is equivalent to:\n\n.error(function(e) {\n    // ...\n});\n```\n\nFor example, if a promisified function errbacks the node-style callback with an error, that could be caught with [`.error`](.). However if the node-style callback **throws** an error, only `.catch` would catch that.\n\nIn the following example you might want to handle just the `SyntaxError` from JSON.parse and Filesystem errors from `fs` but let programmer errors bubble as unhandled rejections:\n\n```js\nvar fs = Promise.promisifyAll(require(\"fs\"));\n\nfs.readFileAsync(\"myfile.json\").then(JSON.parse).then(function (json) {\n    console.log(\"Successful json\")\n}).catch(SyntaxError, function (e) {\n    console.error(\"file contains invalid json\");\n}).error(function (e) {\n    console.error(\"unable to read file, because: \", e.message);\n});\n```\n\nNow, because there is no catch-all handler, if you typed `console.lag` (causes an error you don't expect), you will see:\n\n```\nPossibly unhandled TypeError: Object #<Console> has no method 'lag'\n    at application.js:8:13\nFrom previous event:\n    at Object.<anonymous> (application.js:7:4)\n    at Module._compile (module.js:449:26)\n    at Object.Module._extensions..js (module.js:467:10)\n    at Module.load (module.js:349:32)\n    at Function.Module._load (module.js:305:12)\n    at Function.Module.runMain (module.js:490:10)\n    at startup (node.js:121:16)\n    at node.js:761:3\n```\n\n*( If you don't get the above - you need to enable [long stack traces](/docs/api/promise.config.html) )*\n\nAnd if the file contains invalid JSON:\n\n```\nfile contains invalid json\n```\n\nAnd if the `fs` module causes an error like file not found:\n\n```\nunable to read file, because:  ENOENT, open 'not_there.txt'\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".error\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-error\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/filter.md",
    "content": "---\nlayout: api\nid: filter\ntitle: .filter\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.filter\n\n```js\n.filter(\n    function(any item, int index, int length) filterer,\n    [Object {concurrency: int=Infinity} options]\n) -> Promise\n```\n\nSame as [Promise.filter(this, filterer, options)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".filter\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-filter\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/finally.md",
    "content": "---\nlayout: api\nid: finally\ntitle: .finally\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.finally\n\n```js\n.finally(function() handler) -> Promise\n```\n```js\n.lastly(function() handler) -> Promise\n```\n\n\nPass a handler that will be called regardless of this promise's fate. Returns a new promise chained from this promise. There are special semantics for [`.finally`](.) in that the final value cannot be modified from the handler.\n\n*Note: using [`.finally`](.) for resource management has better alternatives, see [resource management](/docs/api/resource-management.html)*\n\nConsider the example:\n\n```js\nfunction anyway() {\n    $(\"#ajax-loader-animation\").hide();\n}\n\nfunction ajaxGetAsync(url) {\n    return new Promise(function (resolve, reject) {\n        var xhr = new XMLHttpRequest;\n        xhr.addEventListener(\"error\", reject);\n        xhr.addEventListener(\"load\", resolve);\n        xhr.open(\"GET\", url);\n        xhr.send(null);\n    }).then(anyway, anyway);\n}\n```\n\nThis example doesn't work as intended because the `then` handler actually swallows the exception and returns `undefined` for any further chainers.\n\nThe situation can be fixed with `.finally`:\n\n```js\nfunction ajaxGetAsync(url) {\n    return new Promise(function (resolve, reject) {\n        var xhr = new XMLHttpRequest;\n        xhr.addEventListener(\"error\", reject);\n        xhr.addEventListener(\"load\", resolve);\n        xhr.open(\"GET\", url);\n        xhr.send(null);\n    }).finally(function() {\n        $(\"#ajax-loader-animation\").hide();\n    });\n}\n```\n\nNow the animation is hidden but, unless it throws an exception, the function has no effect on the fulfilled or rejected value of the returned promise.  This is similar to how the synchronous `finally` keyword behaves.\n\nIf the handler function passed to `.finally` returns a promise, the promise returned by `.finally` will not be settled until the promise returned by the handler is settled.  If the handler fulfills its promise, the returned promise will be fulfilled or rejected with the original value.  If the handler rejects its promise, the returned promise will be rejected with the handler's value.  This is similar to throwing an exception in a synchronous `finally` block, causing the original value or exception to be forgotten.  This delay can be useful if the actions performed by the handler are done asynchronously.  For example:\n\n```js\nfunction ajaxGetAsync(url) {\n    return new Promise(function (resolve, reject) {\n        var xhr = new XMLHttpRequest;\n        xhr.addEventListener(\"error\", reject);\n        xhr.addEventListener(\"load\", resolve);\n        xhr.open(\"GET\", url);\n        xhr.send(null);\n    }).finally(function() {\n        return Promise.fromCallback(function(callback) {\n            $(\"#ajax-loader-animation\").fadeOut(1000, callback);\n        });\n    });\n}\n```\n\nIf the fade out completes successfully, the returned promise will be fulfilled or rejected with the value from `xhr`.  If `.fadeOut` throws an exception or passes an error to the callback, the returned promise will be rejected with the error from `.fadeOut`.\n\n*For compatibility with earlier ECMAScript version, an alias `.lastly` is provided for [`.finally`](.).*\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".finally\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-finally\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/generators.md",
    "content": "---\nlayout: api\nid: generators\ntitle: Generators\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Generators\n\nUsing ECMAScript6 generators feature to implement C# 5.0 `async/await` like syntax.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Generators\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-generators\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/get.md",
    "content": "---\nlayout: api\nid: get\ntitle: .get\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.get\n\n```js\n.get(String propertyName|int index) -> Promise\n```\n\n\nThis is a convenience method for doing:\n\n```js\npromise.then(function(obj) {\n    return obj[propertyName];\n});\n```\n\nFor example:\n\n```js\ndb.query(\"...\")\n    .get(0)\n    .then(function(firstRow) {\n\n    });\n```\n\nIf `index` is negative, the indexed load will become `obj.length + index`. So that -1 can be used to read last item\nin the array, -2 to read the second last and so on. For example:\n\n```js\nPromise.resolve([1,2,3]).get(-1).then(function(value) {\n    console.log(value); // 3\n});\n```\n\nIf the `index` is still negative after `obj.length + index`, it will be clamped to 0.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".get\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-get\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/iscancelled.md",
    "content": "---\nlayout: api\nid: iscancelled\ntitle: .isCancelled\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.isCancelled\n\n```js\n.isCancelled() -> boolean\n```\n\nSee if this `promise` has been cancelled.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".isCancelled\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-iscancelled\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/isfulfilled.md",
    "content": "---\nlayout: api\nid: isfulfilled\ntitle: .isFulfilled\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.isFulfilled\n\n```js\n.isFulfilled() -> boolean\n```\n\nSee if this promise has been fulfilled.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".isFulfilled\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-isfulfilled\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/ispending.md",
    "content": "---\nlayout: api\nid: ispending\ntitle: .isPending\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.isPending\n\n```js\n.isPending() -> boolean\n```\n\n\nSee if this `promise` is pending (not fulfilled or rejected or cancelled).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".isPending\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-ispending\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/isrejected.md",
    "content": "---\nlayout: api\nid: isrejected\ntitle: .isRejected\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.isRejected\n\n```js\n.isRejected() -> boolean\n```\n\nSee if this promise has been rejected.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".isRejected\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-isrejected\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/map.md",
    "content": "---\nlayout: api\nid: map\ntitle: .map\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.map\n\n```js\n.map(\n    function(any item, int index, int length) mapper,\n    [Object {concurrency: int=Infinity} options]\n) -> Promise\n```\n\nSame as [Promise.map(this, mapper, options)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".map\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-map\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/mapseries.md",
    "content": "---\nlayout: api\nid: mapseries\ntitle: .mapseries\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.mapSeries\n\n```js\n.mapSeries(function(any item, int index, int length) mapper) -> Promise\n```\n\nSame as [Promise.mapSeries(this, iterator)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".mapSeries\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-mapSeries\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/new-promise.md",
    "content": "---\nlayout: api\nid: new-promise\ntitle: new Promise\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##new Promise\n\n```js\nnew Promise(function(function resolve, function reject) resolver) -> Promise\n```\n\n\nCreate a new promise. The passed in function will receive functions `resolve` and `reject` as its arguments which can be called to seal the fate of the created promise.\n\n*Note: See [explicit construction anti-pattern]({{ \"/docs/anti-patterns.html#the-explicit-construction-anti-pattern\" | prepend: site.baseurl }}) before creating promises yourself*\n\nExample:\n\n```js\nfunction ajaxGetAsync(url) {\n    return new Promise(function (resolve, reject) {\n        var xhr = new XMLHttpRequest;\n        xhr.addEventListener(\"error\", reject);\n        xhr.addEventListener(\"load\", resolve);\n        xhr.open(\"GET\", url);\n        xhr.send(null);\n    });\n}\n```\n\nIf you pass a promise object to the `resolve` function, the created promise will follow the state of that promise.\n\n<hr>\n\nTo make sure a function that returns a promise is following the implicit but critically important contract of promises, you can start a function with `new Promise` if you cannot start a chain immediately:\n\n```js\nfunction getConnection(urlString) {\n    return new Promise(function(resolve) {\n        //Without new Promise, this throwing will throw an actual exception\n        var params = parse(urlString);\n        resolve(getAdapter(params).getConnection());\n    });\n}\n```\n\nThe above ensures `getConnection` fulfills the contract of a promise-returning function of never throwing a synchronous exception. Also see [`Promise.try`](.) and [`Promise.method`](.)\n\nThe resolver is called synchronously (the following is for documentation purposes and not idiomatic code):\n\n```js\nfunction getPromiseResolveFn() {\n    var res;\n    new Promise(function (resolve) {\n        res = resolve;\n    });\n    // res is guaranteed to be set\n    return res;\n}\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"new Promise\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-new-promise\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/operationalerror.md",
    "content": "---\nlayout: api\nid: operationalerror\ntitle: OperationalError\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##OperationalError\n\n```js\nnew OperationalError(String message) -> OperationalError\n```\n\n\nRepresents an error is an explicit promise rejection as opposed to a thrown error. For example, if an error is errbacked by a callback API promisified through [`Promise.promisify`](.) or [`Promise.promisifyAll`](.)\nand is not a typed error, it will be converted to a `OperationalError` which has the original error in the `.cause` property.\n\n`OperationalError`s are caught in [`.error`](.) handlers.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"OperationalError\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-operationalerror\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/progression-migration.md",
    "content": "---\nlayout: api\nid: progression-migration\ntitle: Progression migration\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Progression migration\n\nProgression has been removed as there are composability and chaining issues with APIs that use promise progression handlers. Implementing the common use case of progress bars can be accomplished using a pattern similar to [IProgress](http://blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx) in C#.\n\nFor old code that still uses it, see [the progression docs in the deprecated API documentation](/docs/deprecated-apis.html#progression).\n\nUsing jQuery before:\n\n```js\nPromise.resolve($.get(...))\n    .progressed(function() {\n        // ...\n    })\n    .then(function() {\n        // ...\n    })\n    .catch(function(e) {\n        // ...\n    })\n```\n\nUsing jQuery after:\n\n```js\nPromise.resolve($.get(...).progress(function() {\n        // ...\n    }))\n    .then(function() {\n        // ...\n    })\n    .catch(function(e) {\n        // ...\n    })\n```\n\nImplementing general progress interfaces like in C#:\n\n```js\nfunction returnsPromiseWithProgress(progressHandler) {\n    return doFirstAction().tap(function() {\n        progressHandler(0.33);\n    }).then(doSecondAction).tap(function() {\n        progressHandler(0.66);\n    }).then(doThirdAction).tap(function() {\n        progressHandler(1.00);\n    });\n}\n\nreturnsPromiseWithProgress(function(progress) {\n    ui.progressbar.setWidth((progress * 200) + \"px\"); // update width on client side\n}).then(function(value) { // action complete\n   // entire chain is complete.\n}).catch(function(e) {\n    // error\n});\n```\n\nAnother example using `coroutine`:\n\n```js\nvar doNothing = function() {};\nvar progressSupportingCoroutine = Promise.coroutine(function* (progress) {\n        progress = typeof progress === \"function\" ? progress : doNothing;\n        var first = yield getFirstValue();\n        // 33% done\n        progress(0.33);\n        var second = yield getSecondValue();\n        progress(0.67);\n        var third = yield getThirdValue();\n        progress(1);\n        return [first, second, third];\n});\n\nvar progressConsumingCoroutine = Promise.coroutine(function* () {\n    var allValues = yield progressSupportingCoroutine(function(p) {\n         ui.progressbar.setWidth((p * 200) + \"px\");\n    });\n    var second = allValues[1];\n    // ...\n});\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Progression migration\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-progression-migration\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.all.md",
    "content": "---\nlayout: api\nid: promise.all\ntitle: Promise.all\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.all\n\n```js\nPromise.all(Iterable<any>|Promise<Iterable<any>> input) -> Promise<Array<any>>\n```\n\nThis method is useful for when you want to wait for more than one promise to complete.\n\nGiven an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)\\(arrays are `Iterable`\\), or a promise of an `Iterable`, which produces promises (or a mix of promises and values), iterate over all the values in the `Iterable` into an array and return a promise that is fulfilled when all the items in the array are fulfilled. The promise's fulfillment value is an array with fulfillment values at respective positions to the original array. If any promise in the array rejects, the returned promise is rejected with the rejection reason.\n\n\n```js\nvar files = [];\nfor (var i = 0; i < 100; ++i) {\n    files.push(fs.writeFileAsync(\"file-\" + i + \".txt\", \"\", \"utf-8\"));\n}\nPromise.all(files).then(function() {\n    console.log(\"all the files were created\");\n});\n```\n\n\nThis method is compatible with [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) from native promises.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.all\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.all\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.any.md",
    "content": "---\nlayout: api\nid: promise.any\ntitle: Promise.any\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.any\n\n```js\nPromise.any(Iterable<any>|Promise<Iterable<any>> input) -> Promise\n```\n\nLike [Promise.some](.), with 1 as `count`. However, if the promise fulfills, the fulfillment value is not an array of 1 but the value directly.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.any\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.any\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/promise.bind.md",
    "content": "---\nlayout: api\nid: promise.bind\ntitle: Promise.bind\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.bind\n\n```js\nPromise.bind(\n    any|Promise<any> thisArg,\n    [any|Promise<any> value=undefined]\n) -> BoundPromise\n```\n\nCreate a promise that follows this promise or in the static method is resolved with the given `value`, but is bound to the given `thisArg` value. A bound promise will call its handlers with the bound value set to `this`. Additionally promises derived from a bound promise will also be bound promises with the same `thisArg` binding as the original promise.\n\nIf `thisArg` is a promise or thenable, its resolution will be awaited for and the bound value will be the promise's fulfillment value. If `thisArg` rejects\nthen the returned promise is rejected with the `thisArg's` rejection reason. Note that this means you cannot use `this` without checking inside catch handlers for promises that bind to promise because in case of rejection of `thisArg`, `this` will be `undefined`.\n\n<hr>\n\nWithout arrow functions that provide lexical `this`, the correspondence between async and sync code breaks down when writing object-oriented code. [`.bind`](.) alleviates this.\n\nConsider:\n\n```js\nMyClass.prototype.method = function() {\n    try {\n        var contents = fs.readFileSync(this.file);\n        var url = urlParse(contents);\n        var result = this.httpGetSync(url);\n        var refined = this.refine(result);\n        return this.writeRefinedSync(refined);\n    }\n    catch (e) {\n        this.error(e.stack);\n    }\n};\n```\n\nThe above has a direct translation:\n\n```js\nMyClass.prototype.method = function() {\n    return fs.readFileAsync(this.file).bind(this)\n    .then(function(contents) {\n        var url = urlParse(contents);\n        return this.httpGetAsync(url);\n    }).then(function(result) {\n        var refined = this.refine(result);\n        return this.writeRefinedAsync(refined);\n    }).catch(function(e) {\n        this.error(e.stack);\n    });\n};\n```\n\n`.bind` is the most efficient way of utilizing `this` with promises. The handler functions in the above code are not closures and can therefore even be hoisted out if needed. There is literally no overhead when propagating the bound value from one promise to another.\n\n<hr>\n\n`.bind` also has a useful side purpose - promise handlers don't need to share a function to use shared state:\n\n```js\nsomethingAsync().bind({})\n.spread(function (aValue, bValue) {\n    this.aValue = aValue;\n    this.bValue = bValue;\n    return somethingElseAsync(aValue, bValue);\n})\n.then(function (cValue) {\n    return this.aValue + this.bValue + cValue;\n});\n```\n\nThe above without [`.bind`](.) could be achieved with:\n\n```js\nvar scope = {};\nsomethingAsync()\n.spread(function (aValue, bValue) {\n    scope.aValue = aValue;\n    scope.bValue = bValue;\n    return somethingElseAsync(aValue, bValue);\n})\n.then(function (cValue) {\n    return scope.aValue + scope.bValue + cValue;\n});\n```\n\nHowever, there are many differences when you look closer:\n\n- Requires a statement so cannot be used in an expression context\n- If not there already, an additional wrapper function is required to undefined leaking or sharing `scope`\n- The handler functions are now closures, thus less efficient and not reusable\n\n<hr>\n\nNote that bind is only propagated with promise transformation. If you create new promise chains inside a handler, those chains are not bound to the \"upper\" `this`:\n\n```js\nsomething().bind(var1).then(function() {\n    //`this` is var1 here\n    return Promise.all(getStuff()).then(function(results) {\n        //`this` is undefined here\n        //refine results here etc\n    });\n}).then(function() {\n    //`this` is var1 here\n});\n```\n\nHowever, if you are utilizing the full bluebird API offering, you will *almost never* need to resort to nesting promises in the first place. The above should be written more like:\n\n```js\nsomething().bind(var1).then(function() {\n    //`this` is var1 here\n    return getStuff();\n}).map(function(result) {\n    //`this` is var1 here\n    //refine result here\n}).then(function() {\n    //`this` is var1 here\n});\n```\n\nAlso see this [Stackoverflow answer](http://stackoverflow.com/a/24412873/191693) as an additional example.\n\n<hr>\n\nIf you don't want to return a bound promise to the consumers of a promise, you can rebind the chain at the end:\n\n```js\nMyClass.prototype.method = function() {\n    return fs.readFileAsync(this.file).bind(this)\n    .then(function(contents) {\n        var url = urlParse(contents);\n        return this.httpGetAsync(url);\n    }).then(function(result) {\n        var refined = this.refine(result);\n        return this.writeRefinedAsync(refined);\n    }).catch(function(e) {\n        this.error(e.stack);\n    }).bind(); //The `thisArg` is implicitly undefined - I.E. the default promise `this` value\n};\n```\n\nRebinding can also be abused to do something gratuitous like this:\n\n```js\nPromise.resolve(\"my-element\")\n    .bind(document)\n    .then(document.getElementById)\n    .bind(console)\n    .then(console.log);\n```\n\nThe above does a `console.log` of `my-element`.  Doing it this way is necessary because neither of the methods (`getElementById`, `console.log`) can be called as stand-alone methods.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.bind\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.bind\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.config.md",
    "content": "---\nlayout: api\nid: promise.config\ntitle: Promise.config\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.config\n\n```js\nPromise.config(Object {\n    warnings: boolean=false,\n    longStackTraces: boolean=false,\n    cancellation: boolean=false,\n    monitoring: boolean=false,\n    asyncHooks: boolean=false\n} options) -> Object;\n```\n\nConfigure long stack traces, warnings, monitoring, [async hooks](https://nodejs.org/api/async_hooks.html) and cancellation. Note that even though `false` is the default here, a development environment might be detected which automatically enables long stack traces and warnings. For **webpack** and **browserify** *development* environment is *always* enabled. See [installation](/docs/install.html#browserify-and-webpack) on how to configure webpack and browserify for production.\n\n```js\nPromise.config({\n    // Enable warnings\n    warnings: true,\n    // Enable long stack traces\n    longStackTraces: true,\n    // Enable cancellation\n    cancellation: true,\n    // Enable monitoring\n    monitoring: true,\n    // Enable async hooks\n    asyncHooks: true,\n});\n```\n\nYou can configure the warning for checking forgotten return statements with `wForgottenReturn`:\n\n```js\nPromise.config({\n    // Enables all warnings except forgotten return statements.\n    warnings: {\n        wForgottenReturn: false\n    }\n});\n```\n\n`wForgottenReturn` is the only warning type that can be separately configured. The corresponding environmental variable key is `BLUEBIRD_W_FORGOTTEN_RETURN`.\n\n<hr>\n\n\n\nIn Node.js you may configure warnings and long stack traces for the entire process using environment variables:\n\n```\nBLUEBIRD_LONG_STACK_TRACES=1 BLUEBIRD_WARNINGS=1 node app.js\n```\n\nBoth features are automatically enabled if the `BLUEBIRD_DEBUG` environment variable has been set or if the `NODE_ENV` environment variable is equal to `\"development\"`.\n\nUsing the value `0` will explicitly disable a feature despite debug environment otherwise activating it:\n\n```\n# Warnings are disabled despite being in development environment\nNODE_ENV=development BLUEBIRD_WARNINGS=0 node app.js\n```\n\nCancellation is always configured separately per bluebird instance.\n\n# Async hooks\n\nBluebird supports [async hooks](https://nodejs.org/api/async_hooks.html) in node versions 9.6.0 and later. After it is enabled promises from the bluebird instance are assigned unique asyncIds:\n\n```js\n// Async hooks disabled for bluebird\nconst ah = require('async_hooks');\nconst Promise = require(\"bluebird\");\nPromise.resolve().then(() => {\n    console.log(`eid ${ah.executionAsyncId()} tid ${ah.triggerAsyncId()}`);\n    //\n});\n```\n\n```js\n// Async hooks enabled for bluebird\nconst ah = require('async_hooks');\nconst Promise = require(\"bluebird\");\nPromise.config({asyncHooks: true});\nPromise.resolve().then(() => {\n    console.log(`eid ${ah.executionAsyncId()} tid ${ah.triggerAsyncId()}`);\n    //\n});\n```\n\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.config\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.config\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.coroutine.addyieldhandler.md",
    "content": "---\nlayout: api\nid: promise.coroutine.addyieldhandler\ntitle: Promise.coroutine.addYieldHandler\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.coroutine.addYieldHandler\n\n```js\nPromise.coroutine.addYieldHandler(function handler) -> undefined\n```\n\n\nBy default you can only yield Promises and Thenables inside coroutines. You can use this function to add yielding support for arbitrary types.\n\nFor example, if you wanted `yield 500` to be same as `yield Promise.delay`:\n\n```js\nPromise.coroutine.addYieldHandler(function(value) {\n     if (typeof value === \"number\") return Promise.delay(value);\n});\n```\n\nYield handlers are called when you yield something that is not supported by default. The first yield handler to return a promise or a thenable will be used.\nIf no yield handler returns a promise or a thenable then an error is raised.\n\nAn example of implementing callback support with `addYieldHandler`:\n\n*This is a demonstration of how powerful the feature is and not the recommended usage. For best performance you need to use `promisifyAll` and yield promises directly.*\n\n```js\nvar Promise = require(\"bluebird\");\nvar fs = require(\"fs\");\n\nvar _ = (function() {\n    var promise = null;\n    Promise.coroutine.addYieldHandler(function(v) {\n        if (v === undefined && promise != null) {\n            return promise;\n        }\n        promise = null;\n    });\n    return function() {\n        var def = Promise.defer();\n        promise = def.promise;\n        return def.callback;\n    };\n})();\n\n\nvar readFileJSON = Promise.coroutine(function* (fileName) {\n   var contents = yield fs.readFile(fileName, \"utf8\", _());\n   return JSON.parse(contents);\n});\n```\n\nAn example of implementing thunks support with `addYieldHandler`:\n\n*This is a demonstration of how powerful the feature is and not the recommended usage. For best performance you need to use `promisifyAll` and yield promises directly.*\n\n```js\nvar Promise = require(\"bluebird\");\nvar fs = require(\"fs\");\n\nPromise.coroutine.addYieldHandler(function(v) {\n    if (typeof v === \"function\") {\n        return Promise.fromCallback(function(cb) {\n            v(cb);\n        });\n    }\n});\n\nvar readFileThunk = function(fileName, encoding) {\n    return function(cb) {\n        return fs.readFile(fileName, encoding, cb);\n    };\n};\n\nvar readFileJSON = Promise.coroutine(function* (fileName) {\n   var contents = yield readFileThunk(fileName, \"utf8\");\n   return JSON.parse(contents);\n});\n```\n\nAn example of handling promises in parallel by adding an `addYieldHandler` for arrays :\n\n```js\nvar Promise = require(\"bluebird\");\nvar fs = Promise.promisifyAll(require(\"fs\"));\n\nPromise.coroutine.addYieldHandler(function(yieldedValue) {\n    if (Array.isArray(yieldedValue)) return Promise.all(yieldedValue);\n});\n\nvar readFiles = Promise.coroutine(function* (fileNames) {\n   return yield fileNames.map(function (fileName) {\n      return fs.readFileAsync(fileName, \"utf8\");\n   });\n});\n```\n\nA custom yield handler can also be used just for a single call to `Promise.coroutine()`:\n\n```js\nvar Promise = require(\"bluebird\");\nvar fs = Promise.promisifyAll(require(\"fs\"));\n\nvar readFiles = Promise.coroutine(function* (fileNames) {\n   return yield fileNames.map(function (fileName) {\n      return fs.readFileAsync(fileName, \"utf8\");\n   });\n}, {\n   yieldHandler: function(yieldedValue) {\n      if (Array.isArray(yieldedValue)) return Promise.all(yieldedValue);\n   }\n});\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.coroutine.addYieldHandler\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.coroutine.addyieldhandler\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/promise.coroutine.md",
    "content": "---\nlayout: api\nid: promise.coroutine\ntitle: Promise.coroutine\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.coroutine\n\n```js\nPromise.coroutine(GeneratorFunction(...arguments) generatorFunction, Object options) -> function\n```\n\nReturns a function that can use `yield` to yield promises. Control is returned back to the generator when the yielded promise settles. This can lead to less verbose code when doing lots of sequential async calls with minimal processing in between. Requires node.js 0.12+, io.js 1.0+ or Google Chrome 40+.\n\n```js\nvar Promise = require(\"bluebird\");\n\nfunction PingPong() {\n\n}\n\nPingPong.prototype.ping = Promise.coroutine(function* (val) {\n    console.log(\"Ping?\", val);\n    yield Promise.delay(500);\n    this.pong(val+1);\n});\n\nPingPong.prototype.pong = Promise.coroutine(function* (val) {\n    console.log(\"Pong!\", val);\n    yield Promise.delay(500);\n    this.ping(val+1);\n});\n\nvar a = new PingPong();\na.ping(0);\n```\n\nRunning the example:\n\n    $ node test.js\n    Ping? 0\n    Pong! 1\n    Ping? 2\n    Pong! 3\n    Ping? 4\n    Pong! 5\n    Ping? 6\n    Pong! 7\n    Ping? 8\n    ...\n\nWhen called, the coroutine function will start an instance of the generator and returns a promise for its final value.\n\nDoing `Promise.coroutine` is almost like using the C# `async` keyword to mark the function, with `yield` working as the `await` keyword. Promises are somewhat like `Task`s.\n\n**Tip**\n\nYou are able to yield non-promise values by adding your own yield handler using  [`Promise.coroutine.addYieldHandler`](.) or calling `Promise.coroutine()` with a yield handler function as `options.yieldHandler`.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.coroutine\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.coroutine\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.delay.md",
    "content": "---\nlayout: api\nid: promise.delay\ntitle: Promise.delay\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.delay\n\n```js\nPromise.delay(\n    int ms,\n    [any|Promise<any> value=undefined]\n) -> Promise\n```\n\n\nReturns a promise that will be resolved with `value` (or `undefined`) after given `ms` milliseconds. If `value` is a promise, the delay will start counting down when it is fulfilled and the returned promise will be fulfilled with the fulfillment value of the `value` promise. If `value` is a rejected promise, the resulting promise will be rejected immediately. \n\n```js\nPromise.delay(500).then(function() {\n    console.log(\"500 ms passed\");\n    return \"Hello world\";\n}).delay(500).then(function(helloWorldString) {\n    console.log(helloWorldString);\n    console.log(\"another 500 ms passed\") ;\n});\n```\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.delay\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.delay\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.each.md",
    "content": "---\nlayout: api\nid: promise.each\ntitle: Promise.each\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.each\n\n```js\nPromise.each(\n    Iterable<any>|Promise<Iterable<any>> input,\n    function(any value, int index, int arrayLength) iterator\n) -> Promise<Array<any>>\n```\n\nGiven an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) (an array, for example), or a promise of an `Iterable`, iterates serially over all the values in it, executing the given `iterator` on each element. If an element is a promise, the iterator will wait for it before proceeding. The `iterator` function has signature `(value, index, arrayLength)` where `value` is the current element (or its resolved value if it is a promise).\n\nIf, at any step:\n\n* The iterator returns a promise or a thenable, it is awaited before continuing to the next iteration.\n\n* The current element of the iteration is a *pending* promise, that promise will be awaited before running the iterator.\n\n* The current element of the iteration is a *rejected* promise, the iteration will stop and be rejected as well (with the same reason).\n\nIf all iterations resolve successfully, the `Promise.each` call resolves to a new array containing the resolved values of the original input elements.\n\n`Promise.each` is very similar to [Promise.mapSeries](.). The difference between `Promise.each` and `Promise.mapSeries` is their resolution value. `Promise.each` resolves with an array as explained above, while `Promise.mapSeries` resolves with an array containing the *outputs* of the iterator function on each step. This way, `Promise.each` is meant to be mainly used for side-effect operations (since the outputs of the iterator are essentially discarded), just like the native `.forEach()` method of arrays, while `Promise.map` is meant to be used as an async version of the native `.map()` method of arrays.\n\nBasic example:\n\n```js\n// The array to be iterated over can be a mix of values and promises.\nvar fileNames = [\"1.txt\", Promise.resolve(\"2.txt\"), \"3.txt\", Promise.delay(3000, \"4.txt\"), \"5.txt\"];\n\nPromise.each(fileNames, function(fileName, index, arrayLength) {\n    // The iteration will be performed sequentially, awaiting for any\n    // promises in the process.\n    return fs.readFileAsync(fileName).then(function(fileContents) {\n        // ...\n\n        // The final resolution value of the iterator is is irrelevant,\n        // since the result of the `Promise.each` has nothing to do with\n        // the outputs of the iterator.\n        return \"anything\"; // Doesn't matter\n    });\n}).then(function(result) {\n    // This will run after the last step is done\n    console.log(\"Done!\")\n    console.log(result); // [\"1.txt\", \"2.txt\", \"3.txt\", \"4.txt\", \"5.txt\"]\n});\n```\n\n\n##Example\n```js\nlet stories = [ '8952', '8884'];\nPromise.each(stories, (item, idx, length) => {\n   return request.getAsync(`https://hacker-news.firebaseio.com/v0/item/${item}.json?print=pretty`)\n   .then(res => {\n      // need to do explicit operations here\n   })\n})\n.then(result => {\n console.log('ALL done', result);//['8952', '8884']\n})\n\n```\n\n[api/promise.each](unfinished-article)\n=======\nExample with a rejected promise in the array:\n\n\n```js\n// If one of the promises in the original array rejects,\n// the iteration will stop once it reaches it\nvar items = [\"A\", Promise.delay(8000, \"B\"), Promise.reject(\"C\"), \"D\"];\n\nPromise.each(items, function(item) {\n    return Promise.delay(4000).then(function() {\n        console.log(\"On iterator: \" + item);\n    });\n}).then(function(result) {\n    // This not run\n}).catch(function(rejection) {\n    console.log(\"Catch: \" + rejection);\n});\n\n// The code above outputs the following after 12 seconds (not 16!):\n// On iterator: A\n// On iterator: B\n// Catch: C\n```\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.each\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.each\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.filter.md",
    "content": "---\nlayout: api\nid: promise.filter\ntitle: Promise.filter\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.filter\n\n```js\nPromise.filter(\n    Iterable<any>|Promise<Iterable<any>> input,\n    function(any item, int index, int length) filterer,\n    [Object {concurrency: int=Infinity} options]\n) -> Promise\n```\n\nGiven an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)\\(arrays are `Iterable`\\), or a promise of an `Iterable`, which produces promises (or a mix of promises and values), iterate over all the values in the `Iterable` into an array and [filter the array to another](http://en.wikipedia.org/wiki/Filter_\\(higher-order_function\\)) using the given `filterer` function.\n\n\nIt is essentially an efficient shortcut for doing a [.map](.) and then [`Array#filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter):\n\n```js\nPromise.map(valuesToBeFiltered, function(value, index, length) {\n    return Promise.all([filterer(value, index, length), value]);\n}).then(function(values) {\n    return values.filter(function(stuff) {\n        return stuff[0] == true\n    }).map(function(stuff) {\n        return stuff[1];\n    });\n});\n```\n\nExample for filtering files that are accessible directories in the current directory:\n\n```js\nvar Promise = require(\"bluebird\");\nvar E = require(\"core-error-predicates\");\nvar fs = Promise.promisifyAll(require(\"fs\"));\n\nfs.readdirAsync(process.cwd()).filter(function(fileName) {\n    return fs.statAsync(fileName)\n        .then(function(stat) {\n            return stat.isDirectory();\n        })\n        .catch(E.FileAccessError, function() {\n            return false;\n        });\n}).each(function(directoryName) {\n    console.log(directoryName, \" is an accessible directory\");\n});\n```\n\n####Filter Option: concurrency\n\nSee [Map Option: concurrency](#map-option-concurrency)\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.filter\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.filter\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/promise.fromcallback.md",
    "content": "---\nlayout: api\nid: promise.fromcallback\ntitle: Promise.fromCallback\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.fromCallback\n\n```js\nPromise.fromCallback(\n    function(function callback) resolver,\n    [Object {multiArgs: boolean=false} options]\n) -> Promise\n```\n```js\nPromise.fromNode(\n    function(function callback) resolver,\n    [Object {multiArgs: boolean=false} options]\n) -> Promise\n```\n\nReturns a promise that is resolved by a node style callback function. This is the most fitting way to do on the fly promisification when libraries don't expose classes for automatic promisification by undefined.\n\nThe resolver function is passed a callback that expects to be called back according to error-first node conventions.\n\nSetting `multiArgs` to `true` means the resulting promise will always fulfill with an array of the callback's success value(s). This is needed because promises only support a single success value while\nsome callback API's have multiple success value. The default is to ignore all but the first success value of a callback function.\n\nUsing manual resolver:\n\n```js\nvar Promise = require(\"bluebird\");\n// \"email-templates\" doesn't expose prototypes for promisification\nvar emailTemplates = Promise.promisify(require('email-templates'));\nvar templatesDir = path.join(__dirname, 'templates');\n\n\nemailTemplates(templatesDir).then(function(template) {\n    return Promise.fromCallback(function(callback) {\n        return template(\"newsletter\", callback);\n    }, {multiArgs: true}).spread(function(html, text) {\n        console.log(html, text);\n    });\n});\n```\n\nThe same can also be written more concisely with `Function.prototype.bind`:\n\n```js\nvar Promise = require(\"bluebird\");\n// \"email-templates\" doesn't expose prototypes for promisification\nvar emailTemplates = Promise.promisify(require('email-templates'));\nvar templatesDir = path.join(__dirname, 'templates');\n\n\nemailTemplates(templatesDir).then(function(template) {\n    return Promise.fromCallback(template.bind(null, \"newsletter\"), {multiArgs: true})\n        .spread(function(html, text) {\n            console.log(html, text);\n        });\n});\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.fromCallback\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.fromcallback\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.getnewlibrarycopy.md",
    "content": "---\nlayout: api\nid: promise.getnewlibrarycopy\ntitle: Promise.getNewLibraryCopy\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.getNewLibraryCopy\n\n```js\nPromise.getNewLibraryCopy() -> Object\n```\n\nReturns a new independent copy of the Bluebird library.\n\nThis method should be used before you use any of the methods which would otherwise alter the global `Bluebird` object - to avoid polluting global state.\n\nA basic example:\n\n```js\nvar Promise = require('bluebird');\nvar Promise2 = Promise.getNewLibraryCopy();\n\nPromise2.x = 123;\n\nconsole.log(Promise2 == Promise); // false\nconsole.log(Promise2.x); // 123\nconsole.log(Promise.x); // undefined\n```\n\n`Promise2` is independent to `Promise`. Any changes to `Promise2` do not affect the copy of Bluebird returned by `require('bluebird')`.\n\nIn practice:\n\n```js\nvar Promise = require('bluebird').getNewLibraryCopy();\n\nPromise.coroutine.addYieldHandler( function() { /* */ } ); // alters behavior of `Promise.coroutine()`\n\n// somewhere in another file or module in same app\nvar Promise = require('bluebird');\n\nPromise.coroutine(function*() {\n    // this code is unaffected by the yieldHandler defined above\n    // because it was defined on an independent copy of Bluebird\n});\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.getNewLibraryCopy\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.getnewlibrarycopy\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.join.md",
    "content": "---\nlayout: api\nid: promise.join\ntitle: Promise.join\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.join\n\n```js\nPromise.join(\n    Promise<any>|any values...,\n    function handler\n) -> Promise\n```\n\n\nFor coordinating multiple concurrent discrete promises. While [`.all`](.) is good for handling a dynamically sized list of uniform promises, `Promise.join` is much easier (and more performant) to use when you have a fixed amount of discrete promises that you want to coordinate concurrently. The final parameter, handler function, will be invoked with the result values of all of the fulfilled promises. For example:\n\n```js\nvar Promise = require(\"bluebird\");\nvar join = Promise.join;\n\njoin(getPictures(), getComments(), getTweets(),\n    function(pictures, comments, tweets) {\n    console.log(\"in total: \" + pictures.length + comments.length + tweets.length);\n});\n```\n\n```js\nvar Promise = require(\"bluebird\");\nvar fs = Promise.promisifyAll(require(\"fs\"));\nvar pg = require(\"pg\");\nPromise.promisifyAll(pg, {\n    filter: function(methodName) {\n        return methodName === \"connect\"\n    },\n    multiArgs: true\n});\n// Promisify rest of pg normally\nPromise.promisifyAll(pg);\nvar join = Promise.join;\nvar connectionString = \"postgres://username:password@localhost/database\";\n\nvar fContents = fs.readFileAsync(\"file.txt\", \"utf8\");\nvar fStat = fs.statAsync(\"file.txt\");\nvar fSqlClient = pg.connectAsync(connectionString).spread(function(client, done) {\n    client.close = done;\n    return client;\n});\n\njoin(fContents, fStat, fSqlClient, function(contents, stat, sqlClient) {\n    var query = \"                                                              \\\n        INSERT INTO files (byteSize, contents)                                 \\\n        VALUES ($1, $2)                                                        \\\n    \";\n   return sqlClient.queryAsync(query, [stat.size, contents]).thenReturn(query);\n})\n.then(function(query) {\n    console.log(\"Successfully ran the Query: \" + query);\n})\n.finally(function() {\n    // This is why you want to use Promise.using for resource management\n    if (fSqlClient.isFulfilled()) {\n        fSqlClient.value().close();\n    }\n});\n```\n\n*Note: In 1.x and 0.x `Promise.join` used to be a `Promise.all` that took the values in as arguments instead of an array. This behavior has been deprecated but is still supported partially - when the last argument is an immediate function value the new semantics will apply*\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.join\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.join\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.longstacktraces.md",
    "content": "---\nlayout: api\nid: promise.longstacktraces\ntitle: Promise.longStackTraces\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n## ~~Promise.longStackTraces~~\n\nThis method is deprecated. Use [Promise.config](/docs/api/promise.config.html) instead.\n\n```js\nPromise.config({\n  longStackTraces: true\n})\n```\n\n---\n\n```js\nPromise.longStackTraces() -> undefined\n```\n\nCall this right after the library is loaded to enable long stack traces. Long stack traces cannot be disabled after being enabled, and cannot be enabled after promises have already been created. Long stack traces imply a substantial performance penalty, around 4-5x for throughput and 0.5x for latency.\n\nLong stack traces are enabled by default in the debug build.\n\nTo enable them in all instances of bluebird in node.js, use the environment variable `BLUEBIRD_DEBUG`:\n\n```\nBLUEBIRD_DEBUG=1 node server.js\n```\n\nSetting the environment variable `NODE_ENV` to `\"development\"` also automatically enables long stack traces.\n\nYou should enabled long stack traces if you want better debugging experience. For example:\n\n```js\nPromise.longStackTraces();\nPromise.resolve().then(function outer() {\n    return Promise.resolve().then(function inner() {\n        return Promise.resolve().then(function evenMoreInner() {\n            a.b.c.d()\n        }).catch(function catcher(e) {\n            console.error(e.stack);\n        });\n    });\n});\n```\n\nGives\n\n    ReferenceError: a is not defined\n        at evenMoreInner (<anonymous>:6:13)\n    From previous event:\n        at inner (<anonymous>:5:24)\n    From previous event:\n        at outer (<anonymous>:4:20)\n    From previous event:\n        at <anonymous>:3:9\n        at Object.InjectedScript._evaluateOn (<anonymous>:581:39)\n        at Object.InjectedScript._evaluateAndWrap (<anonymous>:540:52)\n        at Object.InjectedScript.evaluate (<anonymous>:459:21)\n\nWhile with long stack traces disabled, you would get:\n\n    ReferenceError: a is not defined\n        at evenMoreInner (<anonymous>:6:13)\n        at tryCatch1 (<anonymous>:41:19)\n        at Promise$_resolvePromise [as _resolvePromise] (<anonymous>:1739:13)\n        at Promise$_resolveLast [as _resolveLast] (<anonymous>:1520:14)\n        at Async$_consumeFunctionBuffer [as _consumeFunctionBuffer] (<anonymous>:560:33)\n        at Async$consumeFunctionBuffer (<anonymous>:515:14)\n        at MutationObserver.Promise$_Deferred (<anonymous>:433:17)\n\nOn client side, long stack traces currently only work in recent Firefoxes, Chrome and Internet Explorer 10+.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.longStackTraces\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.longstacktraces\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.map.md",
    "content": "---\nlayout: api\nid: promise.map\ntitle: Promise.map\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.map\n\n```js\nPromise.map(\n    Iterable<any>|Promise<Iterable<any>> input,\n    function(any item, int index, int length) mapper,\n    [Object {concurrency: int=Infinity} options]\n) -> Promise\n```\n\nGiven a finite [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)\\(arrays are `Iterable`\\), or a promise of an `Iterable`, which produces promises (or a mix of promises and values), iterate over all the values in the `Iterable` into an array and [map the array to another](http://en.wikipedia.org/wiki/Map_\\(higher-order_function\\)) using the given `mapper` function.\n\nPromises returned by the `mapper` function are awaited for and the returned promise doesn't fulfill until all mapped promises have fulfilled as well. If any promise in the array is rejected, or any promise returned by the `mapper` function is rejected, the returned promise is rejected as well.\n\nThe mapper function for a given item is called as soon as possible, that is, when the promise for that item's index in the input array is fulfilled. This doesn't mean that the result array has items in random order, it means that `.map` can be used for concurrency coordination unlike `.all`.\n\nA common use of `Promise.map` is to replace the `.push`+`Promise.all` boilerplate:\n\n```js\nvar promises = [];\nfor (var i = 0; i < fileNames.length; ++i) {\n    promises.push(fs.readFileAsync(fileNames[i]));\n}\nPromise.all(promises).then(function() {\n    console.log(\"done\");\n});\n\n// Using Promise.map:\nPromise.map(fileNames, function(fileName) {\n    // Promise.map awaits for returned promises as well.\n    return fs.readFileAsync(fileName);\n}).then(function() {\n    console.log(\"done\");\n});\n\n// Using Promise.map and async/await:\nawait Promise.map(fileNames, function(fileName) {\n    // Promise.map awaits for returned promises as well.\n    return fs.readFileAsync(fileName);\n});\nconsole.log(\"done\");\n\n```\n\nA more involved example:\n\n```js\nvar Promise = require(\"bluebird\");\nvar join = Promise.join;\nvar fs = Promise.promisifyAll(require(\"fs\"));\nfs.readdirAsync(\".\").map(function(fileName) {\n    var stat = fs.statAsync(fileName);\n    var contents = fs.readFileAsync(fileName).catch(function ignore() {});\n    return join(stat, contents, function(stat, contents) {\n        return {\n            stat: stat,\n            fileName: fileName,\n            contents: contents\n        }\n    });\n// The return value of .map is a promise that is fulfilled with an array of the mapped values\n// That means we only get here after all the files have been statted and their contents read\n// into memory. If you need to do more operations per file, they should be chained in the map\n// callback for concurrency.\n}).call(\"sort\", function(a, b) {\n    return a.fileName.localeCompare(b.fileName);\n}).each(function(file) {\n    var contentLength = file.stat.isDirectory() ? \"(directory)\" : file.contents.length + \" bytes\";\n    console.log(file.fileName + \" last modified \" + file.stat.mtime + \" \" + contentLength)\n});\n```\n\n####Map Option: concurrency\n\nYou may optionally specify a concurrency limit:\n\n```js\n...map(..., {concurrency: 3});\n```\n\nThe concurrency limit applies to Promises returned by the mapper function and it basically limits the number of Promises created. For example, if `concurrency` is `3` and the mapper callback has been called enough so that there are three returned Promises currently pending, no further callbacks are called until one of the pending Promises resolves. So the mapper function will be called three times and it will be called again only after at least one of the Promises resolves.\n\nPlaying with the first example with and without limits, and seeing how it affects the duration when reading 20 files:\n\n```js\nvar Promise = require(\"bluebird\");\nvar join = Promise.join;\nvar fs = Promise.promisifyAll(require(\"fs\"));\nvar concurrency = parseFloat(process.argv[2] || \"Infinity\");\nconsole.time(\"reading files\");\nfs.readdirAsync(\".\").map(function(fileName) {\n    var stat = fs.statAsync(fileName);\n    var contents = fs.readFileAsync(fileName).catch(function ignore() {});\n    return join(stat, contents, function(stat, contents) {\n        return {\n            stat: stat,\n            fileName: fileName,\n            contents: contents\n        }\n    });\n// The return value of .map is a promise that is fulfilled with an array of the mapped values\n// That means we only get here after all the files have been statted and their contents read\n// into memory. If you need to do more operations per file, they should be chained in the map\n// callback for concurrency.\n}, {concurrency: concurrency}).call(\"sort\", function(a, b) {\n    return a.fileName.localeCompare(b.fileName);\n}).then(function() {\n    console.timeEnd(\"reading files\");\n});\n```\n\n```bash\n$ sync && echo 3 > /proc/sys/vm/drop_caches\n$ node test.js 1\nreading files 35ms\n$ sync && echo 3 > /proc/sys/vm/drop_caches\n$ node test.js Infinity\nreading files: 9ms\n```\n\nThe order `map` calls the mapper function on the array elements is not specified, there is no guarantee on the order in which it'll execute the `map`er on the elements. For order guarantee in sequential execution - see [Promise.mapSeries](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.map\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.map\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.mapseries.md",
    "content": "---\nlayout: api\nid: promise.mapseries\ntitle: Promise.mapSeries\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.mapSeries\n\n```js\nPromise.mapSeries(\n    Iterable<any>|Promise<Iterable<any>> input,\n    function(any value, int index, int arrayLength) mapper\n) -> Promise<Array<any>>\n```\n\nGiven an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) (an array, for example), or a promise of an `Iterable`, iterates serially over all the values in it, executing the given `mapper` on each element. If an element is a promise, the mapper will wait for it before proceeding. The `mapper` function has signature `(value, index, arrayLength)` where `value` is the current element (or its resolved value if it is a promise).\n\nIf, at any step:\n\n* The mapper returns a promise or a thenable, it is awaited before continuing to the next iteration.\n\n* The current element of the iteration is a *pending* promise, that promise will be awaited before running the mapper.\n\n* The current element of the iteration is a *rejected* promise, the iteration will stop and be rejected as well (with the same reason).\n\nIf all iterations resolve successfully, the `Promise.mapSeries` call resolves to a new array containing the results of each `mapper` execution, in order.\n\n`Promise.mapSeries` is very similar to [Promise.each](.). The difference between `Promise.each` and `Promise.mapSeries` is their resolution value. `Promise.mapSeries` resolves with an array as explained above, while `Promise.each` resolves with an array containing the *resolved values of the input elements* (ignoring the outputs of the iteration steps). This way, `Promise.each` is meant to be mainly used for side-effect operations (since the outputs of the iterator are essentially discarded), just like the native `.forEach()` method of arrays, while `Promise.map` is meant to be used as an async version of the native `.map()` method of arrays.\n\nBasic example:\n\n```js\n// The array to be mapped over can be a mix of values and promises.\nvar fileNames = [\"1.txt\", Promise.resolve(\"2.txt\"), \"3.txt\", Promise.delay(3000, \"4.txt\"), \"5.txt\"];\n\nPromise.mapSeries(fileNames, function(fileName, index, arrayLength) {\n    // The iteration will be performed sequentially, awaiting for any\n    // promises in the process.\n    return fs.readFileAsync(fileName).then(function(fileContents) {\n        // ...\n        return fileName + \"!\";\n    });\n}).then(function(result) {\n    // This will run after the last step is done\n    console.log(\"Done!\")\n    console.log(result); // [\"1.txt!\", \"2.txt!\", \"3.txt!\", \"4.txt!\", \"5.txt!\"]\n});\n```\n\nExample with a rejected promise in the array:\n\n```js\n// If one of the promises in the original array rejects,\n// the iteration will stop once it reaches it\nvar items = [\"A\", Promise.delay(8000, \"B\"), Promise.reject(\"C\"), \"D\"];\n\nPromise.each(items, function(item) {\n    return Promise.delay(4000).then(function() {\n        console.log(\"On mapper: \" + item);\n    });\n}).then(function(result) {\n    // This not run\n}).catch(function(rejection) {\n    console.log(\"Catch: \" + rejection);\n});\n\n// The code above outputs the following after 12 seconds (not 16!):\n// On mapper: A\n// On mapper: B\n// Catch: C\n```\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.mapSeries\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.mapSeries\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.method.md",
    "content": "---\nlayout: api\nid: promise.method\ntitle: Promise.method\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.method\n\n```js\nPromise.method(function(...arguments) fn) -> function\n```\n\n\nReturns a new function that wraps the given function `fn`. The new function will always return a promise that is fulfilled with the original functions return values or rejected with thrown exceptions from the original function.\n\nThis method is convenient when a function can sometimes return synchronously or throw synchronously.\n\nExample without using `Promise.method`:\n\n```js\nMyClass.prototype.method = function(input) {\n    if (!this.isValid(input)) {\n        return Promise.reject(new TypeError(\"input is not valid\"));\n    }\n\n    if (this.cache(input)) {\n        return Promise.resolve(this.someCachedValue);\n    }\n\n    return db.queryAsync(input).bind(this).then(function(value) {\n        this.someCachedValue = value;\n        return value;\n    });\n};\n```\n\nUsing the same function `Promise.method`, there is no need to manually wrap direct return or throw values into a promise:\n\n```js\nMyClass.prototype.method = Promise.method(function(input) {\n    if (!this.isValid(input)) {\n        throw new TypeError(\"input is not valid\");\n    }\n\n    if (this.cache(input)) {\n        return this.someCachedValue;\n    }\n\n    return db.queryAsync(input).bind(this).then(function(value) {\n        this.someCachedValue = value;\n        return value;\n    });\n});\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.method\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.method\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/promise.noconflict.md",
    "content": "---\nlayout: api\nid: promise.noconflict\ntitle: Promise.noConflict\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.noConflict\n\n```js\nPromise.noConflict() -> Object\n```\n\n\nThis is relevant to browser environments with no module loader.\n\nRelease control of the `Promise` namespace to whatever it was before this library was loaded. Returns a reference to the library namespace so you can attach it to something else.\n\n```html\n<!-- the other promise library must be loaded first -->\n<script type=\"text/javascript\" src=\"/scripts/other_promise.js\"></script>\n<script type=\"text/javascript\" src=\"/scripts/bluebird_debug.js\"></script>\n<script type=\"text/javascript\">\n//Release control right after\nvar Bluebird = Promise.noConflict();\n\n//Cast a promise from some other Promise library using the Promise namespace to Bluebird:\nvar promise = Bluebird.resolve(new Promise());\n</script>\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.noConflict\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.noconflict\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/promise.onpossiblyunhandledrejection.md",
    "content": "---\nlayout: api\nid: promise.onpossiblyunhandledrejection\ntitle: Promise.onPossiblyUnhandledRejection\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.onPossiblyUnhandledRejection\n\n```js\nPromise.onPossiblyUnhandledRejection(function(any error, Promise promise) handler) -> undefined\n```\n\n\n*Note: this hook is specific to the bluebird instance it's called on, application developers should use [global rejection events](/docs/api/error-management-configuration.html#global-rejection-events)*\n\nAdd `handler` as the handler to call when there is a possibly unhandled rejection. The default handler logs the error stack to stderr or `console.error` in browsers.\n\n```js\nPromise.onPossiblyUnhandledRejection(function(e, promise) {\n    throw e;\n});\n```\n\nPassing no value or a non-function will have the effect of removing any kind of handling for possibly unhandled rejections.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.onPossiblyUnhandledRejection\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.onpossiblyunhandledrejection\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.onunhandledrejectionhandled.md",
    "content": "---\nlayout: api\nid: promise.onunhandledrejectionhandled\ntitle: Promise.onUnhandledRejectionHandled\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.onUnhandledRejectionHandled\n\n```js\nPromise.onUnhandledRejectionHandled(function(Promise promise) handler) -> undefined\n```\n\n\n*Note: this hook is specific to the bluebird instance its called on, application developers should use [global rejection events](/docs/api/error-management-configuration.html#global-rejection-events)*\n\nAdd `handler` as the handler to call when a rejected promise that was reported as \"possibly unhandled rejection\" became handled.\n\nTogether with `onPossiblyUnhandledRejection` these hooks can be used to implement a debugger that will show a list\nof unhandled promise rejections updated in real time as promises become handled.\n\nFor example:\n\n```js\nvar unhandledPromises = [];\nPromise.onPossiblyUnhandledRejection(function(reason, promise) {\n    unhandledPromises.push(promise);\n    //Update some debugger UI\n});\n\nPromise.onUnhandledRejectionHandled(function(promise) {\n    var index = unhandledPromises.indexOf(promise);\n    unhandledPromises.splice(index, 1);\n    //Update the debugger UI\n});\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.onUnhandledRejectionHandled\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.onunhandledrejectionhandled\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/promise.promisify.md",
    "content": "---\nlayout: api\nid: promise.promisify\ntitle: Promise.promisify\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.promisify\n\n```js\nPromise.promisify(\n    function(any arguments..., function callback) nodeFunction,\n    [Object {\n        multiArgs: boolean=false,\n        context: any=this\n    } options]\n) -> function\n```\n\nReturns a function that will wrap the given `nodeFunction`. Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function. The node function should conform to node.js convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument.\n\nIf the `nodeFunction` calls its callback with multiple success values, the fulfillment value will be the first fulfillment item.\n\nSetting `multiArgs` to `true` means the resulting promise will always fulfill with an array of the callback's success value(s). This is needed because promises only support a single success value while some callback API's have multiple success value. The default is to ignore all but the first success value of a callback function.\n\nIf you pass a `context`, the `nodeFunction` will be called as a method on the `context`.\n\nExample of promisifying the asynchronous `readFile` of node.js `fs`-module:\n\n```js\nvar readFile = Promise.promisify(require(\"fs\").readFile);\n\nreadFile(\"myfile.js\", \"utf8\").then(function(contents) {\n    return eval(contents);\n}).then(function(result) {\n    console.log(\"The result of evaluating myfile.js\", result);\n}).catch(SyntaxError, function(e) {\n    console.log(\"File had syntax error\", e);\n//Catch any other error\n}).catch(function(e) {\n    console.log(\"Error reading file\", e);\n});\n```\n\nNote that if the node function is a method of some object, you can pass the object as the second argument like so:\n\n```js\nvar redisGet = Promise.promisify(redisClient.get, {context: redisClient});\nredisGet('foo').then(function() {\n    //...\n});\n```\n\nBut this will also work:\n\n```js\nvar getAsync = Promise.promisify(redisClient.get);\ngetAsync.call(redisClient, 'foo').then(function() {\n    //...\n});\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.promisify\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.promisify\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.promisifyall.md",
    "content": "---\nlayout: api\nid: promise.promisifyall\ntitle: Promise.promisifyAll\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.promisifyAll\n\n```js\nPromise.promisifyAll(\n    Object target,\n    [Object {\n        suffix: String=\"Async\",\n        multiArgs: boolean=false,\n        filter: boolean function(String name, function func, Object target, boolean passesDefaultFilter),\n        promisifier: function(function originalFunction, function defaultPromisifier)\n    } options]\n) -> Object\n```\n\nPromisifies the entire object by going through the object's properties and creating an async equivalent of each function on the object and its prototype chain. The promisified method name will be the original method name suffixed with `suffix` (default is `\"Async\"`). Any class properties of the object (which is the case for the main export of many modules) are also promisified, both static and instance methods. Class property is a property with a function value that has a non-empty `.prototype` object. Returns the input object.\n\nNote that the original methods on the object are not overwritten but new methods are created with the `Async`-suffix. For example, if you `promisifyAll` the node.js `fs` object use `fs.statAsync` to call the promisified `stat` method.\n\nExample:\n\n```js\nPromise.promisifyAll(require(\"redis\"));\n\n//Later on, all redis client instances have promise returning functions:\n\nredisClient.hexistsAsync(\"myhash\", \"field\").then(function(v) {\n\n}).catch(function(e) {\n\n});\n```\n\nIt also works on singletons or specific instances:\n\n```js\nvar fs = Promise.promisifyAll(require(\"fs\"));\n\nfs.readFileAsync(\"myfile.js\", \"utf8\").then(function(contents) {\n    console.log(contents);\n}).catch(function(e) {\n    console.error(e.stack);\n});\n```\n\nSee [promisification](#promisification) for more examples.\n\nThe entire prototype chain of the object is promisified on the object. Only enumerable are considered. If the object already has a promisified version of the method, it will be skipped. The target methods are assumed to conform to node.js callback convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument. If the node method calls its callback with multiple success values, the fulfillment value will be an array of them.\n\nIf a method name already has an `\"Async\"`-suffix, an exception will be thrown.\n\n####Option: suffix\n\nOptionally, you can define a custom suffix through the options object:\n\n```js\nvar fs = Promise.promisifyAll(require(\"fs\"), {suffix: \"MySuffix\"});\nfs.readFileMySuffix(...).then(...);\n```\n\nAll the above limitations apply to custom suffices:\n\n- Choose the suffix carefully, it must not collide with anything\n- PascalCase the suffix\n- The suffix must be a valid JavaScript identifier using ASCII letters\n- Always use the same suffix everywhere in your application, you could create a wrapper to make this easier:\n\n```js\nmodule.exports = function myPromisifyAll(target) {\n    return Promise.promisifyAll(target, {suffix: \"MySuffix\"});\n};\n```\n\n####Option: multiArgs\n\nSetting `multiArgs` to `true` means the resulting promise will always fulfill with an array of the callback's success value(s). This is needed because promises only support a single success value while some callback API's have multiple success value. The default is to ignore all but the first success value of a callback function.\n\nIf a module has multiple argument callbacks as an exception rather than the rule, you can filter out the multiple argument methods in first go and then promisify rest of the module in second go:\n\n```js\nPromise.promisifyAll(something, {\n    filter: function(name) {\n        return name === \"theMultiArgMethodIwant\";\n    },\n    multiArgs: true\n});\n// Rest of the methods\nPromise.promisifyAll(something);\n```\n\n####Option: filter\n\nOptionally, you can define a custom filter through the options object:\n\n```js\nPromise.promisifyAll(..., {\n    filter: function(name, func, target, passesDefaultFilter) {\n        // name = the property name to be promisified without suffix\n        // func = the function\n        // target = the target object where the promisified func will be put with name + suffix\n        // passesDefaultFilter = whether the default filter would be passed\n        // return boolean (return value is coerced, so not returning anything is same as returning false)\n\n        return passesDefaultFilter && ...\n    }\n})\n```\n\nThe default filter function will ignore properties that start with a leading underscore, properties that are not valid JavaScript identifiers and constructor functions (function which have enumerable properties in their `.prototype`).\n\n\n####Option: promisifier\n\nOptionally, you can define a custom promisifier, so you could promisifyAll e.g. the chrome APIs used in Chrome extensions.\n\nThe promisifier gets a reference to the original method and should return a function which returns a promise.\n\n```js\nfunction DOMPromisifier(originalMethod) {\n    // return a function\n    return function promisified() {\n        var args = [].slice.call(arguments);\n        // Needed so that the original method can be called with the correct receiver\n        var self = this;\n        // which returns a promise\n        return new Promise(function(resolve, reject) {\n            args.push(resolve, reject);\n            originalMethod.apply(self, args);\n        });\n    };\n}\n\n// Promisify e.g. chrome.browserAction\nPromise.promisifyAll(chrome.browserAction, {promisifier: DOMPromisifier});\n\n// Later\nchrome.browserAction.getTitleAsync({tabId: 1})\n    .then(function(result) {\n\n    });\n```\n\nCombining `filter` with `promisifier` for the restler module to promisify event emitter:\n\n```js\nvar Promise = require(\"bluebird\");\nvar restler = require(\"restler\");\nvar methodNamesToPromisify = \"get post put del head patch json postJson putJson\".split(\" \");\n\nfunction EventEmitterPromisifier(originalMethod) {\n    // return a function\n    return function promisified() {\n        var args = [].slice.call(arguments);\n        // Needed so that the original method can be called with the correct receiver\n        var self = this;\n        // which returns a promise\n        return new Promise(function(resolve, reject) {\n            // We call the originalMethod here because if it throws,\n            // it will reject the returned promise with the thrown error\n            var emitter = originalMethod.apply(self, args);\n\n            emitter\n                .on(\"success\", function(data, response) {\n                    resolve([data, response]);\n                })\n                .on(\"fail\", function(data, response) {\n                    // Erroneous response like 400\n                    resolve([data, response]);\n                })\n                .on(\"error\", function(err) {\n                    reject(err);\n                })\n                .on(\"abort\", function() {\n                    reject(new Promise.CancellationError());\n                })\n                .on(\"timeout\", function() {\n                    reject(new Promise.TimeoutError());\n                });\n        });\n    };\n};\n\nPromise.promisifyAll(restler, {\n    filter: function(name) {\n        return methodNamesToPromisify.indexOf(name) > -1;\n    },\n    promisifier: EventEmitterPromisifier\n});\n\n// ...\n\n// Later in some other file\n\nvar restler = require(\"restler\");\nrestler.getAsync(\"http://...\", ...,).spread(function(data, response) {\n\n})\n```\n\nUsing `defaultPromisifier` parameter to add enhancements on top of normal node\npromisification:\n\n```js\nvar fs = Promise.promisifyAll(require(\"fs\"), {\n    promisifier: function(originalFunction, defaultPromisifer) {\n        var promisified = defaultPromisifier(originalFunction);\n\n        return function() {\n            // Enhance normal promisification by supporting promises as\n            // arguments\n\n            var args = [].slice.call(arguments);\n            var self = this;\n            return Promise.all(args).then(function(awaitedArgs) {\n                return promisified.apply(self, awaitedArgs);\n            });\n        };\n    }\n});\n\n// All promisified fs functions now await their arguments if they are promises\nvar version = fs.readFileAsync(\"package.json\", \"utf8\").then(JSON.parse).get(\"version\");\nfs.writeFileAsync(\"the-version.txt\", version, \"utf8\");\n```\n\n####Promisifying multiple classes in one go\n\nYou can promisify multiple classes in one go by constructing an array out of the classes and passing it to `promisifyAll`:\n\n```js\nvar Pool = require(\"mysql/lib/Pool\");\nvar Connection = require(\"mysql/lib/Connection\");\nPromise.promisifyAll([Pool, Connection]);\n```\n\nThis works because the array acts as a \"module\" where the indices are the \"module\"'s properties for classes.\n\n\n\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.promisifyAll\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.promisifyall\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.props.md",
    "content": "---\nlayout: api\nid: promise.props\ntitle: Promise.props\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.props\n\n```js\nPromise.props(Object|Map|Promise<Object|Map> input) -> Promise\n```\n\nLike [`.all`](.) but for object properties or `Map`s\\* entries instead of iterated values. Returns a promise that is fulfilled when all the properties of the object or the `Map`'s' values\\*\\* are fulfilled. The promise's fulfillment value is an object or a `Map` with fulfillment values at respective keys to the original object or a `Map`. If any promise in the object or `Map` rejects, the returned promise is rejected with the rejection reason.\n\nIf `object` is a trusted `Promise`, then it will be treated as a promise for object rather than for its properties. All other objects (except `Map`s) are treated for their properties as is returned by `Object.keys` - the object's own enumerable properties.\n\n*\\*Only the native [ECMAScript 6 `Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) implementation that is provided by the environment as is is supported*\n\n*\\*\\*If the map's keys happen to be `Promise`s, they are not awaited for and the resulting `Map` will still have those same `Promise` instances as keys*\n\n\n```js\nPromise.props({\n    pictures: getPictures(),\n    comments: getComments(),\n    tweets: getTweets()\n}).then(function(result) {\n    console.log(result.tweets, result.pictures, result.comments);\n});\n```\n\n```js\nvar Promise = require(\"bluebird\");\nvar fs = Promise.promisifyAll(require(\"fs\"));\nvar _ = require(\"lodash\");\nvar path = require(\"path\");\nvar util = require(\"util\");\n\nfunction directorySizeInfo(root) {\n    var counts = {dirs: 0, files: 0};\n    var stats = (function reader(root) {\n        return fs.readdirAsync(root).map(function(fileName) {\n            var filePath = path.join(root, fileName);\n            return fs.statAsync(filePath).then(function(stat) {\n                stat.filePath = filePath;\n                if (stat.isDirectory()) {\n                    counts.dirs++;\n                    return reader(filePath)\n                }\n                counts.files++;\n                return stat;\n            });\n        }).then(_.flatten);\n    })(root).then(_.chain);\n\n    var smallest = stats.call(\"min\", \"size\").call(\"pick\", \"size\", \"filePath\").call(\"value\");\n    var largest = stats.call(\"max\", \"size\").call(\"pick\", \"size\", \"filePath\").call(\"value\");\n    var totalSize = stats.call(\"pluck\", \"size\").call(\"reduce\", function(a, b) {\n        return a + b;\n    }, 0);\n\n    return Promise.props({\n        counts: counts,\n        smallest: smallest,\n        largest: largest,\n        totalSize: totalSize\n    });\n}\n\n\ndirectorySizeInfo(process.argv[2] || \".\").then(function(sizeInfo) {\n    console.log(util.format(\"                                                \\n\\\n        %d directories, %d files                                             \\n\\\n        Total size: %d bytes                                                 \\n\\\n        Smallest file: %s with %d bytes                                      \\n\\\n        Largest file: %s with %d bytes                                       \\n\\\n    \", sizeInfo.counts.dirs, sizeInfo.counts.files, sizeInfo.totalSize,\n        sizeInfo.smallest.filePath, sizeInfo.smallest.size,\n        sizeInfo.largest.filePath, sizeInfo.largest.size));\n});\n```\n\nNote that if you have no use for the result object other than retrieving the properties, it is more convenient to use [`Promise.join`](.):\n\n```js\nPromise.join(getPictures(), getComments(), getTweets(),\n    function(pictures, comments, tweets) {\n    console.log(pictures, comments, tweets);\n});\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.props\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.props\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.race.md",
    "content": "---\nlayout: api\nid: promise.race\ntitle: Promise.race\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.race\n\n```js\nPromise.race(Iterable<any>|Promise<Iterable<any>> input) -> Promise\n```\n\nGiven an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)\\(arrays are `Iterable`\\), or a promise of an `Iterable`, which produces promises (or a mix of promises and values), iterate over all the values in the `Iterable` into an array and return a promise that is fulfilled or rejected as soon as a promise in the array is fulfilled or rejected with the respective rejection reason or fulfillment value.\n\nThis method is only implemented because it's in the ES6 standard. If you want to race promises to fulfillment the [`.any`](.) method is more appropriate as it doesn't qualify a rejected promise as the winner. It also has less surprises: `.race` must become infinitely pending if an empty array is passed but passing an empty array to [`.any`](.) is more usefully a `RangeError`\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.race\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.race\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/promise.reduce.md",
    "content": "---\nlayout: api\nid: promise.reduce\ntitle: Promise.reduce\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.reduce\n\n```js\nPromise.reduce(\n    Iterable<any>|Promise<Iterable<any>> input,\n    function(any accumulator, any item, int index, int length) reducer,\n    [any initialValue]\n) -> Promise\n```\n\nGiven an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)\\(arrays are `Iterable`\\), or a promise of an `Iterable`, which produces promises (or a mix of promises and values), iterate over all the values in the `Iterable` into an array and [reduce the array to a value](http://en.wikipedia.org/wiki/Fold_\\(higher-order_function\\)) using the given `reducer` function.\n\nIf the reducer function returns a promise, then the result of the promise is awaited, before continuing with next iteration. If any promise in the array is rejected or a promise returned by the reducer function is rejected, the result is rejected as well.\n\nRead given files sequentially while summing their contents as an integer. Each file contains just the text `10`.\n\n```js\nPromise.reduce([\"file1.txt\", \"file2.txt\", \"file3.txt\"], function(total, fileName) {\n    return fs.readFileAsync(fileName, \"utf8\").then(function(contents) {\n        return total + parseInt(contents, 10);\n    });\n}, 0).then(function(total) {\n    //Total is 30\n});\n```\n\n*If `initialValue` is `undefined` (or a promise that resolves to `undefined`) and the iterable contains only 1 item, the callback will not be called and the iterable's single item is returned. If the iterable is empty, the callback will not be called and `initialValue` is returned (which may be `undefined`).*\n\n`Promise.reduce` will start calling the reducer as soon as possible, this is why you might want to use it over `Promise.all` (which awaits for the entire array before you can call [`Array#reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) on it).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.reduce\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.reduce\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.reject.md",
    "content": "---\nlayout: api\nid: promise.reject\ntitle: Promise.reject\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.reject\n\n```js\nPromise.reject(any error) -> Promise\n```\n\n\nCreate a promise that is rejected with the given `error`.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.reject\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.reject\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/promise.resolve.md",
    "content": "---\nlayout: api\nid: promise.resolve\ntitle: Promise.resolve\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n    \n## Promise.resolve\n\n```js\nPromise.resolve(Promise<any>|any value) -> Promise\n```\n\n\nCreate a promise that is resolved with the given value. If `value` is already a trusted `Promise`, it is returned as is. If `value` is not a thenable, a fulfilled Promise is returned with `value` as its fulfillment value. If `value` is a thenable (Promise-like object, like those returned by jQuery's `$.ajax`), returns a trusted Promise that assimilates the state of the thenable.\n\nThis can be useful if a function returns a promise (say into a chain) but can optionally return a static value. Say, for a lazy-loaded value. Example:\n\n```js\nvar someCachedValue;\n\nvar getValue = function() {\n    if (someCachedValue) {\n        return Promise.resolve(someCachedValue);\n    }\n\n    return db.queryAsync().then(function(value) {\n        someCachedValue = value;\n        return value;\n    });\n};\n```\n\nAnother example with handling jQuery castable objects (`$` is jQuery)\n\n```js\nPromise.resolve($.get(\"http://www.google.com\")).then(function() {\n    //Returning a thenable from a handler is automatically\n    //cast to a trusted Promise as per Promises/A+ specification\n    return $.post(\"http://www.yahoo.com\");\n}).then(function() {\n\n}).catch(function(e) {\n    //jQuery doesn't throw real errors so use catch-all\n    console.log(e.statusText);\n});\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.resolve\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.resolve\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.setscheduler.md",
    "content": "---\nlayout: api\nid: promise.setscheduler\ntitle: Promise.setScheduler\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.setScheduler\n\n```js\nPromise.setScheduler(function(function fn) scheduler) -> function\n```\n\n\nScheduler should be a function that asynchronously schedules the calling of the passed in function:\n\n```js\n// This is just an example of how to use the api, there is no reason to do this\nPromise.setScheduler(function(fn) {\n    setTimeout(fn, 0);\n});\n```\n\nSetting a custom scheduler could be necessary when you need a faster way to schedule functions than bluebird does by default. It also makes bluebird possible to use in platforms where normal timing constructs like `setTimeout` and `process.nextTick` are not available (like Nashhorn).\n\nYou can also use it as a hook:\n\n```js\n// This will synchronize bluebird promise queue flushing with angulars queue flushing\n// Angular is also now responsible for choosing the actual scheduler\nPromise.setScheduler(function(fn) {\n    $rootScope.$evalAsync(fn);\n});\n```\n\n> **Danger** - in order to keep bluebird promises [Promises/A+](https://promisesaplus.com/) compliant a scheduler that executes the function asynchronously (like the examples in this page) must be used. \n\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.setScheduler\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.setscheduler\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.some.md",
    "content": "---\nlayout: api\nid: promise.some\ntitle: Promise.some\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.some\n\n```js\nPromise.some(\n    Iterable<any>|Promise<Iterable<any>> input,\n    int count\n) -> Promise\n```\n\nGiven an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)\\(arrays are `Iterable`\\), or a promise of an `Iterable`, which produces promises (or a mix of promises and values), iterate over all the values in the `Iterable` into an array and return a promise that is fulfilled as soon as `count` promises are fulfilled in the array. The fulfillment value is an array with `count` values in the order they were fulfilled.\n\nThis example pings 4 nameservers, and logs the fastest 2 on console:\n\n```js\nPromise.some([\n    ping(\"ns1.example.com\"),\n    ping(\"ns2.example.com\"),\n    ping(\"ns3.example.com\"),\n    ping(\"ns4.example.com\")\n], 2).spread(function(first, second) {\n    console.log(first, second);\n});\n```\n\nIf too many promises are rejected so that the promise can never become fulfilled, it will be immediately rejected with an [AggregateError](.) of the rejection reasons in the order they were thrown in.\n\nYou can get a reference to [AggregateError](.) from `Promise.AggregateError`.\n\n```js\nPromise.some(...)\n    .then(...)\n    .then(...)\n    .catch(Promise.AggregateError, function(err) {\n        err.forEach(function(e) {\n            console.error(e.stack);\n        });\n    });\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.some\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.some\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promise.try.md",
    "content": "---\nlayout: api\nid: promise.try\ntitle: Promise.try\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.try\n\n```js\nPromise.try(function() fn) -> Promise\n```\n```js\nPromise.attempt(function() fn) -> Promise\n```\n\n\nStart the chain of promises with `Promise.try`. Any synchronous exceptions will be turned into rejections on the returned promise.\n\n```js\nfunction getUserById(id) {\n    return Promise.try(function() {\n        if (typeof id !== \"number\") {\n            throw new Error(\"id must be a number\");\n        }\n        return db.getUserById(id);\n    });\n}\n```\n\nNow if someone uses this function, they will catch all errors in their Promise `.catch` handlers instead of having to handle both synchronous and asynchronous exception flows.\n\n*For compatibility with earlier ECMAScript version, an alias `Promise.attempt` is provided for [`Promise.try`](.).*\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.try\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.try\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/promise.using.md",
    "content": "---\nlayout: api\nid: promise.using\ntitle: Promise.using\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promise.using\n\n```js\nPromise.using(\n    Promise|Disposer|any resource,\n    Promise|Disposer|any resource...,\n    function(any resources...) handler\n) -> Promise\n```\n```js\nPromise.using(\n    Array<Promise|Disposer|Any> resources,\n    function(Array<any> resources) handler\n) -> Promise\n```\n\n\nIn conjunction with [`.disposer`](.), `using` will make sure that no matter what, the specified disposer will be called when the promise returned by the callback passed to `using` has settled. The disposer is necessary because there is no standard interface in node for disposing resources.\n\nHere is a simple example (where `getConnection()` has been defined to return a proper Disposer object)\n\n```js\nusing(getConnection(), function(connection) {\n   // Don't leak the `connection` variable anywhere from here\n   // it is only guaranteed to be open while the promise returned from\n   // this callback is still pending\n   return connection.queryAsync(\"SELECT * FROM TABLE\");\n   // Code that is chained from the promise created in the line above\n   // still has access to `connection`\n}).then(function(rows) {\n    // The connection has been closed by now\n    console.log(rows);\n});\n```\n\nUsing multiple resources:\n\n```js\nusing(getConnection(), function(conn1) {\n    return using(getConnection(), function(conn2) {\n        // use conn1 and conn 2 here\n    });\n}).then(function() {\n    // Both connections closed by now\n})\n```\n\nThe above can also be written as (with a caveat, see below)\n\n```js\nusing(getConnection(), getConnection(), function(conn1, conn2) {\n    // use conn1 and conn2\n}).then(function() {\n    // Both connections closed by now\n})\n```\n\nHowever, if the second `getConnection` throws **synchronously**, the first connection is leaked. This will not happen\nwhen using APIs through bluebird promisified methods though. You can wrap functions that could throw in [`Promise.method`](.) which will turn synchronous rejections into rejected promises.\n\nNote that you can mix promises and disposers, so that you can acquire all the things you need in parallel instead of sequentially\n\n```js\n// The files don't need resource management but you should\n// still start the process of reading them even before you have the connection\n// instead of waiting for the connection\n\n// The connection is always closed, no matter what fails at what point\nusing(readFile(\"1.txt\"), readFile(\"2.txt\"), getConnection(), function(txt1, txt2, conn) {\n    // use conn and have access to txt1 and txt2\n});\n```\n\n\n<hr>\n\nYou can also pass the resources in an array in the first argument. In this case the handler function will only be called with one argument that is the array containing the resolved resources in respective positions in the array. Example:\n\n```js\nvar connectionPromises = [getConnection(), getConnection()];\n\nusing(connectionPromises, function(connections) {\n    var conn1 = connections[0];\n    var conn2 = connections[1];\n    // use conn1 and conn2\n}).then(function() {\n    // Both connections closed by now\n})\n\n```\n\n\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promise.using\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promise.using\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/promiseinspection.md",
    "content": "---\nlayout: api\nid: promiseinspection\ntitle: PromiseInspection\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##PromiseInspection\n\n```js\ninterface PromiseInspection {\n    any reason()\n    any value()\n    boolean isPending()\n    boolean isRejected()\n    boolean isFulfilled()\n    boolean isCancelled()\n}\n```\n\nThis interface is implemented by `Promise` instances as well as the `PromiseInspection` result given by [.reflect()](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"PromiseInspection\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promiseinspection\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/promisification.md",
    "content": "---\nlayout: api\nid: promisification\ntitle: Promisification\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Promisification\n\nPromisification means converting an existing promise-unaware API to a promise-returning API.\n\nThe usual way to use promises in node is to [Promise.promisifyAll](.) some API and start exclusively calling promise returning versions of the APIs methods. E.g.\n\n```js\nvar fs = require(\"fs\");\nPromise.promisifyAll(fs);\n// Now you can use fs as if it was designed to use bluebird promises from the beginning\n\nfs.readFileAsync(\"file.js\", \"utf8\").then(...)\n```\n\nNote that the above is an exceptional case because `fs` is a singleton instance. Most libraries can be promisified by requiring the library's classes (constructor functions) and calling promisifyAll on the `.prototype`. This only needs to be done once in the entire application's lifetime and after that you may use the library's methods exactly as they are documented, except by appending the `\"Async\"`-suffix to method calls and using the promise interface instead of the callback interface.\n\nAs a notable exception in `fs`, `fs.existsAsync` doesn't work as expected, because Node's `fs.exists` doesn't call back with error as first argument.  More at [#418](.).  One possible workaround is using `fs.statAsync`.\n\nSome examples of the above practice applied to some popular libraries:\n\n```js\n// The most popular redis module\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"redis\"));\n```\n\n```js\n// The most popular mongodb module\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"mongodb\"));\n```\n\n```js\n// The most popular mysql module\nvar Promise = require(\"bluebird\");\n// Note that the library's classes are not properties of the main export\n// so we require and promisifyAll them manually\nPromise.promisifyAll(require(\"mysql/lib/Connection\").prototype);\nPromise.promisifyAll(require(\"mysql/lib/Pool\").prototype);\n```\n\n```js\n// Mongoose\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"mongoose\"));\n```\n\n```js\n// Request\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"request\"));\n// Use request.getAsync(...) not request(..), it will not return a promise\n```\n\n```js\n// mkdir\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"mkdirp\"));\n// Use mkdirp.mkdirpAsync not mkdirp(..), it will not return a promise\n```\n\n```js\n// winston\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"winston\"));\n```\n\n```js\n// rimraf\nvar Promise = require(\"bluebird\");\n// The module isn't promisified but the function returned is\nvar rimrafAsync = Promise.promisify(require(\"rimraf\"));\n```\n\n```js\n// xml2js\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"xml2js\"));\n```\n\n```js\n// jsdom\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"jsdom\"));\n```\n\n```js\n// fs-extra\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"fs-extra\"));\n```\n\n```js\n// prompt\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"prompt\"));\n```\n\n```js\n// Nodemailer\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"nodemailer\"));\n```\n\n```js\n// ncp\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"ncp\"));\n```\n\n```js\n// pg\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"pg\"));\n```\n\nIn all of the above cases the library made its classes available in one way or another. If this is not the case, you can still promisify by creating a throwaway instance:\n\n```js\nvar ParanoidLib = require(\"...\");\nvar throwAwayInstance = ParanoidLib.createInstance();\nPromise.promisifyAll(Object.getPrototypeOf(throwAwayInstance));\n// Like before, from this point on, all new instances + even the throwAwayInstance suddenly support promises\n```\n\nSee also [`Promise.promisifyAll`](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Promisification\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-promisification\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/props.md",
    "content": "---\nlayout: api\nid: props\ntitle: .props\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.props\n\n```js\n.props() -> Promise\n```\n\nSame as [Promise.props(this)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".props\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-props\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/race.md",
    "content": "---\nlayout: api\nid: race\ntitle: .race\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.race\n\n```js\n.race() -> Promise\n```\n\nSame as [Promise.race(this)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".race\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-race\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/reason.md",
    "content": "---\nlayout: api\nid: reason\ntitle: .reason\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.reason\n\n```js\n.reason() -> any\n```\n\n\nGet the rejection reason of this promise. Throws an error if the promise isn't rejected - it is a bug to call this method on an unrejected promise.\n\nYou should check if this promise is [.isRejected()](.) in code paths where it's guaranteed that this promise is rejected.\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".reason\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-reason\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/reduce.md",
    "content": "---\nlayout: api\nid: reduce\ntitle: .reduce\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.reduce\n\n```js\n.reduce(\n    function(any accumulator, any item, int index, int length) reducer,\n    [any initialValue]\n) -> Promise\n```\n\nSame as [Promise.reduce(this, reducer, initialValue)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".reduce\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-reduce\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/reflect.md",
    "content": "---\nlayout: api\nid: reflect\ntitle: .reflect\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.reflect\n\n```js\n.reflect() -> Promise<PromiseInspection>\n```\n\n\nThe [`.reflect`](.) method returns a promise that is always successful when this promise is settled. Its fulfillment value is an object that implements the [PromiseInspection](.) interface and reflects the resolution of this promise.\n\nUsing `.reflect()` to implement `settleAll` (wait until all promises in an array are either rejected or fulfilled) functionality\n\n```js\nvar promises = [getPromise(), getPromise(), getPromise()];\nPromise.all(promises.map(function(promise) {\n    return promise.reflect();\n})).each(function(inspection) {\n    if (inspection.isFulfilled()) {\n        console.log(\"A promise in the array was fulfilled with\", inspection.value());\n    } else {\n        console.error(\"A promise in the array was rejected with\", inspection.reason());\n    }\n});\n```\n\nUsing `.reflect()` to implement `settleProps` (like settleAll for an object's properties) functionality\n\n```js\nvar object = {\n    first: getPromise1(),\n    second: getPromise2()\n};\nPromise.props(Object.keys(object).reduce(function(newObject, key) {\n    newObject[key] = object[key].reflect();\n    return newObject;\n}, {})).then(function(object) {\n    if (object.first.isFulfilled()) {\n        console.log(\"first was fulfilled with\", object.first.value());\n    } else {\n        console.error(\"first was rejected with\", object.first.reason());\n    }\n})\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".reflect\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-reflect\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/resource-management.md",
    "content": "---\nlayout: api\nid: resource-management\ntitle: Resource management\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Resource management\n\nManaging resources properly without leaks can be challenging. Simply using `.finally` is not enough as the following example demonstrates:\n\n```js\nfunction doStuff() {\n    return Promise.all([\n        connectionPool.getConnectionAsync(),\n        fs.readFileAsync(\"file.sql\", \"utf8\")\n    ]).spread(function(connection, fileContents) {\n        return connection.query(fileContents).finally(function() {\n            connection.close();\n        });\n    }).then(function() {\n        console.log(\"query successful and connection closed\");\n    });\n}\n```\n\nIt is very subtle but over time this code will exhaust the entire connection pool and the server needs to be restarted. This is because\nreading the file may fail and then of course `.spread` is not called at all and thus the connection is not closed.\n\nOne could solve this by either reading the file first or connecting first, and only proceeding if the first step succeeds. However,\nthis would lose a lot of the benefits of using asynchronity and we might almost as well go back to using simple synchronous code.\n\nWe can do better, retaining concurrency and not leaking resources, by using:\n\n* [disposers](disposer.html), objects that wrap a resource and a method to release that resource, together with  \n* [`Promise.using`](promise.using.html), a function to safely use disposers in a way that automatically calls their release method\n\n```js\nvar using = Promise.using;\n\nusing(getConnection(),\n      fs.readFileAsync(\"file.sql\", \"utf8\"), function(connection, fileContents) {\n    return connection.query(fileContents);\n}).then(function() {\n    console.log(\"query successful and connection closed\");\n});\n```\n\nContinue by reading about [disposers](disposer.html) and [`Promise.using`](promise.using.html)\n\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Resource management\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-resource-management\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/return.md",
    "content": "---\nlayout: api\nid: return\ntitle: .return\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.return\n\n```js\n.return(any value) -> Promise\n```\n```js\n.thenReturn(any value) -> Promise\n```\n\nConvenience method for:\n\n```js\n.then(function() {\n   return value;\n});\n```\n\nin the case where `value` doesn't change its value because its binding time is different than when using a closure.\n\nThat means `value` is bound at the time of calling [`.return`](.) so this will not work as expected:\n\n```js\nfunction getData() {\n    var data;\n\n    return query().then(function(result) {\n        data = result;\n    }).return(data);\n}\n```\n\nbecause `data` is `undefined` at the time `.return` is called.\n\nFunction that returns the full path of the written file:\n\n```js\nvar Promise = require(\"bluebird\");\nvar fs = Promise.promisifyAll(require(\"fs\"));\nvar baseDir = process.argv[2] || \".\";\n\nfunction writeFile(path, contents) {\n    var fullpath = require(\"path\").join(baseDir, path);\n    return fs.writeFileAsync(fullpath, contents).return(fullpath);\n}\n\nwriteFile(\"test.txt\", \"this is text\").then(function(fullPath) {\n    console.log(\"Successfully file at: \" + fullPath);\n});\n```\n\n*For compatibility with earlier ECMAScript version, an alias `.thenReturn` is provided for [`.return`](.).*\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".return\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-return\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/some.md",
    "content": "---\nlayout: api\nid: some\ntitle: .some\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.some\n\n```js\n.some(int count) -> Promise\n```\n\nSame as [Promise.some(this, count)](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".some\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-some\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/spread.md",
    "content": "---\nlayout: api\nid: spread\ntitle: .spread\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.spread\n\n```js\n.spread(\n    [function(any values...) fulfilledHandler]\n) -> Promise\n```\n\n\nLike calling `.then`, but the fulfillment value _must be_ an array, which is flattened to the formal parameters of the fulfillment handler.\n\n```js\nPromise.all([\n    fs.readFileAsync(\"file1.txt\"),\n    fs.readFileAsync(\"file2.txt\")\n]).spread(function(file1text, file2text) {\n    if (file1text === file2text) {\n        console.log(\"files are equal\");\n    }\n    else {\n        console.log(\"files are not equal\");\n    }\n});\n```\n\nWhen chaining `.spread`, returning an array of promises also works:\n\n```js\nPromise.delay(500).then(function() {\n   return [fs.readFileAsync(\"file1.txt\"),\n           fs.readFileAsync(\"file2.txt\")] ;\n}).spread(function(file1text, file2text) {\n    if (file1text === file2text) {\n        console.log(\"files are equal\");\n    }\n    else {\n        console.log(\"files are not equal\");\n    }\n});\n```\n\nNote that if using ES6, the above can be replaced with [.then()](.) and destructuring:\n\n```js\nPromise.delay(500).then(function() {\n   return [fs.readFileAsync(\"file1.txt\"),\n           fs.readFileAsync(\"file2.txt\")] ;\n}).all().then(function([file1text, file2text]) {\n    if (file1text === file2text) {\n        console.log(\"files are equal\");\n    }\n    else {\n        console.log(\"files are not equal\");\n    }\n});\n```\n\nNote that [.spread()](.) implicitly does [.all()](.) but the ES6 destructuring syntax doesn't, hence the manual `.all()` call in the above code.\n\nIf you want to coordinate several discrete concurrent promises, use [`Promise.join`](.)\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".spread\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-spread\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/suppressunhandledrejections.md",
    "content": "---\nlayout: api\nid: suppressunhandledrejections\ntitle: .suppressUnhandledRejections\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.suppressUnhandledRejections\n\n```js\n.suppressUnhandledRejections() -> undefined\n```\n\nBasically sugar for doing:\n\n```js\nsomePromise.catch(function(){});\n```\n\nWhich is needed in case error handlers are attached asynchronously to the promise later, which would otherwise result in premature unhandled rejection reporting.\n\nExample:\n\n```js\nvar tweets = fetchTweets();\n$(document).on(\"ready\", function() {\n    tweets.then(function() {\n        // Render tweets\n    }).catch(function(e) {\n        alert(\"failed to fetch tweets because: \" + e);\n    });\n});\n```\n\nIf fetching tweets fails before the document is ready the rejection is reported as unhandled even though it will be eventually handled when the document is ready. This is of course impossible to determine automatically, but you can explicitly do so using `.suppressUnhandledRejections()`:\n\n```js\nvar tweets = fetchTweets();\ntweets.suppressUnhandledRejections();\n$(document).on(\"ready\", function() {\n    tweets.then(function() {\n        // Render tweets\n    }).catch(function(e) {\n        alert(\"failed to fetch tweets because: \" + e);\n    });\n});\n```\n\nIt should be noted that there is no real need to attach the handlers asynchronously. Exactly the same effect can be achieved with:\n\n```js\nfetchTweets()\n    .finally(function() {\n        return $.ready.promise();\n    })\n    // DOM guaranteed to be ready after this point\n    .then(function() {\n        // Render tweets\n    })\n    .catch(function(e) {\n        alert(\"failed to fetch tweets because: \" + e);\n    });\n```\n\nThe advantage of using `.suppressUnhandledRejections()` over `.catch(function(){})` is that it doesn't increment the branch count of the promise. Branch counts matter when using cancellation because a promise will only be cancelled if all of its branches want to cancel it.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".suppressUnhandledRejections\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-suppressunhandledrejections\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/synchronous-inspection.md",
    "content": "---\nlayout: api\nid: synchronous-inspection\ntitle: Synchronous inspection\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Synchronous inspection\n\nOften it is known in certain code paths that a promise is guaranteed to be fulfilled at that point - it would then be extremely inconvenient to use [`.then`](.) to get at the promise's value as the callback is always called asynchronously.\n\n\n**Note**: In recent versions of Bluebird a design choice was made to expose [.reason()](.) and [.value()](.) as well as other inspection methods on promises directly in order to make the below use case easier to work with. Every promise implements the [PromiseInspection](.) interface.\n\nFor example, if you need to use values of earlier promises in the chain, you could nest:\n\n\n```js\n// From Q Docs https://github.com/kriskowal/q/#chaining\n// MIT License Copyright 2009–2014 Kristopher Michael Kowal.\nfunction authenticate() {\n    return getUsername().then(function (username) {\n        return getUser(username);\n    // chained because we will not need the user name in the next event\n    }).then(function (user) {\n        // nested because we need both user and password next\n        return getPassword().then(function (password) {\n            if (user.passwordHash !== hash(password)) {\n                throw new Error(\"Can't authenticate\");\n            }\n        });\n    });\n}\n```\n\nOr you could take advantage of the fact that if we reach password validation, then the user promise must be fulfilled:\n\n```js\nfunction authenticate() {\n    var user = getUsername().then(function(username) {\n        return getUser(username);\n    });\n\n    return user.then(function(user) {\n        return getPassword();\n    }).then(function(password) {\n        // Guaranteed that user promise is fulfilled, so .value() can be called here\n        if (user.value().passwordHash !== hash(password)) {\n            throw new Error(\"Can't authenticate\");\n        }\n    });\n}\n```\n\nIn the latter the indentation stays flat no matter how many previous variables you need, whereas with the former each additional previous value would require an additional nesting level.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Synchronous inspection\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-synchronous-inspection\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/tap.md",
    "content": "---\nlayout: api\nid: tap\ntitle: .tap\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.tap\n\n```js\n.tap(function(any value) handler) -> Promise\n```\nEssentially like `.then()`, except that the value passed in is the value returned.\n\nThis means you can insert `.tap()` into a `.then()` chain without affecting what is passed through the chain.  (See example below).\n\nUnlike [`.finally`](.) this is not called for rejections.\n\n```js\ngetUser().tap(function(user) {\n    //Like in finally, if you return a promise from the handler\n    //the promise is awaited for before passing the original value through\n    return recordStatsAsync();\n}).then(function(user) {\n    //user is the user from getUser(), not recordStatsAsync()\n});\n```\n\nCommon case includes adding logging to an existing promise chain:\n\n```js\ndoSomething()\n    .then(...)\n    .then(...)\n    .then(...)\n    .then(...)\n```\n\n```js\ndoSomething()\n    .then(...)\n    .then(...)\n    .tap(console.log)\n    .then(...)\n    .then(...)\n```\n\n*Note: in browsers it is necessary to call `.tap` with `console.log.bind(console)` because console methods can not be called as stand-alone functions.*\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".tap\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-tap\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/tapcatch.md",
    "content": "---\nlayout: api\nid: tapCatch\ntitle: .tapCatch\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.tapCatch\n\n\n`.tapCatch` is a convenience method for reacting to errors without handling them with promises - similar to `finally` but only called on rejections. Useful for logging errors.\n\nIt comes in two variants.\n- A tapCatch-all variant similar to [`.catch`](.) block. This variant is compatible with native promises.\n- A filtered variant (like other non-JS languages typically have) that lets you only handle specific errors. **This variant is usually preferable**.\n\n\n### `tapCatch` all\n```js\n.tapCatch(function(any value) handler) -> Promise\n```\n\n\nLike [`.finally`](.) that is not called for fulfillments.\n\n```js\ngetUser().tapCatch(function(err) {\n    return logErrorToDatabase(err);\n}).then(function(user) {\n    //user is the user from getUser(), not logErrorToDatabase()\n});\n```\n\nCommon case includes adding logging to an existing promise chain:\n\n#### Rate Limiting\n\n```js\nPromise.\n  try(logIn).\n  then(respondWithSuccess).\n  tapCatch(countFailuresForRateLimitingPurposes).\n  catch(respondWithError);\n```\n\n#### Circuit Breakers\n\n```js\nPromise.\n  try(makeRequest).\n  then(respondWithSuccess).\n  tapCatch(adjustCircuitBreakerState).\n  catch(respondWithError);\n```\n\n#### Logging\n\n```js\nPromise.\n  try(doAThing).\n  tapCatch(logErrorsRelatedToThatThing).\n  then(respondWithSuccess).\n  catch(respondWithError);\n```\n\n*Note: in browsers it is necessary to call `.tapCatch` with `console.log.bind(console)` because console methods can not be called as stand-alone functions.*\n\n### Filtered `tapCatch`\n\n\n```js\n.tapCatch(\n    class ErrorClass|function(any error),\n    function(any error) handler\n) -> Promise\n```\n```js\n.tapCatch(\n    class ErrorClass|function(any error),\n    function(any error) handler\n) -> Promise\n\n\n```\nThis is an extension to [`.tapCatch`](.) to filter exceptions similarly to languages like Java or C#. Instead of manually checking `instanceof` or `.name === \"SomeError\"`, you may specify a number of error constructors which are eligible for this tapCatch handler. The tapCatch handler that is first met that has eligible constructors specified, is the one that will be called.\n\nUsage examples include:\n\n#### Rate Limiting\n\n```js\nPromise.\n  try(logIn).\n  then(respondWithSuccess).\n  tapCatch(InvalidCredentialsError, countFailuresForRateLimitingPurposes).\n  catch(respondWithError);\n```\n\n#### Circuit Breakers\n\n```js\nPromise.\n  try(makeRequest).\n  then(respondWithSuccess).\n  tapCatch(RequestError, adjustCircuitBreakerState).\n  catch(respondWithError);\n```\n\n#### Logging\n\n```js\nPromise.\n  try(doAThing).\n  tapCatch(logErrorsRelatedToThatThing).\n  then(respondWithSuccess).\n  catch(respondWithError);\n```\n\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".tapCatch\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-tapCatch\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/then.md",
    "content": "---\nlayout: api\nid: then\ntitle: .then\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.then\n\n```js\n.then(\n    [function(any value) fulfilledHandler],\n    [function(any error) rejectedHandler]\n) -> Promise\n```\n\n\n[Promises/A+ `.then`](http://promises-aplus.github.io/promises-spec/). If you are new to promises, see the [Beginner's Guide]({{ \"/docs/beginners-guide.html\" | prepend: site.baseurl }}).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".then\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-then\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/throw.md",
    "content": "---\nlayout: api\nid: throw\ntitle: .throw\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.throw\n\n```js\n.throw(any reason) -> Promise\n```\n```js\n.thenThrow(any reason) -> Promise\n```\n\n\nConvenience method for:\n\n```js\n.then(function() {\n   throw reason;\n});\n```\n\nSame limitations regarding to the binding time of `reason` to apply as with [`.return`](.).\n\n*For compatibility with earlier ECMAScript version, an alias `.thenThrow` is provided for [`.throw`](.).*\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".throw\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-throw\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/timeout.md",
    "content": "---\nlayout: api\nid: timeout\ntitle: .timeout\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.timeout\n\n```js\n.timeout(\n    int ms,\n    [String message=\"operation timed out\"]\n) -> Promise\n```\n```js\n.timeout(\n    int ms,\n    [Error error]\n) -> Promise\n```\n\n\nReturns a promise that will be fulfilled with this promise's fulfillment value or rejection reason. However, if this promise is not fulfilled or rejected within `ms` milliseconds, the returned promise is rejected with a [`TimeoutError`](.) or the `error` as the reason.\n\nWhen using the first signature, you may specify a custom error message with the `message` parameter.\n\n\n```js\nvar Promise = require(\"bluebird\");\nvar fs = Promise.promisifyAll(require('fs'));\nfs.readFileAsync(\"huge-file.txt\").timeout(100).then(function(fileContents) {\n\n}).catch(Promise.TimeoutError, function(e) {\n    console.log(\"could not read file within 100ms\");\n});\n```\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".timeout\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-timeout\";\n\n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api/timeouterror.md",
    "content": "---\nlayout: api\nid: timeouterror\ntitle: TimeoutError\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##TimeoutError\n\n```js\nnew TimeoutError(String message) -> TimeoutError\n```\n\n\nSignals that an operation has timed out. Used as a custom cancellation reason in [`.timeout`](.).\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"TimeoutError\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-timeouterror\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/timers.md",
    "content": "---\nlayout: api\nid: timers\ntitle: Timers\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Timers\n\nMethods to delay and time promises out.\n\n<div class=\"api-code-section\"><markdown>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Timers\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-timers\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/utility.md",
    "content": "---\nlayout: api\nid: utility\ntitle: Utility\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##Utility\n\nFunctions that could potentially be handy in some situations.\n\n<hr>\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \"Utility\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-utility\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>"
  },
  {
    "path": "docs/docs/api/value.md",
    "content": "---\nlayout: api\nid: value\ntitle: .value\n---\n\n\n[← Back To API Reference](/docs/api-reference.html)\n<div class=\"api-code-section\"><markdown>\n##.value\n\n```js\n.value() -> any\n```\n\n\nGet the fulfillment value of this promise. Throws an error if the promise isn't fulfilled - it is a bug to call this method on an unfulfilled promise.\n\nYou should check if this promise is [.isFulfilled()](.) in code paths where it's not guaranteed that this promise is fulfilled.\n</markdown></div>\n\n<div id=\"disqus_thread\"></div>\n<script type=\"text/javascript\">\n    var disqus_title = \".value\";\n    var disqus_shortname = \"bluebirdjs\";\n    var disqus_identifier = \"disqus-id-value\";\n    \n    (function() {\n        var dsq = document.createElement(\"script\"); dsq.type = \"text/javascript\"; dsq.async = true;\n        dsq.src = \"//\" + disqus_shortname + \".disqus.com/embed.js\";\n        (document.getElementsByTagName(\"head\")[0] || document.getElementsByTagName(\"body\")[0]).appendChild(dsq);\n    })();\n</script>\n<noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\" rel=\"nofollow\">comments powered by Disqus.</a></noscript>\n"
  },
  {
    "path": "docs/docs/api-reference.md",
    "content": "---\nid: api-reference\ntitle: API Reference\nredirect_from: \"/docs/api/index.html\"\n---\n\n\n<div class=\"api-reference-menu\">\n<markdown>\n\n- [Core](api/core.html)\n    - [new Promise](api/new-promise.html)\n    - [.then](api/then.html)\n    - [.spread](api/spread.html)\n    - [.catch](api/catch.html)\n    - [.error](api/error.html)\n    - [.finally](api/finally.html)\n    - [.bind](api/bind.html)\n    - [Promise.join](api/promise.join.html)\n    - [Promise.try](api/promise.try.html)\n    - [Promise.method](api/promise.method.html)\n    - [Promise.resolve](api/promise.resolve.html)\n    - [Promise.reject](api/promise.reject.html)\n- [Synchronous inspection](api/synchronous-inspection.html)\n    - [PromiseInspection](api/promiseinspection.html)\n    - [.isFulfilled](api/isfulfilled.html)\n    - [.isRejected](api/isrejected.html)\n    - [.isPending](api/ispending.html)\n    - [.isCancelled](api/iscancelled.html)\n    - [.value](api/value.html)\n    - [.reason](api/reason.html)\n- [Collections](api/collections.html)\n    - [Promise.all](api/promise.all.html)\n    - [Promise.props](api/promise.props.html)\n    - [Promise.any](api/promise.any.html)\n    - [Promise.some](api/promise.some.html)\n    - [Promise.map](api/promise.map.html)\n    - [Promise.reduce](api/promise.reduce.html)\n    - [Promise.filter](api/promise.filter.html)\n    - [Promise.each](api/promise.each.html)\n    - [Promise.mapSeries](api/promise.mapseries.html)\n    - [Promise.race](api/promise.race.html)\n    - [.all](api/all.html)\n    - [.props](api/props.html)\n    - [.any](api/any.html)\n    - [.some](api/some.html)\n    - [.map](api/map.html)\n    - [.reduce](api/reduce.html)\n    - [.filter](api/filter.html)\n    - [.each](api/each.html)\n    - [.mapSeries](api/mapseries.html)\n- [Resource management](api/resource-management.html)\n    - [Promise.using](api/promise.using.html)\n    - [.disposer](api/disposer.html)\n- [Promisification](api/promisification.html)\n    - [Promise.promisify](api/promise.promisify.html)\n    - [Promise.promisifyAll](api/promise.promisifyall.html)\n    - [Promise.fromCallback](api/promise.fromcallback.html)\n    - [.asCallback](api/ascallback.html)\n- [Timers](api/timers.html)\n    - [Promise.delay](api/promise.delay.html)\n    - [.delay](api/delay.html)\n    - [.timeout](api/timeout.html)\n- [Cancellation](api/cancellation.html)\n    - [.cancel](api/cancel.html)\n- [Generators](api/generators.html)\n    - [Promise.coroutine](api/promise.coroutine.html)\n    - [Promise.coroutine.addYieldHandler](api/promise.coroutine.addyieldhandler.html)\n- [Utility](api/utility.html)\n    - [.tap](api/tap.html)\n    - [.tapCatch](api/tapcatch.html)\n    - [.call](api/call.html)\n    - [.get](api/get.html)\n    - [.return](api/return.html)\n    - [.throw](api/throw.html)\n    - [.catchReturn](api/catchreturn.html)\n    - [.catchThrow](api/catchthrow.html)\n    - [.reflect](api/reflect.html)\n    - [Promise.getNewLibraryCopy](api/promise.getnewlibrarycopy.html)\n    - [Promise.noConflict](api/promise.noconflict.html)\n    - [Promise.setScheduler](api/promise.setscheduler.html)\n- [Built-in error types](api/built-in-error-types.html)\n    - [OperationalError](api/operationalerror.html)\n    - [TimeoutError](api/timeouterror.html)\n    - [CancellationError](api/cancellationerror.html)\n    - [AggregateError](api/aggregateerror.html)\n- [Configuration](api/error-management-configuration.html)\n    - [Global rejection events](api/error-management-configuration.html#global-rejection-events)\n    - [Local rejection events](api/promise.onpossiblyunhandledrejection.html)\n    - [Promise.config](api/promise.config.html)\n    - [.suppressUnhandledRejections](api/suppressunhandledrejections.html)\n    - [.done](api/done.html)\n- [Progression migration](api/progression-migration.html)\n- [Deferred migration](api/deferred-migration.html)\n- [Environment variables](api/environment-variables.html)\n\n</markdown>\n</div>\n"
  },
  {
    "path": "docs/docs/async-dialogs.md",
    "content": "---\nid: async-dialogs\ntitle: Async Dialogs\n---\n\n[async-dialogs](unfinished-article)\n\nTypically *promises* are used in conjunction with asynchronous tasks such as a\nnetwork request or a `setTimeout`; a lesser explored use is dealing with user\ninput. Since a program has to wait for a user to continue some actions it makes\nsense to consider it an asynchronous event.\n\nFor comparison I'll start with an example of a *synchronous* user interaction\nusing `window.prompt` and then move to an *asynchronous* interaction by making\nour own DOM based prompt. To begin, here is a template for a simple HTML page:\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Async Dislogs Example</title>\n  <script src=\"//cdn.jsdelivr.net/bluebird/{{ site.version }}/bluebird.js\"></script>\n  <script type=\"text/javascript\">\n    document.addEventListener('DOMContentLoaded', function() {\n      var time = document.getElementById('time-stamp');\n      clockTick();\n      setInterval(clockTick, 1000);\n      function clockTick() {\n        time.innerHTML = new Date().toLocaleTimeString();\n      }\n    });\n  </script>\n</head>\n<body>\n  <p>The current time is <span id=\"time-stamp\"></span>.</p>\n  <p>Your name is <span id=\"prompt\"></span>.</p>\n  <button id=\"action\">Set Name</button>\n</body>\n</html>\n```\n\n`window.prompt` blocks the web page from processing while it waits for the user\nto enter in data. It has to block because the input is returned and the next\nline of code needs that result. But for sake of this tutorial we are going to\nconvert the typical conditional code into a promise API using a [promise\nconstructor](api/new-promise.html).\n\n```javascript\nfunction promptPromise(message) {\n  return new Promise(function(resolve, reject) {\n    var result = window.prompt(message);\n    if (result != null) {\n      resolve(result);\n    } else {\n      reject(new Error('User cancelled'));\n    }\n  });\n}\n\nvar button = document.getElementById('action');\nvar output = document.getElementById('prompt');\n\nbutton.addEventListener('click', function() {\n  promptPromise('What is your name?')\n    .then(function(name) {\n      output.innerHTML = String(name);\n    })\n    .catch(function() {\n      output.innerHTML = '¯\\\\_(ツ)_/¯';\n    });\n});\n```\n\n[Run example on JSBin][Example1]\n\nThis doesn't add much much using `window.prompt`; however, one advantage is the\nAPI that promises provide. In the case where we call `promptPromise(…)` we can\neasily react to the result of the dialog without having to worry about how it is\nimplemented. In our example we've implemented the `window.prompt` but our call\nto `promptPromise()` doesn't care. This makes a change to an *asynchronous*\ndialog a little more future proof.\n\nTo drive home the synchronous nature of the `window.prompt` notice that the time\nstops ticking when the prompt dialog is displayed. Let's fix that by making our\nown prompt. Since our dialog is just DOM manipulation the page won't be blocked\nwhile waiting for user input.\n\nFirst add the prompt dialog to the HTML:\n\n```html\n<style type=\"text/css\">\n  #dialog {\n    width:      200px;\n    margin:     auto;\n    padding:    10px;\n    border:     thin solid black;\n    background: lightgreen;\n  }\n  .hidden {\n    display: none;\n  }\n</style>\n<div id=\"dialog\" class=\"hidden\">\n  <div class=\"message\">foobar</div>\n  <input type=\"text\">\n  <div>\n    <button class=\"ok\">Ok</button>\n    <button class=\"cancel\">Cancel</button>\n  </div>\n</div>\n```\n\nWe will want to keep the same API so our change will be only to the\n`promisePrompt`. It will find the dialog DOM elements, attach events to the\nelements, show the dialog box, return a promise that is resolved based on the\nattached events, and finally detaches the events and cleans up after itself\n(hiding the dialog box for another use later).\n\n```javascript\nfunction promptPromise(message) {\n  var dialog       = document.getElementById('dialog');\n  var input        = dialog.querySelector('input');\n  var okButton     = dialog.querySelector('button.ok');\n  var cancelButton = dialog.querySelector('button.cancel');\n\n  dialog.querySelector('.message').innerHTML = String(message);\n  dialog.className = '';\n\n  return new Promise(function(resolve, reject) {\n    dialog.addEventListener('click', function handleButtonClicks(e) {\n      if (e.target.tagName !== 'BUTTON') { return; }\n      dialog.removeEventListener('click', handleButtonClicks);\n      dialog.className = 'hidden';\n      if (e.target === okButton) {\n        resolve(input.value);\n      } else {\n        reject(new Error('User cancelled'));\n      }\n    });\n  });\n}\n```\n\n[Run example on JSBin][Example2]\n\nNow when the user presses the **Set Name** button the clock continues to update\nwhile the dialog is visible.\n\nBecause the `removeEventListener` requires a reference to the original function\nthat was used with the `addEventListener` it makes it difficult to clean up\nafter itself without storing the references in a scope higher then the handler\nitself. Using a named function we can reference it when a user clicks the\nbutton. To help with performance and to avoid duplicating code the example uses\n[event delegation][1] to capture both buttons in one *click* handler.\n\n[1]: https://davidwalsh.name/event-delegate\n\nThe same thing can be done with less code using jQuery's [event\nnamespacing](https://api.jquery.com/on/#event-names).\n\n```javascript\nreturn new Promise(function(resolve, reject) {\n  $('#okButton').on('click.promptDialog', function() {\n    resolve(input.value);\n  });\n  $('#cancelButton').on('click.promptDialog', reject);\n})\n.finally(function() {\n  $('#okButton').off('click.promptDialog');\n  $('#cancelButton').off('click.promptDialog');\n});\n```\n\nThere are still a few problems with the earlier code example. It feels like it\nis doing too much. A *squint* test reveals behavior for showing the dialog, set\nthe dialog's message, attach two DOM events, construct a promise, event\ndelegation, hide the dialog, and finally detach DOM events. That is a lot for\none little function. A refactoring can help.\n\nAbstraction is the key here. We will make an *object* (or class) that is\nresponsible for managing the dialog box. Its interface will manage only two\nfunction references (callbacks): when the user clicks ok and when user clicks\ncancel. And it will offer the value when asked.\n\nUsing an abstraction like this the `promisePrompt` no longer needs to know\nanything about the DOM and concentrates on just providing a promise. This will\nalso make things easier to create a promised version of a progress bar or\nconfirmation dialog or any other type of UI that we want to have a value for.\nAll we will need to do is write a class for that dialog type with the same\ninterface and just pass that class into our promise making method.\n\nThe dialog interface might look like this:\n\n```javascript\nvar noop = function() {\n  return this;\n};\n\nfunction Dialog() {\n  this.setCallbacks(noop, noop);\n}\nDialog.prototype.setCallbacks = function(okCallback, cancelCallback) {\n  this._okCallback     = okCallback;\n  this._cancelCallback = cancelCallback;\n  return this;\n};\nDialog.prototype.waitForUser = function() {\n  var _this = this;\n  return new Promise(function(resolve, reject) {\n    _this.setCallbacks(resolve, reject);\n  });\n};\nDialog.prototype.show = noop;\nDialog.prototype.hide = noop;\n```\n\nInitially the Dialog class sets the two callbacks to *noop* functions. It is up\nto the child class to call them when necessary. We break down the promise\ncreation to one function `waitForUser()` that sets the callbacks and returns a\npromise. At this level the `show()` and `hide()` are just *noop* functions as\nwell and will be implemented by the child classes.\n\nOur `PromptDialog` class is responsible for inheriting from `Dialog` and setting\nup the required DOM scaffolding and eventually call `this._okCallback` or\n`this._cancelCallback` as appropriate.\n\nIt might look like this:\n\n```javascript\nfunction PromptDialog() {\n  Dialog.call(this);\n  this.el           = document.getElementById('dialog');\n  this.inputEl      = this.el.querySelector('input');\n  this.messageEl    = this.el.querySelector('.message');\n  this.okButton     = this.el.querySelector('button.ok');\n  this.cancelButton = this.el.querySelector('button.cancel');\n  this.attachDomEvents();\n}\nPromptDialog.prototype = Object.create(Dialog.prototype);\nPromptDialog.prototype.attachDomEvents = function() {\n  var _this = this;\n  this.okButton.addEventListener('click', function() {\n    _this._okCallback(_this.inputEl.value);\n  });\n  this.cancelButton.addEventListener('click', function() {\n    _this._cancelCallback();\n  });\n};\nPromptDialog.prototype.show = function(message) {\n  this.messageEl.innerHTML = String(message);\n  this.el.className = '';\n  return this;\n};\nPromptDialog.prototype.hide = function() {\n  this.el.className = 'hidden';\n  return this;\n};\n```\n\nNotice that use of `return this;` in most of the functions? That pattern will\nallow method chaining as you'll see shortly.\n\nThis inherits from `Dialog` and stores references to the required DOM elements\nthat this dialog uses. It then attaches the require DOM events\n(`attachDomEvents()`) which eventually call the callbacks. Then it implements\nthe `show()` and `hide()` methods. Its usage is more flexible and verbose:\n\n```javascript\nvar output = document.getElementById('prompt');\nvar prompt = new PromptDialog();\n\nprompt.show('What is your name?')\n  .waitForUser()\n  .then(function(name) {\n    output.innerHTML = String(name);\n  })\n  .catch(function() {\n    output.innerHTML = '¯\\\\_(ツ)_/¯';\n  })\n  .finally(function() {\n    prompt.hide();\n  });\n```\n\n[Run example on JSBin][Example3]\n\nThis abstraction can be expanded on in other ways. For example a notification\ndialog:\n\n```javascript\nfunction NotifyDialog() {\n  Dialog.call(this);\n  var _this      = this;\n  this.el        = document.getElementById('notify-dialog');\n  this.messageEl = this.el.querySelector('.message');\n  this.okButton  = this.el.querySelector('button.ok');\n  this.okButton.addEventListener('click', function() {\n    _this._okCallback();\n  });\n}\nNotifyDialog.prototype = Object.create(Dialog.prototype);\nNotifyDialog.prototype.show = function(message) {\n  this.messageEl.innerHTML = String(message);\n  this.el.className = '';\n  return this;\n};\nNotifyDialog.prototype.show = function() {\n  this.el.className = 'hidden';\n  return this;\n};\n```\n\n#### Exercises for the student\n\n1.  Write a function that takes a `Dialog` instance and a default value. Have it\n    return a promise that resolves to the default value if the user clicks\n    cancel.\n2.  With the use of abstract classes can the similarities between `PromptDialog`\n    and `NotifyDialog` be abstracted? Make a sub class of `Dialog` that\n    abstracts the common DOM code (`DOMDialog`). Then refactor the\n    `PromptDialog` and `NotifyDialog` to inherate from `DOMDialog` but\n    references the correct DOM selectors.\n\n## Cancellation\n\nSomething missing from the above example is proper error handling. When it comes\nto promises it is a best practise to always *reject a promise with an Error* and\nnot with plain data such as an object, string, number, or null/undefined. The\nreasoning for this is promises are best used as a way to regain some of the\nsyntax you have with the standard `try {} catch() {}` blocks with asynchronous\ncode.\n\nAn advantage of using `Error`s is the ability to test why a promise was rejected\nand make decisions on that. This ability is also baked into how Bluebird works.\nYou can pass in a predicate to the `catch()` block allowing you to have more\nthan one block based on what `Error` it was rejected with. For example:\n\n```javascript\ndoSomething().then(function(value) {\n  // Do something with value or fail with an error.\n  throw new Error('testing errors');\n})\n.catch(ArgumentError, function(e) {\n  console.log('You buggered up something with the arguments.', e);\n})\n.catch(SyntaxError, function(e) {\n  console.log('Check your syntax!', e);\n})\n.catch(function(e) {\n  // e is an Error object.\n  console.log('Well something genaric happened.', e);\n});\n```\n\nIn our dialog example perhaps we want to differentiate between a rejected\npromise because of some problem (bad AJAX, programming error, etc.) or because\nthe user pressed the cancel button.\n\nTo do this we will have two `catch()` functions one for `UserCanceledError` and\none for any other `Error`. We can make a custom error like so:\n\n```javascript\nfunction UserCanceledError() {\n  this.name = 'UserCanceledError';\n  this.message = 'Dialog cancelled';\n}\nUserCanceledError.prototype = Object.create(Error.prototype);\n```\n\nSee [this StackOverflow answer](http://stackoverflow.com/a/17891099/227176) for\na more detailed and feature complete way to make custom errors.\n\nNow we can add a `cancel()` reject with this in our event listener:\n\n```javascript\nDialog.prototype.cancel = function() {\n  this._cancelCallback(new UserCanceledError());\n};\n\n…\n\nPromptDialog.prototype.attachDomEvents = function() {\n  var _this = this;\n  this.okButton.addEventListener('click', function() {\n    _this._okCallback(_this.inputEl.value);\n  });\n  this.cancelButton.addEventListener('click', function() {\n    _this.cancel();\n  });\n};\n```\n\nAnd in our usage case we can test for it:\n\n```javascript\n// Timeout the dialog in five seconds.\nsetTimeout(function() { prompt.cancel(); }, 5000);\n\nprompt.show('What is your name?')\n  .waitForUser()\n  .then(function(name) {\n    output.innerHTML = String(name);\n  })\n  .catch(UserCanceledError, function() {\n    output.innerHTML = '¯\\\\_(ツ)_/¯';\n  })\n  .catch(function(e) {\n    console.log('Something bad happened!', e);\n  })\n  .finally(function() {\n    prompt.hide();\n  });\n```\n\n[Run example on JSBin][Example4]\n\n**NOTE:** Bluebird supports [cancellation](api/cancellation.html) as an optional\nfeature that is turned off by default. However, its implementation (since\nversion 3.0) is meant to stop the then and catch callbacks from firing. It is\nnot helpful in the example of a user cancellation as described here.\n\n## Progress bar\n\nWhen there are asynchronous tasks that have the ability to notify progress as\nthey complete it can be tempting to want that in the promise that represents\nthat task. Unfortunately this is a bit of an anti-pattern. That is because the\npoint of promises is to represent a value as if it was natural (like it is in\nnormal synchronous code) and not to be over glorified callback management.\n\nSo how then could we represent a progress bar like dialog? Well the answer is to\nmanage the progress through callbacks outside the promise API. Bluebird has\nsince [deprecated the progression feature](deprecated-apis.html#progression) and\noffers an alternative which I hope to illustrate here.\n\nAnother key difference between a *progress bar* dialog and any other dialog\nwe've discussed here is that a progress bar represents information on another\ntask and *not* user import. Instead of the program waiting for the user to\nprovide a value the dialog box is waiting on the program to provide a value\n(resolved: 100% complete, rejected: aborted half way through). Because of this\nthe *progress bar* dialog would have a different interface then the previous\ndialogs we've covered. However, there can still be some user interaction so in\nessence we are dealing with two promises.\n\nBluebird has a way to manage more than one promise simultaneously. When you want\nto know if more then one promise completes there is a `Promise.all()` function\nthat takes an array of promises and returns a new promise waiting for them all\nto resolve. But if any one is rejected the returned promise is immediately\nrejected.\n\nBluebird also has a `Promise.race()` function which does the same thing but\ndoesn't wait for all of them to finish. That is what we want. An example how\nthis might look:\n\n```javascript\nfunction showProgress(otherPromise) {\n  var progress = new ProgressbarDialog().show('Uploading…');\n  return Promise.race([otherPromise, promise.waitForUser()])\n    .finally(function() {\n      progress.hide();\n    });\n}\n```\n\nHere is some example HTML for the Progress Dialog:\n\n```html\n<style type=\"text/css\">\n  #progress-dialog {\n    width:      200px;\n    margin:     auto;\n    border:     thin solid black;\n    padding:    10px;\n    background: lightgreen;\n  }\n  #progress-dialog .progress-bar {\n    border:  1px solid black;\n    margin:  10px auto;\n    padding: 0;\n    height:  20px;\n  }\n  #progress-dialog .progress-bar>div {\n    background-color: blue;\n    margin:           0;\n    padding:          0;\n    border:           none;\n    height:           20px;\n  }\n</style>\n<div id=\"progress-dialog\">\n  <div class=\"message\"></div>\n  <div class=\"progress-bar\"><div></div></div>\n  <div>\n    <button class=\"cancel\">Cancel</button>\n  </div>\n</div>\n```\n\nThe JavaScript is the same as the `PromptDialog` only we will add a\n`setProgress()` method:\n\n```javascript\nfunction ProgressDialog() {\n  Dialog.call(this);\n  this.el           = document.getElementById('progress-dialog');\n  this.messageEl    = this.el.querySelector('.message');\n  this.progressBar  = this.el.querySelector('.progress-bar>div');\n  this.cancelButton = this.el.querySelector('button.cancel');\n  this.attachDomEvents();\n}\nProgressDialog.prototype = Object.create(Dialog.prototype);\nProgressDialog.prototype.attachDomEvents = function() {\n  var _this = this;\n  this.cancelButton.addEventListener('click', function() {\n    _this.cancel();\n  });\n\n};\nProgressDialog.prototype.show = function(message) {\n  this.messageEl.innerHTML = String(message);\n  this.el.className = '';\n  return this;\n};\nProgressDialog.prototype.hide = function() {\n  this.el.className = 'hidden';\n  return this;\n};\nProgressDialog.prototype.setProgress = function(percent) {\n  this.progressBar.style.width = percent + '%';\n};\n```\n\nA common misconception is that promises are a form of callback management. This\nis not the case and is why the idea of having a progress callback is not part of\nthe Promise spec. However, much like the Promise library passes in a `resolve`\nand `reject` callback when you create a new promise (`new Promise(…)`) we can do\nthe same patter for a progress callback.\n\nNow to the fun part. For this tutorial we will *fake* a lengthy file upload by\nusing `setTimeout`. The intent is to provide a promise and to allow a progress\nto be periodically ticked away. We will expect a function to be passed which\nis called whenever the progress needs updating. And it returns a promise.\n\n```javascript\nfunction delayedPromise(progressCallback) {\n  var step = 10;\n  return new Promise(function(resolve, reject) {\n    var progress = 0 - step; // So first run of nextTick will set progress to 0\n    function nextTick() {\n      if (progress >= 100 ) {\n        resolve('done');\n      } else {\n        progress += step;\n        progressCallback(progress);\n        setTimeout(nextTick, 500);\n      }\n    }\n    nextTick();\n  });\n}\n```\n\nWhen we construct our `ProgressDialog` we use the `waitForUser()` method to\ncapture the user interaction promise and then use `delayedPromise()` to capture\nthe fake network promise and finally `Promise.reace()` to manage the two\nsimultaneously and end with a single promise as usual.\n\n```javascript\ndocument.addEventListener('DOMContentLoaded', function() {\n  var button = document.getElementById('action');\n  var output = document.getElementById('output');\n\n  var prompt = new ProgressDialog();\n\n  button.addEventListener('click', function() {\n    var pendingProgress = true;\n    var waitForPromise = delayedPromise(function(progress) {\n      if (pendingProgress) {\n        prompt.setProgress(progress);\n      }\n    });\n\n    // Prevent user from pressing button while dialog is visible.\n    button.disabled = true;\n\n    prompt.show('Simulating a file upload.');\n\n    Promise.race([waitForPromise, prompt.waitForUser()])\n      .then(function() {\n        output.innerHTML = 'Progress completed';\n      })\n      .catch(UserCanceledError, function() {\n        output.innerHTML = 'Progress canceled by user';\n      })\n      .catch(function(e) {\n        console.log('Error', e);\n      })\n      .finally(function() {\n        pendingProgress = false;\n        button.disabled = false;\n        prompt.hide();\n      });\n  });\n});\n```\n\n[Run example on JSBin][Example5]\n\nI hope this helps illustrate some concepts available with Promises and a\ndifferent perspective on how promises can represent more then just AJAX data.\n\nAlthough the code may look verbose it does provide the benefit that it is\nmodular and can be easily changed. A trait difficult to achieve with a more\nprocedural style.\n\nHappy coding, [@sukima](https://github.com/sukima).\n\n[Example1]: http://jsbin.com/kowama/edit?js,output\n[Example2]: http://jsbin.com/fucofu/edit?js,output\n[Example3]: http://jsbin.com/wupixi/edit?js,output\n[Example4]: http://jsbin.com/yaropo/edit?js,output\n[Example5]: http://jsbin.com/bipeve/edit?js,output\n"
  },
  {
    "path": "docs/docs/beginners-guide.md",
    "content": "---\nid: beginners-guide\ntitle: Beginner's Guide\n---\n\n[beginners-guide](unfinished-article)\n"
  },
  {
    "path": "docs/docs/benchmarks.md",
    "content": "---\nid: benchmarks\ntitle: Benchmarks\n---\n\nBenchmarks have been ran with the following versions of modules.\n\n```\n├── async@1.5.2\n├── babel@5.8.35\n├── davy@1.1.0\n├── deferred@0.7.5\n├── kew@0.7.0\n├── lie@3.0.2\n├── neo-async@1.7.3\n├── optimist@0.6.1\n├── promise@7.1.1\n├── q@1.4.1\n├── rsvp@3.2.1\n├── streamline@2.0.16\n├── streamline-runtime@1.0.38\n├── text-table@0.2.0\n├── vow@0.4.12\n└── when@3.7.7\n```\n\n###1\\. DoxBee sequential\n\nThis is Gorki Kosev's benchmark used in the article [Analysis of generators and other async patterns in node](http://spion.github.io/posts/analysis-generators-and-other-async-patterns-node.html). The benchmark emulates a situation where N=10000 requests are being made concurrently to execute some mixed async/sync action with fast I/O response times.\n\nThis is a throughput benchmark.\n\nEvery implementation runs in a freshly created isolated process which is warmed up to the benchmark code before timing it. The memory column represents the highest snapshotted RSS memory (as reported by `process.memoryUsage().rss`) during processing.\n\nCommand: `./bench doxbee` (<a href=\"{{ \"/docs/contribute.html#benchmarking\" | prepend: site.baseurl }}\">needs cloned repository</a>)\n\nThe implementations for this benchmark are found in [`benchmark/doxbee-sequential`](https://github.com/petkaantonov/bluebird/tree/master/benchmark/doxbee-sequential) directory.\n\n\n```\nresults for 10000 parallel executions, 1 ms per I/O op\n\nfile                                       time(ms)  memory(MB)\ncallbacks-baseline.js                           116       33.98\ncallbacks-suguru03-neo-async-waterfall.js       145       43.81\npromises-bluebird-generator.js                  183       42.35\npromises-bluebird.js                            214       43.41\npromises-cujojs-when.js                         312       64.37\npromises-then-promise.js                        396       74.33\npromises-tildeio-rsvp.js                        414       84.80\npromises-native-async-await.js                  422      104.23\npromises-ecmascript6-native.js                  424       92.12\ngenerators-tj-co.js                             444       90.98\npromises-lvivski-davy.js                        480      114.46\ncallbacks-caolan-async-waterfall.js             520      109.01\npromises-dfilatov-vow.js                        612      134.38\npromises-obvious-kew.js                         725      208.63\npromises-calvinmetcalf-lie.js                   730      164.96\nstreamline-generators.js                        809      154.36\npromises-medikoo-deferred.js                    913      178.51\nobservables-pozadi-kefir.js                     991      194.00\nstreamline-callbacks.js                        1127      196.54\nobservables-Reactive-Extensions-RxJS.js        1906      268.41\nobservables-caolan-highland.js                 6887      662.08\npromises-kriskowal-q.js                        8533      435.51\nobservables-baconjs-bacon.js.js               21282      882.61\n\nPlatform info:\nLinux 4.4.0-79-generic x64\nNode.JS 8.6.0\nV8 6.0.287.53\nIntel(R) Core(TM) i5-6600K CPU @ 3.50GHz × 4\n\n```\n\n###2\\. Parallel\n\nThis made-up scenario runs 25 shimmed queries in parallel per each request (N=10000) with fast I/O response times.\n\nThis is a throughput benchmark.\n\nEvery implementation runs in a freshly created isolated process which is warmed up to the benchmark code before timing it. The memory column represents the highest snapshotted RSS memory (as reported by `process.memoryUsage().rss`) during processing.\n\nCommand: `./bench parallel` (<a href=\"{{ \"/docs/contribute.html#benchmarking\" | prepend: site.baseurl }}\">needs cloned repository</a>)\n\nThe implementations for this benchmark are found in [`benchmark/madeup-parallel`](https://github.com/petkaantonov/bluebird/tree/master/benchmark/madeup-parallel) directory.\n\n```\nresults for 10000 parallel executions, 1 ms per I/O op\n\nfile                                      time(ms)  memory(MB)\ncallbacks-baseline.js                          274       75.11\ncallbacks-suguru03-neo-async-parallel.js       320       88.84\npromises-bluebird.js                           407      107.25\npromises-bluebird-generator.js                 432      113.19\ncallbacks-caolan-async-parallel.js             550      154.27\npromises-cujojs-when.js                        648      168.65\npromises-ecmascript6-native.js                1145      308.87\npromises-lvivski-davy.js                      1153      257.36\npromises-native-async-await.js                1260      323.68\npromises-then-promise.js                      1372      313.24\npromises-tildeio-rsvp.js                      1435      398.73\npromises-medikoo-deferred.js                  1626      306.02\npromises-calvinmetcalf-lie.js                 1805      351.21\npromises-dfilatov-vow.js                      2492      558.25\npromises-obvious-kew.js                       3403      784.61\nstreamline-generators.js                     13068      919.24\nstreamline-callbacks.js                      25509     1141.57\n\nPlatform info:\nLinux 4.4.0-79-generic x64\nNode.JS 8.6.0\nV8 6.0.287.53\nIntel(R) Core(TM) i5-6600K CPU @ 3.50GHz × 4\n```\n\n###3\\. Latency benchmarks\n\nFor reasonably fast promise implementations latency is going to be fully determined by the scheduler being used and is therefore not interesting to benchmark. [JSPerfs](https://jsperf.com/) that benchmark promises tend to benchmark latency.\n"
  },
  {
    "path": "docs/docs/changelog.md",
    "content": "---\nid: changelog\ntitle: Changelog\n---\n\n## 3.7.2 (2019-11-28)\n\nBugfixes:\n\n - Fixes firefox settimeout not initialized error \\([#1623](.)\\)\n\n\n## 3.7.1 (2019-10-15)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - Fix \\([#1614](.)\\)\n - Fix \\([#1613](.)\\)\n - Fix \\([#1616](.)\\)\n\n## 3.7.0 (2019-10-01)\n\nFeatures:\n\n - Add [Promise.allSettled](.) method \\([#1606](.)\\)\n\n## 3.6.0 (2019-10-01)\n\nFeatures:\n\n - Add support for AsyncResource \\([#1403](.)\\)\n\nBugfixes:\n\n - Fix [.reduce](.) generating unhandled rejection events \\([#1501](.)\\)\n - Fix [Promise.reduce](.) generating unhandled rejction events \\([#1502](.)\\)\n - Fix [.map](.) and [.filter](.) generating unhandled rejection events \\([#1487](.)\\)\n - Fix [Promise.map](.) unhandled rejection events \\([#1489](.)\\)\n - Fix cancel skipping upward propagation \\([#1459](.)\\)\n - Fix loadTimes deprecation \\([#1505](.)\\)\n - Fix [Promise.each](.) maximum stack exceeded error \\([#1326](.)\\)\n - Make PromiseRejectionEvent confrom to spec \\([#1509](.)\\)\n - Fix false unhandled rejection events \\([#1468](.)\\)\n\n## 3.5.5 (2019-05-24)\n\nFeatures:\n\n - Added Symbol.toStringTag support to Promise \\([#1421](.)\\)\n\nBugfixes:\n\n - Fix error in IE9 \\([#1591](.), [#1592](.)\\)\n - Fix error with undefined stack trace \\([#1537](.)\\)\n - Fix [.catch](.) throwing an error later rather than immediately when passed non-function handler \\([#1517](.)\\)\n\n## 3.5.4 (2019-04-03)\n\n- Proper version check supporting VSCode\\([#1576](.)\\)\n\n## 3.5.3 (2018-11-06)\n\nBugfixes:\n\n - Update acorn dependency\n\n## 3.5.2 (2018-09-03)\n\nBugfixes:\n\n - Fix `PromiseRejectionEvent` to contain `.reason` and `.promise` properties. \\([#1509](.), [#1464](.)\\)\n - Fix promise chain retaining memory until the entire chain is resolved  \\([#1544](.), [#1529](.)\\)\n\n\n## 3.5.1 (2017-10-04)\n\nBugfixes:\n\n - Fix false positive unhandled rejection when using async await \\([#1404](.)\\)\n - Fix false positive when reporting error as non-error \\([#990](.)\\)\n\n## 3.5.0 (2017-03-03)\n\nFeatures:\n\n - Added new method: [.tapCatch](.) \\([#1220](.)\\)\n\nBugfixes:\n\n - Fixed streamline benchmarks \\([#1233](.)\\)\n - Fixed yielding a function calling the function \\([#1314](.), [#1315](.)\\)\n - Fixed confusing error message when calling [.catch](.) with non function predicate \\([#1350](.)\\)\n - Fixed [.props](.) resolving to empty object when called with empty `Map` \\([#1338](.)\\)\n - Fixed confusing error message when invoking `Promise` directly without `new` \\([#1320](.)\\)\n - Added dedicated webpack entry point \\([#1318](.)\\)\n\n## 3.4.7 (2016-12-22)\n\n- Promise config returns reference to Bluebird library\n- Updated logo\n- Benchmark fix\n- Don't drop syntaxerror context from stack traces\n- Fix environment variables sometimes causing long stack traces  to be enabled\n\n## 3.4.6 (2016-09-01)\n\nBugfixes:\n\n- Fix [Promise.map](.) and [.map](.) not always calling the callback asynchronously \\([#1148](.)\\)\n\n## 3.4.5 (2016-08-31)\n\nBugfixes:\n\n - Fix unhandled error regression introduced in 3.4.3 [#1217](.)\n\n## 3.4.4 (2016-08-30)\n\nBugfixes:\n\n - Fix benchmark parallel in node 6 [#1165](.)\n - Fix memory leak with Promise.each [#1057](.)\n - Fix thenable passed to .return being evaluated too early [#1210](.)\n - Fix \"unhandledrejection\" event not having .detail field when using DOM3 event listener api [#1209](.)\n - Fix [Promise.join](.) not ensuring asynchronous callback [#1153](.)\n - Fix domains leaking when synchronous error is thrown while a domain is active [#1125](.)\n\n\n\n## 3.4.3 (2016-08-25)\n\nBugfixes:\n\n - The \"a promise was created in a handler but not returned from it\" warning now highlights the file, line and column where the return statement is missing.\n  - The \"a promise was created in a handler but not returned from it\" warning now adds the bluebird API method used to create the non-returned promise at the top of the warning stack\n\n## 3.4.2 (2016-08-24)\n\n\nBugfixes:\n\n - Add missing link to unhandled warning docs \\([#1205](.)\\)\n - Fix [Promise.delay](.) not having a long stack trace \\([#1182](.)\\)\n - Fix false unhandled rejection when a rejected promise originating from one copy of bluebird is passed to another copy's [.return](.) or [.catchReturn](.) \\([#1186](.)\\)\n - Fix Promise.resolve is not a function error \\([#1192](.)\\)\n - Fix global events not being fired through DOM 3 API inside a worker \\([#1190](.)\\)\n - Fix .cancel() not immediately marking a promise as being cancelled if it has cancellable parent \\([#1187](.)\\)\n - Fix maximum callstack exceeded with [Promise.coroutine](.) \\([#1170](.)\\)\n\n## 3.4.1 (2016-06-17)\n\nFeatures:\n\n - Added [Promise.getNewLibraryCopy](.)\n\n## 3.4.0 (2016-05-17)\n\nFeatures:\n\n - Add `Promise.version` which tells the bluebird version as a string e.g. `\"3.4.0\"` ([#1042](.)).\n - [.map](.), [Promise.map](.), [.filter](.) and [Promise.filter](.) now return rejected promise when inappropriate options argument is passed ([#1097](.)).\n\nBugfixes:\n\n- Fix bug where callback to [.disposer](.) is not called if the resource is `null` ([#1099](.)).\n- Fix bug where assimilating thenable throws unexpectedly when using hostile host objects as thenables ([#1104](.)).\n\n## 3.3.5 (2016-04-12)\n\nBugfixes:\n\n - Fix then sometimes not being called on iOS/Firefox ([#1022](.)).\n - Fix custom schedulers not being called when using promisified functions ([#1023](.)).\n - Fix unexpected error being thrown when promisifed function is called with no arguments ([#1063](.)).\n\n## 3.3.4 (2016-03-07)\n\nFeatures:\n\n - Warnings about created promises that are not returned are no longer given if the handler promise has not been chained. This should reduce the amount of false positives with this warning.\n\n## 3.3.3 (2016-02-25)\n\nBugfixes:\n\n - Fix stack overflow error when a promise returned by promisified function rejects early in a huge array when using [Promise.mapSeries](.) or [Promise.each](.)\n\n\n## 3.3.2 (2016-02-25)\n\nBugfixes:\n\n - Fix missing newline in stack trace reported by [.done()](.) ([#1020](.)).\n - Detect deep circular resolutions\n\n## 3.3.1 (2016-02-13)\n\nBugfixes:\n\n - Fix crash when cancelling a [.tap()](.) handler promise ([#1006](.)).\n\n## 3.3.0 (2016-02-12)\n\nFeatures:\n\n - Cancelling Promise returned from [Promise.delay()](.) and [.delay()](.) now calls `clearTimeout` ([#1000](.))\n - Add [monitoring and lifecycle hooks](http://bluebirdjs.com/docs/features.html#promise-monitoring)\n - Add `'warning'` hook for warnings ([#980](.))\n\nBugfixes:\n\n - Fix warnings for \"promise was rejected with non-error\" being output when promises are rejected with errors from different realm ([#990](.))\n\n\n## 3.2.2 (2016-02-05)\n\nBugfixes:\n\n - Make build script's output work without TTY\n\n## 3.2.1 (2016-02-01)\n\nBugfixes:\n\n - Revert monitoring feature due to crash in browser\n\n\n## 3.2.0 (2016-02-01)\n\n- Broken build\n\n## 3.1.5 (2016-01-26)\n\nDummy release to trigger CDN update.\n\n## 3.1.4 (2016-01-25)\n\nBugfixes:\n\n - Fix broken npm prepublish script release\n\n\n## 3.1.3 (2016-01-25)\n\nBugfixes:\n\n - Fix generators crashing in node 0.12 ([#978](.))\n - Add minimal build files to build ([#976](.), [#757](.))\n\n## 3.1.2 (2016-01-23)\n\nFeatures:\n\n - [.timeout()](.) now `clearTimeout`s the timer if the resulting promise is cancelled ([#926](.))\n - [Promise.coroutine](.) now returns function with same `.length` as the original function ([#927](.), [#933](.))\n\nBugfixes:\n\n - Fix long stack traces not working when promise is created from [Promise.fromCallback](.) ([#971](.))\n - Fix [.finally()](.) handlers not being called when promise is cancelled while a domain is active ([#963](.))\n - Fix [.timeout()](.) trying to cancel a promise even if cancellation is disabled ([#970](.))\n\n## 3.1.1 (2015-12-16)\n\nBugfixes:\n\n - Disable wForgottenWarning when all warnings are disabled\n\n\n## 3.1.0 (2015-12-16)\n\nFeatures:\n\n - Added ability to configure the [forgotten return statement](http://bluebirdjs.com/docs/warning-explanations.html#warning-a-promise-was-created-in-a-handler-but-none-were-returned-from-it) warning separately \\([#920](.)\\).\n\nBugfixes:\n\n- Fixed the bug where returning a value from [.finally](.) or [.tap](.) handler did not make a warning about a forgotten return go away \\([#846](.)\\).\n- Fixed the bug where setTimeout is used in Chrome instead of MutationObserver \\([#915](.)\\)\n- Fixed the bug where using [.bind](.) suppressed unhandled rejections \\([#841](.)\\)\n\n## 3.0.6 (2015-12-01)\n\nBugfixes:\n\n - Fix [.timeout()](.) not cancelling parent \\([#891](.)\\)\n - Fix long stack traces when using [Promise.resolve()](.) \\([#861](.)\\)\n - Fix [Promise.config()](.) not disabling long stack traces when passing `longStackTraces: false` \\([#897](.)\\)\n\n## 3.0.5 (2015-11-01)\n\nBugfixes:\n\n - Added [forgotten return warnings](http://bluebirdjs.com/docs/warning-explanations.html#warning-a-promise-was-created-in-a-handler-but-none-were-returned-from-it)  to [Promise.try](.) and [Promise.method](.)\n\n## 3.0.4 (2015-11-01)\n\nBugfixes:\n\n - The stack trace for [forgotten return warnings](http://bluebirdjs.com/docs/warning-explanations.html#warning-a-promise-was-created-in-a-handler-but-none-were-returned-from-it) is more useful now.\n\n\n## 3.0.3 (2015-11-01)\n\nBugfixes:\n\n - 3rd party libraries rejecting promises with non-errors no longer causes warnings\n - When `NODE_ENV` environment variable is `\"development\"` setting `BLUEBIRD_DEBUG` environment variable to `0` can now be used to disable debug mode\n\n## 3.0.2 (2015-10-29)\n\nBugfixes:\n\n - Fix crash when using node.js domains [#829](.)\n\n## 3.0.1 (2015-10-28)\n\nSee [New in 3.0](new-in-bluebird-3.html).\n\n## 3.0.0 (2015-10-27)\n\nSee [New in 3.0](new-in-bluebird-3.html).\n\n## 2.11.0 (2016-08-30)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 2.10.2 (2015-10-01)\n\nFeatures:\n\n - [.timeout()](.) now takes a custom error object as second argument\n\n## 2.10.1 (2015-09-21)\n\n - Fix error \"Cannot promisify an API that has normal methods with 'Async'-suffix\" when promisifying certain objects with a custom promisifier\n\n## 2.10.0 (2015-09-08)\n\nFeatures:\n\n - `Promise.using` can now take the promises-for-resources as an array ([#733](.)).\n - Browser builds for minimal core are now hosted on CDN ([#724](.)).\n\nBugfixes:\n\n - Disabling debug mode with `BLUEBIRD_DEBUG=0` environment variable now works ([#719](.)).\n - Fix unhandled rejection reporting when passing rejected promise to `.return()` ([#721](.)).\n - Fix unbound promise's then handlers being called with wrong `this` value ([#738](.)).\n\n## 2.9.34 (2015-07-15)\n\nBugfixes:\n\n-  Correct domain for .map, .each, .filter, .reduce callbacks ([#701](.)).\n - Preserve bound-with-promise promises across the entire chain ([#702](.)).\n\n## 2.9.33 (2015-07-09)\n\nBugfixes:\n\n - Methods on `Function.prototype` are no longer promisified ([#680](.)).\n\n## 2.9.32 (2015-07-03)\n\nBugfixes:\n\n - Fix `.return(primitiveValue)` returning a wrapped version of the primitive value when a Node.js domain is active ([#689](.)).\n\n## 2.9.31 (2015-07-03)\n\nBugfixes:\n\n - Fix Promises/A+ compliance issue regarding circular thenables: the correct behavior is to go into an infinite loop instead of warning with an error (Fixes [#682](.)).\n - Fix \"(node) warning: possible EventEmitter memory leak detected\" ([#661](.)).\n - Fix callbacks sometimes being called with a wrong node.js domain ([#664](.)).\n - Fix callbacks sometimes not being called at all in iOS 8.1 WebApp mode ([#666](.), [#687](.)).\n\n## 2.9.30 (2015-06-14)\n\nBugfixes:\n\n - Fix regression with `promisifyAll` not promisifying certain methods\n\n## 2.9.29 (2015-06-14)\n\nBugfixes:\n\n - Improve `promisifyAll` detection of functions that are class constructors. Fixes mongodb 2.x promisification.\n\n## 2.9.28 (2015-06-14)\n\nBugfixes:\n\n - Fix handled rejection being reported as unhandled in certain scenarios when using [.all](.) or [Promise.join](.) ([#645](.))\n - Fix custom scheduler not being called in Google Chrome when long stack traces are enabled ([#650](.))\n\n## 2.9.27 (2015-05-30)\n\nBugfixes:\n\n - Fix `sinon.useFakeTimers()` breaking scheduler ([#631](.))\n\nMisc:\n\n - Add nw testing facilities (`node tools/test --nw`)\n\n## 2.9.26 (2015-05-25)\n\nBugfixes:\n\n - Fix crash in NW [#624](.)\n - Fix [`.return()`](.) not supporting `undefined` as return value [#627](.)\n\n## 2.9.25 (2015-04-28)\n\nBugfixes:\n\n - Fix crash in node 0.8\n\n## 2.9.24 (2015-04-02)\n\nBugfixes:\n\n - Fix not being able to load multiple bluebird copies introduced in 2.9.22 ([#559](.), [#561](.), [#560](.)).\n\n## 2.9.23 (2015-04-02)\n\nBugfixes:\n\n - Fix node.js domain propagation ([#521](.)).\n\n## 2.9.22 (2015-04-02)\n\n - Fix `.promisify` crashing in phantom JS ([#556](.))\n\n## 2.9.21 (2015-03-30)\n\n - Fix error object's `'stack'`' overwriting causing an error when its defined to be a setter that throws an error ([#552](.)).\n\n## 2.9.20 (2015-03-29)\n\nBugfixes:\n\n - Fix regression where there is a long delay between calling `.cancel()` and promise actually getting cancelled in Chrome when long stack traces are enabled\n\n## 2.9.19 (2015-03-29)\n\nBugfixes:\n\n - Fix crashing in Chrome when long stack traces are disabled\n\n## 2.9.18 (2015-03-29)\n\nBugfixes:\n\n - Fix settlePromises using trampoline\n\n## 2.9.17 (2015-03-29)\n\n\nBugfixes:\n\n - Fix Chrome DevTools async stack traceability ([#542](.)).\n\n## 2.9.16 (2015-03-28)\n\nFeatures:\n\n - Use setImmediate if available\n\n## 2.9.15 (2015-03-26)\n\nFeatures:\n\n - Added `.asCallback` alias for `.nodeify`.\n\nBugfixes:\n\n - Don't always use nextTick, but try to pick up setImmediate or setTimeout in NW. Fixes [#534](.), [#525](.)\n - Make progress a core feature. Fixes [#535](.) Note that progress has been removed in 3.x - this is only a fix necessary for 2.x custom builds.\n\n## 2.9.14 (2015-03-12)\n\nBugfixes:\n\n - Always use process.nextTick. Fixes [#525](.)\n\n## 2.9.13 (2015-02-27)\n\nBugfixes:\n\n - Fix .each, .filter, .reduce and .map callbacks being called synchornously if the input is immediate. ([#513](.))\n\n## 2.9.12 (2015-02-19)\n\nBugfixes:\n\n - Fix memory leak introduced in 2.9.0 ([#502](.))\n\n## 2.9.11 (2015-02-19)\n\nBugfixes:\n\n - Fix [#503](.)\n\n## 2.9.10 (2015-02-18)\n\nBugfixes:\n\n - Fix [#501](.)\n\n## 2.9.9 (2015-02-12)\n\nBugfixes:\n\n - Fix `TypeError: Cannot assign to read only property 'length'` when jsdom has declared a read-only length for all objects to inherit.\n\n## 2.9.8 (2015-02-10)\n\nBugfixes:\n\n - Fix regression introduced in 2.9.7 where promisify didn't properly dynamically look up methods on `this`\n\n## 2.9.7 (2015-02-08)\n\nBugfixes:\n\n - Fix `promisify` not retaining custom properties of the function. This enables promisifying the `\"request\"` module's export function and its methods at the same time.\n - Fix `promisifyAll` methods being dependent on `this` when they are not originally dependent on `this`. This enables e.g. passing promisified `fs` functions directly as callbacks without having to bind them to `fs`.\n - Fix `process.nextTick` being used over `setImmediate` in node.\n\n## 2.9.6 (2015-02-02)\n\nBugfixes:\n\n - Node environment detection can no longer be fooled\n\n## 2.9.5 (2015-02-02)\n\nMisc:\n\n - Warn when [`.then()`](.) is passed non-functions\n\n## 2.9.4 (2015-01-30)\n\nBugfixes:\n\n - Fix [.timeout()](.) not calling `clearTimeout` with the proper handle in node causing the process to wait for unneeded timeout. This was a regression introduced in 2.9.1.\n\n## 2.9.3 (2015-01-27)\n\nBugfixes:\n\n - Fix node-webkit compatibility issue ([#467](https://github.com/petkaantonov/bluebird/pull/467))\n - Fix long stack trace support in recent firefox versions\n\n## 2.9.2 (2015-01-26)\n\nBugfixes:\n\n - Fix critical bug regarding to using promisifyAll in browser that was introduced in 2.9.0 ([#466](https://github.com/petkaantonov/bluebird/issues/466)).\n\nMisc:\n\n - Add `\"browser\"` entry point to package.json\n\n## 2.9.1 (2015-01-24)\n\nFeatures:\n\n - If a bound promise is returned by the callback to [`Promise.method`](.) and [`Promise.try`](.), the returned promise will be bound to the same value\n\n## 2.9.0 (2015-01-24)\n\nFeatures:\n\n - Add [`Promise.fromNode`](.)\n - Add new paramter `value` for [`Promise.bind`](.)\n\nBugfixes:\n\n - Fix several issues with [`cancellation`](.) and [`.bind()`](.) interoperation when `thisArg` is a promise or thenable\n - Fix promises created in [`disposers`](.) not having proper long stack trace context\n - Fix [`Promise.join`](.) sometimes passing the passed in callback function as the last argument to itself.\n\nMisc:\n\n - Reduce minified full browser build file size by not including unused code generation functionality.\n - Major internal refactoring related to testing code and source code file layout\n\n## 2.8.2 (2015-01-20)\n\nFeatures:\n\n - [Global rejection events](https://github.com/petkaantonov/bluebird/blob/master/API.md#global-rejection-events) are now fired both as DOM3 events and as legacy events in browsers\n\n## 2.8.1 (2015-01-20)\n\nBugfixes:\n\n - Fix long stack trace stiching consistency when rejected from thenables\n\n## 2.8.0 (2015-01-19)\n\nFeatures:\n\n - Major debuggability improvements:\n    - Long stack traces have been re-designed. They are now much more readable,\n      succint, relevant and consistent across bluebird features.\n    - Long stack traces are supported now in IE10+\n\n## 2.7.1 (2015-01-15)\n\nBugfixes:\n\n - Fix [#447](.)\n\n## 2.7.0 (2015-01-15)\n\nFeatures:\n\n - Added more context to stack traces originating from coroutines ([#421](https://github.com/petkaantonov/bluebird/issues/421))\n - Implemented [global rejection events](https://github.com/petkaantonov/bluebird/blob/master/API.md#global-rejection-events) ([#428](https://github.com/petkaantonov/bluebird/issues/428), [#357](https://github.com/petkaantonov/bluebird/issues/357))\n - [Custom promisifiers](https://github.com/petkaantonov/bluebird/blob/master/API.md#option-promisifier) are now passed the default promisifier which can be used to add enhancements on top of normal node promisification\n - [Promisification filters](https://github.com/petkaantonov/bluebird/blob/master/API.md#option-filter) are now passed `passesDefaultFilter` boolean\n\nBugfixes:\n\n - Fix `.noConflict()` call signature ([#446]())\n - Fix `Promise.method`ified functions being called with `undefined` when they were called with no arguments\n\n## 2.6.4 (2015-01-12)\n\nBugfixes:\n\n - `OperationalErrors` thrown by promisified functions retain custom properties, such as `.code` and `.path`.\n\n## 2.6.3 (2015-01-12)\n\nBugfixes:\n\n - Fix [#429](https://github.com/petkaantonov/bluebird/issues/429)\n - Fix [#432](https://github.com/petkaantonov/bluebird/issues/432)\n - Fix [#433](https://github.com/petkaantonov/bluebird/issues/433)\n\n## 2.6.2 (2015-01-07)\n\nBugfixes:\n\n - Fix [#426](https://github.com/petkaantonov/bluebird/issues/426)\n\n## 2.6.1 (2015-01-07)\n\nBugfixes:\n\n - Fixed built browser files not being included in the git tag release for bower\n\n## 2.6.0 (2015-01-06)\n\nFeatures:\n\n - Significantly improve parallel promise performance and memory usage (+50% faster, -50% less memory)\n\n\n## 2.5.3 (2014-12-30)\n\n## 2.5.2 (2014-12-29)\n\nBugfixes:\n\n - Fix bug where already resolved promise gets attached more handlers while calling its handlers resulting in some handlers not being called\n - Fix bug where then handlers are not called in the same order as they would run if Promises/A+ 2.3.2 was implemented as adoption\n - Fix bug where using `Object.create(null)` as a rejection reason would crash bluebird\n\n## 2.5.1 (2014-12-29)\n\nBugfixes:\n\n - Fix `.finally` throwing null error when it is derived from a promise that is resolved with a promise that is resolved with a promise\n\n## 2.5.0 (2014-12-28)\n\nFeatures:\n\n - [`.get`](.) now supports negative indexing.\n\nBugfixes:\n\n - Fix bug with `Promise.method` wrapped function returning a promise that never resolves if the function returns a promise that is resolved with another promise\n - Fix bug with `Promise.delay` never resolving if the value is a promise that is resolved with another promise\n\n## 2.4.3 (2014-12-28)\n\nBugfixes:\n\n - Fix memory leak as described in [this Promises/A+ spec issue](https://github.com/promises-aplus/promises-spec/issues/179).\n\n## 2.4.2 (2014-12-21)\n\nBugfixes:\n\n - Fix bug where spread rejected handler is ignored in case of rejection\n - Fix synchronous scheduler passed to `setScheduler` causing infinite loop\n\n## 2.4.1 (2014-12-20)\n\nFeatures:\n\n - Error messages now have links to wiki pages for additional information\n - Promises now clean up all references (to handlers, child promises etc) as soon as possible.\n\n## 2.4.0 (2014-12-18)\n\nFeatures:\n\n - Better filtering of bluebird internal calls in long stack traces, especially when using minified file in browsers\n - Small performance improvements for all collection methods\n - Promises now delete references to handlers attached to them as soon as possible\n - Additional stack traces are now output on stderr/`console.warn` for errors that are thrown in the process/window from rejected `.done()` promises. See [#411](https://github.com/petkaantonov/bluebird/issues/411)\n\n## 2.3.11 (2014-10-31)\n\nBugfixes:\n\n - Fix [#371](https://github.com/petkaantonov/bluebird/issues/371), [#373](https://github.com/petkaantonov/bluebird/issues/373)\n\n\n## 2.3.10 (2014-10-28)\n\nFeatures:\n\n - `Promise.method` no longer wraps primitive errors\n - `Promise.try` no longer wraps primitive errors\n\n## 2.3.7 (2014-10-25)\n\nBugfixes:\n\n - Fix [#359](https://github.com/petkaantonov/bluebird/issues/359), [#362](https://github.com/petkaantonov/bluebird/issues/362) and [#364](https://github.com/petkaantonov/bluebird/issues/364)\n\n## 2.3.6 (2014-10-15)\n\nFeatures:\n\n - Implement [`.reflect()`](.)\n\n## 2.3.5 (2014-10-06)\n\nBugfixes:\n\n - Fix issue when promisifying methods whose names contain the string 'args'\n\n## 2.3.4 (2014-09-27)\n\n - `P` alias was not declared inside WebWorkers\n\n## 2.3.3 (2014-09-27)\n\nBugfixes:\n\n - Fix [#318](https://github.com/petkaantonov/bluebird/issues/318), [#314](https://github.com/petkaantonov/bluebird/issues/#314)\n\n## 2.3.2 (2014-08-25)\n\nBugfixes:\n\n - `P` alias for `Promise` now exists in global scope when using browser builds without a module loader, fixing an issue with firefox extensions\n\n## 2.3.1 (2014-08-23)\n\nFeatures:\n\n - `.using` can now be used with disposers created from different bluebird copy\n\n## 2.3.0 (2014-08-13)\n\nFeatures:\n\n - [`.bind()`](.) and [`Promise.bind()`](.) now await for the resolution of the `thisArg` if it's a promise or a thenable\n\nBugfixes:\n\n - Fix [#276](https://github.com/petkaantonov/bluebird/issues/276)\n\n## 2.2.2 (2014-07-14)\n\n - Fix [#259](https://github.com/petkaantonov/bluebird/issues/259)\n\n## 2.2.1 (2014-07-07)\n\n - Fix multiline error messages only showing the first line\n\n## 2.2.0 (2014-07-07)\n\nBugfixes:\n\n - `.any` and `.some` now consistently reject with RangeError when input array contains too few promises\n - Fix iteration bug with `.reduce` when input array contains already fulfilled promises\n\n## 2.1.3 (2014-06-18)\n\nBugfixes:\n\n - Fix [#235](https://github.com/petkaantonov/bluebird/issues/235)\n\n## 2.1.2 (2014-06-15)\n\nBugfixes:\n\n - Fix [#232](https://github.com/petkaantonov/bluebird/issues/232)\n\n## 2.1.1 (2014-06-11)\n\n## 2.1.0 (2014-06-11)\n\nFeatures:\n\n - Add [`promisifier`](.) option to `Promise.promisifyAll()`\n - Improve performance of `.props()` and collection methods when used with immediate values\n\n\nBugfixes:\n\n - Fix a bug where .reduce calls the callback for an already visited item\n - Fix a bug where stack trace limit is calculated to be too small, which resulted in too short stack traces\n\n<sub>Add undocumented experimental `yieldHandler` option to `Promise.coroutine`</sub>\n\n## 2.0.7 (2014-06-08)\n## 2.0.6 (2014-06-07)\n## 2.0.5 (2014-06-05)\n## 2.0.4 (2014-06-05)\n## 2.0.3 (2014-06-05)\n## 2.0.2 (2014-06-04)\n## 2.0.1 (2014-06-04)\n\n## 2.0.0 (2014-06-04)\n\n#What's new in 2.0\n\n- [Resource management](api-reference.html#resource-management) - never leak resources again\n- [Promisification](api-reference.html#promisification) on steroids - entire modules can now be promisified with one line of code\n- [`.map()`](.), [`.each()`](.), [`.filter()`](.), [`.reduce()`](.) reimagined from simple sugar to powerful concurrency coordination tools\n- [API Documentation](api-reference.html) has been reorganized and more elaborate examples added\n- Deprecated [progression](#progression-migration) and [deferreds](#deferred-migration)\n- Improved performance and readability\n\nFeatures:\n\n- Added [`using()`](.) and [`disposer()`](.)\n- [`.map()`](.) now calls the handler as soon as items in the input array become fulfilled\n- Added a concurrency option to [`.map()`](.)\n- [`.filter()`](.) now calls the handler as soon as items in the input array become fulfilled\n- Added a concurrency option to [`.filter()`](.)\n- [`.reduce()`](.) now calls the handler as soon as items in the input array become fulfilled, but in-order\n- Added [`.each()`](.)\n- [`Promise.resolve()`](.) behaves like `Promise.cast`. `Promise.cast` deprecated.\n- [Synchronous inspection](api-reference.html#synchronous-inspection): Removed `.inspect()`, added [`.value()`](.) and [`.reason()`](.)\n- [`Promise.join()`](.) now takes a function as the last argument\n- Added [`Promise.setScheduler()`](.)\n- [`.cancel()`](.) supports a custom cancellation reason\n- [`.timeout()`](.) now cancels the promise instead of rejecting it\n- [`.nodeify()`](.) now supports passing multiple success results when mapping promises to nodebacks\n- Added `suffix` and `filter` options to [`Promise.promisifyAll()`](.)\n\nBreaking changes:\n\n- Sparse array holes are not skipped by collection methods but treated as existing elements with `undefined` value\n- `.map()` and `.filter()` do not call the given mapper or filterer function in any specific order\n- Removed the `.inspect()` method\n- Yielding an array from a coroutine is not supported by default. You can use [`coroutine.addYieldHandler()`](.) to configure the old behavior (or any behavior you want).\n- [`.any()`](.) and [`.some()`](.) no longer use an array as the rejection reason. [`AggregateError`](.) is used instead.\n\n\n## 1.2.4 (2014-04-27)\n\nBugfixes:\n\n - Fix promisifyAll causing a syntax error when a method name is not a valid identifier\n - Fix syntax error when es5.js is used in strict mode\n\n## 1.2.3 (2014-04-17)\n\nBugfixes:\n\n - Fix [#179](https://github.com/petkaantonov/bluebird/issues/179)\n\n## 1.2.2 (2014-04-09)\n\nBugfixes:\n\n - Promisified methods from promisifyAll no longer call the original method when it is overriden\n - Nodeify doesn't pass second argument to the callback if the promise is fulfilled with `undefined`\n\n## 1.2.1 (2014-03-31)\n\nBugfixes:\n\n - Fix [#168](https://github.com/petkaantonov/bluebird/issues/168)\n\n## 1.2.0 (2014-03-29)\n\nFeatures:\n\n - New method: [`.value()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#value---dynamic)\n - New method: [`.reason()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#reason---dynamic)\n - New method: [`Promise.onUnhandledRejectionHandled()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#promiseonunhandledrejectionhandledfunction-handler---undefined)\n - `Promise.map()`, `.map()`, `Promise.filter()` and `.filter()` start calling their callbacks as soon as possible while retaining a correct order. See [`8085922f`](https://github.com/petkaantonov/bluebird/commit/8085922fb95a9987fda0cf2337598ab4a98dc315).\n\nBugfixes:\n\n - Fix [#165](https://github.com/petkaantonov/bluebird/issues/165)\n - Fix [#166](https://github.com/petkaantonov/bluebird/issues/166)\n\n## 1.1.1 (2014-03-18)\n\nBugfixes:\n\n - [#138](https://github.com/petkaantonov/bluebird/issues/138)\n - [#144](https://github.com/petkaantonov/bluebird/issues/144)\n - [#148](https://github.com/petkaantonov/bluebird/issues/148)\n - [#151](https://github.com/petkaantonov/bluebird/issues/151)\n\n## 1.1.0 (2014-03-08)\n\nFeatures:\n\n - Implement [`Promise.prototype.tap()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#tapfunction-handler---promise)\n - Implement [`Promise.coroutine.addYieldHandler()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#promisecoroutineaddyieldhandlerfunction-handler---void)\n - Deprecate `Promise.prototype.spawn`\n\nBugfixes:\n\n - Fix already rejected promises being reported as unhandled when handled through collection methods\n - Fix browserisfy crashing from checking `process.version.indexOf`\n\n## 1.0.8 (2014-03-03)\n\nBugfixes:\n\n - Fix active domain being lost across asynchronous boundaries in Node.JS 10.xx\n\n## 1.0.7 (2014-02-25)\n\nBugfixes:\n\n - Fix handled errors being reported\n\n## 1.0.6 (2014-02-17)\n\nBugfixes:\n\n -  Fix bug with unhandled rejections not being reported\n    when using `Promise.try` or `Promise.method` without\n    attaching further handlers\n\n## 1.0.5 (2014-02-15)\n\nFeatures:\n\n - Node.js performance: promisified functions try to check amount of passed arguments in most optimal order\n - Node.js promisified functions will have same `.length` as the original function minus one (for the callback parameter)\n\n## 1.0.4 (2014-02-09)\n\nFeatures:\n\n - Possibly unhandled rejection handler will always get a stack trace, even if the rejection or thrown error was not an error\n - Unhandled rejections are tracked per promise, not per error. So if you create multiple branches from a single ancestor and that ancestor gets rejected, each branch with no error handler with the end will cause a possibly unhandled rejection handler invocation\n\nBugfixes:\n\n - Fix unhandled non-writable objects or primitives not reported by possibly unhandled rejection handler\n\n## 1.0.3 (2014-02-05)\n\nBugfixes:\n\n - [#93](https://github.com/petkaantonov/bluebird/issues/88)\n\n## 1.0.2 (2014-02-04)\n\nFeatures:\n\n - Significantly improve performance of foreign bluebird thenables\n\nBugfixes:\n\n - [#88](https://github.com/petkaantonov/bluebird/issues/88)\n\n## 1.0.1 (2014-01-28)\n\nFeatures:\n\n - Error objects that have property `.isAsync = true` will now be caught by `.error()`\n\nBugfixes:\n\n - Fix TypeError and RangeError shims not working without `new` operator\n\n## 1.0.0 (2014-01-12)\n\nFeatures:\n\n - `.filter`, `.map`, and `.reduce` no longer skip sparse array holes. This is a backwards incompatible change.\n - Like `.map` and `.filter`, `.reduce` now allows returning promises and thenables from the iteration function.\n\nBugfixes:\n\n - [#58](https://github.com/petkaantonov/bluebird/issues/58)\n - [#61](https://github.com/petkaantonov/bluebird/issues/61)\n - [#64](https://github.com/petkaantonov/bluebird/issues/64)\n - [#60](https://github.com/petkaantonov/bluebird/issues/60)\n\n## 0.11.6-1 (2013-12-29)\n\n## 0.11.6-0 (2013-12-29)\n\nFeatures:\n\n - You may now return promises and thenables from the filterer function used in `Promise.filter` and `Promise.prototype.filter`.\n\n - `.error()` now catches additional sources of rejections:\n\n    - Rejections originating from `Promise.reject`\n\n    - Rejections originating from thenables using\n    the `reject` callback\n\n    - Rejections originating from promisified callbacks\n    which use the `errback` argument\n\n    - Rejections originating from `new Promise` constructor\n    where the `reject` callback is called explicitly\n\n    - Rejections originating from `PromiseResolver` where\n    `.reject()` method is called explicitly\n\nBugfixes:\n\n - Fix `captureStackTrace` being called when it was `null`\n - Fix `Promise.map` not unwrapping thenables\n\n## 0.11.5-1 (2013-12-15)\n\n## 0.11.5-0 (2013-12-03)\n\nFeatures:\n\n - Improve performance of collection methods\n - Improve performance of promise chains\n\n## 0.11.4-1 (2013-12-02)\n\n## 0.11.4-0 (2013-12-02)\n\nBugfixes:\n\n - Fix `Promise.some` behavior with arguments like negative integers, 0...\n - Fix stack traces of synchronously throwing promisified functions'\n\n## 0.11.3-0 (2013-12-02)\n\nFeatures:\n\n - Improve performance of generators\n\nBugfixes:\n\n - Fix critical bug with collection methods.\n\n## 0.11.2-0 (2013-12-02)\n\nFeatures:\n\n - Improve performance of all collection methods\n\n## 0.11.1-0 (2013-12-02)\n\nFeatures:\n\n- Improve overall performance.\n- Improve performance of promisified functions.\n- Improve performance of catch filters.\n- Improve performance of .finally.\n\nBugfixes:\n\n- Fix `.finally()` rejecting if passed non-function. It will now ignore non-functions like `.then`.\n- Fix `.finally()` not converting thenables returned from the handler to promises.\n- `.spread()` now rejects if the ultimate value given to it is not spreadable.\n\n## 0.11.0-0 (2013-12-02)\n\nFeatures:\n\n - Improve overall performance when not using `.bind()` or cancellation.\n - Promises are now not cancellable by default. This is backwards incompatible change - see [`.cancellable()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#cancellable---promise)\n - [`Promise.delay`](https://github.com/petkaantonov/bluebird/blob/master/API.md#promisedelaydynamic-value-int-ms---promise)\n - [`.delay()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#delayint-ms---promise)\n - [`.timeout()`](https://github.com/petkaantonov/bluebird/blob/master/API.md#timeoutint-ms--string-message---promise)\n\n## 0.10.14-0 (2013-12-01)\n\nBugfixes:\n\n - Fix race condition when mixing 3rd party asynchrony.\n\n## 0.10.13-1 (2013-11-30)\n\n## 0.10.13-0 (2013-11-30)\n\nBugfixes:\n\n - Fix another bug with progression.\n\n## 0.10.12-0 (2013-11-30)\n\nBugfixes:\n\n - Fix bug with progression.\n\n## 0.10.11-4 (2013-11-29)\n\n## 0.10.11-2 (2013-11-29)\n\nBugfixes:\n\n - Fix `.race()` not propagating bound values.\n\n## 0.10.11-1 (2013-11-29)\n\nFeatures:\n\n - Improve performance of `Promise.race`\n\n## 0.10.11-0 (2013-11-29)\n\nBugfixes:\n\n - Fixed `Promise.promisifyAll` invoking property accessors. Only data properties with function values are considered.\n\n## 0.10.10-0 (2013-11-28)\n\nFeatures:\n\n - Disable long stack traces in browsers by default. Call `Promise.longStackTraces()` to enable them.\n\n## 0.10.9-1 (2013-11-27)\n\nBugfixes:\n\n - Fail early when `new Promise` is constructed incorrectly\n\n## 0.10.9-0 (2013-11-27)\n\nBugfixes:\n\n - Promise.props now takes a [thenable-for-collection](https://github.com/petkaantonov/bluebird/blob/f41edac61b7c421608ff439bb5a09b7cffeadcf9/test/mocha/props.js#L197-L217)\n - All promise collection methods now reject when a promise-or-thenable-for-collection turns out not to give a collection\n\n## 0.10.8-0 (2013-11-25)\n\nFeatures:\n\n - All static collection methods take thenable-for-collection\n\n## 0.10.7-0 (2013-11-25)\n\nFeatures:\n\n - throw TypeError when thenable resolves with itself\n - Make .race() and Promise.race() forever pending on empty collections\n\n## 0.10.6-0 (2013-11-25)\n\nBugfixes:\n\n - Promise.resolve and PromiseResolver.resolve follow thenables too.\n\n## 0.10.5-0 (2013-11-24)\n\nBugfixes:\n\n - Fix infinite loop when thenable resolves with itself\n\n## 0.10.4-1 (2013-11-24)\n\nBugfixes:\n\n - Fix a file missing from build. (Critical fix)\n\n## 0.10.4-0 (2013-11-24)\n\nFeatures:\n\n - Remove dependency of es5-shim and es5-sham when using ES3.\n\n## 0.10.3-0 (2013-11-24)\n\nFeatures:\n\n - Improve performance of `Promise.method`\n\n## 0.10.2-1 (2013-11-24)\n\nFeatures:\n\n - Rename PromiseResolver#asCallback to PromiseResolver#callback\n\n## 0.10.2-0 (2013-11-24)\n\nFeatures:\n\n - Remove memoization of thenables\n\n## 0.10.1-0 (2013-11-21)\n\nFeatures:\n\n - Add methods `Promise.resolve()`, `Promise.reject()`, `Promise.defer()` and `.resolve()`.\n\n## 0.10.0-1 (2013-11-17)\n\n## 0.10.0-0 (2013-11-17)\n\nFeatures:\n\n - Implement `Promise.method()`\n - Implement `.return()`\n - Implement `.throw()`\n\nBugfixes:\n\n - Fix promises being able to use themselves as resolution or follower value\n\n## 0.9.11-1 (2013-11-14)\n\nFeatures:\n\n - Implicit `Promise.all()` when yielding an array from generators\n\n## 0.9.11-0 (2013-11-13)\n\nBugfixes:\n\n - Fix `.spread` not unwrapping thenables\n\n## 0.9.10-2 (2013-11-13)\n\nFeatures:\n\n - Improve performance of promisified functions on V8\n\nBugfixes:\n\n - Report unhandled rejections even when long stack traces are disabled\n - Fix `.error()` showing up in stack traces\n\n## 0.9.10-1 (2013-11-05)\n\nBugfixes:\n\n - Catch filter method calls showing in stack traces\n\n## 0.9.10-0 (2013-11-05)\n\nBugfixes:\n\n - Support primitives in catch filters\n\n## 0.9.9-0 (2013-11-05)\n\nFeatures:\n\n - Add `Promise.race()` and `.race()`\n\n## 0.9.8-0 (2013-11-01)\n\nBugfixes:\n\n - Fix bug with `Promise.try` not unwrapping returned promises and thenables\n\n## 0.9.7-0 (2013-10-29)\n\nBugfixes:\n\n - Fix bug with build files containing duplicated code for promise.js\n\n## 0.9.6-0 (2013-10-28)\n\nFeatures:\n\n - Improve output of reporting unhandled non-errors\n - Implement RejectionError wrapping and `.error()` method\n\n## 0.9.5-0 (2013-10-27)\n\nFeatures:\n\n - Allow fresh copies of the library to be made\n\n## 0.9.4-1 (2013-10-27)\n\n## 0.9.4-0 (2013-10-27)\n\nBugfixes:\n\n - Rollback non-working multiple fresh copies feature\n\n## 0.9.3-0 (2013-10-27)\n\nFeatures:\n\n - Allow fresh copies of the library to be made\n - Add more components to customized builds\n\n## 0.9.2-1 (2013-10-25)\n\n## 0.9.2-0 (2013-10-25)\n\nFeatures:\n\n - Allow custom builds\n\n## 0.9.1-1 (2013-10-22)\n\nBugfixes:\n\n - Fix unhandled rethrown exceptions not reported\n\n## 0.9.1-0 (2013-10-22)\n\nFeatures:\n\n - Improve performance of `Promise.try`\n - Extend `Promise.try` to accept arguments and ctx to make it more usable in promisification of synchronous functions.\n\n## 0.9.0-0 (2013-10-18)\n\nFeatures:\n\n - Implement `.bind` and `Promise.bind`\n\nBugfixes:\n\n - Fix `.some()` when argument is a pending promise that later resolves to an array\n\n## 0.8.5-1 (2013-10-17)\n\nFeatures:\n\n - Enable process wide long stack traces through BLUEBIRD_DEBUG environment variable\n\n## 0.8.5-0 (2013-10-16)\n\nFeatures:\n\n - Improve performance of all collection methods\n\nBugfixes:\n\n - Fix .finally passing the value to handlers\n - Remove kew from benchmarks due to bugs in the library breaking the benchmark\n - Fix some bluebird library calls potentially appearing in stack traces\n\n## 0.8.4-1 (2013-10-15)\n\nBugfixes:\n\n - Fix .pending() call showing in long stack traces\n\n## 0.8.4-0 (2013-10-15)\n\nBugfixes:\n\n - Fix PromiseArray and its sub-classes swallowing possibly unhandled rejections\n\n## 0.8.3-3 (2013-10-14)\n\nBugfixes:\n\n - Fix AMD-declaration using named module.\n\n## 0.8.3-2 (2013-10-14)\n\nFeatures:\n\n - The mortals that can handle it may now release Zalgo by `require(\"bluebird/zalgo\");`\n\n## 0.8.3-1 (2013-10-14)\n\nBugfixes:\n\n - Fix memory leak when using the same promise to attach handlers over and over again\n\n## 0.8.3-0 (2013-10-13)\n\nFeatures:\n\n - Add `Promise.props()` and `Promise.prototype.props()`. They work like `.all()` for object properties.\n\nBugfixes:\n\n - Fix bug with .some returning garbage when sparse arrays have rejections\n\n## 0.8.2-2 (2013-10-13)\n\nFeatures:\n\n - Improve performance of `.reduce()` when `initialValue` can be synchronously cast to a value\n\n## 0.8.2-1 (2013-10-12)\n\nBugfixes:\n\n - Fix .npmignore having irrelevant files\n\n## 0.8.2-0 (2013-10-12)\n\nFeatures:\n\n - Improve performance of `.some()`\n\n## 0.8.1-0 (2013-10-11)\n\nBugfixes:\n\n - Remove uses of dynamic evaluation (`new Function`, `eval` etc) when strictly not necessary. Use feature detection to use static evaluation to avoid errors when dynamic evaluation is prohibited.\n\n## 0.8.0-3 (2013-10-10)\n\nFeatures:\n\n - Add `.asCallback` property to `PromiseResolver`s\n\n## 0.8.0-2 (2013-10-10)\n\n## 0.8.0-1 (2013-10-09)\n\nFeatures:\n\n - Improve overall performance. Be able to sustain infinite recursion when using promises.\n\n## 0.8.0-0 (2013-10-09)\n\nBugfixes:\n\n - Fix stackoverflow error when function calls itself \"synchronously\" from a promise handler\n\n## 0.7.12-2 (2013-10-09)\n\nBugfixes:\n\n - Fix safari 6 not using `MutationObserver` as a scheduler\n - Fix process exceptions interfering with internal queue flushing\n\n## 0.7.12-1 (2013-10-09)\n\nBugfixes:\n\n - Don't try to detect if generators are available to allow shims to be used\n\n## 0.7.12-0 (2013-10-08)\n\nFeatures:\n\n - Promisification now consider all functions on the object and its prototype chain\n - Individual promisifcation uses current `this` if no explicit receiver is given\n - Give better stack traces when promisified callbacks throw or errback primitives such as strings by wrapping them in an `Error` object.\n\nBugfixes:\n\n - Fix runtime APIs throwing synchronous errors\n\n## 0.7.11-0 (2013-10-08)\n\nFeatures:\n\n - Deprecate `Promise.promisify(Object target)` in favor of `Promise.promisifyAll(Object target)` to avoid confusion with function objects\n - Coroutines now throw error when a non-promise is `yielded`\n\n## 0.7.10-1 (2013-10-05)\n\nFeatures:\n\n - Make tests pass Internet Explorer 8\n\n## 0.7.10-0 (2013-10-05)\n\nFeatures:\n\n - Create browser tests\n\n## 0.7.9-1 (2013-10-03)\n\nBugfixes:\n\n - Fix promise cast bug when thenable fulfills using itself as the fulfillment value\n\n## 0.7.9-0 (2013-10-03)\n\nFeatures:\n\n - More performance improvements when long stack traces are enabled\n\n## 0.7.8-1 (2013-10-02)\n\nFeatures:\n\n - Performance improvements when long stack traces are enabled\n\n## 0.7.8-0 (2013-10-02)\n\nBugfixes:\n\n - Fix promisified methods not turning synchronous exceptions into rejections\n\n## 0.7.7-1 (2013-10-02)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.7-0 (2013-10-01)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.6-0 (2013-09-29)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.5-0 (2013-09-28)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.4-1 (2013-09-28)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.4-0 (2013-09-28)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.3-1 (2013-09-28)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.3-0 (2013-09-27)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.2-0 (2013-09-27)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.1-5 (2013-09-26)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.1-4 (2013-09-25)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.1-3 (2013-09-25)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.1-2 (2013-09-24)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.1-1 (2013-09-24)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.1-0 (2013-09-24)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.0-1 (2013-09-23)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.7.0-0 (2013-09-23)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.5-2 (2013-09-20)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.5-1 (2013-09-18)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.5-0 (2013-09-18)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.4-1 (2013-09-18)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.4-0 (2013-09-18)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.3-4 (2013-09-18)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.3-3 (2013-09-18)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.3-2 (2013-09-16)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.3-1 (2013-09-16)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.3-0 (2013-09-15)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.2-1 (2013-09-14)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.2-0 (2013-09-14)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.1-0 (2013-09-14)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.6.0-0 (2013-09-13)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.9-6 (2013-09-12)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.9-5 (2013-09-12)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.9-4 (2013-09-12)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.9-3 (2013-09-11)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.9-2 (2013-09-11)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.9-1 (2013-09-11)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.9-0 (2013-09-11)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.8-1 (2013-09-11)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.8-0 (2013-09-11)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.7-0 (2013-09-11)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.6-1 (2013-09-10)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.6-0 (2013-09-10)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.5-1 (2013-09-10)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.5-0 (2013-09-09)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.4-1 (2013-09-08)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.4-0 (2013-09-08)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.3-0 (2013-09-07)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.2-0 (2013-09-07)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.1-0 (2013-09-07)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.5.0-0 (2013-09-07)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.4.0-0 (2013-09-06)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.3.0-1 (2013-09-06)\n\nFeatures:\n\n - feature\n\nBugfixes:\n\n - bugfix\n\n## 0.3.0 (2013-09-06)\n"
  },
  {
    "path": "docs/docs/coming-from-other-languages.md",
    "content": "---\nid: coming-from-other-languages\ntitle: Coming from Other Languages\n---\n\nThis page describes parallels of using promises in other languages. Promises as a pattern are very common in other languages and knowing what they map to in other languages might help you with grasping them conceptually\n\n - [C#](#c)\n - [Scala](#scala)\n - [Python](#python)\n - [C++](#c)\n - [Haskell](#haskell)\n - [Java](#java)\n - [Android Java](#android-java)\n - [Objective-C](#objective-c)\n\n\n## C&#35;\n\nA promise is similar to a C# `Task`. They both represent the result of an operation.\n\nA promise's `then` method is similar to a Task's `ContinueWith` method in that both allow attaching a continuation to the promise. Bluebird's [Promise.coroutine](.) is analogous to C#'s `async/await` syntax.\n\nA `TaskCompletionSource` is analogous to the promise constructor. Although usually promisification is preferred (see the API reference or working with callbacks section).\n\n`Task.FromResult` is analogous to [Promise.resolve](.).\n\nThe difference between a `Task` and a promise are that a task might not be started and might require a `.Start` call where a promise always represents an already started operation.\n\nIn addition promises are always unwrapped. A promise implicitly has `Task.Unwrap` called on it - that is, promises perform recursive assimilation of promises within them.\n\nSee [this question on StackOverflow](http://stackoverflow.com/questions/26136389/how-can-i-realize-pattern-promise-deffered) for more differences.\n\n## Scala\n\nA bluebird promise is similar to a Scala `Future`. A scala `Promise` is similar to how the promise constructor can be used (previously, to a bluebird Deferred).\n\nJust like a future, a promise represents a value over time. The value can resolve to either a fulfilled (ok completion) or rejected (error completion) state.\n\nWhere blocking on a Future in scala is discouraged, in JavaScript it's downright impossible.\n\nIn addition promises are always unwrapped. That is, promises perform recursive assimilation of promises within them. You can't have a `Promise<Promise<T>>` where a `Future[Future[T]]` is valid in Scala.\n\nSee [this question on StackOverflow](http://stackoverflow.com/questions/22724883/js-deferred-promise-future-compared-to-functional-languages-like-scala) for more differences.\n\n## Python\n\nA promise is similar to a Twisted Deferred object. In fact the first JavaScript implementations of promises were based on it. However, the APIs have diverged since. The mental model is still very similar.\n\nA promise is _not_ similar to a Python `concurrent.Future` which does not chain actions.\n\nAsyncio coroutines are similar to bluebird coroutines in what they let you do, however bluebird coroutines also enable functional-style chaining.\n\n## C++\n\nA bluebird promise is similar to a `std::future` and the promise constructor is similar to an `std::promise` although it should rarely be used in practice (see the promisification section).\n\nHowever, a bluebird promise is more powerful than the current implementation of `std::future` since while chaining has been discussed it is not yet implemented. Promises can be chained together.\n\nBoost futures expose a `.then` method similar to promises and allow this functionality.\n\n## Haskell\n\nA promise is a monadic construct with `.then` filling the role of `>>=` (bind). The major difference is that `.then` performs recursive assimilation which acts like a `flatMap` or a map. The type signature of `then` is quote complicated. If we omit the error argument and not throw - it's similar to:\n\n```hs\nthen::Promise a -> (a -> (Either (Promise b) b)) -> Promise b\n```\n\nThat is, you can return either a promise _or a plain value_ from a `then` without wrapping it.\n\nPromises perform a role similar to `IO` in that they allow for easy chaining of asynchronous non-blocking operations. `Promise.coroutine` can be seen as similar to `do` notation although in practice it's not an accurate comparison.\n\n## Java\n\nA promise is similar to a guava `Future` with `chain` being similar to `then`.\n\nIf your'e familiar with Java 8 lambdas, you can think of a promise as a `Future` you can `map` to another future.\n\n## Android Java\n\nSeveral popular Android libraries use promises - for example the Parse Java API returns `Task`s which are similar to JavaScript promises.\n\n## Objective-C\n\nIf you're familiar with PromiseKit, it is based on a same specification bluebird is based on so the API should feel familiar right away.\n"
  },
  {
    "path": "docs/docs/coming-from-other-libraries.md",
    "content": "---\nid: coming-from-other-libraries\ntitle: Coming from Other Libraries\n---\n\nThis page is a reference for migrating to bluebird from other flow control or promise libraries. See [installation](install.html) on how to use bluebird in your environment.\n\n - [Coming from native promises](#coming-from-native-promises)\n - [Coming from jQuery deferreds](#coming-from-jquery-deferreds)\n - [Coming from `async` module](#coming-from-async-module)\n - [Coming from Q](#coming-from-q)\n - [Coming from co/koa](#coming-from-co)\n - [Coming from highland, RxJS or BaconJS](#coming-from-highland)\n\n##Coming from native promises\n\nBluebird promises are a drop-in replacement for native promises except for subclassing. Additionally you might want to replace usages of the often incorrectly used [Promise.race](.) with bluebird's [Promise.any](.) which does what is usually mistakenly expected from [Promise.race](.). For maximum compatibility, bluebird does provide [Promise.race](.) with ES6 semantics.\n\nYou can also refactor some looping patterns to a more natural form that would [leak memory when using native promises](https://github.com/promises-aplus/promises-spec/issues/179).\n\n##Coming from jQuery deferreds\n\nBluebird treats jQuery deferreds and promises interchangeably. Wherever you can take a promise or return a promise, you can take or return a jQuery deferred instead and it works the same.\n\nFor instance, there is no need to write something like this:\n\n```js\nvar firstRequest = new Promise(function(resolve, reject) {\n    $.ajax({...}).done(resolve).fail(reject);\n});\nvar secondRequest = new Promise(function(resolve, reject) {\n    $.ajax({...}).done(resolve).fail(reject);\n});\n\nPromise.all([firstRequest, secondRequest]).then(function() {\n    // ...\n});\n```\n\nSince [Promise.all](.) takes promises, it must also take jQuery deferreds, so the above can be shortened to:\n\n```js\nvar firstRequest = $.ajax({...});\nvar secondRequest = $.ajax({...});\n\nPromise.all([firstRequest, secondRequest]).then(function() {\n    // ...\n});\n```\n\nThat said, if you have code written using jQuery deferred methods, such as `.then`, `.done` and so on, you cannot drop-in replace the jQuery deferred with a bluebird promise in that code. Despite having the same names, jQuery deferred methods have different semantics than bluebird promise methods. These differences are due to the completely different goals of the implementations. Bluebird is [an internal DSL](http://en.wikipedia.org/wiki/Domain-specific_language) for the domain of asynchronous control flow while jQuery deferreds are a callback aggregator utility (\"glorified event emitters\").\n\nIf you do have some code using jQuery deferred methods extensively try to see if some of these jQuery deferred patterns and their replacements can be applied:\n\n```js\n// jQuery\n$.when.apply($, someArray).then(...)\n// bluebird\nPromise.all(someArray).then(...)\n```\n\n```js\n// jQuery\nvar data = [1,2,3,4];\nvar processItemsDeferred = [];\n\nfor(var i = 0; i < data.length; i++) {\n  processItemsDeferred.push(processItem(data[i]));\n}\n\n$.when.apply($, processItemsDeferred).then(everythingDone);\n\n// bluebird\nvar data = [1,2,3,4];\nPromise.map(data, function(item) {\n    return processItem(item);\n}).then(everythingDone);\n```\n\n```js\n// jQuery\nvar d = $.Deferred();\nd.resolve(\"value\");\n// bluebird\nvar d = Promise.resolve(\"value\");\n```\n\n```js\n// jQuery\nvar d = $.Deferred();\nd.reject(new Error(\"error\"));\n// bluebird\nvar d = Promise.reject(new Error(\"error\"));\n```\n\n```js\n// jQuery\nvar clicked = $.Deferred();\n$(\"body\").one(\"click\", function(e) {\n    clicked.resolve(e);\n});\n// bluebird\nvar clicked = new Promise(function(resolve) {\n    $(\"body\").one(\"click\", resolve);\n});\n```\n\n```js\n// jQuery\n.always(removeSpinner);\n// bluebird\n.finally(removeSpinner);\n```\n\n##Coming from `async` module\n\nWhen working with promises the philosophy is basically a complete opposite than when using `async`. Async provides a huge bag of uncomposable helper functions that work at a very low level of abstraction. When using promises you can get the utility otherwise provided by uncountable amount of inflexible helper functions by just combining and composing a few existing functions and concepts.\n\nThat means when you have a problem there probably isn't an existing function tailored exactly to that problem but instead you can just combine the existing utilities to arrive at a solution. The upside of this is that you don't need to come up with all these different functions to solve problems that are not that different from each other. The most important thing to do when migrating from async to bluebird is this profound shift in philosophy.\n\nThis section lists the most common async module replacements.\n\n###`async.waterfall`\n\nIf the waterfall elements are static, you can just replace it with a normal promise chain. For waterfalls with dynamic steps, use [Promise.each](.). Multiple arguments can be ferried in an array.\n\nImplementing the example from [async homepage](https://github.com/caolan/async#waterfalltasks-callback)\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\nSince the array passed to waterfall is static (always the same 3 functions) a plain old promise chain is used:\n\n```js\nPromise.resolve(['one', 'two']).spread(function(arg1, arg2) {\n    // arg1 now equals 'one' and arg2 now equals 'two'\n    return 'three';\n}).then(function(arg1) {\n    // arg1 now equals 'three'\n    return 'done';\n}).then(function(result) {\n    // result now equals 'done'\n});\n```\n\nIf destructuring parameters are supported, `.spread(function(arg1, arg2) {})` can be replaced with `.then(function([arg1, arg2]){})`.\n\n###`async.series`\n\nUsing [Promise.mapSeries](.) to implement the example from [async homepage](https://github.com/caolan/async#seriestasks-callback):\n\n```js\nasync.series([\n    function(callback){\n        setTimeout(function(){\n            callback(null, 1);\n        }, 200);\n    },\n    function(callback){\n        setTimeout(function(){\n            callback(null, 2);\n        }, 100);\n    }\n],\n// optional callback\nfunction(err, results){\n    // results is now equal to [1, 2]\n});\n```\n\n```js\nPromise.mapSeries([{timeout: 200, value: 1},\n                   {timeout: 100, value: 2}], function(item) {\n    return Promise.delay(item.timeout, item.value);\n}).then(function(results) {\n    // results is now equal to [1, 2]\n});\n```\n\n\n###`async.parallel`\n\nUsing [Promise.all](.) to implement the example from [async homepage](https://github.com/caolan/async#parallel):\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```js\nPromise.all([Promise.delay(200, 'one'),\n             Promise.delay(100, 'two')]).then(function(results) {\n    // the results array will equal ['one','two'] even though\n    // the second function had a shorter timeout.\n});\n```\n\n###`async.mapSeries`\n\nUsing [Promise.each](.) to implement the example from [async homepage](https://github.com/caolan/async#maparr-iterator-callback):\n\n```js\nvar fs = require('fs');\nasync.mapSeries(['file1','file2','file3'], fs.stat, function(err, results){\n    // results is now an array of stats for each file\n});\n```\n\n```js\nvar fs = Promise.promisifyAll(require('fs'));\nPromise.each(['file1','file2','file3'], function(fileName, index, length) {\n    return fs.statAsync(fileName);\n}).then(function(results) {\n    // results is now an array of stats for each file\n});\n```\n\n###`async.map`\n\nUsing [Promise.map](.) to implement the example from [async homepage](https://github.com/caolan/async#maparr-iterator-callback):\n\n```js\nvar fs = require('fs');\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```js\nvar fs = Promise.promisifyAll(require('fs'));\nPromise.map(['file1','file2','file3'], function(fileName, index, length) {\n    return fs.statAsync(fileName);\n}).then(function(results) {\n    // results is now an array of stats for each file\n});\n```\n\n###`async.whilst`\n\nUsing recursion to implement the example from [async homepage](https://github.com/caolan/async#whilsttest-fn-callback):\n\n```js\nvar count = 0;\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```js\n(function loop() {\n    if (count < 5) {\n        count++;\n        return Promise.delay(1000).then(loop);\n    }\n    return Promise.resolve();\n})().then(function() {\n    // 5 seconds have passed\n});\n```\n\nBe warned that the above example implementations are only superficially equivalent. Callbacks, even with the help of async, require too much boilerplate code to provide the same guarantees as promises.\n\n##Coming from Q\n\nQ and bluebird share a lot of common methods that nevertheless have different names:\n\n- `Q(...)` -> [Promise.resolve()](.)\n- `.fail()` -> [.catch()](.) or `.caught()`\n- `.fin()` -> [.finally()](.) or `.lastly()`\n- `Q.fcall()` -> [Promise.try](.) or `Promise.attempt()`\n- `.thenResolve()` -> [.return()](.) or `.thenReturn()`\n- `.thenReject()` -> [.throw()](.) or `thenThrow()`\n\n##Coming from co/koa\n\nIn recent versions generator libraries started abandoning old ideas of special tokens passed to callbacks and started using promises for what's being yielded.\n\nBluebird's [Promise.coroutine](.) is a superset of the `co` library, being more extensible as well as supporting cancellation (in environments where [`Generator#return`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/return) is implemented).\n\n##Coming from highland, RxJS or BaconJS\n\nStream libraries tend to serve a different purpose than promise libraries. Unlike promise libraries streams can represent multiple values.\n\nCheck out the benchmarks section for examples of transitioning an API from Bacon/Rx to promises.\n"
  },
  {
    "path": "docs/docs/contribute.md",
    "content": "---\nid: contribute\ntitle: Contribute\n---\n\nFor development tasks such as contributing, running benchmarks or testing, you need to clone the repository and install dev-dependencies.\n\nInstall [node](http://nodejs.org/)\n\n    git clone git@github.com:petkaantonov/bluebird.git\n    cd bluebird\n    npm install\n\n- [Directory structure](#directory-structure)\n- [Style guide](#style-guide)\n- [Building](#building)\n    - [Supported options by the build tool](#supported-options-by-the-build-tool)\n- [Testing](#testing)\n    - [Testing in browsers](#testing-in-browsers)\n    - [Supported options by the test tool](#supported-options-by-the-test-tool)\n- [Benchmarking](#benchmarking)\n\n## Directory structure\n\n- `/benchmark` contains benchmark scripts and stats of benchmarks\n\n- `/tools` contains building and testing tools and scripts\n\n- `/src` contains the source code\n\n- `/test` contains test code\n\n    - `/test/mocha` contains tests using the mocha testing framework\n    - `/test/browser` a directory that can be statically served using a webserver to run tests in browsers. See [testing in browsers](README.md#testing-in-browsers).\n\n\n## Style guide\n\nUse the same style as is used in the surrounding code.\n\n###Whitespace\n\n- No more than 80 columns per line\n- 4 space indentation\n- No trailing whitespace\n- LF at end of files\n- Curly braces can be left out of single statement `if/else/else if`s when it is obvious there will never be multiple statements such as null check at the top of a function for an early return.\n- Add an additional new line between logical sections of code.\n\n###Variables\n\n- Use multiple `var` statements instead of a single one with comma separator. Do not declare variables until you need them.\n\n###Equality and type checks\n\n- Always use `===` except when checking for null or undefined. To check for null or undefined, use `x == null`.\n- For checks that can be done with `typeof`: do not make helper functions, save results of `typeof` to a variable or make the type string a non-constant. Always write the check in the form `typeof expression === \"constant string\"` even if it feels like repeating yourself.\n\n##Building\n\n```\nnode tools/build --debug --release --zalgo --browser --minify\n```\n\n###Supported options by the build tool\n\nThe value of boolean flags is determined by presence, if you want to pass false value for a boolean flag, use the `no-`-prefix e.g. `--no-debug`.\n\n - `--release` - Whether to build the release build. The release build is placed at `js/release` directory. Default `false`.\n - `--debug` - Whether to build the debug build. The debug build is placed at `js/debug` directory. Default `false`.\n - `--zalgo` - Whether to build the zalgo build. The zalgo build is placed at `js/zalgo` directory. Default `false`.\n - `--browser` - Whether to compile the browser build. The browser build file is placed at `js/browser/bluebird.js` Default `false`.\n - `--minify` - Whether to minify the compiled browser build. The minified browser build file is placed at `js/browser/bluebird.min.js` Default `true`.\n\n##Testing\n\nTo run all tests, run\n\n    node --expose-gc tools/test\n\nIf you need to run generator tests in older versions of NodeJS run the `tool/test.js` script with `--harmony` argument and 0.11+:\n\n    node-dev --harmony tools/test\n\nIn recent versions of NodeJS where generators are enabled by default:\n\n    node tools/test\n\nYou may specify an individual test file to run with the `--run` script flag:\n\n    node tools/test --run=cancel.js\n\n\nThis enables output from the test and may give a better idea where the test is failing. The paramter to `--run` can be any file name located in `test/mocha` folder.\n\n###Testing in browsers\n\nTo run the test in a browser instead of node, pass the flag `--browser` to the test tool\n\n    node tools/test --run=cancel.js --browser\n\nThis will automatically create a server (default port 9999) and open it in your default browser once the tests have been compiled.\n\nKeep the test tab active because some tests are timing-sensitive and will fail if the browser is throttling timeouts. Chrome will do this for example when the tab is not active.\n\n###Supported options by the test tool\n\nThe value of boolean flags is determined by presence, if you want to pass false value for a boolean flag, use the `no-`-prefix e.g. `--no-browser`.\n\n - `--run=String`. Which tests to run (or compile when testing in browser). Default `\"all\"`. Can also be a glob string (relative to ./test/mocha folder)\n - `--cover=String`. Create code coverage using the String as istanbul reporter. Coverage is created in the ./coverage folder. No coverage is created by default, default reporter is `\"html\"` (use `--cover` to use default reporter).\n - `--browser` - Whether to compile tests for browsers. Default `false`.\n - `--port=Number` - Whe port where local server is hosted when testing in browser. Default `9999`\n - `--execute-browser-tests` - Whether to execute the compiled tests for browser when using `--browser`. Default `true`.\n - `--open-browser` - Whether to open the default browser when executing browser tests. Default `true`.\n - `--fake-timers` - Whether to use fake timers (`setTimeout` etc) when running tests in node. Default `true`.\n - `--js-hint` - Whether to run JSHint on source files. Default `true`.\n - `--saucelabs` Wheter to create a tunnel to sauce labs and run tests in their VMs instead of your browser when compiling tests for browser.Default `false`.\n\n##Benchmarking\n\nTo run a benchmark, run the given command for a benchmark while on the project root. Requires bash (on windows the mingw32 that comes with git works fine too).\n\nEach benchmark must\n\n - Have implementations that do the same thing\n - Run each implementation of a benchmark in a separate freshly created process\n - Warmup each implementation before timing\n\n###1\\. DoxBee sequential\n\nCurrently the most relevant benchmark is @gorkikosev's benchmark in the article [Analysis of generators and other async patterns in node](http://spion.github.io/posts/analysis-generators-and-other-async-patterns-node.html). The benchmark emulates a situation where n amount of users are making a request in parallel to execute some mixed async/sync action.\n\nCommand: `bench doxbee`\n\nThe implementations for this benchmark are found in `benchmark/doxbee-sequential` directory.\n\n###2\\. Parallel\n\nThis made-up scenario runs 25 shimmed queries in parallel.\n\nCommand: `bench parallel`\n\nThe implementations for this benchmark are found in `benchmark/madeup-parallel` directory.\n"
  },
  {
    "path": "docs/docs/deprecated-apis.md",
    "content": "---\nid: deprecated-apis\ntitle: Deprecated APIs\n---\n\n[deprecated-apis](unfinished-article)\n\nThis file contains documentation for APIs that are no longer supported by Bluebird.\nThese APIs still work in Bluebird but will be removed at a future version of the library.\n\nFor every use case that the methods below solve there exists a better alternative in [the API reference](/docs/api-reference.html).\n\n- [Progression](#progression)\n    - [`.progressed(Function handler)`](#progressedfunction-handler---promise)\n    - [`.then([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])`](#thenfunction-fulfilledhandler--function-rejectedhandler---function-progresshandler----promise)\n    - [`.done([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])`](#donefunction-fulfilledhandler--function-rejectedhandler---function-progresshandler----promise)\n\n- [Promise resolution](#promise-resolution)\n    - [`.resolve(dynamic value)`](#resolvedynamic-value---undefined)\n    - [`.reject(dynamic reason)`](#rejectdynamic-reason---undefined)\n    - [`.progress(dynamic value)`](#progressdynamic-value---undefined)\n    - [`.callback`](#callback---function)\n\n - [Old Promise Cancellation](#old-promise-cancellation)\n  \n\n##Progression\n\nThe old progression API was meant to be used for tracking the progress of promise resolution. In retrospect, it did not work or compose very well. We understand that problem better now and the use case could be better solved without it.\n\nSee [Progression Migration](./api/progression-migration.html) for migration assistance and examples of how to convert APIs that use progression to ones that do not.\n\n#####`.progressed(Function handler)` -> `Promise`\n\n\nShorthand for `.then(null, null, handler);`. Attach a progress handler that will be called if this promise is progressed. Returns a new promise chained from this promise.\n\n<hr>\n\n#####`.then([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])` -> `Promise`\n\nThe standard [Promises/A+ `.then()`](http://promises-aplus.github.io/promises-spec/) is still supported by Bluebird and support for it will continue indefinitely . However, the variant accepting a third `progressHandler` argument is no longer supported.\n\n<hr>\n\n\n#####`.done([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])` -> `void`\n\nLike `.then()`, but any unhandled rejection that ends up here will be thrown as an error. Again, only the variant with the progression handler is deprecated here. `.done` is still fully supported.\n\n<hr>\n\n\n\n##Promise resolution\n\nA `PromiseResolver` can be used to control the fate of a promise. It is like \"Deferred\" in jQuery or `$q.defer` in $q. The `PromiseResolver` objects have a `.promise` property which returns a reference to the controlled promise that can be passed to clients. `.promise` of a `PromiseResolver` is not a getter function to match other implementations.\n\nThe methods of a `PromiseResolver` have no effect if the fate of the underlying promise is already decided (follow, reject, fulfill).\n\n**The use of `Promise.defer` and deferred objects is discouraged - it is much more awkward and error-prone than using `new Promise`.**\n\n<hr>\n\n#####`.resolve(dynamic value)` -> `undefined`\n\nResolve the underlying promise with `value` as the resolution value. If `value` is a thenable or a promise, the underlying promise will assume its state.\n\n<hr>\n\n#####`.reject(dynamic reason)` -> `undefined`\n\nReject the underlying promise with `reason` as the rejection reason.\n\n<hr>\n\n#####`.progress(dynamic value)` -> `undefined`\n\nProgress the underlying promise with `value` as the progression value.\n\nExample\n\n```js\nfunction delay(ms) {\n    var resolver = Promise.defer();\n    var now = Date.now();\n    setTimeout(function(){\n        resolver.resolve(Date.now() - now);\n    }, ms);\n    return resolver.promise;\n}\n\ndelay(500).then(function(ms){\n    console.log(ms + \" ms passed\");\n});\n```\n\n<hr>\n\n##Old Promise Cancellation\n\nIn 2.x, promise cancellation looked very differently. Promise cancellation received a major overhaul for version 3 in order to create a sound variant of cancellable promises. You can still use 2.x cancellation with bluebird 2.x (which is still supported - but not recommended). See [Cancellation](/cancellation.html) for more details. The 2.x docs are [still accessible under the 2.x branch](https://github.com/petkaantonov/bluebird/blob/2.x/API.md).\n\n"
  },
  {
    "path": "docs/docs/deprecated_apis.md",
    "content": "---\nid: deprecated_apis\ntitle: Deprecated APIs\n---\n\nThis file contains documentation for APIs that are no longer supported by Bluebird.\nThese APIs still work in Bluebird but will be removed at a future version of the library.\n\nFor every use case that the methods below solve there exists a better alternative in [the API reference](./API.md).\n\n- [Progression](#progression)\n    - [`.progressed(Function handler)`](#.progressed)\n    - [`.then([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])`](#.then)\n    - [`.done([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])`](#.done)\n    - [`.fork([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])`](#.fork)\n\n- [Promise resolution](#promise-resolution)\n    - [`.resolve(dynamic value)`](#.resolve)\n    - [`.reject(dynamic reason)`](#.reject)\n    - [`.progress(dynamic value)`](#.progress)\n    - [`.callback`](#.callback)\n\n\n\n##Progression\n\nThe old progression API was meant to be used for tracking the progress of promise resolution. In retrospect, it did not work or compose very well. We understand that problem better now and the use case could be better solved without it.\n\nSee [Progression Migration](./API.md#progression-migration) for migration assistance and examples of how to convert APIs that use progression to ones that do not.\n\n#####`.progressed(Function handler)` -> `Promise`\n\n\nShorthand for [`.then(null, null, handler);`](.). Attach a progress handler that will be called if this promise is progressed. Returns a new promise chained from this promise.\n\n<hr>\n\n#####`.then([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])` -> `Promise`\n\nThe standard [Promises/A+ `.then()`](http://promises-aplus.github.io/promises-spec/) is still supported by Bluebird and support for it will continue indefinitely. However, the variant accepting a third `progressHandler` argument is no longer supported.\n\n<hr>\n\n\n#####`.done([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])` -> `void`\n\nLike [`.then()`](.), but any unhandled rejection that ends up here will be thrown as an error. Again, only the variant with the progression handler is deprecated here. `.done` is still fully supported.\n\n<hr>\n\n\n#####`.fork([Function fulfilledHandler] [, Function rejectedHandler ] [, Function progressHandler ])` -> `Promise`\n\nLike [`.then()`](.), but cancellation of the returned promise or any of its descendant will not propagate cancellation to this promise or this promise's ancestors. Again, only the variant with the progression handler is deprecated here. `.fork` is still fully supported.\n\n<hr>\n\n\n##Promise resolution\n\nA `PromiseResolver` can be used to control the fate of a promise. It is like \"Deferred\" in jQuery or `$q.defer` in $q. The `PromiseResolver` objects have a `.promise` property which is a reference to the controlled promise that can be passed to clients. `.promise` of a `PromiseResolver` is not a getter function to match other implementations.\n\nThe methods of a `PromiseResolver` have no effect if the fate of the underlying promise is already decided (follow, reject, fulfill).\n\n**The use of `Promise.defer` and deferred objects is discouraged - it is much more awkward and error-prone than using `new Promise`.**\n\n<hr>\n\n#####`.resolve(dynamic value)` -> `undefined`\n\nResolve the underlying promise with `value` as the resolution value. If `value` is a thenable or a promise, the underlying promise will assume its state.\n\n<hr>\n\n#####`.reject(dynamic reason)` -> `undefined`\n\nReject the underlying promise with `reason` as the rejection reason.\n\n<hr>\n\n#####`.progress(dynamic value)` -> `undefined`\n\nProgress the underlying promise with `value` as the progression value.\n\nExample\n\n```js\nfunction delay(ms) {\n    var resolver = Promise.defer();\n    var now = Date.now();\n    setTimeout(function() {\n        resolver.resolve(Date.now() - now);\n    }, ms);\n    return resolver.promise;\n}\n\ndelay(500).then(function(ms) {\n    console.log(ms + \" ms passed\");\n});\n```\n\n<hr>\n"
  },
  {
    "path": "docs/docs/download-api-reference.md",
    "content": "---\nid: download-api-reference\ntitle: Download API Reference\n---\n\nIn order to use the documentation offline (without a stable internet connection).\n\n - Go to [the GitHub Pages Branch `gh-pages`](https://github.com/petkaantonov/bluebird/tree/gh-pages).\n - Click \"Clone Or Download\".\n - Click \"Download Zip\".\n - Extract the contents of the zip and open the \"docs\" folder.\n - Open `api-reference.html` which is the documentation root.\n"
  },
  {
    "path": "docs/docs/error-explanations.md",
    "content": "---\nid: error-explanations\ntitle: Error Explanations\n---\n\n - [Error: Promise.promisify called on an object](#error-promise.promisify-called-on-an-object)\n - [Error: the promise constructor requires a resolver function](#error-the-promise-constructor-requires-a-resolver-function)\n - [Error: the promise constructor cannot be invoked directly](#error-the-promise-constructor-cannot-be-invoked-directly)\n - [Error: expecting an array, a promise or a thenable](#error-expecting-an-array-a-promise-or-a-thenable)\n - [Error: generatorFunction must be a function](#error-generatorfunction-must-be-a-function)\n - [Error: fn must be a function](#error-fn-must-be-a-function)\n - [Error: cannot enable long stack traces after promises have been created](#error-cannot-enable-long-stack-traces-after-promises-have-been-created)\n - [Error: cannot get fulfillment value of a non-fulfilled promise](#error-cannot-get-fulfillment-value-of-a-non-fulfilled-promise)\n - [Error: cannot get rejection reason of a non-rejected promise](#error-cannot-get-rejection-reason-of-a-non-rejected-promise)\n - [Error: the target of promisifyAll must be an object or a function](#error-the-target-of-promisifyall-must-be-an-object-or-a-function)\n - [Error: circular promise resolution chain](#error-circular-promise-resolution-chain)\n - [Error: cannot await properties of a non-object](#error-cannot-await-properties-of-a-non-object)\n - [Error: expecting a positive integer](#error-expecting-a-positive-integer)\n - [Error: A value was yielded that could not be treated as a promise](#error-a-value-was-yielded-that-could-not-be-treated-as-a-promise)\n - [Error: cannot await properties of a non object](#error-cannot-await-properties-of-a-non-object)\n - [Error: Cannot promisify an API that has normal methods](#error-cannot-promisify-an-api-that-has-normal-methods)\n - [Error: Catch filter must inherit from Error or be a simple predicate function](#error-catch-filter-must-inherit-from-error-or-be-a-simple-predicate-function)\n - [Error: No async scheduler available](#error-no-async-scheduler-available)\n\n\n## Error: Promise.promisify called on an object\n\n\nYou got this this error because you've used `Promise.promisify` on an object, for example:\n\n```js\nvar fs = Promise.promisify(require(\"fs\"));\n```\n\nInstead, use [`Promise.promisifyAll`](.) :\n\n```js\nvar fs = Promise.promisifyAll(require(\"fs\"));\n```\n\n## Error: the promise constructor requires a resolver function\n\nYou got this error because you used `new Promise()` or `new Promise(something)` without passing a function as the parameter.\n\nIf you want to wrap an API with a promise manually, the correct syntax is:\n\n```js\nfunction wrapWithPromise(parameter) {\n    return new Promise(function (resolve, reject) {\n        doSomethingAsync({\n              error:reject,\n              success:resolve\n        });\n    });\n}\n```\n\nPlease consider reading about [new Promise](.) and also consider checking out automatic [promisification](.) as well as [Promise.method](.)\n\n## Error: the promise constructor cannot be invoked directly\n\nYou can get this error for several reasons:\n\n#### 1. You forgot to use `new` when creating a new promise using `new Promise(resolver)` syntax.\n\nThis can happen when you tried to do something like:\n\n    return Promise(function(resolve,reject){\n           //...\n    })\n\nYou can correct this by doing:\n\n    return new Promise(function(resolve,reject){\n           //...\n    })\n\nPlease consider reading about [new Promise](.) and also consider checking out automatic [promisification](.) as well as [Promise.method](.)\n\n#### 2. You are trying to subclass `Promise`\n\nBluebird does not support extending promises this way. Instead, see [scoped prototypes](features.html#scoped-prototypes).\n\n## Error: expecting an array, a promise or a thenable\n\nThe function being called expects a Promise, but is given something different. There are two main reasons why this may occur.\n\n**1. Working with collections (like arrays) but pass a single, non-collection element instead**\n\nExample:\n\n```js\nfunction returnThree(){ return 3;}\n\nPromise.resolve(5).map(returnThree).then(function(val){\n     console.log(\"Hello Value!\",val); \n});\n```\n\nThe `map` operation is expecting an array here (or a promise on one) and instead gets the number `5`.\n\n```js\nfunction returnThree(){ return 3;}\n\nPromise.resolve([5]).map(returnThree).then(function(val){\n     console.log(\"Hello Value!\",val); \n});\n```\n```map``` is given an array with a single element (see ```[5]``` instead of ```5```), so this statement will work (but is bad practice).\n\n---\n\n**2.```return``` is forgotten in a 'fat' arrow / anonymous function call ```=>```:**\n\nWhen debugging or performing a one-time operation on a variable before passing it to a function, a return variable is forgotten.\n\nExample:\n\n```js\nfunction nextFunction(something){ return Promise.resolve(something*3); }\n\nmyFunction()\n    .then(result => nextFunction(result)); // We are implicitly returning a Promise\n```\n\nDebugging, we want to see the value of result, so we add a ```console.log()``` line:\n\n```js\nfunction nextFunction(something){ return Promise.resolve(something*3); }\n\nmyFunction().then(result => {\n    console.log(\"Debug:\", result);\n    nextFunction(result)); // The chain is broken! We don't return anything to the .then() call\n});\n```\n\nAs this is an anonymous function call, we need to **return** something, which is not currently happening.\n\nTo fix, simply remember to add ```return``` in front of your promise-complying function:\n\n```js\nfunction nextFunction(something){ return Promise.resolve(something*3); }\n\nmyFunction().then(result => {\n    console.log(\"Debug:\", result);\n    return nextFunction(result)); // The anonymous function returns the function which returns the promise .then() needs\n});\n```\n\n\n## Error: generatorFunction must be a function\n\nYou are getting this error when trying to use [Promise.coroutine](.) and not passing it a generator function as a parameter.  For example:\n\n```js\nPromise.coroutine(function* () { // Note the *\n    var data = yield $.get(\"http://www.example.com\");\n    var moreUrls = data.split(\"\\n\");\n    var contents = [];\n    for( var i = 0, len = moreUrls.length; i < len; ++i ) {\n        contents.push(yield $.get(moreUrls[i]));\n    }\n    return contents;\n});\n```\n\nPlease refer to the relevant section in the documentation about [Generators](.) in order to get usage instructions:\n\n**Note**: Bluebird used to eagerly check for generators which caused problems with transpilers. Because of this, you might get an error similar to `TypeError: Cannot read property 'next' of undefined` if you pass a function instead of a generator function to Bluebird.\n\n[Promise.coroutine](.) is built to work with generators to form C# like `async/await`\n\n## Error: fn must be a function\n\nYou passed a non-function where a function was expected.\n\n## Error: cannot enable long stack traces after promises have been created\n\nYou are getting this error because you are enabling long stack traces after a promise has already been created.\n\nWhen using `longStackTraces` the first line in your code after requiring Bluebird should be:\n\n```js\nPromise.config({\n    longStackTraces: true\n});\n```\n\nSee the API page about [Promise.longStackTraces](.)\n\n## Error: cannot get fulfillment value of a non-fulfilled promise\n\nYou can get this error when you're trying to call `.value` or `.error` when inspecting a promise where the promise has not been fulfilled or rejected yet.\n\nFor example:\n\n```js\nvar p = Promise.delay(1000);\np.inspect().value();\n```\n\nConsider using [.isPending()](.) [.isFulfilled()](.) and [.isRejected()](.) in order to inspect the promise for status.\n\nPlease consider reading more about [synchronous inspection](.)\n\n## Error: cannot get rejection reason of a non-rejected promise\n\nYou can get this error when you're trying to call `.value` or `.error` when inspecting a promise where the promise has not been fulfilled or rejected yet.\n\nFor example:\n\n```js\nvar p = Promise.delay(1000);\np.inspect().value();\n```\n\nConsider using [.isPending()](.) [.isFulfilled()](.) and [.isRejected()](.) in order to inspect the promise for status.\n\nPlease consider reading more about [synchronous inspection](.)\n\n\n##Error: the target of promisifyAll must be an object or a function\n\nThis can happen when you are calling [Promise.promisifyAll](.) on a function and invoking it instead of passing it.\n\nIn general, the usage of [Promise.promisifyAll](.) is along the lines of `var fs = Promise.promisifyAll(require(\"fs\"))`.\n\nConsider reading the section about [promisification](.)\n\n## Error: circular promise resolution chain\n\nThis usually happens when you have a promise that resolves or rejects with itself.\n\nFor example: `var p = Promise.delay(100).then(function(){ return p});` .\n\nIn this case, the promise resolves with itself which was is not intended.\n\nThis also happens when implementing live-updating models with a `.then` method that indicates when the model is \"ready\". A promise is a process, it starts and it ends.\n\nPromises do not aim to solve such live updating problems directly. One option would be to use an intermediate promise - for example a `.loaded` property on the model that fulfills with nothing.\n\nresolving it with itself tells it \"it is done when it is done\"\n\n## Error: cannot await properties of a non-object\n\nThe `.props` method expects to receive an object.\n\nFor example:\n\n```js\nPromise.props({\n    pictures: getPictures(),\n    comments: getComments(),\n    tweets: getTweets()\n}).then(function(result){\n    console.log(result.tweets, result.pictures, result.comments);\n});\n```\n\nThis happens when a non object value or a promise that resolves with something that is not an object is being passed instead.\n\n## Error: expecting a positive integer\n\nThis happens when you call `.some` passing it a negative value or a non-integer.\n\nOne possible cause is using `.indexOf` which returns `-1` when it doesn't find the value being searched for.\n\nPlease consider reading the API docs for [`.some`](.)\n\n## Error: A value was yielded that could not be treated as a promise\n\nYou are getting this error because you have tried to `yield` something in a coroutine without a yield handler, for example:\n\n```js\nvar coroutine = Promise.coroutine(function*(){\n    var bar = yield \"Foo\";\n    console.log(bar);\n});\n```\n\nThe solution is to either convert it to a promise by calling `Promise.resolve` on it or `Promise.promisify` if it's a callback:\n\n```js\nvar coroutine = Promise.coroutine(function*(){\n    var bar = yield Promise.resolve(\"Foo\");\n    console.log(bar);\n});\n```\n\nOr to use [Promise.coroutine.addYieldHandler`](.) to teach [Promise.coroutine](.) to accept these sort of values.\n\n## Error: cannot await properties of a non object\n\nThe `.props` method expects to receive an object.\n\nFor example:\n\n```js\nPromise.props({\n    pictures: getPictures(),\n    comments: getComments(),\n    tweets: getTweets()\n}).then(function(result){\n    console.log(result.tweets, result.pictures, result.comments);\n});\n```\n\nThis happens when a non object value or a promise that resolves with something that is not an object is being passed instead.\n\n\n## Error: Cannot promisify an API that has normal methods\n\nThis error indicates you have tried to call [Promise.promisifyAll](.) on an object that already has a property with the `Async` suffix:\n\n```js\nvar myApi = { foo: function(cb){ ... }, fooAsync(cb) { ... }\n```\n\nThis is because Bluebird adds the `Async` suffix to distinguish the original method from the promisified one, so `fooAsync` would have been overridden. In order to avoid this - either rename `fooAsync` before promisifying the API, or call [Promise.promisify](.) manually on select properties.\n\nYou may also use the custom suffix option to choose another suffix that doesn't result in conflicts.\n\nIf you find this issue in a common library please [open an issue](https://github.com/petkaantonov/bluebird/issues/new).\n\n## Error: Catch filter must inherit from Error or be a simple predicate function\n\nBluebird supports typed and predicate [.catch()](.) calls]. However in order to use the typed/predicate catch syntax for error handling you must do one of two things.\n\nPass it a constructor that inherits from `Error`:\n\n    }).catch(ReferenceError, function(e) { // this is fine\n    }).catch(Array, function(e) { // arrays don't capture stack traces\n\nThis is to enable better stack trace support and to have more consistent and logical code.\n\nAlternatively, if you provide it a predicate be sure it's a simple function:\n\n    }).catch(function(e){ return false; }, function(e) { // this catches nothing\n    }).catch(function(e){ return e.someProp = 5; }, function(e) { // this is fine\n\nPlease see the API docs of [.catch()](.) on how to use predicate catches.\n\n## Error: No async scheduler available\n\nAsync scheduler is a function that takes a callback function and calls the callback function as soon as possible, but asynchronously. For example `setTimeout`.\n\nBy default bluebird only tries a few common async schedulers, such as `setTimeout`, `process.nextTick` and `MutationObserver`. However if your JavaScript runtime environment doesn't expose any of these, you will see this error.\n\nYou may use [Promise.setScheduler](.) to pass a custom scheduler that your environment supports. For example in DukTape:\n\n```js\nPromise.setScheduler(function(fn){ // fn is what to execute\n    var timer = uv.new_timer.call({});\n    uv.timer_start(timer, 0, 0, fn); // add the function as a callback to the timer\n});\n```\n\n\n\n\n"
  },
  {
    "path": "docs/docs/features.md",
    "content": "---\nid: features\ntitle: Features\n---\n\n[features](unfinished-article)\n\n\n- [Synchronous inspection](#synchronous-inspection)\n- [Concurrency coordination](#concurrency-coordination)\n- [Promisification on steroids](#promisification-on-steroids)\n- [Debuggability and error handling](#debuggability-and-error-handling)\n- [Resource management](#resource-management)\n- [Cancellation and timeouts](#cancellation-and-timeouts)\n- [Scoped prototypes](#scoped-prototypes)\n- [Promise monitoring](#promise-monitoring)\n- [Async/Await](#async-await)\n\n##Synchronous inspection\n\nSynchronous inspection allows you to retrieve the fulfillment value of an already fulfilled promise or the rejection reason of an already rejected promise synchronously.\n\nOften it is known in certain code paths that a promise is guaranteed to be fulfilled at that point - it would then be extremely inconvenient to use [`.then`](.) to get at the promise's value as the callback is always called asynchronously.\n\nSee the API on [synchronous inspection](.) for more information.\n\n##Concurrency coordination\n\nThrough the use of [.each](.) and [.map](.) doing things just at the right concurrency level becomes a breeze.\n\n##Promisification on steroids\n\nPromisification means converting an existing promise-unaware API to a promise-returning API.\n\nThe usual way to use promises in node is to [Promise.promisifyAll](.) some API and start exclusively calling promise returning versions of the APIs methods. E.g.\n\n```js\nvar fs = require(\"fs\");\nPromise.promisifyAll(fs);\n// Now you can use fs as if it was designed to use bluebird promises from the beginning\n\nfs.readFileAsync(\"file.js\", \"utf8\").then(...)\n```\n\nNote that the above is an exceptional case because `fs` is a singleton instance. Most libraries can be promisified by requiring the library's classes (constructor functions) and calling promisifyAll on the `.prototype`. This only needs to be done once in the entire application's lifetime and after that you may use the library's methods exactly as they are documented, except by appending the `\"Async\"`-suffix to method calls and using the promise interface instead of the callback interface.\n\nAs a notable exception in `fs`, `fs.existsAsync` doesn't work as expected, because Node's `fs.exists` doesn't call back with error as first argument.  More at [#418](.).  One possible workaround is using `fs.statAsync`.\n\nSome examples of the above practice applied to some popular libraries:\n\n```js\n// The most popular redis module\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"redis\"));\n```\n\n```js\n// The most popular mongodb module\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"mongodb\"));\n```\n\n```js\n// The most popular mysql module\nvar Promise = require(\"bluebird\");\n// Note that the library's classes are not properties of the main export\n// so we require and promisifyAll them manually\nPromise.promisifyAll(require(\"mysql/lib/Connection\").prototype);\nPromise.promisifyAll(require(\"mysql/lib/Pool\").prototype);\n```\n\n```js\n// Mongoose\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"mongoose\"));\n```\n\n```js\n// Request\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"request\"));\n// Use request.getAsync(...) not request(..), it will not return a promise\n```\n\n```js\n// mkdir\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"mkdirp\"));\n// Use mkdirp.mkdirpAsync not mkdirp(..), it will not return a promise\n```\n\n```js\n// winston\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"winston\"));\n```\n\n```js\n// rimraf\nvar Promise = require(\"bluebird\");\n// The module isn't promisified but the function returned is\nvar rimrafAsync = Promise.promisify(require(\"rimraf\"));\n```\n\n```js\n// xml2js\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"xml2js\"));\n```\n\n```js\n// jsdom\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"jsdom\"));\n```\n\n```js\n// fs-extra\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"fs-extra\"));\n```\n\n```js\n// prompt\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"prompt\"));\n```\n\n```js\n// Nodemailer\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"nodemailer\"));\n```\n\n```js\n// ncp\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"ncp\"));\n```\n\n```js\n// pg\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"pg\"));\n```\n\nIn all of the above cases the library made its classes available in one way or another. If this is not the case, you can still promisify by creating a throwaway instance:\n\n```js\nvar ParanoidLib = require(\"...\");\nvar throwAwayInstance = ParanoidLib.createInstance();\nPromise.promisifyAll(Object.getPrototypeOf(throwAwayInstance));\n// Like before, from this point on, all new instances + even the throwAwayInstance suddenly support promises\n```\n\nSee also [`Promise.promisifyAll`](.).\n\n##Debuggability and error handling\n\n - [Surfacing unhandled errors](#surfacing-unhandled-errors)\n - [Long stack traces](#long-stack-traces)\n - [Error pattern matching](#error-pattern-matching)\n - [Warnings](#warnings)\n\n###Surfacing unhandled errors\n\nThe default approach of bluebird is to immediately log the stack trace when there is an unhandled rejection. This is similar to how uncaught exceptions cause the stack trace to be logged so that you have something to work with when something is not working as expected.\n\nHowever because it is possible to handle a rejected promise at any time in the indeterminate future, some programming patterns will result in false positives. Because such programming patterns are not necessary and can always be refactored to never cause false positives, we recommend doing that to keep debugging as easy as possible . You may however feel differently so bluebird provides hooks to implement more complex failure policies.\n\nSuch policies could include:\n\n- Logging after the promise became GCd (requires a native node.js module)\n- Showing a live list of rejected promises\n- Using no hooks and using [`.done`](.) to manually to mark end points where rejections will not be handled\n- Swallowing all errors (challenge your debugging skills)\n- ...\n\nSee [global rejection events](http://bluebirdjs.com/docs/api/error-management-configuration.html#global-rejection-events) to learn more about the hooks.\n\n###Long stack traces\n\nNormally stack traces don't go beyond asynchronous boundaries so their utility is greatly reduced in asynchronous code:\n\n```js\nsetTimeout(function() {\n    setTimeout(function() {\n        setTimeout(function() {\n            a.b.c;\n        }, 1);\n    }, 1)\n}, 1)\n```\n\n```\nReferenceError: a is not defined\n    at null._onTimeout file.js:4:13\n    at Timer.listOnTimeout (timers.js:90:15)\n```\n\nOf course you could use hacks like monkey patching or domains but these break down when something can't be monkey patched or new apis are introduced.\n\nSince in bluebird [promisification](.) is made trivial, you can get long stack traces all the time:\n\n```js\nvar Promise = require(\"bluebird\");\n\nPromise.delay(1)\n    .delay(1)\n    .delay(1).then(function() {\n        a.b.c;\n    });\n```\n\n```\nUnhandled rejection ReferenceError: a is not defined\n    at file.js:6:9\n    at processImmediate [as _immediateCallback] (timers.js:321:17)\nFrom previous event:\n    at Object.<anonymous> (file.js:5:15)\n    at Module._compile (module.js:446:26)\n    at Object.Module._extensions..js (module.js:464:10)\n    at Module.load (module.js:341:32)\n    at Function.Module._load (module.js:296:12)\n    at Function.Module.runMain (module.js:487:10)\n    at startup (node.js:111:16)\n    at node.js:799:3\n```\n\nAnd there is more. Bluebird's long stack traces additionally eliminate cycles, don't leak memory, are not limited to a certain amount of asynchronous boundaries and are fast enough for most applications to be used in production. All these are non-trivial problems that haunt straight-forward long stack trace implementations.\n\nSee [installation](install.html) on how to enable long stack traces in your environment.\n\n###Error pattern matching\n\nPerhaps the greatest thing about promises is that it unifies all error handling into one mechanism where errors propagate automatically and have to be explicitly ignored.\n\n###Warnings\n\nPromises can have a steep learning curve and it doesn't help that promise standards go out of their way to make it even harder. Bluebird works around the limitations by providing warnings where the standards disallow throwing errors when incorrect usage is detected. See [Warning Explanations](warning-explanations.html) for the possible warnings that bluebird covers.\n\nSee [installation](install.html) on how to enable warnings in your environment.\n\nNote - in order to get full stack traces with warnings in Node 6.x+ you need to enable to `--trace-warnings` flag which will give you a full stack trace of where the warning is coming from.\n\n###Promise monitoring\n\nThis feature enables subscription to promise lifecycle events via standard global events mechanisms in browsers and Node.js.\n\nThe following lifecycle events are available: \n\n - `\"promiseCreated\"` - Fired when a promise is created through the constructor.\n - `\"promiseChained\"` - Fired when a promise is created through chaining (e.g. [.then](.)).\n - `\"promiseFulfilled\"` - Fired when a promise is fulfilled.\n - `\"promiseRejected\"` - Fired when a promise is rejected.\n - `\"promiseResolved\"` - Fired when a promise adopts another's state.\n - `\"promiseCancelled\"` - Fired when a promise is cancelled.\n\nThis feature has to be explicitly enabled by calling [Promise.config](.) with `monitoring: true`.\n\nThe actual subscription API depends on the environment.\n\n1\\. In Node.js, use `process.on`:\n\n```js\n// Note the event name is in camelCase, as per Node.js convention.\nprocess.on(\"promiseChained\", function(promise, child) {\n    // promise - The parent promise the child was chained from\n    // child - The created child promise.\n});\n```\n\n2\\. In modern browsers use `window.addEventListener` (window context) or `self.addEventListener()` (web worker or window context) method:\n\n```js\n// Note the event names are in mashedtogetherlowercase, as per DOM convention.\nself.addEventListener(\"promisechained\", function(event) {\n    // event.details.promise - The parent promise the child was chained from\n    // event.details.child - The created child promise.\n});\n```\n\n3\\. In legacy browsers use `window.oneventname = handlerFunction;`.\n\n```js\n// Note the event names are in mashedtogetherlowercase, as per legacy convention.\nwindow.onpromisechained = function(promise, child) {\n    // event.details.promise - The parent promise the child was chained from\n    // event.details.child - The created child promise.\n};\n```\n\n##Resource management\n\n##Cancellation and timeouts\n\nSee [`Cancellation`](.) for how to use cancellation.\n\n```js\n// Enable cancellation\nPromise.config({cancellation: true});\n\nvar fs = Promise.promisifyAll(require(\"fs\"));\n\n// In 2000ms or less, load & parse a file 'config.json'\nvar p = Promise.resolve('./config.json')\n .timeout(2000)\n .catch(console.error.bind(console, 'Failed to load config!'))\n .then(fs.readFileAsync)\n .then(JSON.parse);\n// Listen for exception event to trigger promise cancellation\nprocess.on('unhandledException', function(event) {\n // cancel config loading\n p.cancel();\n});\n```\n\n##Scoped prototypes\n\nBuilding a library that depends on bluebird? You should know about the \"scoped prototype\" feature.\n\nIf your library needs to do something obtrusive like adding or modifying methods on the `Promise` prototype, uses long stack traces or uses a custom unhandled rejection handler then... that's totally ok as long as you don't use `require(\"bluebird\")`. Instead you should create a file\nthat creates an isolated copy. For example, creating a file called `bluebird-extended.js` that contains:\n\n```js\n                //NOTE the function call right after\nmodule.exports = require(\"bluebird/js/main/promise\")();\n```\n\nYour library can then use `var Promise = require(\"bluebird-extended\");` and do whatever it wants with it. Then if the application or other library uses their own bluebird promises they will all play well together because of Promises/A+ thenable assimilation magic.\n\n\n##Async/Await\n\n"
  },
  {
    "path": "docs/docs/getting-started.md",
    "content": "---\nid: getting-started\ntitle: Getting Started\nredirect_from: \"/index.html\"\nredirect_from: \"/docs/index.html\"\n---\n\n[getting-started](unfinished-article)\n\n## Node.js\n\n    npm install bluebird\n\nThen:\n\n```js\nvar Promise = require(\"bluebird\");\n```\n\nAlternatively in ES6 \n\n```js\nimport * as Promise from \"bluebird\";\n```\n\nIf that ES6 import [doesn't work](https://github.com/petkaantonov/bluebird/pull/1594)\n\n```js\nimport {Promise} from \"bluebird\";\n```\n\n## Browsers\n\n(See also [Installation](install.html).)\n\nThere are many ways to use bluebird in browsers:\n\n- Direct downloads\n    - Full build [bluebird.js](https://cdn.jsdelivr.net/bluebird/latest/bluebird.js)\n    - Full build minified [bluebird.min.js](https://cdn.jsdelivr.net/bluebird/latest/bluebird.min.js)\n    - Core build [bluebird.core.js](https://cdn.jsdelivr.net/bluebird/latest/bluebird.core.js)\n    - Core build minified [bluebird.core.min.js](https://cdn.jsdelivr.net/bluebird/latest/bluebird.core.min.js)\n- You may use browserify on the main export\n- You may use the [bower](http://bower.io) package.\n\nWhen using script tags the global variables `Promise` and `P` (alias for `Promise`) become available. Bluebird runs on a wide variety of browsers including older versions. We'd like to thank BrowserStack for giving us a free account which helps us test that. \n"
  },
  {
    "path": "docs/docs/install.md",
    "content": "---\nid: install\ntitle: Installation\n---\n\n- [Browser installation](#browser-installation)\n- [Node installation](#node-installation)\n- [Supported platforms](#supported-platforms)\n\n##Browser installation\n\nDownload <a href=\"https://cdn.jsdelivr.net/npm/bluebird@{{ site.version }}/js/browser/bluebird.js\">bluebird {{ site.version }} (development)</a>\n\nUnminified source file meant to be used in development. Warnings and long stack traces are enabled which are taxing on performance.\n\n```html\n<script src=\"//cdn.jsdelivr.net/npm/bluebird@{{ site.version }}/js/browser/bluebird.js\"></script>\n```\n\nDownload <a href=\"https://cdn.jsdelivr.net/npm/bluebird@{{ site.version }}/js/browser/bluebird.min.js\">bluebird {{ site.version }} (production)</a>\n\nMinified source file meant to be used in production. Warnings and long straces are disabled. The gzipped size is 17.76KB.\n\n```html\n<script src=\"//cdn.jsdelivr.net/npm/bluebird@{{ site.version }}/js/browser/bluebird.min.js\"></script>\n```\n\nUnless an AMD loader is installed, the script tag installation exposes the library in the `Promise` and `P` namespaces. If you want to restore the `Promise` namespace, use `var Bluebird = Promise.noConflict()`.\n\n###Bower\n\n```\n$ bower install --save bluebird\n```\n\n###Browserify and Webpack\n\n```\n$ npm install bluebird\n```\n\nUsing webpack for development/debugging:\n\n```js\nvar Promise = require(\"bluebird\");\n// Configure webpack and browserify for development/debugging\nPromise.config({\n    longStackTraces: true,\n    warnings: true // note, run node with --trace-warnings to see full stack traces for warnings\n})\n```\n\nUsing webpack for production/performance:\n\n\n```js\nvar Promise = require(\"bluebird\");\n// Configure webpack and browserify for production/performance\nPromise.config({\n    longStackTraces: false,\n    warnings: false\n})\n```\n\n##Node installation\n\n```\n$ npm install bluebird\n```\n\n```js\nvar Promise = require(\"bluebird\");\n```\n\nTo enable long stack traces and warnings in node development:\n\n```\n$ NODE_ENV=development node server.js\n```\n\nTo enable long stack traces and warnings in node production:\n\n```\n$ BLUEBIRD_DEBUG=1 node server.js\n```\n\nSee [Environment Variables](.).\n\n##Supported platforms\n\nBluebird officially supports and is tested on node.js, iojs and browsers starting from IE7. Unofficial platforms are supported with best effort only.\n\nIE7 and IE8 do not support using keywords as property names, so if supporting these browsers is required you need to use the compatibility aliases:\n\n\n- [`Promise.try()`](.) -> `Promise.attempt()`\n- [`.catch()`](.) -> `.caught()`\n- [`.finally()`](.) -> `.lastly()`\n- [`.return()`](.) -> `.thenReturn()`\n- [`.throw()`](.) -> `.thenThrow()`\n\nLong stack traces are only supported in Chrome, recent Firefoxes and Internet Explorer 10+\n\n[![Selenium Test Status](https://saucelabs.com/browser-matrix/petka_antonov.svg)](https://saucelabs.com/u/petka_antonov)\n"
  },
  {
    "path": "docs/docs/new-in-bluebird-3.md",
    "content": "---\nid: new-in-bluebird-3\ntitle: New in bluebird 3.0\n---\n\n##Cancellation overhaul\n\nCancellation has been redesigned for bluebird 3.0. Any code that relies on 2.x cancellation semantics won't work in 3.0 or later. See [Cancellation](.) for more information.\n\n##Promisification API changes\n\nBoth promisification \\([Promise.promisify](.) and [Promise.promisifyAll](.)\\) methods and [Promise.fromCallback](.) now by default ignore multiple arguments passed to the callback adapter and instead only the first argument is used to resolve the promise. The behavior in 2.x is to construct an array of the arguments and resolve the promise with it when more than one argument is passed to the callback adapter. The problems with this approach and reasons for the change are discussed in [#307](.).\n\n[Promise.promisify](.)'s second argument is now an options object, so any code using the second argument needs to change:\n\n```js\n// 2.x\nPromise.promisify(fn, ctx);\n// 3.0\nPromise.promisify(fn, {context: ctx});\n```\n\nBoth promisification \\([Promise.promisify](.) and [Promise.promisifyAll](.)\\) methods and [Promise.fromCallback](.) all take a new boolean option `multiArgs` which defaults to `false`. Enabling this option will make the adapter callback *always* construct an array of the passed arguments regardless of amount of arguments. This can be used to reliably get access to all arguments rather than just the first one.\n\n##Collection method changes\n\nAll collection methods now support objects that implement [ES6's *iterable*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) protocol along with regular arrays.\n\n[Promise.props](.) and [.props](.) now support [ES6 `Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) objects along with normal objects. Actual `Map` objects are only considered for their entries in the map instead of both entries and properties.\n\n\n##Warnings\n\nWarnings have been added to report usages which are very likely to be programmer errors. See [Promise.config](.) for how to enable warnings. See [Warning Explanations](warning-explanations.html) for list of the warnings and their explanations.\n\n##Feature additions\n\n- [.catch\\(\\)](.) now supports an object predicate as a filter: `.catch({code: 'ENOENT'}, e => ...)`.\n- Added [.suppressUnhandledRejections\\(\\)](.).\n- Added [.catchThrow\\(\\)](.).\n- Added [.catchReturn\\(\\)](.).\n- Added [Promise.mapSeries\\(\\)](.) and [.mapSeries\\(\\)](.)\n\n##Deprecations\n\n- `Promise.settle` has been deprecated. Use [.reflect](.) instead.\n- `Promise.spawn` has been deprecated. Use [Promise.coroutine](.) instead.\n- [Promise.try](.)'s `ctx` and `arg` arguments have been deprecated.\n- `.nodeify` is now better known as [.asCallback](.)\n- `.fromNode` is now better known as [Promise.fromCallback](.)\n\n\n##Summary of breaking changes\n\n- Promisifier APIs.\n- Cancellation redesign.\n- Promise progression has been completely removed.\n- [.spread](.)'s second argument has been removed.\n- [.done](.) causes an irrecoverable fatal error in Node.js environments now. See [#471](.) for rationale.\n- Errors created with [Promise.reject](.) or `reject` callback of [new Promise](.) are no longer marked as [OperationalError](.)s.\n\n##3.0.1 update\n\nNote that the 3.0.1 update is strictly speaking backward-incompatible with 3.0.0. Version 3.0.0 changed the previous behavior of the `.each` method and made it work the same as the new `.mapSeries` - 3.0.1 unrolls this change by reverting to the `.tap`-like behavior found in 2.x However, this would only affect users who updated to 3.0.0 during the short time that it wasn't deprecated and started relying on the new `.each` behavior. This seems unlikely, and therefore the major version was not changed.\n"
  },
  {
    "path": "docs/docs/support.md",
    "content": "---\nid: support\ntitle: Support\n---\n\nDepending on the nature of your problem there are a few possible ways of getting help with your problem.\n\n###Stack Overflow\n\nStack Overflow has an active community answering questions on both the [bluebird](http://stackoverflow.com/questions/tagged/bluebird) and [promise](http://stackoverflow.com/questions/tagged/promise) tags. If you are unfamiliar with Stack Overflow, do review [the asking guidelines](http://stackoverflow.com/help/asking) before asking a new question there.\n\n###Google Groups mailing list\n\nThe [bluebird-js@googlegroups.com](https://groups.google.com/forum/#!forum/bluebird-js) mailing list is the best place to ask any question that cannot be easily fit in the stack overflow question format.\n\n###IRC\n\nYou can usually get fast answers on the freenode.net channels [#bluebird](irc://chat.freenode.net/bluebird) and [#promises](irc://chat.freenode.net/promises).\n\n###Gitter\n\nIf you are not comfortable using IRC you can also join the [bluebird gitter chat](https://gitter.im/petkaantonov/bluebird)\n\n###Github issue tracker\n\nIf you feel that your problem is caused by a bug or a missing feature that should be added, you should use the [Github issue tracker](https://github.com/petkaantonov/bluebird/issues/) to report it. However in any other case the issue tracker is not the appropriate channel.\n"
  },
  {
    "path": "docs/docs/warning-explanations.md",
    "content": "---\nid: warning-explanations\ntitle: Warning Explanations\n---\n\n[warning-explanations](unfinished-article)\n\n - [Warning: .then() only accepts functions](#warning-then-only-accepts-functions)\n - [Warning: a promise was rejected with a non-error](#warning-a-promise-was-rejected-with-a-non-error)\n - [Warning: a promise was created in a handler but was not returned from it](#warning-a-promise-was-created-in-a-handler-but-was-not-returned-from-it)\n\nNote - in order to get full stack traces with warnings in Node 6.x+ you need to enable to `--trace-warnings` flag which will give you a full stack trace of where the warning is coming from.\n\n## Warning: .then() only accepts functions\n\nIf you see this warning your code is probably not doing what you expect it to, the most common reason is passing the *result* of calling a function to [.then()](.) instead of the function *itself*:\n\n```js\nfunction processImage(image) {\n    // Code that processes image\n}\n\ngetImage().then(processImage());\n```\n\nThe above calls the function `processImage()` *immediately* and passes the result to [.then()](.) (which is most likely `undefined` - the default return value when a function doesn't return anything).\n\nTo fix it, simply pass the function reference to [.then()](.) as is:\n\n```js\ngetImage().then(processImage)\n```\n\n*If you are wondering why this is a warning and not a simple TypeError it is because the due to historic reasons Promises/A+ specification requires that incorrect usage is silently ignored.*\n\n## Warning: a promise was rejected with a non-error\n\nDue to a historic mistake in JavaScript, the `throw` statement is allowed to be used with any value, not just errors, and Promises/A+ choosing to inherit this mistake, it is possible to reject a promise with a value that is not an error.\n\nAn error is an object that is a `instanceof Error`. It will at minimum have the properties `.stack` and `.message`, which are an absolute *must* have for any value that is being used in an automatic propagation mechanism, such as exceptions and rejections. This is because errors are usually handled many levels above where they actually originate - the error object must have sufficient metadata about it so that its ultimate handler (possibly many levels above) will have all the information needed for creating a useful high level error report.\n\nSince all objects support having properties you might still wonder why exactly does it have to be an error object and not just any object. In addition to supporting properties, an equally important feature necessary for values that are automatically propagated is the stack trace property (`.stack`). A stack trace allows you easily find where an error originated from as it gives the code's call stack - along with line numbers for reference in code files.\n\nYou should heed this warning because rejecting a promise with a non-error makes debugging extremely hard and costly. Additionally, if you reject with simple primitives such as `undefined` (commonly caused by simply calling `reject()`) you cannot handle errors at all because it's impossible to tell from `undefined` what exactly went wrong. All you can tell the user is that \"something went wrong\" and lose them forever.\n\n\n## Warning: a promise was created in a handler but was not returned from it\n\nThis usually means that you simply forgot a `return` statement somewhere, which will cause a runaway promise that is not connected to any promise chain.\n\nFor example:\n\n```js\ngetUser().then(function(user) {\n    getUserData(user);\n}).then(function(userData) {\n    // userData is undefined\n});\n```\n\nBecause the result of `getUserData()` is not returned from the first then handler, it becomes a runaway promise that is not awaited for by the second then. The second [.then()](.) simply gets immediately called with `undefined` (because `undefined` is the default return value when you don't return anything).\n\nTo fix it, you need to `return` the promise:\n\n```js\ngetUser().then(function(user) {\n    return getUserData(user);\n}).then(function(userData) {\n    // userData is the user's data\n});\n```\n\n<hr>\n\nIf you know what you're doing and don't want to silence all warnings, you can create runaway promises without causing this warning by returning e.g. `null`:\n\n```js\ngetUser().then(function(user) {\n    // Perform this in the \"background\" and don't care about its result at all\n    saveAnalytics(user);\n    // return a non-undefined value to signal that we didn't forget to return\n    return null;\n});\n```\n\n\n"
  },
  {
    "path": "docs/docs/what-about-generators.md",
    "content": "---\nid: what-about-generators\ntitle: What About Generators?\n---\n\nThere is an [excellent article](https://www.promisejs.org/generators/) on promisejs.org detailing how to combine promises with generators to achieve much cleaner code. Instead of the `async` function the article proposes, you can use [Promise.coroutine](.).\n\n[what-about-generators](unfinished-article)\n"
  },
  {
    "path": "docs/docs/why-bluebird.md",
    "content": "---\nid: why-bluebird\ntitle: Why bluebird?\n---\n\nThere are many third party promise libraries available for JavaScript and even the standard library contains a promise implementation in newer versions of browsers and node/io.js. This page will explore why one might use bluebird promises over other third party or the standard library implementations. For reasons to use promises in general, see the [Why Promises?](why-promises.html) article.\n\n###Bluebird design principles\n\nBluebird is built with the following design principles in mind:\n\n - **Pragmatic and not theoretical** - Bluebird will always pick the pragmatic route vs the theoretically elegant one when there is a conflict. The library's API was created based on real-life use cases and after a lot of consideration.\n - **Fully featured without bloat** - Bluebird provides all the tools and utilities needed to realize a highly expressive and fluent DSL for asynchronous JavaScript without suffering from bloat by avoiding incorporating features that are solely motivated by theoretical arguments, have extremely narrow applicability, or have limited synergy and composability with existing features.\n - **Easy to debug** - A major consequence of choosing pragmatism over theoretical elegance, a property that is unique to bluebird among promise libraries taken to this extent.\n    - Bluebird ships with the best cross-platform long stack traces out there and a warning system. This helps you recognize common and devastating promise usage mistakes early before they lead to hard to debug code later.\n    - Unhandled errors are not silently swallowed by default but reported along with helpful stack traces where applicable. All of this is of course configurable.\n - **Zero overhead abstraction** - In server-side applications the performance of a promise implementation matters. Bluebird's server-side performance is measured with highly relevant and realistic end-to-end macro [benchmarks](benchmarks.html), and consistently comes out on top. We understand that if bluebird is as close to a zero cost abstraction as possible, developers won't be tempted to short-circuit and absorb complexity themselves.\n - **Runs everywhere** - Bluebird runs on pretty much every platform. This makes bluebird ideal for projects who care about providing consistent cross-platform and cross-version experience. It runs on old IE, it has even been known to run on Netscape 7.\n - **Spec compatible** - Bluebird can work as a drop-in replacement for native promises for an instant performance boost. It passes the Promises/A+ test suite and is fully spec compliant.\n\n\n\n"
  },
  {
    "path": "docs/docs/why-performance.md",
    "content": "---\nid: why-performance\ntitle: Why Performance?\n---\n\n[why-performance](unfinished-article)\n"
  },
  {
    "path": "docs/docs/why-promises.md",
    "content": "---\nid: why-promises\ntitle: Why Promises?\n---\n\nPromises are a concurrency primitive with a proven track record and language integration in most modern programming languages. They have been extensively studied since the 80s and will make your life much easier.\n\nYou should use promises to turn this:\n\n```js\nfs.readFile(\"file.json\", function (err, val) {\n    if (err) {\n        console.error(\"unable to read file\");\n    }\n    else {\n        try {\n            val = JSON.parse(val);\n            console.log(val.success);\n        }\n        catch (e) {\n            console.error(\"invalid json in file\");\n        }\n    }\n});\n```\n\nInto this:\n\n```js\nfs.readFileAsync(\"file.json\").then(JSON.parse).then(function (val) {\n    console.log(val.success);\n})\n.catch(SyntaxError, function (e) {\n    console.error(\"invalid json in file\");\n})\n.catch(function (e) {\n    console.error(\"unable to read file\");\n});\n```\n\n*If you're thinking, \"There's no `readFileAsync` method on `fs` that returns a promise!\" see [promisification](api/promisification.html)*\n\nYou might notice that the promise approach looks very similar to using synchronous I/O:\n\n```js\ntry {\n    var val = JSON.parse(fs.readFileSync(\"file.json\"));\n    console.log(val.success);\n}\n// Gecko-only syntax; used for illustrative purposes\ncatch (e if e instanceof SyntaxError) {\n    console.error(\"invalid json in file\");\n}\ncatch (e) {\n    console.error(\"unable to read file\");\n}\n```\n\nThis is the point—to have something that works like `return` and `throw` in synchronous code.\n\nYou can also use promises to improve code that was written with callbacks:\n\n```js\n//Copyright Plato http://stackoverflow.com/a/19385911/995876\n//CC BY-SA 2.5\nmapSeries(URLs, function (URL, done) {\n    var options = {};\n    needle.get(URL, options, function (error, response, body) {\n        if (error) {\n            return done(error);\n        }\n        try {\n            var ret = JSON.parse(body);\n            return done(null, ret);\n        }\n        catch (e) {\n            done(e);\n        }\n    });\n}, function (err, results) {\n    if (err) {\n        console.log(err);\n    } else {\n        console.log('All Needle requests successful');\n        // results is a 1 to 1 mapping in order of URLs > needle.body\n        processAndSaveAllInDB(results, function (err) {\n            if (err) {\n                return done(err);\n            }\n            console.log('All Needle requests saved');\n            done(null);\n        });\n    }\n});\n```\n\nThis is far more readable when done with promises:\n\n```js\nPromise.promisifyAll(needle);\nvar options = {};\n\nvar current = Promise.resolve();\nPromise.map(URLs, function (URL) {\n    current = current.then(function () {\n        return needle.getAsync(URL, options);\n    });\n    return current;\n}).map(function (responseAndBody) {\n    return JSON.parse(responseAndBody[1]);\n}).then(function (results) {\n    return processAndSaveAllInDB(results);\n}).then(function () {\n    console.log('All Needle requests saved');\n}).catch(function (e) {\n    console.log(e);\n});\n```\n\nAlso, promises don't just give you correspondences for synchronous features; they can also be used as limited event emitters or callback aggregators.\n\nMore reading:\n\n - [Promise nuggets](https://promise-nuggets.github.io/)\n - [Why I am switching to promises](http://spion.github.io/posts/why-i-am-switching-to-promises.html)\n - [What is the the point of promises](http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/#toc_1)\n - [Aren't Promises Just Callbacks?](http://stackoverflow.com/questions/22539815/arent-promises-just-callbacks)\n"
  },
  {
    "path": "docs/docs/working-with-callbacks.md",
    "content": "---\nid: working-with-callbacks\ntitle: Working with Callbacks\n---\n\nThis page explains how to interface your code with existing callback APIs and libraries you're using. We'll see that making bluebird work with callback APIs is not only easy - it's also fast.\n\nWe'll cover several subjects. If you want to get the tl;dr what you need is likely the [Working with callback APIs using the Node convention](#working-with-callback-apis-using-the-node-convention) section.\n\nFirst to make sure we're on the same page:\n\nPromises have state, they start as pending and can settle to:\n\n - __fulfilled__ meaning that the computation completed successfully.\n - __rejected__ meaning that the computation failed.\n\nPromise returning functions _should never throw_, they should always successfully return a promise which is rejected in the case of an error. Throwing from a promise returning function will force you to use both a `} catch { ` _and_ a `.catch`. People using promisified APIs do not expect promises to throw. If you're not sure how async APIs work in JS - please [see this answer](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call/16825593#16825593) first.\n\n * [Automatic vs. Manual conversion](#automatic-vs.-manual-conversion)\n * [Working with callback APIs using the Node convention](#working-with-callback-apis-using-the-node-convention)\n * [Working with one time events.](#working-with-one-time-events)\n * [Working with delays](#working-with-delays/setTimeout)\n * [Working with browser APIs](#working-with-browser-apis)\n * [Working with databases](#working-with-databases)\n * [More Common Examples](#more-common-examples)\n * [Working with any other APIs](#working-with-any-other-apis)\n\nThere is also [this more general StackOverflow question](http://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises) about conversion of callback APIs to promises. If you find anything missing in this guide however, please do open an issue or pull request.\n\n###Automatic vs. Manual conversion\n\nThere are two primary methods of converting callback based APIs into promise based ones. You can either manually map the API calls to promise returning functions or you can let the bluebird do it for you. We **strongly** recommend the latter.\n\nPromises provide a lot of really cool and powerful guarantees like throw safety which are hard to provide when manually converting APIs to use promises. Thus, whenever it is possible to use the `Promise.promisify` and `Promise.promisifyAll` methods - we recommend you use them. Not only are they the safest form of conversion - they also use techniques of dynamic recompilation to introduce very little overhead.\n\n###Working with callback APIs using the Node convention\n\nIn Node/io.js most APIs follow a convention of ['error-first, single-parameter'](https://gist.github.com/CrabDude/10907185) as such:\n\n```js\nfunction getStuff(data, callback) {\n    ...\n}\n\ngetStuff(\"dataParam\", function(err, data) {\n    if (!err) {\n\n    }\n});\n```\n\nThis APIs are what most core modules in Node/io use and bluebird comes with a fast and efficient way to convert them to promise based APIs through the `Promise.promisify` and `Promise.promisifyAll` function calls.\n\n - [Promise.promisify](.) - converts a _single_ callback taking function into a promise returning function. It does not alter the original function and returns the modified version.\n - [Promise.promisifyAll](.) - takes an _object_ full of functions and _converts each function_ into the new one with the `Async` suffix (by default). It does not change the original functions but instead adds new ones.\n\n> **Note** - please check the linked docs for more parameters and usage examples.\n\nHere's an example of `fs.readFile` with or without promises:\n\n```js\n// callbacks\nvar fs = require(\"fs\");\nfs.readFile(\"name\", \"utf8\", function(err, data) {\n\n});\n```\n\nPromises:\n\n```js\nvar fs = Promise.promisifyAll(require(\"fs\"));\nfs.readFileAsync(\"name\", \"utf8\").then(function(data) {\n\n});\n```\n\nNote the new method is suffixed with `Async`, as in `fs.readFileAsync`. It did not replace the `fs.readFile` function. Single functions can also be promisified for example:\n\n```js\nvar request = Promise.promisify(require(\"request\"));\nrequest(\"foo.bar\").then(function(result) {\n\n});\n```\n\n> **Note** `Promise.promisify` and `Promise.promisifyAll` use dynamic recompilation for really fast wrappers and thus calling them should be done only once. [Promise.fromCallback](.) exists for cases where this is not possible.\n\n###Working with one time events\n\nSometimes, we want to find out when a single one time event has finished. For example - a stream is done. For this we can use [new Promise](.). Note that this option should be considered only if [automatic conversion](#working-with-callback-apis-using-the-node-convention) isn't possible.\n\nNote that promises model a _single value through time_, they only resolve _once_ - so while they're a good fit for a single event, they are not recommended for multiple event APIs.\n\nFor example, let's say you have a window `onload` event you want to bind to. We can use the promise construction and resolve when the window has loaded as such:\n\n```js\n// onload example, the promise constructor takes a\n// 'resolver' function that tells the promise when\n// to resolve and fire off its `then` handlers.\nvar loaded = new Promise(function(resolve, reject) {\n    window.addEventListener(\"load\", resolve);\n});\n\nloaded.then(function() {\n    // window is loaded here\n});\n```\n\nHere is another example with an API that lets us know when a connection is ready. The attempt here is imperfect and we'll describe why soon:\n\n```js\nfunction connect() {\n   var connection = myConnector.getConnection();  // Synchronous.\n   return new Promise(function(resolve, reject) {\n        connection.on(\"ready\", function() {\n            // When a connection has been established\n            // mark the promise as fulfilled.\n            resolve(connection);\n        });\n        connection.on(\"error\", function(e) {\n            // If it failed connecting, mark it\n            // as rejected.\n            reject(e);  // e is preferably an `Error`.\n        });\n   });\n}\n```\n\nThe problem with the above is that `getConnection` itself might throw for some reason and if it does we'll get a synchronous rejection. An asynchronous operation should always be asynchronous to prevent double guarding and race conditions so it's best to always put the sync parts inside the promise constructor as such:\n\n```js\nfunction connect() {\n   return new Promise(function(resolve, reject) {\n        // If getConnection throws here instead of getting\n        // an exception we're getting a rejection thus\n        // producing a much more consistent API.\n        var connection = myConnector.getConnection();\n        connection.on(\"ready\", function() {\n            // When a connection has been established\n            // mark the promise as fulfilled.\n            resolve(connection);\n        });\n        connection.on(\"error\", function(e) {\n            // If it failed connecting, mark it\n            // as rejected.\n            reject(e); //  e is preferably an `Error`\n        });\n   });\n}\n```\n###Working with delays/setTimeout\n\nThere is no need to convert timeouts/delays to a bluebird API, bluebird already ships with the [Promise.delay](.) function for this use case. Please consult the [timers](.) section of the docs on usage and examples.\n\n###Working with browser APIs\n\nOften browser APIs are nonstandard and automatic promisification will fail for them. If you're running into an API that you can't promisify with [promisify](.) and [promisifyAll](.) - please consult the [working with other APIs section](#working-with-any-other-apis)\n\n###Working with databases\n\nFor resource management in general and databases in particular, bluebird includes the powerful  [Promise.using](.) and disposers system. This is similar to `with` in Python, `using` in C#, try/resource in Java or RAII in C++ in that it lets you handle resource management in an automatic way.\n\nSeveral examples of databases follow.\n\n> **Note** for more examples please see the [Promise.using](.) section.\n\n####Mongoose/MongoDB\n\nMongoose works with persistent connections and the driver takes care of reconnections/disposals. For this reason using `using` with it isn't required - instead connect on server startup and use promisification to expose promises.\n\nNote that Mongoose already ships with promise support but the promises it offers are significantly slower and don't report unhandled rejections so it is recommended to use automatic promisification with it anyway:\n\n```js\nvar Mongoose = Promise.promisifyAll(require(\"mongoose\"));\n```\n\n####Sequelize\n\nSequelize already uses Bluebird promises internally and has promise returning APIs. Use those.\n\n####RethinkDB\n\nRethink already uses Bluebird promises internally and has promise returning APIs. Use those.\n\n####Bookshelf\n\nBookshelf already uses Bluebird promises internally and has promise returning APIs. Use those.\n\n\n####PostgreSQL\n\nHere is how to create a disposer for the PostgreSQL driver:\n\n```js\nvar pg = require(\"pg\");\n// Uncomment if pg has not been properly promisified yet.\n//var Promise = require(\"bluebird\");\n//Promise.promisifyAll(pg, {\n//    filter: function(methodName) {\n//        return methodName === \"connect\"\n//    },\n//    multiArgs: true\n//});\n// Promisify rest of pg normally.\n//Promise.promisifyAll(pg);\n\nfunction getSqlConnection(connectionString) {\n    var close;\n    return pg.connectAsync(connectionString).spread(function(client, done) {\n        close = done;\n        return client;\n    }).disposer(function() {\n        if (close) close();\n    });\n}\n\nmodule.exports = getSqlConnection;\n```\n\nWhich would allow you to use:\n\n```js\nvar using = Promise.using;\n\nusing(getSqlConnection(), function(conn) {\n    // use connection here and _return the promise_\n\n}).then(function(result) {\n    // connection already disposed here\n\n});\n```\n\nIt's also possible to use a disposer pattern (but not actual disposers) for transaction management:\n\n```js\n\nfunction withTransaction(fn) {\n  return Promise.using(pool.acquireConnection(), function(connection) {\n    var tx = connection.beginTransaction()\n    return Promise\n      .try(fn, tx)\n      .then(function(res) { return connection.commit().thenReturn(res) },\n            function(err) {\n              return connection.rollback()\n                     .catch(function(e) {/* maybe add the rollback error to err */})\n                     .thenThrow(err);\n            });\n  });\n}\nexports.withTransaction = withTransaction;\n```\n\nWhich would let you do:\n\n```js\nwithTransaction(tx => {\n    return tx.queryAsync(...).then(function() {\n        return tx.queryAsync(...)\n    }).then(function() {\n        return tx.queryAsync(...)\n    });\n});\n```\n\n####MySQL\n\nHere is how to create a disposer for the MySQL driver:\n\n```js\nvar mysql = require(\"mysql\");\n// Uncomment if mysql has not been properly promisified yet\n// var Promise = require(\"bluebird\");\n// Promise.promisifyAll(mysql);\n// Promise.promisifyAll(require(\"mysql/lib/Connection\").prototype);\n// Promise.promisifyAll(require(\"mysql/lib/Pool\").prototype);\nvar pool  = mysql.createPool({\n    connectionLimit: 10,\n    host: 'example.org',\n    user: 'bob',\n    password: 'secret'\n});\n\nfunction getSqlConnection() {\n    return pool.getConnectionAsync().disposer(function(connection) {\n        connection.release();\n    });\n}\n\nmodule.exports = getSqlConnection;\n```\n\nThe usage pattern is similar to the PostgreSQL example above. You can also use a disposer pattern (but not an actual .disposer). See the PostgreSQL example above for instructions.\n\n###More common examples\n\n\nSome examples of the above practice applied to some popular libraries:\n\n```js\n// The most popular redis module\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"redis\"));\n```\n\n```js\n// The most popular mongodb module\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"mongodb\"));\n```\n\n```js\n// The most popular mysql module\nvar Promise = require(\"bluebird\");\n// Note that the library's classes are not properties of the main export\n// so we require and promisifyAll them manually\nPromise.promisifyAll(require(\"mysql/lib/Connection\").prototype);\nPromise.promisifyAll(require(\"mysql/lib/Pool\").prototype);\n```\n\n```js\n// Mongoose\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"mongoose\"));\n```\n\n```js\n// Request\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"request\"));\n// Use request.getAsync(...) not request(..), it will not return a promise\n```\n\n```js\n// mkdir\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"mkdirp\"));\n// Use mkdirp.mkdirpAsync not mkdirp(..), it will not return a promise\n```\n\n```js\n// winston\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"winston\"));\n```\n\n```js\n// rimraf\nvar Promise = require(\"bluebird\");\n// The module isn't promisified but the function returned is\nvar rimrafAsync = Promise.promisify(require(\"rimraf\"));\n```\n\n```js\n// xml2js\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"xml2js\"));\n```\n\n```js\n// jsdom\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"jsdom\"));\n```\n\n```js\n// fs-extra\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"fs-extra\"));\n```\n\n```js\n// prompt\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"prompt\"));\n```\n\n```js\n// Nodemailer\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"nodemailer\"));\n```\n\n```js\n// ncp\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"ncp\"));\n```\n\n```js\n// pg\nvar Promise = require(\"bluebird\");\nPromise.promisifyAll(require(\"pg\"));\n```\n\nIn all of the above cases the library made its classes available in one way or another. If this is not the case, you can still promisify by creating a throwaway instance:\n\n```js\nvar ParanoidLib = require(\"...\");\nvar throwAwayInstance = ParanoidLib.createInstance();\nPromise.promisifyAll(Object.getPrototypeOf(throwAwayInstance));\n// Like before, from this point on, all new instances + even the throwAwayInstance suddenly support promises\n```\n\n###Working with any other APIs\n\nSometimes you have to work with APIs that are inconsistent and do not follow a common convention.\n\n> **Note** Promise returning function should never throw\n\nFor example, something like:\n\n```js\nfunction getUserData(userId, onLoad, onFail) { ...\n```\n\nWe can use the promise constructor to convert it to a promise returning function:\n\n```js\nfunction getUserDataAsync(userId) {\n    return new Promise(function(resolve, reject) {\n        // Put all your code here, this section is throw-safe.\n        getUserData(userId, resolve, reject);\n    });\n}\n```\n"
  },
  {
    "path": "docs/helpers.rb",
    "content": "require \"sanitize\"\n\nclass Helpers\n    def self.clean(input)\n        return Sanitize.fragment(input)\n            .downcase\n            .gsub(/\\s+/, \"-\")\n            .gsub(/^([A-Za-z0-9\\-_.:]+).*?$/, \"\\\\1\")\n            .gsub(/^\\./, \"\")\n            .gsub(/\\.$/, \"\")\n            .gsub(/[^A-Za-z0-9\\-_.]/, \"\")\n            .sub(/^-+/, \"\")\n            .sub(/-+$/, \"\")\n\n    end\nend\n"
  },
  {
    "path": "docs/img/README.txt",
    "content": "SVG available upon request.\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!DOCTYPE html>\n<meta charset=utf-8>\n<title>Redirecting...</title>\n<link rel=canonical href=\"/docs/getting-started.html\">\n<meta http-equiv=refresh content=\"0; url=/docs/getting-started.html\">\n<h1>Redirecting...</h1>\n<a href=\"/docs/getting-started.html\">Click here if you are not redirected.</a>\n<script>location='/docs/getting-started.html'</script>\n"
  },
  {
    "path": "issue_template.md",
    "content": "(This issue tracker is only for bug reports or feature requests, if this is neither, please choose appropriate channel from http://bluebirdjs.com/docs/support.html)\n\nPlease answer the questions the best you can:\n\n1) What version of bluebird is the issue happening on?\n\n2) What platform and version? (For example Node.js 0.12 or Google Chrome 32)\n\n3) Did this issue happen with earlier version of bluebird?\n\n(Write description of your issue here, stack traces from errors and code that reproduces the issue are helpful)\n\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"bluebird\",\n  \"description\": \"Full featured Promises/A+ implementation with exceptionally good performance\",\n  \"version\": \"3.7.2\",\n  \"keywords\": [\n    \"promise\",\n    \"performance\",\n    \"promises\",\n    \"promises-a\",\n    \"promises-aplus\",\n    \"async\",\n    \"await\",\n    \"deferred\",\n    \"deferreds\",\n    \"future\",\n    \"flow control\",\n    \"dsl\",\n    \"fluent interface\"\n  ],\n  \"scripts\": {\n    \"lint\": \"node scripts/jshint.js\",\n    \"test\": \"node --expose-gc tools/test.js\",\n    \"istanbul\": \"istanbul\",\n    \"prepublish\": \"npm run generate-browser-core && npm run generate-browser-full\",\n    \"generate-browser-full\": \"node tools/build.js --no-clean --no-debug --release --browser --minify\",\n    \"generate-browser-core\": \"node tools/build.js --features=core --no-debug --release --zalgo --browser --minify && mv js/browser/bluebird.js js/browser/bluebird.core.js && mv js/browser/bluebird.min.js js/browser/bluebird.core.min.js\"\n  },\n  \"homepage\": \"https://github.com/petkaantonov/bluebird\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/petkaantonov/bluebird.git\"\n  },\n  \"bugs\": {\n    \"url\": \"http://github.com/petkaantonov/bluebird/issues\"\n  },\n  \"license\": \"MIT\",\n  \"author\": {\n    \"name\": \"Petka Antonov\",\n    \"email\": \"petka_antonov@hotmail.com\",\n    \"url\": \"http://github.com/petkaantonov/\"\n  },\n  \"devDependencies\": {\n    \"acorn\": \"^6.0.2\",\n    \"acorn-walk\": \"^6.1.0\",\n    \"baconjs\": \"^0.7.43\",\n    \"bluebird\": \"^2.9.2\",\n    \"body-parser\": \"^1.10.2\",\n    \"browserify\": \"^8.1.1\",\n    \"cli-table\": \"~0.3.1\",\n    \"co\": \"^4.2.0\",\n    \"cross-spawn\": \"^0.2.3\",\n    \"glob\": \"^4.3.2\",\n    \"grunt-saucelabs\": \"~8.6.3\",\n    \"highland\": \"^2.3.0\",\n    \"istanbul\": \"^0.3.5\",\n    \"jshint\": \"^2.6.0\",\n    \"jshint-stylish\": \"~0.2.0\",\n    \"kefir\": \"^2.4.1\",\n    \"mkdirp\": \"~0.5.0\",\n    \"mocha\": \"~10.2\",\n    \"open\": \"~0.0.5\",\n    \"optimist\": \"~0.6.1\",\n    \"rimraf\": \"~2.2.6\",\n    \"rx\": \"^2.3.25\",\n    \"serve-static\": \"^1.7.1\",\n    \"sinon\": \"~1.7.3\",\n    \"uglify-js\": \"~2.4.16\"\n  },\n  \"readmeFilename\": \"README.md\",\n  \"main\": \"./js/release/bluebird.js\",\n  \"webpack\": \"./js/release/bluebird.js\",\n  \"browser\": \"./js/browser/bluebird.js\",\n  \"files\": [\n    \"js/browser\",\n    \"js/release\",\n    \"LICENSE\"\n  ]\n}\n"
  },
  {
    "path": "src/any.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise) {\nvar SomePromiseArray = Promise._SomePromiseArray;\nvar ASSERT = require(\"./assert\");\n\nfunction any(promises) {\n    var ret = new SomePromiseArray(promises);\n    var promise = ret.promise();\n    ASSERT(promise.isPending());\n    ASSERT(ret instanceof SomePromiseArray);\n    ret.setHowMany(1);\n    ret.setUnwrap();\n    ret.init();\n    return promise;\n}\n\nPromise.any = function (promises) {\n    return any(promises);\n};\n\nPromise.prototype.any = function () {\n    return any(this);\n};\n\n};\n"
  },
  {
    "path": "src/assert.js",
    "content": "\"use strict\";\nmodule.exports = (function(){\nvar AssertionError = (function() {\n    function AssertionError(a) {\n        this.constructor$(a);\n        this.message = a;\n        this.name = \"AssertionError\";\n    }\n    AssertionError.prototype = new Error();\n    AssertionError.prototype.constructor = AssertionError;\n    AssertionError.prototype.constructor$ = Error;\n    return AssertionError;\n})();\n\nfunction getParams(args) {\n    var params = [];\n    for (var i = 0; i < args.length; ++i) params.push(\"arg\" + i);\n    return params;\n}\n\nfunction nativeAssert(callName, args, expect) {\n    try {\n        var params = getParams(args);\n        var constructorArgs = params;\n        constructorArgs.push(\"return \" +\n                callName + \"(\"+ params.join(\",\") + \");\");\n        var fn = Function.apply(null, constructorArgs);\n        return fn.apply(null, args);\n    } catch (e) {\n        if (!(e instanceof SyntaxError)) {\n            throw e;\n        } else {\n            return expect;\n        }\n    }\n}\n\nreturn function assert(boolExpr, message) {\n    if (boolExpr === true) return;\n\n    if (typeof boolExpr === \"string\" &&\n        boolExpr.charAt(0) === \"%\") {\n        var nativeCallName = boolExpr;\n        INLINE_SLICE(args, arguments, 2);\n        if (nativeAssert(nativeCallName, args, message) === message) return;\n        message = (nativeCallName + \" !== \" + message);\n    }\n\n    var ret = new AssertionError(message);\n    if (Error.captureStackTrace) {\n        Error.captureStackTrace(ret, assert);\n    }\n    throw ret;\n};\n})();\n"
  },
  {
    "path": "src/async.js",
    "content": "\"use strict\";\nvar firstLineError;\ntry {throw new Error(); } catch (e) {firstLineError = e;}\nvar ASSERT = require(\"./assert\");\nvar schedule = require(\"./schedule\");\nvar Queue = require(\"./queue\");\n\nfunction Async() {\n    this._customScheduler = false;\n    this._isTickUsed = false;\n    this._lateQueue = new Queue(LATE_QUEUE_CAPACITY);\n    this._normalQueue = new Queue(NORMAL_QUEUE_CAPACITY);\n    this._haveDrainedQueues = false;\n    var self = this;\n    this.drainQueues = function () {\n        self._drainQueues();\n    };\n    this._schedule = schedule;\n}\n\nAsync.prototype.setScheduler = function(fn) {\n    var prev = this._schedule;\n    this._schedule = fn;\n    this._customScheduler = true;\n    return prev;\n};\n\nAsync.prototype.hasCustomScheduler = function() {\n    return this._customScheduler;\n};\n\nAsync.prototype.haveItemsQueued = function () {\n    return this._isTickUsed || this._haveDrainedQueues;\n};\n\n\nAsync.prototype.fatalError = function(e, isNode) {\n    if (isNode) {\n        process.stderr.write(\"Fatal \" + (e instanceof Error ? e.stack : e) +\n            \"\\n\");\n        process.exit(2);\n    } else {\n        this.throwLater(e);\n    }\n};\n\n// Must be used if fn can throw\nAsync.prototype.throwLater = function(fn, arg) {\n    if (arguments.length === 1) {\n        arg = fn;\n        fn = function () { throw arg; };\n    }\n    if (typeof setTimeout !== \"undefined\") {\n        setTimeout(function() {\n            fn(arg);\n        }, 0);\n    } else try {\n        this._schedule(function() {\n            fn(arg);\n        });\n    } catch (e) {\n        throw new Error(NO_ASYNC_SCHEDULER);\n    }\n};\n\n//When the fn absolutely needs to be called after\n//the queue has been completely flushed\nfunction AsyncInvokeLater(fn, receiver, arg) {\n    ASSERT(arguments.length === 3);\n    this._lateQueue.push(fn, receiver, arg);\n    this._queueTick();\n}\n\nfunction AsyncInvoke(fn, receiver, arg) {\n    ASSERT(arguments.length === 3);\n    this._normalQueue.push(fn, receiver, arg);\n    this._queueTick();\n}\n\nfunction AsyncSettlePromises(promise) {\n    this._normalQueue._pushOne(promise);\n    this._queueTick();\n}\n\nAsync.prototype.invokeLater = AsyncInvokeLater;\nAsync.prototype.invoke = AsyncInvoke;\nAsync.prototype.settlePromises = AsyncSettlePromises;\n\n\nfunction _drainQueue(queue) {\n    while (queue.length() > 0) {\n        _drainQueueStep(queue);\n    }\n}\n\n// Shift the queue in a separate function to allow\n// garbage collection after each step\nfunction _drainQueueStep(queue) {\n    var fn = queue.shift();\n    if (typeof fn !== \"function\") {\n        fn._settlePromises();\n    } else {\n        var receiver = queue.shift();\n        var arg = queue.shift();\n        fn.call(receiver, arg);\n    }\n}\n\nAsync.prototype._drainQueues = function () {\n    ASSERT(this._isTickUsed);\n    _drainQueue(this._normalQueue);\n    this._reset();\n    this._haveDrainedQueues = true;\n    _drainQueue(this._lateQueue);\n};\n\nAsync.prototype._queueTick = function () {\n    if (!this._isTickUsed) {\n        this._isTickUsed = true;\n        this._schedule(this.drainQueues);\n    }\n};\n\nAsync.prototype._reset = function () {\n    this._isTickUsed = false;\n};\n\nmodule.exports = Async;\nmodule.exports.firstLineError = firstLineError;\n"
  },
  {
    "path": "src/bind.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise, INTERNAL, tryConvertToPromise, debug) {\nvar calledBind = false;\nvar rejectThis = function(_, e) {\n    this._reject(e);\n};\n\nvar targetRejected = function(e, context) {\n    context.promiseRejectionQueued = true;\n    context.bindingPromise._then(rejectThis, rejectThis, null, this, e);\n};\n\nvar bindingResolved = function(thisArg, context) {\n    if (BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG, this._bitField)) {\n        this._resolveCallback(context.target);\n    }\n};\n\nvar bindingRejected = function(e, context) {\n    if (!context.promiseRejectionQueued) this._reject(e);\n};\n\nPromise.prototype.bind = function (thisArg) {\n    if (!calledBind) {\n        calledBind = true;\n        Promise.prototype._propagateFrom = debug.propagateFromFunction();\n        Promise.prototype._boundValue = debug.boundValueFunction();\n    }\n    var maybePromise = tryConvertToPromise(thisArg);\n    var ret = new Promise(INTERNAL);\n    ret._propagateFrom(this, PROPAGATE_CANCEL);\n    var target = this._target();\n    ret._setBoundTo(maybePromise);\n    if (maybePromise instanceof Promise) {\n        var context = {\n            promiseRejectionQueued: false,\n            promise: ret,\n            target: target,\n            bindingPromise: maybePromise\n        };\n        target._then(INTERNAL, targetRejected, undefined, ret, context);\n        maybePromise._then(\n            bindingResolved, bindingRejected, undefined, ret, context);\n        ret._setOnCancel(maybePromise);\n    } else {\n        ret._resolveCallback(target);\n    }\n    return ret;\n};\n\nPromise.prototype._setBoundTo = function (obj) {\n    if (obj !== undefined) {\n        this._bitField = this._bitField | IS_BOUND;\n        this._boundTo = obj;\n    } else {\n        this._bitField = this._bitField & (~IS_BOUND);\n    }\n};\n\nPromise.prototype._isBound = function () {\n    return (this._bitField & IS_BOUND) === IS_BOUND;\n};\n\nPromise.bind = function (thisArg, value) {\n    return Promise.resolve(value).bind(thisArg);\n};\n};\n"
  },
  {
    "path": "src/bluebird.js",
    "content": "\"use strict\";\nvar old;\nif (typeof Promise !== \"undefined\") old = Promise;\nfunction noConflict() {\n    try { if (Promise === bluebird) Promise = old; }\n    catch (e) {}\n    return bluebird;\n}\nvar bluebird = require(\"./promise\")();\nbluebird.noConflict = noConflict;\nmodule.exports = bluebird;\n"
  },
  {
    "path": "src/call_get.js",
    "content": "\"use strict\";\nvar cr = Object.create;\nif (cr) {\n    var callerCache = cr(null);\n    var getterCache = cr(null);\n    callerCache[\" size\"] = getterCache[\" size\"] = 0;\n}\n\nmodule.exports = function(Promise) {\nvar util = require(\"./util\");\nvar canEvaluate = util.canEvaluate;\nvar isIdentifier = util.isIdentifier;\n\nvar getMethodCaller;\nvar getGetter;\nif (!__BROWSER__) {\nvar makeMethodCaller = function (methodName) {\n    return new Function(\"ensureMethod\", \"                                    \\n\\\n        return function(obj) {                                               \\n\\\n            'use strict'                                                     \\n\\\n            var len = this.length;                                           \\n\\\n            ensureMethod(obj, 'methodName');                                 \\n\\\n            switch(len) {                                                    \\n\\\n                case 1: return obj.methodName(this[0]);                      \\n\\\n                case 2: return obj.methodName(this[0], this[1]);             \\n\\\n                case 3: return obj.methodName(this[0], this[1], this[2]);    \\n\\\n                case 0: return obj.methodName();                             \\n\\\n                default:                                                     \\n\\\n                    return obj.methodName.apply(obj, this);                  \\n\\\n            }                                                                \\n\\\n        };                                                                   \\n\\\n        \".replace(/methodName/g, methodName))(ensureMethod);\n};\n\nvar makeGetter = function (propertyName) {\n    return new Function(\"obj\", \"                                             \\n\\\n        'use strict';                                                        \\n\\\n        return obj.propertyName;                                             \\n\\\n        \".replace(\"propertyName\", propertyName));\n};\n\nvar getCompiled = function(name, compiler, cache) {\n    var ret = cache[name];\n    if (typeof ret !== \"function\") {\n        if (!isIdentifier(name)) {\n            return null;\n        }\n        ret = compiler(name);\n        cache[name] = ret;\n        cache[\" size\"]++;\n        if (cache[\" size\"] > 512) {\n            var keys = Object.keys(cache);\n            for (var i = 0; i < 256; ++i) delete cache[keys[i]];\n            cache[\" size\"] = keys.length - 256;\n        }\n    }\n    return ret;\n};\n\ngetMethodCaller = function(name) {\n    return getCompiled(name, makeMethodCaller, callerCache);\n};\n\ngetGetter = function(name) {\n    return getCompiled(name, makeGetter, getterCache);\n};\n}\n\nfunction ensureMethod(obj, methodName) {\n    var fn;\n    if (obj != null) fn = obj[methodName];\n    if (typeof fn !== \"function\") {\n        var message = \"Object \" + util.classString(obj) + \" has no method '\" +\n            util.toString(methodName) + \"'\";\n        throw new Promise.TypeError(message);\n    }\n    return fn;\n}\n\nfunction caller(obj) {\n    var methodName = this.pop();\n    var fn = ensureMethod(obj, methodName);\n    return fn.apply(obj, this);\n}\nPromise.prototype.call = function (methodName) {\n    INLINE_SLICE(args, arguments, 1);\n    if (!__BROWSER__) {\n        if (canEvaluate) {\n            var maybeCaller = getMethodCaller(methodName);\n            if (maybeCaller !== null) {\n                return this._then(\n                    maybeCaller, undefined, undefined, args, undefined);\n            }\n        }\n    }\n    args.push(methodName);\n    return this._then(caller, undefined, undefined, args, undefined);\n};\n\nfunction namedGetter(obj) {\n    return obj[this];\n}\nfunction indexedGetter(obj) {\n    var index = +this;\n    if (index < 0) index = Math.max(0, index + obj.length);\n    return obj[index];\n}\nPromise.prototype.get = function (propertyName) {\n    var isIndex = (typeof propertyName === \"number\");\n    var getter;\n    if (!isIndex) {\n        if (canEvaluate) {\n            var maybeGetter = getGetter(propertyName);\n            getter = maybeGetter !== null ? maybeGetter : namedGetter;\n        } else {\n            getter = namedGetter;\n        }\n    } else {\n        getter = indexedGetter;\n    }\n    return this._then(getter, undefined, undefined, propertyName, undefined);\n};\n};\n"
  },
  {
    "path": "src/cancel.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise, PromiseArray, apiRejection, debug) {\nvar ASSERT = require(\"./assert\");\nvar util = require(\"./util\");\nvar tryCatch = util.tryCatch;\nvar errorObj = util.errorObj;\nvar async = Promise._async;\n\nPromise.prototype[\"break\"] = Promise.prototype.cancel = function() {\n    if (!debug.cancellation()) return this._warn(\"cancellation is disabled\");\n\n    var promise = this;\n    var child = promise;\n    while (promise._isCancellable()) {\n        if (!promise._cancelBy(child)) {\n            if (child._isFollowing()) {\n                child._followee().cancel();\n            } else {\n                child._cancelBranched();\n            }\n            break;\n        }\n\n        var parent = promise._cancellationParent;\n        if (parent == null || !parent._isCancellable()) {\n            if (promise._isFollowing()) {\n                promise._followee().cancel();\n            } else {\n                promise._cancelBranched();\n            }\n            break;\n        } else {\n            if (promise._isFollowing()) promise._followee().cancel();\n            promise._setWillBeCancelled();\n            child = promise;\n            promise = parent;\n        }\n    }\n};\n\nPromise.prototype._branchHasCancelled = function() {\n    ASSERT(typeof this._branchesRemainingToCancel === \"number\");\n    this._branchesRemainingToCancel--;\n};\n\nPromise.prototype._enoughBranchesHaveCancelled = function() {\n    return this._branchesRemainingToCancel === undefined ||\n           this._branchesRemainingToCancel <= 0;\n};\n\nPromise.prototype._cancelBy = function(canceller) {\n    if (canceller === this) {\n        this._branchesRemainingToCancel = 0;\n        this._invokeOnCancel();\n        return true;\n    } else {\n        ASSERT(canceller._cancellationParent === this);\n        this._branchHasCancelled();\n        if (this._enoughBranchesHaveCancelled()) {\n            this._invokeOnCancel();\n            return true;\n        }\n    }\n    return false;\n};\n\nPromise.prototype._cancelBranched = function() {\n    if (this._enoughBranchesHaveCancelled()) {\n        this._cancel();\n    }\n};\n\nPromise.prototype._cancel = function() {\n    if (!this._isCancellable()) return;\n    ASSERT(!this._isFollowing());\n    this._setCancelled();\n    async.invoke(this._cancelPromises, this, undefined);\n};\n\nPromise.prototype._cancelPromises = function() {\n    if (this._length() > 0) this._settlePromises();\n};\n\nPromise.prototype._unsetOnCancel = function() {\n    ASSERT(this._isCancellable() || this._isCancelled());\n    this._onCancelField = undefined;\n};\n\nPromise.prototype._isCancellable = function() {\n    return this.isPending() && !this._isCancelled();\n};\n\nPromise.prototype.isCancellable = function() {\n    return this.isPending() && !this.isCancelled();\n};\n\nPromise.prototype._doInvokeOnCancel = function(onCancelCallback, internalOnly) {\n    if (util.isArray(onCancelCallback)) {\n        for (var i = 0; i < onCancelCallback.length; ++i) {\n            this._doInvokeOnCancel(onCancelCallback[i], internalOnly);\n        }\n    } else if (onCancelCallback !== undefined) {\n        if (typeof onCancelCallback === \"function\") {\n            if (!internalOnly) {\n                var e = tryCatch(onCancelCallback).call(this._boundValue());\n                if (e === errorObj) {\n                    this._attachExtraTrace(e.e);\n                    async.throwLater(e.e);\n                }\n            }\n        } else {\n            onCancelCallback._resultCancelled(this);\n        }\n    }\n};\n\nPromise.prototype._invokeOnCancel = function() {\n    var onCancelCallback = this._onCancel();\n    // The existence of onCancel handler on a promise signals that the handler\n    // has not been queued for invocation yet.\n    this._unsetOnCancel();\n    async.invoke(this._doInvokeOnCancel, this, onCancelCallback);\n};\n\nPromise.prototype._invokeInternalOnCancel = function() {\n    if (this._isCancellable()) {\n        this._doInvokeOnCancel(this._onCancel(), true);\n        this._unsetOnCancel();\n    }\n};\n\nPromise.prototype._resultCancelled = function() {\n    this.cancel();\n};\n\n};\n"
  },
  {
    "path": "src/catch_filter.js",
    "content": "\"use strict\";\nmodule.exports = function(NEXT_FILTER) {\nvar util = require(\"./util\");\nvar getKeys = require(\"./es5\").keys;\nvar tryCatch = util.tryCatch;\nvar errorObj = util.errorObj;\n\nfunction catchFilter(instances, cb, promise) {\n    return function(e) {\n        var boundTo = promise._boundValue();\n        predicateLoop: for (var i = 0; i < instances.length; ++i) {\n            var item = instances[i];\n\n            if (item === Error ||\n                (item != null && item.prototype instanceof Error)) {\n                if (e instanceof item) {\n                    return tryCatch(cb).call(boundTo, e);\n                }\n            } else if (typeof item === \"function\") {\n                var matchesPredicate = tryCatch(item).call(boundTo, e);\n                if (matchesPredicate === errorObj) {\n                    return matchesPredicate;\n                } else if (matchesPredicate) {\n                    return tryCatch(cb).call(boundTo, e);\n                }\n            } else if (util.isObject(e)) {\n                var keys = getKeys(item);\n                for (var j = 0; j < keys.length; ++j) {\n                    var key = keys[j];\n                    if (item[key] != e[key]) {\n                        continue predicateLoop;\n                    }\n                }\n                return tryCatch(cb).call(boundTo, e);\n            }\n        }\n        return NEXT_FILTER;\n    };\n}\n\nreturn catchFilter;\n};\n"
  },
  {
    "path": "src/constants.js",
    "content": "//This is pretty lame but what you gonna do\n\n//async.js\nCONSTANT(LATE_QUEUE_CAPACITY, 16);\nCONSTANT(NORMAL_QUEUE_CAPACITY, 16);\n\n//errors.js\nCONSTANT(ERROR_HANDLED_KEY, \"__promiseHandled__\");\nCONSTANT(OPERATIONAL_ERROR_KEY, \"isOperational\");\nCONSTANT(DEFAULT_STATE, 0);\nCONSTANT(STACK_ATTACHED, 1);\nCONSTANT(ERROR_HANDLED, 2);\n\n//join.js\nCONSTANT(GENERATED_CLASS_COUNT, 8);\n\n//promise.js\nCONSTANT(USE_BOUND, true);\nCONSTANT(DONT_USE_BOUND, false);\n\nCONSTANT(PROPAGATE_CANCEL, 1);\nCONSTANT(PROPAGATE_BIND, 2);\nCONSTANT(PROPAGATE_ALL, PROPAGATE_CANCEL | PROPAGATE_BIND);\n\nCONSTANT(CALLBACK_FULFILL_OFFSET, 0);\nCONSTANT(CALLBACK_REJECT_OFFSET, 1);\nCONSTANT(CALLBACK_PROMISE_OFFSET, 2);\nCONSTANT(CALLBACK_RECEIVER_OFFSET, 3);\nCONSTANT(CALLBACK_SIZE, 4);\n//Layout for ._bitField\n//[RR]XO GWFN CTBH IUDE LLLL LLLL LLLL LLLL\n//[RR] = [Reserved] (Both bits are either on or off to represent\n//                    1 bit due to 31-bit integers in 32-bit v8)\n//R = [Reserved]\n//X = noAsyncGuarantee\n//O = returnedNonUndefined\n//G = isAsyncGuaranteed\n//W = isFollowing (The promise that is being followed is not stored explicitly)\n//F = isFulfilled\n//N = isRejected\n//C = willBeCancelled\n//T = isFinal (used for .done() implementation)\n//B = isBound\n//I = isRejectionIgnored\n//H = isRejectionUnhandled\n//U = isUnhanldedRejectionNotified\n//D = isDisposable\n//E = isCancelled\n//L = Length, 16 bit unsigned\nCONSTANT(ASYNC_GUARANTEE_SHIFT, 2)\nCONSTANT(NO_STATE, 0x0|0);\nCONSTANT(NO_ASYNC_GUARANTEE, 0x20000000|0);\nCONSTANT(RETURNED_NON_UNDEFINED, 0x10000000|0);\nCONSTANT(IS_ASYNC_GUARANTEED, 0x8000000|0);\nCONSTANT(IS_FOLLOWING, 0x4000000|0);\nCONSTANT(IS_FULFILLED, 0x2000000|0);\nCONSTANT(IS_REJECTED, 0x1000000|0);\nCONSTANT(WILL_BE_CANCELLED, 0x800000|0);\nCONSTANT(IS_FINAL, 0x400000|0);\nCONSTANT(IS_BOUND, 0x200000|0);\nCONSTANT(IS_REJECTION_UNHANDLED, 0x100000|0);\nCONSTANT(IS_REJECTION_IGNORED, 0x80000|0);\nCONSTANT(IS_UNHANDLED_REJECTION_NOTIFIED, 0x40000|0);\nCONSTANT(IS_DISPOSABLE, 0x20000|0);\nCONSTANT(IS_CANCELLED, 0x10000|0);\nCONSTANT(IS_CANCELLED_OR_WILL_BE_CANCELLED, IS_CANCELLED | WILL_BE_CANCELLED)\nCONSTANT(LENGTH_MASK, 0xFFFF|0);\nCONSTANT(LENGTH_CLEAR_MASK, ~LENGTH_MASK);\nCONSTANT(MAX_LENGTH, LENGTH_MASK);\nCONSTANT(IS_REJECTED_OR_CANCELLED, IS_REJECTED | IS_CANCELLED);\nCONSTANT(IS_REJECTED_OR_FULFILLED, IS_REJECTED | IS_FULFILLED);\nCONSTANT(IS_REJECTED_OR_FULFILLED_OR_CANCELLED, IS_REJECTED | IS_FULFILLED| IS_CANCELLED);\nCONSTANT(IS_PENDING_AND_WAITING_NEG, IS_REJECTED_OR_FULFILLED_OR_CANCELLED);\n\nCONSTANT(IS_FATE_SEALED, IS_REJECTED | IS_FULFILLED | IS_FOLLOWING | IS_CANCELLED);\n\nCONSTANT(AFTER_PROMISIFIED_SUFFIX, \"Async\");\nCONSTANT(UNHANDLED_REJECTION_EVENT, \"unhandledRejection\");\nCONSTANT(REJECTION_HANDLED_EVENT, \"rejectionHandled\");\n\n//promise_array.js\n//MUST BE NEGATIVE NUMBERS\nCONSTANT(RESOLVE_UNDEFINED, -1);\nCONSTANT(RESOLVE_ARRAY, -2);\nCONSTANT(RESOLVE_OBJECT, -3);\nCONSTANT(RESOLVE_FOREVER_PENDING, -4);\nCONSTANT(RESOLVE_CALL_METHOD, -5);\nCONSTANT(RESOLVE_MAP, -6);\n\n//queue.js\nCONSTANT(QUEUE_MAX_CAPACITY, (1 << 30) | 0);\nCONSTANT(QUEUE_MIN_CAPACITY, 16);\n\n//captured_trace.js\nCONSTANT(FROM_PREVIOUS_EVENT, \"From previous event:\");\nCONSTANT(NO_STACK_TRACE, \"    (No stack trace)\");\nCONSTANT(ADDITIONAL_STACK_TRACE, \"^--- With additional stack trace: \");\nCONSTANT(UNHANDLED_REJECTION_HEADER, \"Unhandled rejection \");\n\n//finally.js\nCONSTANT(FINALLY_TYPE, 0);\nCONSTANT(TAP_TYPE, 1);\n\n//direct_resolve.js\nCONSTANT(THROW, 1);\nCONSTANT(RETURN, 2);\n\n//promisify.js\nCONSTANT(MAX_PARAM_COUNT, 1023);\nCONSTANT(PARAM_COUNTS_TO_TRY, 3);\n\n//error.js\nCONSTANT(BLUEBIRD_ERRORS, \"__BluebirdErrorTypes__\");\n\n//deprecated\nCONSTANT(OBJECT_PROMISIFY_DEPRECATED, \"Promise.promisify for promisifying entire objects is deprecated. Use Promise.promisifyAll instead.\\n\\n\\\n    See http://goo.gl/MqrFmX\");\nCONSTANT(SPAWN_DEPRECATED, \"Promise.spawn is deprecated. Use Promise.coroutine instead.\");\n\n//errors\nCONSTANT(LATE_CANCELLATION_OBSERVER, \"late cancellation observer\");\nCONSTANT(TIMEOUT_ERROR, \"operation timed out\");\nCONSTANT(COLLECTION_ERROR,  \"expecting an array or an iterable object but got \");\nCONSTANT(OBJECT_ERROR,  \"expecting an object but got \");\nCONSTANT(FUNCTION_ERROR,  \"expecting a function but got \");\nCONSTANT(CONSTRUCT_ERROR_INVOCATION, \"the promise constructor cannot be invoked directly\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(NOT_GENERATOR_ERROR, \"generatorFunction must be a function\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(LONG_STACK_TRACES_ERROR, \"cannot enable long stack traces after promises have been created\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(INSPECTION_VALUE_ERROR, \"cannot get fulfillment value of a non-fulfilled promise\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(INSPECTION_REASON_ERROR, \"cannot get rejection reason of a non-rejected promise\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(PROMISIFY_TYPE_ERROR, \"the target of promisifyAll must be an object or a function\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(CIRCULAR_RESOLUTION_ERROR, \"circular promise resolution chain\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(PROPS_TYPE_ERROR, \"cannot await properties of a non-object\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(POSITIVE_INTEGER_ERROR, \"expecting a positive integer\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(YIELDED_NON_PROMISE_ERROR, \"A value %s was yielded that could not be treated as a promise\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\\n\");\nCONSTANT(FROM_COROUTINE_CREATED_AT, \"From coroutine:\\n\");\nCONSTANT(UNBOUND_RESOLVER_INVOCATION, \"Illegal invocation, resolver resolve/reject must be called within a resolver context. Consider using the promise constructor instead.\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(PROMISIFICATION_NORMAL_METHODS_ERROR, \"Cannot promisify an API that has normal methods with '%s'-suffix\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(SUFFIX_NOT_IDENTIFIER, \"suffix must be a valid identifier\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\nCONSTANT(NO_ASYNC_SCHEDULER, \"No async scheduler available\\n\\n\\\n    See http://goo.gl/MqrFmX\\n\");\n"
  },
  {
    "path": "src/context.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise) {\nvar longStackTraces = false;\nvar contextStack = [];\n\nPromise.prototype._promiseCreated = function() {};\nPromise.prototype._pushContext = function() {};\nPromise.prototype._popContext = function() {return null;};\nPromise._peekContext = Promise.prototype._peekContext = function() {};\n\nfunction Context() {\n    this._trace = new Context.CapturedTrace(peekContext());\n}\nContext.prototype._pushContext = function () {\n    if (this._trace !== undefined) {\n        this._trace._promiseCreated = null;\n        contextStack.push(this._trace);\n    }\n};\n\nContext.prototype._popContext = function () {\n    if (this._trace !== undefined) {\n        var trace = contextStack.pop();\n        var ret = trace._promiseCreated;\n        trace._promiseCreated = null;\n        return ret;\n    }\n    return null;\n};\n\nfunction createContext() {\n    if (longStackTraces) return new Context();\n}\n\nfunction peekContext() {\n    var lastIndex = contextStack.length - 1;\n    if (lastIndex >= 0) {\n        return contextStack[lastIndex];\n    }\n    return undefined;\n}\nContext.CapturedTrace = null;\nContext.create = createContext;\nContext.deactivateLongStackTraces = function() {};\nContext.activateLongStackTraces = function() {\n    var Promise_pushContext = Promise.prototype._pushContext;\n    var Promise_popContext = Promise.prototype._popContext;\n    var Promise_PeekContext = Promise._peekContext;\n    var Promise_peekContext = Promise.prototype._peekContext;\n    var Promise_promiseCreated = Promise.prototype._promiseCreated;\n    Context.deactivateLongStackTraces = function() {\n        Promise.prototype._pushContext = Promise_pushContext;\n        Promise.prototype._popContext = Promise_popContext;\n        Promise._peekContext = Promise_PeekContext;\n        Promise.prototype._peekContext = Promise_peekContext;\n        Promise.prototype._promiseCreated = Promise_promiseCreated;\n        longStackTraces = false;\n    };\n    longStackTraces = true;\n    Promise.prototype._pushContext = Context.prototype._pushContext;\n    Promise.prototype._popContext = Context.prototype._popContext;\n    Promise._peekContext = Promise.prototype._peekContext = peekContext;\n    Promise.prototype._promiseCreated = function() {\n        var ctx = this._peekContext();\n        if (ctx && ctx._promiseCreated == null) ctx._promiseCreated = this;\n    };\n};\nreturn Context;\n};\n"
  },
  {
    "path": "src/debuggability.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise, Context,\n    enableAsyncHooks, disableAsyncHooks) {\nvar async = Promise._async;\nvar Warning = require(\"./errors\").Warning;\nvar util = require(\"./util\");\nvar es5 = require(\"./es5\");\nvar ASSERT = require(\"./assert\");\nvar canAttachTrace = util.canAttachTrace;\nvar unhandledRejectionHandled;\nvar possiblyUnhandledRejection;\nvar bluebirdFramePattern =\n    /[\\\\\\/]bluebird[\\\\\\/]js[\\\\\\/](release|debug|instrumented)/;\nvar nodeFramePattern = /\\((?:timers\\.js):\\d+:\\d+\\)/;\nvar parseLinePattern = /[\\/<\\(](.+?):(\\d+):(\\d+)\\)?\\s*$/;\nvar stackFramePattern = null;\nvar formatStack = null;\nvar indentStackFrames = false;\nvar printWarning;\nvar debugging = !!(util.env(\"BLUEBIRD_DEBUG\") != 0 &&\n                        (__DEBUG__ ||\n                         util.env(\"BLUEBIRD_DEBUG\") ||\n                         util.env(\"NODE_ENV\") === \"development\"));\n\nvar warnings = !!(util.env(\"BLUEBIRD_WARNINGS\") != 0 &&\n    (debugging || util.env(\"BLUEBIRD_WARNINGS\")));\n\nvar longStackTraces = !!(util.env(\"BLUEBIRD_LONG_STACK_TRACES\") != 0 &&\n    (debugging || util.env(\"BLUEBIRD_LONG_STACK_TRACES\")));\n\nvar wForgottenReturn = util.env(\"BLUEBIRD_W_FORGOTTEN_RETURN\") != 0 &&\n    (warnings || !!util.env(\"BLUEBIRD_W_FORGOTTEN_RETURN\"));\n\nvar deferUnhandledRejectionCheck;\n(function() {\n    var promises = [];\n\n    function unhandledRejectionCheck() {\n        for (var i = 0; i < promises.length; ++i) {\n            promises[i]._notifyUnhandledRejection();\n        }\n        unhandledRejectionClear();\n    }\n\n    function unhandledRejectionClear() {\n        promises.length = 0;\n    }\n\n    deferUnhandledRejectionCheck = function(promise) {\n        promises.push(promise);\n        setTimeout(unhandledRejectionCheck, 1);\n    };\n\n    es5.defineProperty(Promise, \"_unhandledRejectionCheck\", {\n        value: unhandledRejectionCheck\n    });\n    es5.defineProperty(Promise, \"_unhandledRejectionClear\", {\n        value: unhandledRejectionClear\n    });\n})();\n\nPromise.prototype.suppressUnhandledRejections = function() {\n    var target = this._target();\n    target._bitField = ((target._bitField & (~IS_REJECTION_UNHANDLED)) |\n                      IS_REJECTION_IGNORED);\n};\n\nPromise.prototype._ensurePossibleRejectionHandled = function () {\n    if ((this._bitField & IS_REJECTION_IGNORED) !== 0) return;\n    this._setRejectionIsUnhandled();\n    deferUnhandledRejectionCheck(this);\n};\n\nPromise.prototype._notifyUnhandledRejectionIsHandled = function () {\n    fireRejectionEvent(REJECTION_HANDLED_EVENT,\n                                  unhandledRejectionHandled, undefined, this);\n};\n\nPromise.prototype._setReturnedNonUndefined = function() {\n    this._bitField = this._bitField | RETURNED_NON_UNDEFINED;\n};\n\nPromise.prototype._returnedNonUndefined = function() {\n    return (this._bitField & RETURNED_NON_UNDEFINED) !== 0;\n};\n\nPromise.prototype._notifyUnhandledRejection = function () {\n    if (this._isRejectionUnhandled()) {\n        var reason = this._settledValue();\n        this._setUnhandledRejectionIsNotified();\n        fireRejectionEvent(UNHANDLED_REJECTION_EVENT,\n                                      possiblyUnhandledRejection, reason, this);\n    }\n};\n\nPromise.prototype._setUnhandledRejectionIsNotified = function () {\n    this._bitField = this._bitField | IS_UNHANDLED_REJECTION_NOTIFIED;\n};\n\nPromise.prototype._unsetUnhandledRejectionIsNotified = function () {\n    this._bitField = this._bitField & (~IS_UNHANDLED_REJECTION_NOTIFIED);\n};\n\nPromise.prototype._isUnhandledRejectionNotified = function () {\n    return (this._bitField & IS_UNHANDLED_REJECTION_NOTIFIED) > 0;\n};\n\nPromise.prototype._setRejectionIsUnhandled = function () {\n    ASSERT(!this._isFollowing());\n    this._bitField = this._bitField | IS_REJECTION_UNHANDLED;\n};\n\nPromise.prototype._unsetRejectionIsUnhandled = function () {\n    ASSERT(!this._isFollowing());\n    this._bitField = this._bitField & (~IS_REJECTION_UNHANDLED);\n    if (this._isUnhandledRejectionNotified()) {\n        this._unsetUnhandledRejectionIsNotified();\n        this._notifyUnhandledRejectionIsHandled();\n    }\n};\n\nPromise.prototype._isRejectionUnhandled = function () {\n    ASSERT(!this._isFollowing());\n    return (this._bitField & IS_REJECTION_UNHANDLED) > 0;\n};\n\nPromise.prototype._warn = function(message, shouldUseOwnTrace, promise) {\n    return warn(message, shouldUseOwnTrace, promise || this);\n};\n\nPromise.onPossiblyUnhandledRejection = function (fn) {\n    var context = Promise._getContext();\n    possiblyUnhandledRejection = util.contextBind(context, fn);\n};\n\nPromise.onUnhandledRejectionHandled = function (fn) {\n    var context = Promise._getContext();\n    unhandledRejectionHandled = util.contextBind(context, fn);\n};\n\nvar disableLongStackTraces = function() {};\nPromise.longStackTraces = function () {\n    if (async.haveItemsQueued() && !config.longStackTraces) {\n        throw new Error(LONG_STACK_TRACES_ERROR);\n    }\n    if (!config.longStackTraces && longStackTracesIsSupported()) {\n        var Promise_captureStackTrace = Promise.prototype._captureStackTrace;\n        var Promise_attachExtraTrace = Promise.prototype._attachExtraTrace;\n        var Promise_dereferenceTrace = Promise.prototype._dereferenceTrace;\n        config.longStackTraces = true;\n        disableLongStackTraces = function() {\n            if (async.haveItemsQueued() && !config.longStackTraces) {\n                throw new Error(LONG_STACK_TRACES_ERROR);\n            }\n            Promise.prototype._captureStackTrace = Promise_captureStackTrace;\n            Promise.prototype._attachExtraTrace = Promise_attachExtraTrace;\n            Promise.prototype._dereferenceTrace = Promise_dereferenceTrace;\n            Context.deactivateLongStackTraces();\n            config.longStackTraces = false;\n        };\n        Promise.prototype._captureStackTrace = longStackTracesCaptureStackTrace;\n        Promise.prototype._attachExtraTrace = longStackTracesAttachExtraTrace;\n        Promise.prototype._dereferenceTrace = longStackTracesDereferenceTrace;\n        Context.activateLongStackTraces();\n    }\n};\n\nPromise.hasLongStackTraces = function () {\n    return config.longStackTraces && longStackTracesIsSupported();\n};\n\n\nvar legacyHandlers = {\n    unhandledrejection: {\n        before: function() {\n            var ret = util.global.onunhandledrejection;\n            util.global.onunhandledrejection = null;\n            return ret;\n        },\n        after: function(fn) {\n            util.global.onunhandledrejection = fn;\n        }\n    },\n    rejectionhandled: {\n        before: function() {\n            var ret = util.global.onrejectionhandled;\n            util.global.onrejectionhandled = null;\n            return ret;\n        },\n        after: function(fn) {\n            util.global.onrejectionhandled = fn;\n        }\n    }\n};\n\nvar fireDomEvent = (function() {\n    var dispatch = function(legacy, e) {\n        if (legacy) {\n            var fn;\n            try {\n                fn = legacy.before();\n                return !util.global.dispatchEvent(e);\n            } finally {\n                legacy.after(fn);\n            }\n        } else {\n            return !util.global.dispatchEvent(e);\n        }\n    };\n    try {\n        if (typeof CustomEvent === \"function\") {\n            var event = new CustomEvent(\"CustomEvent\");\n            util.global.dispatchEvent(event);\n            return function(name, event) {\n                name = name.toLowerCase();\n                var eventData = {\n                    detail: event,\n                    cancelable: true\n                };\n                var domEvent = new CustomEvent(name, eventData);\n                es5.defineProperty(\n                    domEvent, \"promise\", {value: event.promise});\n                es5.defineProperty(\n                    domEvent, \"reason\", {value: event.reason});\n\n                return dispatch(legacyHandlers[name], domEvent);\n            };\n        // In Firefox < 48 CustomEvent is not available in workers but\n        // Event is.\n        } else if (typeof Event === \"function\") {\n            var event = new Event(\"CustomEvent\");\n            util.global.dispatchEvent(event);\n            return function(name, event) {\n                name = name.toLowerCase();\n                var domEvent = new Event(name, {\n                    cancelable: true\n                });\n                domEvent.detail = event;\n                es5.defineProperty(domEvent, \"promise\", {value: event.promise});\n                es5.defineProperty(domEvent, \"reason\", {value: event.reason});\n                return dispatch(legacyHandlers[name], domEvent);\n            };\n        } else {\n            var event = document.createEvent(\"CustomEvent\");\n            event.initCustomEvent(\"testingtheevent\", false, true, {});\n            util.global.dispatchEvent(event);\n            return function(name, event) {\n                name = name.toLowerCase();\n                var domEvent = document.createEvent(\"CustomEvent\");\n                domEvent.initCustomEvent(name, false, true,\n                    event);\n                return dispatch(legacyHandlers[name], domEvent);\n            };\n        }\n    } catch (e) {}\n    return function() {\n        return false;\n    };\n})();\n\nvar fireGlobalEvent = (function() {\n    if (util.isNode) {\n        return function() {\n            return process.emit.apply(process, arguments);\n        };\n    } else {\n        if (!util.global) {\n            return function() {\n                return false;\n            };\n        }\n        return function(name) {\n            var methodName = \"on\" + name.toLowerCase();\n            var method = util.global[methodName];\n            if (!method) return false;\n            method.apply(util.global, [].slice.call(arguments, 1));\n            return true;\n        };\n    }\n})();\n\nfunction generatePromiseLifecycleEventObject(name, promise) {\n    return {promise: promise};\n}\n\nvar eventToObjectGenerator = {\n    promiseCreated: generatePromiseLifecycleEventObject,\n    promiseFulfilled: generatePromiseLifecycleEventObject,\n    promiseRejected: generatePromiseLifecycleEventObject,\n    promiseResolved: generatePromiseLifecycleEventObject,\n    promiseCancelled: generatePromiseLifecycleEventObject,\n    promiseChained: function(name, promise, child) {\n        return {promise: promise, child: child};\n    },\n    warning: function(name, warning) {\n        return {warning: warning};\n    },\n    unhandledRejection: function (name, reason, promise) {\n        return {reason: reason, promise: promise};\n    },\n    rejectionHandled: generatePromiseLifecycleEventObject\n};\n\nvar activeFireEvent = function (name) {\n    var globalEventFired = false;\n    try {\n        globalEventFired = fireGlobalEvent.apply(null, arguments);\n    } catch (e) {\n        async.throwLater(e);\n        globalEventFired = true;\n    }\n\n    var domEventFired = false;\n    try {\n        domEventFired = fireDomEvent(name,\n                    eventToObjectGenerator[name].apply(null, arguments));\n    } catch (e) {\n        async.throwLater(e);\n        domEventFired = true;\n    }\n\n    return domEventFired || globalEventFired;\n};\n\nPromise.config = function(opts) {\n    opts = Object(opts);\n    if (\"longStackTraces\" in opts) {\n        if (opts.longStackTraces) {\n            Promise.longStackTraces();\n        } else if (!opts.longStackTraces && Promise.hasLongStackTraces()) {\n            disableLongStackTraces();\n        }\n    }\n    if (\"warnings\" in opts) {\n        var warningsOption = opts.warnings;\n        config.warnings = !!warningsOption;\n        wForgottenReturn = config.warnings;\n\n        if (util.isObject(warningsOption)) {\n            if (\"wForgottenReturn\" in warningsOption) {\n                wForgottenReturn = !!warningsOption.wForgottenReturn;\n            }\n        }\n    }\n    if (\"cancellation\" in opts && opts.cancellation && !config.cancellation) {\n        if (async.haveItemsQueued()) {\n            throw new Error(\n                \"cannot enable cancellation after promises are in use\");\n        }\n        Promise.prototype._clearCancellationData =\n            cancellationClearCancellationData;\n        Promise.prototype._propagateFrom = cancellationPropagateFrom;\n        Promise.prototype._onCancel = cancellationOnCancel;\n        Promise.prototype._setOnCancel = cancellationSetOnCancel;\n        Promise.prototype._attachCancellationCallback =\n            cancellationAttachCancellationCallback;\n        Promise.prototype._execute = cancellationExecute;\n        propagateFromFunction = cancellationPropagateFrom;\n        config.cancellation = true;\n    }\n    if (\"monitoring\" in opts) {\n        if (opts.monitoring && !config.monitoring) {\n            config.monitoring = true;\n            Promise.prototype._fireEvent = activeFireEvent;\n        } else if (!opts.monitoring && config.monitoring) {\n            config.monitoring = false;\n            Promise.prototype._fireEvent = defaultFireEvent;\n        }\n    }\n    if (\"asyncHooks\" in opts && util.nodeSupportsAsyncResource) {\n        var prev = config.asyncHooks;\n        var cur = !!opts.asyncHooks;\n        if (prev !== cur) {\n            config.asyncHooks = cur;\n            if (cur) {\n                enableAsyncHooks();\n            } else {\n                disableAsyncHooks();\n            }\n        }\n    }\n    return Promise;\n};\n\nfunction defaultFireEvent() { return false; }\n\nPromise.prototype._fireEvent = defaultFireEvent;\nPromise.prototype._execute = function(executor, resolve, reject) {\n    try {\n        executor(resolve, reject);\n    } catch (e) {\n        return e;\n    }\n};\nPromise.prototype._onCancel = function () {};\nPromise.prototype._setOnCancel = function (handler) { USE(handler); };\nPromise.prototype._attachCancellationCallback = function(onCancel) {\n    USE(onCancel);\n};\nPromise.prototype._captureStackTrace = function () {};\nPromise.prototype._attachExtraTrace = function () {};\nPromise.prototype._dereferenceTrace = function () {};\nPromise.prototype._clearCancellationData = function() {};\nPromise.prototype._propagateFrom = function (parent, flags) {\n    USE(parent);\n    USE(flags);\n};\n\nfunction cancellationExecute(executor, resolve, reject) {\n    var promise = this;\n    try {\n        executor(resolve, reject, function(onCancel) {\n            if (typeof onCancel !== \"function\") {\n                throw new TypeError(\"onCancel must be a function, got: \" +\n                                    util.toString(onCancel));\n            }\n            promise._attachCancellationCallback(onCancel);\n        });\n    } catch (e) {\n        return e;\n    }\n}\n\nfunction cancellationAttachCancellationCallback(onCancel) {\n    if (!this._isCancellable()) return this;\n\n    var previousOnCancel = this._onCancel();\n    if (previousOnCancel !== undefined) {\n        if (util.isArray(previousOnCancel)) {\n            previousOnCancel.push(onCancel);\n        } else {\n            this._setOnCancel([previousOnCancel, onCancel]);\n        }\n    } else {\n        this._setOnCancel(onCancel);\n    }\n}\n\nfunction cancellationOnCancel() {\n    ASSERT(this._isCancellable());\n    return this._onCancelField;\n}\n\nfunction cancellationSetOnCancel(onCancel) {\n    ASSERT(this._isCancellable());\n    this._onCancelField = onCancel;\n}\n\nfunction cancellationClearCancellationData() {\n    this._cancellationParent = undefined;\n    this._onCancelField = undefined;\n}\n\nfunction cancellationPropagateFrom(parent, flags) {\n    ASSERT(flags !== 0);\n    if ((flags & PROPAGATE_CANCEL) !== 0) {\n        this._cancellationParent = parent;\n        var branchesRemainingToCancel = parent._branchesRemainingToCancel;\n        if (branchesRemainingToCancel === undefined) {\n            branchesRemainingToCancel = 0;\n        }\n        parent._branchesRemainingToCancel = branchesRemainingToCancel + 1;\n    }\n    if ((flags & PROPAGATE_BIND) !== 0 && parent._isBound()) {\n        this._setBoundTo(parent._boundTo);\n    }\n}\n\nfunction bindingPropagateFrom(parent, flags) {\n    ASSERT(flags !== 0);\n    if ((flags & PROPAGATE_BIND) !== 0 && parent._isBound()) {\n        this._setBoundTo(parent._boundTo);\n    }\n}\nvar propagateFromFunction = bindingPropagateFrom;\n\nfunction boundValueFunction() {\n    var ret = this._boundTo;\n    if (ret !== undefined) {\n        if (ret instanceof Promise) {\n            if (ret.isFulfilled()) {\n                return ret.value();\n            } else {\n                return undefined;\n            }\n        }\n    }\n    return ret;\n}\n\nfunction longStackTracesCaptureStackTrace() {\n    ASSERT(this._trace == null);\n    this._trace = new CapturedTrace(this._peekContext());\n}\n\nfunction longStackTracesAttachExtraTrace(error, ignoreSelf) {\n    if (canAttachTrace(error)) {\n        var trace = this._trace;\n        if (trace !== undefined) {\n            if (ignoreSelf) trace = trace._parent;\n        }\n        if (trace !== undefined) {\n            trace.attachExtraTrace(error);\n        } else if (!error.__stackCleaned__) {\n            var parsed = parseStackAndMessage(error);\n            util.notEnumerableProp(error, \"stack\",\n                parsed.message + \"\\n\" + parsed.stack.join(\"\\n\"));\n            util.notEnumerableProp(error, \"__stackCleaned__\", true);\n        }\n    }\n}\n\nfunction longStackTracesDereferenceTrace() {\n    this._trace = undefined;\n}\n\nfunction checkForgottenReturns(returnValue, promiseCreated, name, promise,\n                               parent) {\n    if (returnValue === undefined && promiseCreated !== null &&\n        wForgottenReturn) {\n        if (parent !== undefined && parent._returnedNonUndefined()) return;\n        if (BIT_FIELD_READ(LENGTH_MASK, promise._bitField) === 0) return;\n\n        if (name) name = name + \" \";\n        var handlerLine = \"\";\n        var creatorLine = \"\";\n        if (promiseCreated._trace) {\n            var traceLines = promiseCreated._trace.stack.split(\"\\n\");\n            var stack = cleanStack(traceLines);\n            for (var i = stack.length - 1; i >= 0; --i) {\n                var line = stack[i];\n                if (!nodeFramePattern.test(line)) {\n                    var lineMatches = line.match(parseLinePattern);\n                    if (lineMatches) {\n                        handlerLine  = \"at \" + lineMatches[1] +\n                            \":\" + lineMatches[2] + \":\" + lineMatches[3] + \" \";\n                    }\n                    break;\n                }\n            }\n\n            if (stack.length > 0) {\n                var firstUserLine = stack[0];\n                for (var i = 0; i < traceLines.length; ++i) {\n\n                    if (traceLines[i] === firstUserLine) {\n                        if (i > 0) {\n                            creatorLine = \"\\n\" + traceLines[i - 1];\n                        }\n                        break;\n                    }\n                }\n\n            }\n        }\n        var msg = \"a promise was created in a \" + name +\n            \"handler \" + handlerLine + \"but was not returned from it, \" +\n            \"see http://goo.gl/rRqMUw\" +\n            creatorLine;\n        promise._warn(msg, true, promiseCreated);\n    }\n}\n\nfunction deprecated(name, replacement) {\n    var message = name +\n        \" is deprecated and will be removed in a future version.\";\n    if (replacement) message += \" Use \" + replacement + \" instead.\";\n    return warn(message);\n}\n\nfunction warn(message, shouldUseOwnTrace, promise) {\n    if (!config.warnings) return;\n    var warning = new Warning(message);\n    var ctx;\n    if (shouldUseOwnTrace) {\n        promise._attachExtraTrace(warning);\n    } else if (config.longStackTraces && (ctx = Promise._peekContext())) {\n        ctx.attachExtraTrace(warning);\n    } else {\n        var parsed = parseStackAndMessage(warning);\n        warning.stack = parsed.message + \"\\n\" + parsed.stack.join(\"\\n\");\n    }\n\n    if (!activeFireEvent(\"warning\", warning)) {\n        formatAndLogError(warning, \"\", true);\n    }\n}\n\nfunction reconstructStack(message, stacks) {\n    for (var i = 0; i < stacks.length - 1; ++i) {\n        stacks[i].push(FROM_PREVIOUS_EVENT);\n        stacks[i] = stacks[i].join(\"\\n\");\n    }\n    if (i < stacks.length) {\n        stacks[i] = stacks[i].join(\"\\n\");\n    }\n    return message + \"\\n\" + stacks.join(\"\\n\");\n}\n\nfunction removeDuplicateOrEmptyJumps(stacks) {\n    for (var i = 0; i < stacks.length; ++i) {\n        if (stacks[i].length === 0 ||\n            ((i + 1 < stacks.length) && stacks[i][0] === stacks[i+1][0])) {\n            stacks.splice(i, 1);\n            i--;\n        }\n    }\n}\n\nfunction removeCommonRoots(stacks) {\n    var current = stacks[0];\n    for (var i = 1; i < stacks.length; ++i) {\n        var prev = stacks[i];\n        var currentLastIndex = current.length - 1;\n        var currentLastLine = current[currentLastIndex];\n        var commonRootMeetPoint = -1;\n\n        for (var j = prev.length - 1; j >= 0; --j) {\n            if (prev[j] === currentLastLine) {\n                commonRootMeetPoint = j;\n                break;\n            }\n        }\n\n        for (var j = commonRootMeetPoint; j >= 0; --j) {\n            var line = prev[j];\n            if (current[currentLastIndex] === line) {\n                current.pop();\n                currentLastIndex--;\n            } else {\n                break;\n            }\n        }\n        current = prev;\n    }\n}\n\nfunction cleanStack(stack) {\n    var ret = [];\n    for (var i = 0; i < stack.length; ++i) {\n        var line = stack[i];\n        var isTraceLine = NO_STACK_TRACE === line ||\n            stackFramePattern.test(line);\n        var isInternalFrame = isTraceLine && shouldIgnore(line);\n        if (isTraceLine && !isInternalFrame) {\n            if (indentStackFrames && line.charAt(0) !== \" \") {\n                // Make Firefox stack traces readable...it is almost\n                // impossible to see the event boundaries without\n                // indentation.\n                line = \"    \" + line;\n            }\n            ret.push(line);\n        }\n    }\n    return ret;\n}\n\nfunction stackFramesAsArray(error) {\n    var stack = error.stack.replace(/\\s+$/g, \"\").split(\"\\n\");\n    for (var i = 0; i < stack.length; ++i) {\n        var line = stack[i];\n        if (NO_STACK_TRACE === line || stackFramePattern.test(line)) {\n            break;\n        }\n    }\n    // Chrome and IE include the error message in the stack\n    if (i > 0 && error.name != \"SyntaxError\") {\n        stack = stack.slice(i);\n    }\n    return stack;\n}\n\nfunction parseStackAndMessage(error) {\n    var stack = error.stack;\n    var message = error.toString();\n    stack = typeof stack === \"string\" && stack.length > 0\n                ? stackFramesAsArray(error) : [NO_STACK_TRACE];\n    return {\n        message: message,\n        stack: error.name == \"SyntaxError\" ? stack : cleanStack(stack)\n    };\n}\n\nfunction formatAndLogError(error, title, isSoft) {\n    if (typeof console !== \"undefined\") {\n        var message;\n        if (util.isObject(error)) {\n            var stack = error.stack;\n            message = title + formatStack(stack, error);\n        } else {\n            message = title + String(error);\n        }\n        if (typeof printWarning === \"function\") {\n            printWarning(message, isSoft);\n        } else if (typeof console.log === \"function\" ||\n            typeof console.log === \"object\") {\n            console.log(message);\n        }\n    }\n}\n\nfunction fireRejectionEvent(name, localHandler, reason, promise) {\n    var localEventFired = false;\n    try {\n        if (typeof localHandler === \"function\") {\n            localEventFired = true;\n            if (name === REJECTION_HANDLED_EVENT) {\n                localHandler(promise);\n            } else {\n                localHandler(reason, promise);\n            }\n        }\n    } catch (e) {\n        async.throwLater(e);\n    }\n\n    if (name === UNHANDLED_REJECTION_EVENT) {\n        if (!activeFireEvent(name, reason, promise) && !localEventFired) {\n            formatAndLogError(reason, UNHANDLED_REJECTION_HEADER);\n        }\n    } else {\n        activeFireEvent(name, promise);\n    }\n}\n\nfunction formatNonError(obj) {\n    var str;\n    if (typeof obj === \"function\") {\n        str = \"[function \" +\n            (obj.name || \"anonymous\") +\n            \"]\";\n    } else {\n        str = obj && typeof obj.toString === \"function\"\n            ? obj.toString() : util.toString(obj);\n        var ruselessToString = /\\[object [a-zA-Z0-9$_]+\\]/;\n        if (ruselessToString.test(str)) {\n            try {\n                var newStr = JSON.stringify(obj);\n                str = newStr;\n            }\n            catch(e) {\n\n            }\n        }\n        if (str.length === 0) {\n            str = \"(empty array)\";\n        }\n    }\n    return (\"(<\" + snip(str) + \">, no stack trace)\");\n}\n\nfunction snip(str) {\n    var maxChars = 41;\n    if (str.length < maxChars) {\n        return str;\n    }\n    return str.substr(0, maxChars - 3) + \"...\";\n}\n\nfunction longStackTracesIsSupported() {\n    return typeof captureStackTrace === \"function\";\n}\n\n// For filtering out internal calls from stack traces\nvar shouldIgnore = function() { return false; };\nvar parseLineInfoRegex = /[\\/<\\(]([^:\\/]+):(\\d+):(?:\\d+)\\)?\\s*$/;\nfunction parseLineInfo(line) {\n    var matches = line.match(parseLineInfoRegex);\n    if (matches) {\n        return {\n            fileName: matches[1],\n            line: parseInt(matches[2], 10)\n        };\n    }\n}\n\nfunction setBounds(firstLineError, lastLineError) {\n    if (!longStackTracesIsSupported()) return;\n    var firstStackLines = (firstLineError.stack || \"\").split(\"\\n\");\n    var lastStackLines = (lastLineError.stack || \"\").split(\"\\n\");\n    var firstIndex = -1;\n    var lastIndex = -1;\n    var firstFileName;\n    var lastFileName;\n    for (var i = 0; i < firstStackLines.length; ++i) {\n        var result = parseLineInfo(firstStackLines[i]);\n        if (result) {\n            firstFileName = result.fileName;\n            firstIndex = result.line;\n            break;\n        }\n    }\n    for (var i = 0; i < lastStackLines.length; ++i) {\n        var result = parseLineInfo(lastStackLines[i]);\n        if (result) {\n            lastFileName = result.fileName;\n            lastIndex = result.line;\n            break;\n        }\n    }\n    if (firstIndex < 0 || lastIndex < 0 || !firstFileName || !lastFileName ||\n        firstFileName !== lastFileName || firstIndex >= lastIndex) {\n        return;\n    }\n\n    shouldIgnore = function(line) {\n        if (bluebirdFramePattern.test(line)) return true;\n        var info = parseLineInfo(line);\n        if (info) {\n            if (info.fileName === firstFileName &&\n                (firstIndex <= info.line && info.line <= lastIndex)) {\n                return true;\n            }\n        }\n        return false;\n    };\n}\n\nfunction CapturedTrace(parent) {\n    ASSERT(parent === undefined || parent instanceof CapturedTrace);\n    this._parent = parent;\n    this._promisesCreated = 0;\n    var length = this._length = 1 + (parent === undefined ? 0 : parent._length);\n    captureStackTrace(this, CapturedTrace);\n    // Unless the user manually nested > 32 indentation levels,\n    // there must be cycles\n    if (length > 32) this.uncycle();\n}\nutil.inherits(CapturedTrace, Error);\nContext.CapturedTrace = CapturedTrace;\n\nCapturedTrace.prototype.uncycle = function() {\n    var length = this._length;\n    if (length < 2) return;\n    var nodes = [];\n    var stackToIndex = {};\n\n    for (var i = 0, node = this; node !== undefined; ++i) {\n        nodes.push(node);\n        node = node._parent;\n    }\n    // the node length is only used as heuristic to decide when to decycle, as\n    // there may be multiple linked lists that share members and decycling one\n    // will fail to update lenghts in the other. This is the correct length.\n    length = this._length = i;\n    ASSERT(nodes[0] === this);\n    ASSERT(nodes[nodes.length - 1] instanceof CapturedTrace);\n\n    for (var i = length - 1; i >= 0; --i) {\n        var stack = nodes[i].stack;\n        if (stackToIndex[stack] === undefined) {\n            stackToIndex[stack] = i;\n        }\n    }\n    for (var i = 0; i < length; ++i) {\n        var currentStack = nodes[i].stack;\n        var index = stackToIndex[currentStack];\n        ASSERT(currentStack === nodes[index].stack);\n\n        if (index !== undefined && index !== i) {\n            if (index > 0) {\n                ASSERT(nodes[index - 1]._parent === nodes[index]);\n                nodes[index - 1]._parent = undefined;\n                nodes[index - 1]._length = 1;\n            }\n            nodes[i]._parent = undefined;\n            nodes[i]._length = 1;\n            var cycleEdgeNode = i > 0 ? nodes[i - 1] : this;\n\n            if (index < length - 1) {\n                cycleEdgeNode._parent = nodes[index + 1];\n                cycleEdgeNode._parent.uncycle();\n                cycleEdgeNode._length =\n                    cycleEdgeNode._parent._length + 1;\n            } else {\n                cycleEdgeNode._parent = undefined;\n                cycleEdgeNode._length = 1;\n            }\n            var currentChildLength = cycleEdgeNode._length + 1;\n            for (var j = i - 2; j >= 0; --j) {\n                nodes[j]._length = currentChildLength;\n                currentChildLength++;\n            }\n            return;\n        }\n    }\n};\n\nCapturedTrace.prototype.attachExtraTrace = function(error) {\n    if (error.__stackCleaned__) return;\n    this.uncycle();\n    var parsed = parseStackAndMessage(error);\n    var message = parsed.message;\n    var stacks = [parsed.stack];\n\n    var trace = this;\n    while (trace !== undefined) {\n        stacks.push(cleanStack(trace.stack.split(\"\\n\")));\n        trace = trace._parent;\n    }\n    removeCommonRoots(stacks);\n    removeDuplicateOrEmptyJumps(stacks);\n    util.notEnumerableProp(error, \"stack\", reconstructStack(message, stacks));\n    util.notEnumerableProp(error, \"__stackCleaned__\", true);\n};\n\nvar captureStackTrace = (function stackDetection() {\n    var v8stackFramePattern = /^\\s*at\\s*/;\n    var v8stackFormatter = function(stack, error) {\n        ASSERT(error !== null);\n\n        if (typeof stack === \"string\") return stack;\n\n        if (error.name !== undefined &&\n            error.message !== undefined) {\n            return error.toString();\n        }\n        return formatNonError(error);\n    };\n\n    //V8\n    if (typeof Error.stackTraceLimit === \"number\" &&\n        typeof Error.captureStackTrace === \"function\") {\n        Error.stackTraceLimit += 6;\n        stackFramePattern = v8stackFramePattern;\n        formatStack = v8stackFormatter;\n        var captureStackTrace = Error.captureStackTrace;\n\n        // For node\n        shouldIgnore = function(line) {\n            return bluebirdFramePattern.test(line);\n        };\n        return function(receiver, ignoreUntil) {\n            Error.stackTraceLimit += 6;\n            captureStackTrace(receiver, ignoreUntil);\n            Error.stackTraceLimit -= 6;\n        };\n    }\n    var err = new Error();\n\n    //SpiderMonkey\n    if (typeof err.stack === \"string\" &&\n        err.stack.split(\"\\n\")[0].indexOf(\"stackDetection@\") >= 0) {\n        stackFramePattern = /@/;\n        formatStack = v8stackFormatter;\n        indentStackFrames = true;\n        return function captureStackTrace(o) {\n            o.stack = new Error().stack;\n        };\n    }\n\n    var hasStackAfterThrow;\n    try { throw new Error(); }\n    catch(e) {\n        hasStackAfterThrow = (\"stack\" in e);\n    }\n    // IE 10+\n    if (!(\"stack\" in err) && hasStackAfterThrow &&\n        typeof Error.stackTraceLimit === \"number\") {\n        stackFramePattern = v8stackFramePattern;\n        formatStack = v8stackFormatter;\n        return function captureStackTrace(o) {\n            Error.stackTraceLimit += 6;\n            try { throw new Error(); }\n            catch(e) { o.stack = e.stack; }\n            Error.stackTraceLimit -= 6;\n        };\n    }\n\n    formatStack = function(stack, error) {\n        if (typeof stack === \"string\") return stack;\n\n        if ((typeof error === \"object\" ||\n            typeof error === \"function\") &&\n            error.name !== undefined &&\n            error.message !== undefined) {\n            return error.toString();\n        }\n        return formatNonError(error);\n    };\n\n    return null;\n\n})([]);\n\nif (typeof console !== \"undefined\" && typeof console.warn !== \"undefined\") {\n    printWarning = function (message) {\n        console.warn(message);\n    };\n    if (util.isNode && process.stderr.isTTY) {\n        printWarning = function(message, isSoft) {\n            var color = isSoft ? \"\\u001b[33m\" : \"\\u001b[31m\";\n            console.warn(color + message + \"\\u001b[0m\\n\");\n        };\n    } else if (!util.isNode && typeof (new Error().stack) === \"string\") {\n        printWarning = function(message, isSoft) {\n            console.warn(\"%c\" + message,\n                        isSoft ? \"color: darkorange\" : \"color: red\");\n        };\n    }\n}\n\nvar config = {\n    warnings: warnings,\n    longStackTraces: false,\n    cancellation: false,\n    monitoring: false,\n    asyncHooks: false\n};\n\nif (longStackTraces) Promise.longStackTraces();\n\nreturn {\n    asyncHooks: function() {\n        return config.asyncHooks;\n    },\n    longStackTraces: function() {\n        return config.longStackTraces;\n    },\n    warnings: function() {\n        return config.warnings;\n    },\n    cancellation: function() {\n        return config.cancellation;\n    },\n    monitoring: function() {\n        return config.monitoring;\n    },\n    propagateFromFunction: function() {\n        return propagateFromFunction;\n    },\n    boundValueFunction: function() {\n        return boundValueFunction;\n    },\n    checkForgottenReturns: checkForgottenReturns,\n    setBounds: setBounds,\n    warn: warn,\n    deprecated: deprecated,\n    CapturedTrace: CapturedTrace,\n    fireDomEvent: fireDomEvent,\n    fireGlobalEvent: fireGlobalEvent\n};\n};\n"
  },
  {
    "path": "src/direct_resolve.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise) {\nfunction returner() {\n    return this.value;\n}\nfunction thrower() {\n    throw this.reason;\n}\n\nPromise.prototype[\"return\"] =\nPromise.prototype.thenReturn = function (value) {\n    if (value instanceof Promise) value.suppressUnhandledRejections();\n    return this._then(\n        returner, undefined, undefined, {value: value}, undefined);\n};\n\nPromise.prototype[\"throw\"] =\nPromise.prototype.thenThrow = function (reason) {\n    return this._then(\n        thrower, undefined, undefined, {reason: reason}, undefined);\n};\n\nPromise.prototype.catchThrow = function (reason) {\n    if (arguments.length <= 1) {\n        return this._then(\n            undefined, thrower, undefined, {reason: reason}, undefined);\n    } else {\n        var _reason = arguments[1];\n        var handler = function() {throw _reason;};\n        return this.caught(reason, handler);\n    }\n};\n\nPromise.prototype.catchReturn = function (value) {\n    if (arguments.length <= 1) {\n        if (value instanceof Promise) value.suppressUnhandledRejections();\n        return this._then(\n            undefined, returner, undefined, {value: value}, undefined);\n    } else {\n        var _value = arguments[1];\n        if (_value instanceof Promise) _value.suppressUnhandledRejections();\n        var handler = function() {return _value;};\n        return this.caught(value, handler);\n    }\n};\n};\n"
  },
  {
    "path": "src/each.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise, INTERNAL) {\nvar PromiseReduce = Promise.reduce;\nvar PromiseAll = Promise.all;\n\nfunction promiseAllThis() {\n    return PromiseAll(this);\n}\n\nfunction PromiseMapSeries(promises, fn) {\n    return PromiseReduce(promises, fn, INTERNAL, INTERNAL);\n}\n\nPromise.prototype.each = function (fn) {\n    return PromiseReduce(this, fn, INTERNAL, 0)\n              ._then(promiseAllThis, undefined, undefined, this, undefined);\n};\n\nPromise.prototype.mapSeries = function (fn) {\n    return PromiseReduce(this, fn, INTERNAL, INTERNAL);\n};\n\nPromise.each = function (promises, fn) {\n    return PromiseReduce(promises, fn, INTERNAL, 0)\n              ._then(promiseAllThis, undefined, undefined, promises, undefined);\n};\n\nPromise.mapSeries = PromiseMapSeries;\n};\n\n"
  },
  {
    "path": "src/errors.js",
    "content": "\"use strict\";\nvar es5 = require(\"./es5\");\nvar Objectfreeze = es5.freeze;\nvar util = require(\"./util\");\nvar inherits = util.inherits;\nvar notEnumerableProp = util.notEnumerableProp;\n\nfunction subError(nameProperty, defaultMessage) {\n    function SubError(message) {\n        if (!(this instanceof SubError)) return new SubError(message);\n        notEnumerableProp(this, \"message\",\n            typeof message === \"string\" ? message : defaultMessage);\n        notEnumerableProp(this, \"name\", nameProperty);\n        if (Error.captureStackTrace) {\n            Error.captureStackTrace(this, this.constructor);\n        } else {\n            Error.call(this);\n        }\n    }\n    inherits(SubError, Error);\n    return SubError;\n}\n\nvar _TypeError, _RangeError;\nvar Warning = subError(\"Warning\", \"warning\");\nvar CancellationError = subError(\"CancellationError\", \"cancellation error\");\nvar TimeoutError = subError(\"TimeoutError\", \"timeout error\");\nvar AggregateError = subError(\"AggregateError\", \"aggregate error\");\ntry {\n    _TypeError = TypeError;\n    _RangeError = RangeError;\n} catch(e) {\n    _TypeError = subError(\"TypeError\", \"type error\");\n    _RangeError = subError(\"RangeError\", \"range error\");\n}\n\nvar methods = (\"join pop push shift unshift slice filter forEach some \" +\n    \"every map indexOf lastIndexOf reduce reduceRight sort reverse\").split(\" \");\n\nfor (var i = 0; i < methods.length; ++i) {\n    if (typeof Array.prototype[methods[i]] === \"function\") {\n        AggregateError.prototype[methods[i]] = Array.prototype[methods[i]];\n    }\n}\n\nes5.defineProperty(AggregateError.prototype, \"length\", {\n    value: 0,\n    configurable: false,\n    writable: true,\n    enumerable: true\n});\nAggregateError.prototype[OPERATIONAL_ERROR_KEY] = true;\nvar level = 0;\nAggregateError.prototype.toString = function() {\n    var indent = Array(level * 4 + 1).join(\" \");\n    var ret = \"\\n\" + indent + \"AggregateError of:\" + \"\\n\";\n    level++;\n    indent = Array(level * 4 + 1).join(\" \");\n    for (var i = 0; i < this.length; ++i) {\n        var str = this[i] === this ? \"[Circular AggregateError]\" : this[i] + \"\";\n        var lines = str.split(\"\\n\");\n        for (var j = 0; j < lines.length; ++j) {\n            lines[j] = indent + lines[j];\n        }\n        str = lines.join(\"\\n\");\n        ret += str + \"\\n\";\n    }\n    level--;\n    return ret;\n};\n\nfunction OperationalError(message) {\n    if (!(this instanceof OperationalError))\n        return new OperationalError(message);\n    notEnumerableProp(this, \"name\", \"OperationalError\");\n    notEnumerableProp(this, \"message\", message);\n    this.cause = message;\n    this[OPERATIONAL_ERROR_KEY] = true;\n\n    if (message instanceof Error) {\n        notEnumerableProp(this, \"message\", message.message);\n        notEnumerableProp(this, \"stack\", message.stack);\n    } else if (Error.captureStackTrace) {\n        Error.captureStackTrace(this, this.constructor);\n    }\n\n}\ninherits(OperationalError, Error);\n\n//Ensure all copies of the library throw the same error types\nvar errorTypes = Error[BLUEBIRD_ERRORS];\nif (!errorTypes) {\n    errorTypes = Objectfreeze({\n        CancellationError: CancellationError,\n        TimeoutError: TimeoutError,\n        OperationalError: OperationalError,\n        RejectionError: OperationalError,\n        AggregateError: AggregateError\n    });\n    es5.defineProperty(Error, BLUEBIRD_ERRORS, {\n        value: errorTypes,\n        writable: false,\n        enumerable: false,\n        configurable: false\n    });\n}\n\nmodule.exports = {\n    Error: Error,\n    TypeError: _TypeError,\n    RangeError: _RangeError,\n    CancellationError: errorTypes.CancellationError,\n    OperationalError: errorTypes.OperationalError,\n    TimeoutError: errorTypes.TimeoutError,\n    AggregateError: errorTypes.AggregateError,\n    Warning: Warning\n};\n"
  },
  {
    "path": "src/es5.js",
    "content": "var isES5 = (function(){\n    \"use strict\";\n    return this === undefined;\n})();\n\nif (isES5) {\n    module.exports = {\n        freeze: Object.freeze,\n        defineProperty: Object.defineProperty,\n        getDescriptor: Object.getOwnPropertyDescriptor,\n        keys: Object.keys,\n        names: Object.getOwnPropertyNames,\n        getPrototypeOf: Object.getPrototypeOf,\n        isArray: Array.isArray,\n        isES5: isES5,\n        propertyIsWritable: function(obj, prop) {\n            var descriptor = Object.getOwnPropertyDescriptor(obj, prop);\n            return !!(!descriptor || descriptor.writable || descriptor.set);\n        }\n    };\n} else {\n    var has = {}.hasOwnProperty;\n    var str = {}.toString;\n    var proto = {}.constructor.prototype;\n\n    var ObjectKeys = function (o) {\n        var ret = [];\n        for (var key in o) {\n            if (has.call(o, key)) {\n                ret.push(key);\n            }\n        }\n        return ret;\n    };\n\n    var ObjectGetDescriptor = function(o, key) {\n        return {value: o[key]};\n    };\n\n    var ObjectDefineProperty = function (o, key, desc) {\n        o[key] = desc.value;\n        return o;\n    };\n\n    var ObjectFreeze = function (obj) {\n        return obj;\n    };\n\n    var ObjectGetPrototypeOf = function (obj) {\n        try {\n            return Object(obj).constructor.prototype;\n        }\n        catch (e) {\n            return proto;\n        }\n    };\n\n    var ArrayIsArray = function (obj) {\n        try {\n            return str.call(obj) === \"[object Array]\";\n        }\n        catch(e) {\n            return false;\n        }\n    };\n\n    module.exports = {\n        isArray: ArrayIsArray,\n        keys: ObjectKeys,\n        names: ObjectKeys,\n        defineProperty: ObjectDefineProperty,\n        getDescriptor: ObjectGetDescriptor,\n        freeze: ObjectFreeze,\n        getPrototypeOf: ObjectGetPrototypeOf,\n        isES5: isES5,\n        propertyIsWritable: function() {\n            return true;\n        }\n    };\n}\n"
  },
  {
    "path": "src/filter.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise, INTERNAL) {\nvar PromiseMap = Promise.map;\n\nPromise.prototype.filter = function (fn, options) {\n    return PromiseMap(this, fn, options, INTERNAL);\n};\n\nPromise.filter = function (promises, fn, options) {\n    return PromiseMap(promises, fn, options, INTERNAL);\n};\n};\n"
  },
  {
    "path": "src/finally.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise, tryConvertToPromise, NEXT_FILTER) {\nvar util = require(\"./util\");\nvar CancellationError = Promise.CancellationError;\nvar errorObj = util.errorObj;\nvar catchFilter = require(\"./catch_filter\")(NEXT_FILTER);\n\nfunction PassThroughHandlerContext(promise, type, handler) {\n    this.promise = promise;\n    this.type = type;\n    this.handler = handler;\n    this.called = false;\n    this.cancelPromise = null;\n}\n\nPassThroughHandlerContext.prototype.isFinallyHandler = function() {\n    return this.type === FINALLY_TYPE;\n};\n\nfunction FinallyHandlerCancelReaction(finallyHandler) {\n    this.finallyHandler = finallyHandler;\n}\n\nFinallyHandlerCancelReaction.prototype._resultCancelled = function() {\n    checkCancel(this.finallyHandler);\n};\n\nfunction checkCancel(ctx, reason) {\n    if (ctx.cancelPromise != null) {\n        if (arguments.length > 1) {\n            ctx.cancelPromise._reject(reason);\n        } else {\n            ctx.cancelPromise._cancel();\n        }\n        ctx.cancelPromise = null;\n        return true;\n    }\n    return false;\n}\n\nfunction succeed() {\n    return finallyHandler.call(this, this.promise._target()._settledValue());\n}\nfunction fail(reason) {\n    if (checkCancel(this, reason)) return;\n    errorObj.e = reason;\n    return errorObj;\n}\nfunction finallyHandler(reasonOrValue) {\n    var promise = this.promise;\n    var handler = this.handler;\n\n    if (!this.called) {\n        this.called = true;\n        var ret = this.isFinallyHandler()\n            ? handler.call(promise._boundValue())\n            : handler.call(promise._boundValue(), reasonOrValue);\n        if (ret === NEXT_FILTER) {\n            return ret;\n        } else if (ret !== undefined) {\n            promise._setReturnedNonUndefined();\n            var maybePromise = tryConvertToPromise(ret, promise);\n            if (maybePromise instanceof Promise) {\n                if (this.cancelPromise != null) {\n                    if (maybePromise._isCancelled()) {\n                        var reason =\n                            new CancellationError(LATE_CANCELLATION_OBSERVER);\n                        promise._attachExtraTrace(reason);\n                        errorObj.e = reason;\n                        return errorObj;\n                    } else if (maybePromise.isPending()) {\n                        maybePromise._attachCancellationCallback(\n                            new FinallyHandlerCancelReaction(this));\n                    }\n                }\n                return maybePromise._then(\n                    succeed, fail, undefined, this, undefined);\n            }\n        }\n    }\n\n    if (promise.isRejected()) {\n        checkCancel(this);\n        errorObj.e = reasonOrValue;\n        return errorObj;\n    } else {\n        checkCancel(this);\n        return reasonOrValue;\n    }\n}\n\nPromise.prototype._passThrough = function(handler, type, success, fail) {\n    if (typeof handler !== \"function\") return this.then();\n    return this._then(success,\n                      fail,\n                      undefined,\n                      new PassThroughHandlerContext(this, type, handler),\n                      undefined);\n};\n\nPromise.prototype.lastly =\nPromise.prototype[\"finally\"] = function (handler) {\n    return this._passThrough(handler,\n                             FINALLY_TYPE,\n                             finallyHandler,\n                             finallyHandler);\n};\n\n\nPromise.prototype.tap = function (handler) {\n    return this._passThrough(handler, TAP_TYPE, finallyHandler);\n};\n\nPromise.prototype.tapCatch = function (handlerOrPredicate) {\n    var len = arguments.length;\n    if(len === 1) {\n        return this._passThrough(handlerOrPredicate,\n                                 TAP_TYPE,\n                                 undefined,\n                                 finallyHandler);\n    } else {\n         var catchInstances = new Array(len - 1),\n            j = 0, i;\n        for (i = 0; i < len - 1; ++i) {\n            var item = arguments[i];\n            if (util.isObject(item)) {\n                catchInstances[j++] = item;\n            } else {\n                return Promise.reject(new TypeError(\n                    \"tapCatch statement predicate: \"\n                    + OBJECT_ERROR + util.classString(item)\n                ));\n            }\n        }\n        catchInstances.length = j;\n        var handler = arguments[i];\n        return this._passThrough(catchFilter(catchInstances, handler, this),\n                                 TAP_TYPE,\n                                 undefined,\n                                 finallyHandler);\n    }\n\n};\n\nreturn PassThroughHandlerContext;\n};\n"
  },
  {
    "path": "src/generators.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise,\n                          apiRejection,\n                          INTERNAL,\n                          tryConvertToPromise,\n                          Proxyable,\n                          debug) {\nvar errors = require(\"./errors\");\nvar TypeError = errors.TypeError;\nvar ASSERT = require(\"./assert\");\nvar util = require(\"./util\");\nvar errorObj = util.errorObj;\nvar tryCatch = util.tryCatch;\nvar yieldHandlers = [];\n\nfunction promiseFromYieldHandler(value, yieldHandlers, traceParent) {\n    for (var i = 0; i < yieldHandlers.length; ++i) {\n        traceParent._pushContext();\n        var result = tryCatch(yieldHandlers[i])(value);\n        traceParent._popContext();\n        if (result === errorObj) {\n            traceParent._pushContext();\n            var ret = Promise.reject(errorObj.e);\n            traceParent._popContext();\n            return ret;\n        }\n        var maybePromise = tryConvertToPromise(result, traceParent);\n        if (maybePromise instanceof Promise) return maybePromise;\n    }\n    return null;\n}\n\nfunction PromiseSpawn(generatorFunction, receiver, yieldHandler, stack) {\n    if (debug.cancellation()) {\n        var internal = new Promise(INTERNAL);\n        var _finallyPromise = this._finallyPromise = new Promise(INTERNAL);\n        this._promise = internal.lastly(function() {\n            return _finallyPromise;\n        });\n        internal._captureStackTrace();\n        internal._setOnCancel(this);\n    } else {\n        var promise = this._promise = new Promise(INTERNAL);\n        promise._captureStackTrace();\n    }\n    this._stack = stack;\n    this._generatorFunction = generatorFunction;\n    this._receiver = receiver;\n    this._generator = undefined;\n    this._yieldHandlers = typeof yieldHandler === \"function\"\n        ? [yieldHandler].concat(yieldHandlers)\n        : yieldHandlers;\n    this._yieldedPromise = null;\n    this._cancellationPhase = false;\n}\nutil.inherits(PromiseSpawn, Proxyable);\n\nPromiseSpawn.prototype._isResolved = function() {\n    return this._promise === null;\n};\n\nPromiseSpawn.prototype._cleanup = function() {\n    this._promise = this._generator = null;\n    if (debug.cancellation() && this._finallyPromise !== null) {\n        this._finallyPromise._fulfill();\n        this._finallyPromise = null;\n    }\n};\n\nPromiseSpawn.prototype._promiseCancelled = function() {\n    if (this._isResolved()) return;\n    var implementsReturn = typeof this._generator[\"return\"] !== \"undefined\";\n\n    var result;\n    if (!implementsReturn) {\n        var reason = new Promise.CancellationError(\n            \"generator .return() sentinel\");\n        Promise.coroutine.returnSentinel = reason;\n        this._promise._attachExtraTrace(reason);\n        this._promise._pushContext();\n        result = tryCatch(this._generator[\"throw\"]).call(this._generator,\n                                                         reason);\n        this._promise._popContext();\n    } else {\n        this._promise._pushContext();\n        result = tryCatch(this._generator[\"return\"]).call(this._generator,\n                                                          undefined);\n        this._promise._popContext();\n    }\n    this._cancellationPhase = true;\n    this._yieldedPromise = null;\n    this._continue(result);\n};\n\nPromiseSpawn.prototype._promiseFulfilled = function(value) {\n    this._yieldedPromise = null;\n    this._promise._pushContext();\n    var result = tryCatch(this._generator.next).call(this._generator, value);\n    this._promise._popContext();\n    this._continue(result);\n};\n\nPromiseSpawn.prototype._promiseRejected = function(reason) {\n    this._yieldedPromise = null;\n    this._promise._attachExtraTrace(reason);\n    this._promise._pushContext();\n    var result = tryCatch(this._generator[\"throw\"])\n        .call(this._generator, reason);\n    this._promise._popContext();\n    this._continue(result);\n};\n\nPromiseSpawn.prototype._resultCancelled = function() {\n    if (this._yieldedPromise instanceof Promise) {\n        var promise = this._yieldedPromise;\n        this._yieldedPromise = null;\n        promise.cancel();\n    }\n};\n\nPromiseSpawn.prototype.promise = function () {\n    return this._promise;\n};\n\nPromiseSpawn.prototype._run = function () {\n    this._generator = this._generatorFunction.call(this._receiver);\n    this._receiver =\n        this._generatorFunction = undefined;\n    this._promiseFulfilled(undefined);\n};\n\nPromiseSpawn.prototype._continue = function (result) {\n    ASSERT(this._yieldedPromise == null);\n    var promise = this._promise;\n    if (result === errorObj) {\n        this._cleanup();\n        if (this._cancellationPhase) {\n            return promise.cancel();\n        } else {\n            return promise._rejectCallback(result.e, false);\n        }\n    }\n\n    var value = result.value;\n    if (result.done === true) {\n        this._cleanup();\n        if (this._cancellationPhase) {\n            return promise.cancel();\n        } else {\n            return promise._resolveCallback(value);\n        }\n    } else {\n        var maybePromise = tryConvertToPromise(value, this._promise);\n        if (!(maybePromise instanceof Promise)) {\n            maybePromise =\n                promiseFromYieldHandler(maybePromise,\n                                        this._yieldHandlers,\n                                        this._promise);\n            ASSERT(maybePromise === null || maybePromise instanceof Promise);\n            if (maybePromise === null) {\n                this._promiseRejected(\n                    new TypeError(\n                        YIELDED_NON_PROMISE_ERROR.replace(\"%s\", String(value)) +\n                        FROM_COROUTINE_CREATED_AT +\n                        this._stack.split(\"\\n\").slice(1, -7).join(\"\\n\")\n                    )\n                );\n                return;\n            }\n        }\n        maybePromise = maybePromise._target();\n        var bitField = maybePromise._bitField;\n        USE(bitField);\n        if (BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG)) {\n            this._yieldedPromise = maybePromise;\n            maybePromise._proxy(this, null);\n        } else if (BIT_FIELD_CHECK(IS_FULFILLED)) {\n            Promise._async.invoke(\n                this._promiseFulfilled, this, maybePromise._value()\n            );\n        } else if (BIT_FIELD_CHECK(IS_REJECTED)) {\n            Promise._async.invoke(\n                this._promiseRejected, this, maybePromise._reason()\n            );\n        } else {\n            this._promiseCancelled();\n        }\n    }\n};\n\nPromise.coroutine = function (generatorFunction, options) {\n    //Throw synchronously because Promise.coroutine is semantically\n    //something you call at \"compile time\" to annotate static functions\n    if (typeof generatorFunction !== \"function\") {\n        throw new TypeError(NOT_GENERATOR_ERROR);\n    }\n    var yieldHandler = Object(options).yieldHandler;\n    var PromiseSpawn$ = PromiseSpawn;\n    var stack = new Error().stack;\n    return function () {\n        var generator = generatorFunction.apply(this, arguments);\n        var spawn = new PromiseSpawn$(undefined, undefined, yieldHandler,\n                                      stack);\n        var ret = spawn.promise();\n        spawn._generator = generator;\n        spawn._promiseFulfilled(undefined);\n        return ret;\n    };\n};\n\nPromise.coroutine.addYieldHandler = function(fn) {\n    if (typeof fn !== \"function\") {\n        throw new TypeError(FUNCTION_ERROR + util.classString(fn));\n    }\n    yieldHandlers.push(fn);\n};\n\nPromise.spawn = function (generatorFunction) {\n    debug.deprecated(\"Promise.spawn()\", \"Promise.coroutine()\");\n    //Return rejected promise because Promise.spawn is semantically\n    //something that will be called at runtime with possibly dynamic values\n    if (typeof generatorFunction !== \"function\") {\n        return apiRejection(NOT_GENERATOR_ERROR);\n    }\n    var spawn = new PromiseSpawn(generatorFunction, this);\n    var ret = spawn.promise();\n    spawn._run(Promise.spawn);\n    return ret;\n};\n};\n"
  },
  {
    "path": "src/join.js",
    "content": "\"use strict\";\nmodule.exports =\nfunction(Promise, PromiseArray, tryConvertToPromise, INTERNAL, async) {\nvar util = require(\"./util\");\nvar canEvaluate = util.canEvaluate;\nvar tryCatch = util.tryCatch;\nvar errorObj = util.errorObj;\nvar reject;\n\nif (!__BROWSER__) {\nif (canEvaluate) {\n    var thenCallback = function(i) {\n        return new Function(\"value\", \"holder\", \"                             \\n\\\n            'use strict';                                                    \\n\\\n            holder.pIndex = value;                                           \\n\\\n            holder.checkFulfillment(this);                                   \\n\\\n            \".replace(/Index/g, i));\n    };\n\n    var promiseSetter = function(i) {\n        return new Function(\"promise\", \"holder\", \"                           \\n\\\n            'use strict';                                                    \\n\\\n            holder.pIndex = promise;                                         \\n\\\n            \".replace(/Index/g, i));\n    };\n\n    var generateHolderClass = function(total) {\n        var props = new Array(total);\n        for (var i = 0; i < props.length; ++i) {\n            props[i] = \"this.p\" + (i+1);\n        }\n        var assignment = props.join(\" = \") + \" = null;\";\n        var cancellationCode= \"var promise;\\n\" + props.map(function(prop) {\n            return \"                                                         \\n\\\n                promise = \" + prop + \";                                      \\n\\\n                if (promise instanceof Promise) {                            \\n\\\n                    promise.cancel();                                        \\n\\\n                }                                                            \\n\\\n            \";\n        }).join(\"\\n\");\n        var passedArguments = props.join(\", \");\n        var name = \"Holder$\" + total;\n\n\n        var code = \"return function(tryCatch, errorObj, Promise, async) {    \\n\\\n            'use strict';                                                    \\n\\\n            function [TheName](fn) {                                         \\n\\\n                [TheProperties]                                              \\n\\\n                this.fn = fn;                                                \\n\\\n                this.asyncNeeded = true;                                     \\n\\\n                this.now = 0;                                                \\n\\\n            }                                                                \\n\\\n                                                                             \\n\\\n            [TheName].prototype._callFunction = function(promise) {          \\n\\\n                promise._pushContext();                                      \\n\\\n                var ret = tryCatch(this.fn)([ThePassedArguments]);           \\n\\\n                promise._popContext();                                       \\n\\\n                if (ret === errorObj) {                                      \\n\\\n                    promise._rejectCallback(ret.e, false);                   \\n\\\n                } else {                                                     \\n\\\n                    promise._resolveCallback(ret);                           \\n\\\n                }                                                            \\n\\\n            };                                                               \\n\\\n                                                                             \\n\\\n            [TheName].prototype.checkFulfillment = function(promise) {       \\n\\\n                var now = ++this.now;                                        \\n\\\n                if (now === [TheTotal]) {                                    \\n\\\n                    if (this.asyncNeeded) {                                  \\n\\\n                        async.invoke(this._callFunction, this, promise);     \\n\\\n                    } else {                                                 \\n\\\n                        this._callFunction(promise);                         \\n\\\n                    }                                                        \\n\\\n                                                                             \\n\\\n                }                                                            \\n\\\n            };                                                               \\n\\\n                                                                             \\n\\\n            [TheName].prototype._resultCancelled = function() {              \\n\\\n                [CancellationCode]                                           \\n\\\n            };                                                               \\n\\\n                                                                             \\n\\\n            return [TheName];                                                \\n\\\n        }(tryCatch, errorObj, Promise, async);                               \\n\\\n        \";\n\n        code = code.replace(/\\[TheName\\]/g, name)\n            .replace(/\\[TheTotal\\]/g, total)\n            .replace(/\\[ThePassedArguments\\]/g, passedArguments)\n            .replace(/\\[TheProperties\\]/g, assignment)\n            .replace(/\\[CancellationCode\\]/g, cancellationCode);\n\n        return new Function(\"tryCatch\", \"errorObj\", \"Promise\", \"async\", code)\n                           (tryCatch, errorObj, Promise, async);\n    };\n\n    var holderClasses = [];\n    var thenCallbacks = [];\n    var promiseSetters = [];\n\n    for (var i = 0; i < GENERATED_CLASS_COUNT; ++i) {\n        holderClasses.push(generateHolderClass(i + 1));\n        thenCallbacks.push(thenCallback(i + 1));\n        promiseSetters.push(promiseSetter(i + 1));\n    }\n\n    reject = function (reason) {\n        this._reject(reason);\n    };\n}}\n\nPromise.join = function () {\n    var last = arguments.length - 1;\n    var fn;\n    if (last > 0 && typeof arguments[last] === \"function\") {\n        fn = arguments[last];\n        if (!__BROWSER__) {\n            if (last <= GENERATED_CLASS_COUNT && canEvaluate) {\n                var ret = new Promise(INTERNAL);\n                ret._captureStackTrace();\n                var HolderClass = holderClasses[last - 1];\n                var holder = new HolderClass(fn);\n                var callbacks = thenCallbacks;\n\n                for (var i = 0; i < last; ++i) {\n                    var maybePromise = tryConvertToPromise(arguments[i], ret);\n                    if (maybePromise instanceof Promise) {\n                        maybePromise = maybePromise._target();\n                        var bitField = maybePromise._bitField;\n                        USE(bitField);\n                        if (BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG)) {\n                            maybePromise._then(callbacks[i], reject,\n                                               undefined, ret, holder);\n                            promiseSetters[i](maybePromise, holder);\n                            holder.asyncNeeded = false;\n                        } else if (BIT_FIELD_CHECK(IS_FULFILLED)) {\n                            callbacks[i].call(ret,\n                                              maybePromise._value(), holder);\n                        } else if (BIT_FIELD_CHECK(IS_REJECTED)) {\n                            ret._reject(maybePromise._reason());\n                        } else {\n                            ret._cancel();\n                        }\n                    } else {\n                        callbacks[i].call(ret, maybePromise, holder);\n                    }\n                }\n\n                if (!ret._isFateSealed()) {\n                    if (holder.asyncNeeded) {\n                        var context = Promise._getContext();\n                        holder.fn = util.contextBind(context, holder.fn);\n                    }\n                    ret._setAsyncGuaranteed();\n                    ret._setOnCancel(holder);\n                }\n                return ret;\n            }\n        }\n    }\n    INLINE_SLICE(args, arguments);\n    if (fn) args.pop();\n    var ret = new PromiseArray(args).promise();\n    return fn !== undefined ? ret.spread(fn) : ret;\n};\n\n};\n"
  },
  {
    "path": "src/map.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise,\n                          PromiseArray,\n                          apiRejection,\n                          tryConvertToPromise,\n                          INTERNAL,\n                          debug) {\nvar ASSERT = require(\"./assert\");\nvar util = require(\"./util\");\nvar tryCatch = util.tryCatch;\nvar errorObj = util.errorObj;\nvar async = Promise._async;\n\nfunction MappingPromiseArray(promises, fn, limit, _filter) {\n    this.constructor$(promises);\n    this._promise._captureStackTrace();\n    var context = Promise._getContext();\n    this._callback = util.contextBind(context, fn);\n    this._preservedValues = _filter === INTERNAL\n        ? new Array(this.length())\n        : null;\n    this._limit = limit;\n    this._inFlight = 0;\n    this._queue = [];\n    async.invoke(this._asyncInit, this, undefined);\n    if (util.isArray(promises)) {\n        for (var i = 0; i < promises.length; ++i) {\n            var maybePromise = promises[i];\n            if (maybePromise instanceof Promise) {\n                maybePromise.suppressUnhandledRejections();\n            }\n        }\n    }\n}\nutil.inherits(MappingPromiseArray, PromiseArray);\n\nMappingPromiseArray.prototype._asyncInit = function() {\n    this._init$(undefined, RESOLVE_ARRAY);\n};\n\n// The following hack is required because the super constructor\n// might call promiseFulfilled before this.callback = fn is set\n//\n// The super constructor call must always be first so that fields\n// are initialized in the same order so that the sub-class instances\n// will share same memory layout as the super class instances\n\n// Override\nMappingPromiseArray.prototype._init = function () {};\n\n// Override\nMappingPromiseArray.prototype._promiseFulfilled = function (value, index) {\n    ASSERT(!this._isResolved());\n    var values = this._values;\n    var length = this.length();\n    var preservedValues = this._preservedValues;\n    var limit = this._limit;\n\n    // Callback has been called for this index if it's negative\n    if (index < 0) {\n        // Restore the actual index value\n        index = (index * -1) - 1;\n        values[index] = value;\n        if (limit >= 1) {\n            this._inFlight--;\n            this._drainQueue();\n            if (this._isResolved()) return true;\n        }\n    } else {\n        if (limit >= 1 && this._inFlight >= limit) {\n            values[index] = value;\n            this._queue.push(index);\n            return false;\n        }\n        if (preservedValues !== null) preservedValues[index] = value;\n\n        var promise = this._promise;\n        var callback = this._callback;\n        var receiver = promise._boundValue();\n        promise._pushContext();\n        var ret = tryCatch(callback).call(receiver, value, index, length);\n        var promiseCreated = promise._popContext();\n        debug.checkForgottenReturns(\n            ret,\n            promiseCreated,\n            preservedValues !== null ? \"Promise.filter\" : \"Promise.map\",\n            promise\n        );\n        if (ret === errorObj) {\n            this._reject(ret.e);\n            return true;\n        }\n\n        // If the mapper function returned a promise we simply reuse\n        // The MappingPromiseArray as a PromiseArray for round 2.\n        // To mark an index as \"round 2\" its inverted by adding +1 and\n        // multiplying by -1\n        var maybePromise = tryConvertToPromise(ret, this._promise);\n        if (maybePromise instanceof Promise) {\n            maybePromise = maybePromise._target();\n            var bitField = maybePromise._bitField;\n            USE(bitField);\n            if (BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG)) {\n                if (limit >= 1) this._inFlight++;\n                values[index] = maybePromise;\n                maybePromise._proxy(this, (index + 1) * -1);\n                return false;\n            } else if (BIT_FIELD_CHECK(IS_FULFILLED)) {\n                ret = maybePromise._value();\n            } else if (BIT_FIELD_CHECK(IS_REJECTED)) {\n                this._reject(maybePromise._reason());\n                return true;\n            } else {\n                this._cancel();\n                return true;\n            }\n        }\n        values[index] = ret;\n    }\n    var totalResolved = ++this._totalResolved;\n    if (totalResolved >= length) {\n        if (preservedValues !== null) {\n            this._filter(values, preservedValues);\n        } else {\n            this._resolve(values);\n        }\n        return true;\n    }\n    return false;\n};\n\nMappingPromiseArray.prototype._drainQueue = function () {\n    var queue = this._queue;\n    var limit = this._limit;\n    var values = this._values;\n    while (queue.length > 0 && this._inFlight < limit) {\n        if (this._isResolved()) return;\n        var index = queue.pop();\n        this._promiseFulfilled(values[index], index);\n    }\n};\n\nMappingPromiseArray.prototype._filter = function (booleans, values) {\n    var len = values.length;\n    var ret = new Array(len);\n    var j = 0;\n    for (var i = 0; i < len; ++i) {\n        if (booleans[i]) ret[j++] = values[i];\n    }\n    ret.length = j;\n    this._resolve(ret);\n};\n\nMappingPromiseArray.prototype.preservedValues = function () {\n    return this._preservedValues;\n};\n\nfunction map(promises, fn, options, _filter) {\n    if (typeof fn !== \"function\") {\n        return apiRejection(FUNCTION_ERROR + util.classString(fn));\n    }\n\n    var limit = 0;\n    if (options !== undefined) {\n        if (typeof options === \"object\" && options !== null) {\n            if (typeof options.concurrency !== \"number\") {\n                return Promise.reject(\n                    new TypeError(\"'concurrency' must be a number but it is \" +\n                                    util.classString(options.concurrency)));\n            }\n            limit = options.concurrency;\n        } else {\n            return Promise.reject(new TypeError(\n                            \"options argument must be an object but it is \" +\n                             util.classString(options)));\n        }\n    }\n    limit = typeof limit === \"number\" &&\n        isFinite(limit) && limit >= 1 ? limit : 0;\n    return new MappingPromiseArray(promises, fn, limit, _filter).promise();\n}\n\nPromise.prototype.map = function (fn, options) {\n    return map(this, fn, options, null);\n};\n\nPromise.map = function (promises, fn, options, _filter) {\n    return map(promises, fn, options, _filter);\n};\n\n\n};\n"
  },
  {
    "path": "src/method.js",
    "content": "\"use strict\";\nmodule.exports =\nfunction(Promise, INTERNAL, tryConvertToPromise, apiRejection, debug) {\nvar util = require(\"./util\");\nvar ASSERT = require(\"./assert\");\nvar tryCatch = util.tryCatch;\n\nPromise.method = function (fn) {\n    if (typeof fn !== \"function\") {\n        throw new Promise.TypeError(FUNCTION_ERROR + util.classString(fn));\n    }\n    return function () {\n        var ret = new Promise(INTERNAL);\n        ret._captureStackTrace();\n        ret._pushContext();\n        var value = tryCatch(fn).apply(this, arguments);\n        var promiseCreated = ret._popContext();\n        debug.checkForgottenReturns(\n            value, promiseCreated, \"Promise.method\", ret);\n        ret._resolveFromSyncValue(value);\n        return ret;\n    };\n};\n\nPromise.attempt = Promise[\"try\"] = function (fn) {\n    if (typeof fn !== \"function\") {\n        return apiRejection(FUNCTION_ERROR + util.classString(fn));\n    }\n    var ret = new Promise(INTERNAL);\n    ret._captureStackTrace();\n    ret._pushContext();\n    var value;\n    if (arguments.length > 1) {\n        debug.deprecated(\"calling Promise.try with more than 1 argument\");\n        var arg = arguments[1];\n        var ctx = arguments[2];\n        value = util.isArray(arg) ? tryCatch(fn).apply(ctx, arg)\n                                  : tryCatch(fn).call(ctx, arg);\n    } else {\n        value = tryCatch(fn)();\n    }\n    var promiseCreated = ret._popContext();\n    debug.checkForgottenReturns(\n        value, promiseCreated, \"Promise.try\", ret);\n    ret._resolveFromSyncValue(value);\n    return ret;\n};\n\nPromise.prototype._resolveFromSyncValue = function (value) {\n    ASSERT(!this._isFollowing());\n    if (value === util.errorObj) {\n        this._rejectCallback(value.e, false);\n    } else {\n        this._resolveCallback(value, true);\n    }\n};\n};\n"
  },
  {
    "path": "src/nodeback.js",
    "content": "\"use strict\";\nvar util = require(\"./util\");\nvar maybeWrapAsError = util.maybeWrapAsError;\nvar errors = require(\"./errors\");\nvar OperationalError = errors.OperationalError;\nvar es5 = require(\"./es5\");\n\nfunction isUntypedError(obj) {\n    return obj instanceof Error &&\n        es5.getPrototypeOf(obj) === Error.prototype;\n}\n\nvar rErrorKey = /^(?:name|message|stack|cause)$/;\nfunction wrapAsOperationalError(obj) {\n    var ret;\n    if (isUntypedError(obj)) {\n        ret = new OperationalError(obj);\n        ret.name = obj.name;\n        ret.message = obj.message;\n        ret.stack = obj.stack;\n        var keys = es5.keys(obj);\n        for (var i = 0; i < keys.length; ++i) {\n            var key = keys[i];\n            if (!rErrorKey.test(key)) {\n                ret[key] = obj[key];\n            }\n        }\n        return ret;\n    }\n    util.markAsOriginatingFromRejection(obj);\n    return obj;\n}\n\nfunction nodebackForPromise(promise, multiArgs) {\n    return function(err, value) {\n        if (promise === null) return;\n        if (err) {\n            var wrapped = wrapAsOperationalError(maybeWrapAsError(err));\n            promise._attachExtraTrace(wrapped);\n            promise._reject(wrapped);\n        } else if (!multiArgs) {\n            promise._fulfill(value);\n        } else {\n            INLINE_SLICE(args, arguments, 1);\n            promise._fulfill(args);\n        }\n        promise = null;\n    };\n}\n\nmodule.exports = nodebackForPromise;\n"
  },
  {
    "path": "src/nodeify.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise) {\nvar util = require(\"./util\");\nvar async = Promise._async;\nvar ASSERT = require(\"./assert\");\nvar tryCatch = util.tryCatch;\nvar errorObj = util.errorObj;\n\nfunction spreadAdapter(val, nodeback) {\n    var promise = this;\n    if (!util.isArray(val)) return successAdapter.call(promise, val, nodeback);\n    var ret =\n        tryCatch(nodeback).apply(promise._boundValue(), [null].concat(val));\n    if (ret === errorObj) {\n        async.throwLater(ret.e);\n    }\n}\n\nfunction successAdapter(val, nodeback) {\n    var promise = this;\n    var receiver = promise._boundValue();\n    ASSERT(typeof nodeback == \"function\");\n    var ret = val === undefined\n        ? tryCatch(nodeback).call(receiver, null)\n        : tryCatch(nodeback).call(receiver, null, val);\n    if (ret === errorObj) {\n        async.throwLater(ret.e);\n    }\n}\nfunction errorAdapter(reason, nodeback) {\n    var promise = this;\n    if (!reason) {\n        var newReason = new Error(reason + \"\");\n        newReason.cause = reason;\n        reason = newReason;\n        ASSERT(!!reason);\n    }\n    ASSERT(typeof nodeback == \"function\");\n    var ret = tryCatch(nodeback).call(promise._boundValue(), reason);\n    if (ret === errorObj) {\n        async.throwLater(ret.e);\n    }\n}\n\nPromise.prototype.asCallback = Promise.prototype.nodeify = function (nodeback,\n                                                                     options) {\n    if (typeof nodeback == \"function\") {\n        var adapter = successAdapter;\n        if (options !== undefined && Object(options).spread) {\n            adapter = spreadAdapter;\n        }\n        this._then(\n            adapter,\n            errorAdapter,\n            undefined,\n            this,\n            nodeback\n        );\n    }\n    return this;\n};\n};\n"
  },
  {
    "path": "src/promise.js",
    "content": "\"use strict\";\nmodule.exports = function() {\nvar makeSelfResolutionError = function () {\n    return new TypeError(CIRCULAR_RESOLUTION_ERROR);\n};\nvar reflectHandler = function() {\n    return new Promise.PromiseInspection(this._target());\n};\nvar apiRejection = function(msg) {\n    return Promise.reject(new TypeError(msg));\n};\nfunction Proxyable() {}\nvar UNDEFINED_BINDING = {};\nvar ASSERT = require(\"./assert\");\nvar util = require(\"./util\");\nutil.setReflectHandler(reflectHandler);\n\nvar getDomain = function() {\n    var domain = process.domain;\n    if (domain === undefined) {\n        return null;\n    }\n    return domain;\n};\nvar getContextDefault = function() {\n    return null;\n};\nvar getContextDomain = function() {\n    return {\n        domain: getDomain(),\n        async: null\n    };\n};\nvar AsyncResource = util.isNode && util.nodeSupportsAsyncResource ?\n    require(\"async_hooks\").AsyncResource : null;\nvar getContextAsyncHooks = function() {\n    return {\n        domain: getDomain(),\n        async: new AsyncResource(\"Bluebird::Promise\")\n    };\n};\nvar getContext = util.isNode ? getContextDomain : getContextDefault;\nutil.notEnumerableProp(Promise, \"_getContext\", getContext);\nvar enableAsyncHooks = function() {\n    getContext = getContextAsyncHooks;\n    util.notEnumerableProp(Promise, \"_getContext\", getContextAsyncHooks);\n};\nvar disableAsyncHooks = function() {\n    getContext = getContextDomain;\n    util.notEnumerableProp(Promise, \"_getContext\", getContextDomain);\n};\n\nvar es5 = require(\"./es5\");\nvar Async = require(\"./async\");\nvar async = new Async();\nes5.defineProperty(Promise, \"_async\", {value: async});\nvar errors = require(\"./errors\");\nvar TypeError = Promise.TypeError = errors.TypeError;\nPromise.RangeError = errors.RangeError;\nvar CancellationError = Promise.CancellationError = errors.CancellationError;\nPromise.TimeoutError = errors.TimeoutError;\nPromise.OperationalError = errors.OperationalError;\nPromise.RejectionError = errors.OperationalError;\nPromise.AggregateError = errors.AggregateError;\nvar INTERNAL = function(){};\nvar APPLY = {};\nvar NEXT_FILTER = {};\nvar tryConvertToPromise = require(\"./thenables\")(Promise, INTERNAL);\nvar PromiseArray =\n    require(\"./promise_array\")(Promise, INTERNAL,\n                               tryConvertToPromise, apiRejection, Proxyable);\nvar Context = require(\"./context\")(Promise);\n /*jshint unused:false*/\nvar createContext = Context.create;\n\nvar debug = require(\"./debuggability\")(Promise, Context,\n    enableAsyncHooks, disableAsyncHooks);\nvar CapturedTrace = debug.CapturedTrace;\nvar PassThroughHandlerContext =\n    require(\"./finally\")(Promise, tryConvertToPromise, NEXT_FILTER);\nvar catchFilter = require(\"./catch_filter\")(NEXT_FILTER);\nvar nodebackForPromise = require(\"./nodeback\");\nvar errorObj = util.errorObj;\nvar tryCatch = util.tryCatch;\nfunction check(self, executor) {\n    if (self == null || self.constructor !== Promise) {\n        throw new TypeError(CONSTRUCT_ERROR_INVOCATION);\n    }\n    if (typeof executor !== \"function\") {\n        throw new TypeError(FUNCTION_ERROR + util.classString(executor));\n    }\n\n}\n\nfunction Promise(executor) {\n    if (executor !== INTERNAL) {\n        check(this, executor);\n    }\n    this._bitField = NO_STATE;\n    this._fulfillmentHandler0 = undefined;\n    this._rejectionHandler0 = undefined;\n    this._promise0 = undefined;\n    this._receiver0 = undefined;\n    this._resolveFromExecutor(executor);\n    this._promiseCreated();\n    this._fireEvent(\"promiseCreated\", this);\n}\n\nPromise.prototype.toString = function () {\n    return \"[object Promise]\";\n};\n\nPromise.prototype.caught = Promise.prototype[\"catch\"] = function (fn) {\n    var len = arguments.length;\n    if (len > 1) {\n        var catchInstances = new Array(len - 1),\n            j = 0, i;\n        for (i = 0; i < len - 1; ++i) {\n            var item = arguments[i];\n            if (util.isObject(item)) {\n                catchInstances[j++] = item;\n            } else {\n                return apiRejection(\"Catch statement predicate: \" +\n                    OBJECT_ERROR + util.classString(item));\n            }\n        }\n        catchInstances.length = j;\n        fn = arguments[i];\n\n        if (typeof fn !== \"function\") {\n            throw new TypeError(\"The last argument to .catch() \" +\n                \"must be a function, got \" + util.toString(fn));\n        }\n        return this.then(undefined, catchFilter(catchInstances, fn, this));\n    }\n    return this.then(undefined, fn);\n};\n\nPromise.prototype.reflect = function () {\n    return this._then(reflectHandler,\n        reflectHandler, undefined, this, undefined);\n};\n\nPromise.prototype.then = function (didFulfill, didReject) {\n    if (debug.warnings() && arguments.length > 0 &&\n        typeof didFulfill !== \"function\" &&\n        typeof didReject !== \"function\") {\n        var msg = \".then() only accepts functions but was passed: \" +\n                util.classString(didFulfill);\n        if (arguments.length > 1) {\n            msg += \", \" + util.classString(didReject);\n        }\n        this._warn(msg);\n    }\n    return this._then(didFulfill, didReject, undefined, undefined, undefined);\n};\n\nPromise.prototype.done = function (didFulfill, didReject) {\n    var promise =\n        this._then(didFulfill, didReject, undefined, undefined, undefined);\n    promise._setIsFinal();\n};\n\nPromise.prototype.spread = function (fn) {\n    if (typeof fn !== \"function\") {\n        return apiRejection(FUNCTION_ERROR + util.classString(fn));\n    }\n    return this.all()._then(fn, undefined, undefined, APPLY, undefined);\n};\n\nPromise.prototype.toJSON = function () {\n    var ret = {\n        isFulfilled: false,\n        isRejected: false,\n        fulfillmentValue: undefined,\n        rejectionReason: undefined\n    };\n    if (this.isFulfilled()) {\n        ret.fulfillmentValue = this.value();\n        ret.isFulfilled = true;\n    } else if (this.isRejected()) {\n        ret.rejectionReason = this.reason();\n        ret.isRejected = true;\n    }\n    return ret;\n};\n\nPromise.prototype.all = function () {\n    if (arguments.length > 0) {\n        this._warn(\".all() was passed arguments but it does not take any\");\n    }\n    return new PromiseArray(this).promise();\n};\n\nPromise.prototype.error = function (fn) {\n    return this.caught(util.originatesFromRejection, fn);\n};\n\nPromise.getNewLibraryCopy = module.exports;\n\nPromise.is = function (val) {\n    return val instanceof Promise;\n};\n\nPromise.fromNode = Promise.fromCallback = function(fn) {\n    var ret = new Promise(INTERNAL);\n    ret._captureStackTrace();\n    var multiArgs = arguments.length > 1 ? !!Object(arguments[1]).multiArgs\n                                         : false;\n    var result = tryCatch(fn)(nodebackForPromise(ret, multiArgs));\n    if (result === errorObj) {\n        ret._rejectCallback(result.e, true);\n    }\n    if (!ret._isFateSealed()) ret._setAsyncGuaranteed();\n    return ret;\n};\n\nPromise.all = function (promises) {\n    return new PromiseArray(promises).promise();\n};\n\nPromise.cast = function (obj) {\n    var ret = tryConvertToPromise(obj);\n    if (!(ret instanceof Promise)) {\n        ret = new Promise(INTERNAL);\n        ret._captureStackTrace();\n        ret._setFulfilled();\n        ret._rejectionHandler0 = obj;\n    }\n    return ret;\n};\n\nPromise.resolve = Promise.fulfilled = Promise.cast;\n\nPromise.reject = Promise.rejected = function (reason) {\n    var ret = new Promise(INTERNAL);\n    ret._captureStackTrace();\n    ret._rejectCallback(reason, true);\n    return ret;\n};\n\nPromise.setScheduler = function(fn) {\n    if (typeof fn !== \"function\") {\n        throw new TypeError(FUNCTION_ERROR + util.classString(fn));\n    }\n    return async.setScheduler(fn);\n};\n\nPromise.prototype._then = function (\n    didFulfill,\n    didReject,\n    _, // For fast-cast compatibility between bluebird versions\n    receiver,\n    internalData\n) {\n    ASSERT(arguments.length === 5);\n    var haveInternalData = internalData !== undefined;\n    var promise = haveInternalData ? internalData : new Promise(INTERNAL);\n    var target = this._target();\n    var bitField = target._bitField;\n\n    if (!haveInternalData) {\n        promise._propagateFrom(this, PROPAGATE_ALL);\n        promise._captureStackTrace();\n        if (receiver === undefined &&\n            BIT_FIELD_CHECK(IS_BOUND, this._bitField)) {\n            if (!BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG)) {\n                receiver = this._boundValue();\n            } else {\n                receiver = target === this ? undefined : this._boundTo;\n            }\n        }\n        this._fireEvent(\"promiseChained\", this, promise);\n    }\n\n    var context = getContext();\n    if (!BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG)) {\n        var handler, value, settler = target._settlePromiseCtx;\n        if (BIT_FIELD_CHECK(IS_FULFILLED)) {\n            value = target._rejectionHandler0;\n            handler = didFulfill;\n        } else if (BIT_FIELD_CHECK(IS_REJECTED)) {\n            value = target._fulfillmentHandler0;\n            handler = didReject;\n            target._unsetRejectionIsUnhandled();\n        } else {\n            settler = target._settlePromiseLateCancellationObserver;\n            value = new CancellationError(LATE_CANCELLATION_OBSERVER);\n            target._attachExtraTrace(value);\n            handler = didReject;\n        }\n\n        async.invoke(settler, target, {\n            handler: util.contextBind(context, handler),\n            promise: promise,\n            receiver: receiver,\n            value: value\n        });\n    } else {\n        target._addCallbacks(didFulfill, didReject, promise,\n                receiver, context);\n    }\n\n    return promise;\n};\n\nPromise.prototype._length = function () {\n    ASSERT(arguments.length === 0);\n    return this._bitField & LENGTH_MASK;\n};\n\nPromise.prototype._isFateSealed = function () {\n    return (this._bitField & IS_FATE_SEALED) !== 0;\n};\n\nPromise.prototype._isFollowing = function () {\n    return (this._bitField & IS_FOLLOWING) === IS_FOLLOWING;\n};\n\nPromise.prototype._setLength = function (len) {\n    this._bitField = (this._bitField & LENGTH_CLEAR_MASK) |\n        (len & LENGTH_MASK);\n};\n\nPromise.prototype._setFulfilled = function () {\n    this._bitField = this._bitField | IS_FULFILLED;\n    this._fireEvent(\"promiseFulfilled\", this);\n};\n\nPromise.prototype._setRejected = function () {\n    this._bitField = this._bitField | IS_REJECTED;\n    this._fireEvent(\"promiseRejected\", this);\n};\n\nPromise.prototype._setFollowing = function () {\n    this._bitField = this._bitField | IS_FOLLOWING;\n    this._fireEvent(\"promiseResolved\", this);\n};\n\nPromise.prototype._setIsFinal = function () {\n    this._bitField = this._bitField | IS_FINAL;\n};\n\nPromise.prototype._isFinal = function () {\n    return (this._bitField & IS_FINAL) > 0;\n};\n\nPromise.prototype._unsetCancelled = function() {\n    this._bitField = this._bitField & (~IS_CANCELLED);\n};\n\nPromise.prototype._setCancelled = function() {\n    this._bitField = this._bitField | IS_CANCELLED;\n    this._fireEvent(\"promiseCancelled\", this);\n};\n\nPromise.prototype._setWillBeCancelled = function() {\n    this._bitField = this._bitField | WILL_BE_CANCELLED;\n};\n\nPromise.prototype._setAsyncGuaranteed = function() {\n    if (async.hasCustomScheduler()) return;\n    var bitField = this._bitField;\n    this._bitField = bitField |\n        (((bitField & NO_ASYNC_GUARANTEE) >> ASYNC_GUARANTEE_SHIFT) ^\n        IS_ASYNC_GUARANTEED);\n};\n\nPromise.prototype._setNoAsyncGuarantee = function() {\n    this._bitField = (this._bitField | NO_ASYNC_GUARANTEE) &\n        (~IS_ASYNC_GUARANTEED);\n};\n\nPromise.prototype._receiverAt = function (index) {\n    ASSERT(!this._isFollowing());\n    var ret = index === 0 ? this._receiver0 : this[\n            index * CALLBACK_SIZE - CALLBACK_SIZE + CALLBACK_RECEIVER_OFFSET];\n    //Only use the bound value when not calling internal methods\n    if (ret === UNDEFINED_BINDING) {\n        return undefined;\n    } else if (ret === undefined && this._isBound()) {\n        return this._boundValue();\n    }\n    return ret;\n};\n\nPromise.prototype._promiseAt = function (index) {\n    ASSERT(index > 0);\n    ASSERT(!this._isFollowing());\n    return this[\n            index * CALLBACK_SIZE - CALLBACK_SIZE + CALLBACK_PROMISE_OFFSET];\n};\n\nPromise.prototype._fulfillmentHandlerAt = function (index) {\n    ASSERT(!this._isFollowing());\n    ASSERT(index > 0);\n    return this[\n            index * CALLBACK_SIZE - CALLBACK_SIZE + CALLBACK_FULFILL_OFFSET];\n};\n\nPromise.prototype._rejectionHandlerAt = function (index) {\n    ASSERT(!this._isFollowing());\n    ASSERT(index > 0);\n    return this[\n            index * CALLBACK_SIZE - CALLBACK_SIZE + CALLBACK_REJECT_OFFSET];\n};\n\nPromise.prototype._boundValue = function() {};\n\nPromise.prototype._migrateCallback0 = function (follower) {\n    var bitField = follower._bitField;\n    var fulfill = follower._fulfillmentHandler0;\n    var reject = follower._rejectionHandler0;\n    var promise = follower._promise0;\n    var receiver = follower._receiverAt(0);\n    if (receiver === undefined) receiver = UNDEFINED_BINDING;\n    this._addCallbacks(fulfill, reject, promise, receiver, null);\n};\n\nPromise.prototype._migrateCallbackAt = function (follower, index) {\n    ASSERT(index > 0);\n    var fulfill = follower._fulfillmentHandlerAt(index);\n    var reject = follower._rejectionHandlerAt(index);\n    var promise = follower._promiseAt(index);\n    var receiver = follower._receiverAt(index);\n    if (receiver === undefined) receiver = UNDEFINED_BINDING;\n    this._addCallbacks(fulfill, reject, promise, receiver, null);\n};\n\nPromise.prototype._addCallbacks = function (\n    fulfill,\n    reject,\n    promise,\n    receiver,\n    context\n) {\n    ASSERT(typeof context === \"object\");\n    ASSERT(!this._isFateSealed());\n    ASSERT(!this._isFollowing());\n    var index = this._length();\n\n    if (index >= MAX_LENGTH - CALLBACK_SIZE) {\n        index = 0;\n        this._setLength(0);\n    }\n\n    if (index === 0) {\n        ASSERT(this._promise0 === undefined);\n        ASSERT(this._receiver0 === undefined);\n        ASSERT(this._fulfillmentHandler0 === undefined);\n        ASSERT(this._rejectionHandler0 === undefined);\n\n        this._promise0 = promise;\n        this._receiver0 = receiver;\n        if (typeof fulfill === \"function\") {\n            this._fulfillmentHandler0 = util.contextBind(context, fulfill);\n        }\n        if (typeof reject === \"function\") {\n            this._rejectionHandler0 = util.contextBind(context, reject);\n        }\n    } else {\n        ASSERT(this[base + CALLBACK_PROMISE_OFFSET] === undefined);\n        ASSERT(this[base + CALLBACK_RECEIVER_OFFSET] === undefined);\n        ASSERT(this[base + CALLBACK_FULFILL_OFFSET] === undefined);\n        ASSERT(this[base + CALLBACK_REJECT_OFFSET] === undefined);\n        var base = index * CALLBACK_SIZE - CALLBACK_SIZE;\n        this[base + CALLBACK_PROMISE_OFFSET] = promise;\n        this[base + CALLBACK_RECEIVER_OFFSET] = receiver;\n        if (typeof fulfill === \"function\") {\n            this[base + CALLBACK_FULFILL_OFFSET] =\n                util.contextBind(context, fulfill);\n        }\n        if (typeof reject === \"function\") {\n            this[base + CALLBACK_REJECT_OFFSET] =\n                util.contextBind(context, reject);\n        }\n    }\n    this._setLength(index + 1);\n    return index;\n};\n\nPromise.prototype._proxy = function (proxyable, arg) {\n    ASSERT(proxyable instanceof Proxyable);\n    ASSERT(!(arg instanceof Promise));\n    ASSERT(!this._isFollowing());\n    ASSERT(arguments.length === 2);\n    ASSERT(!this._isFateSealed());\n    this._addCallbacks(undefined, undefined, arg, proxyable, null);\n};\n\nPromise.prototype._resolveCallback = function(value, shouldBind) {\n    if (BIT_FIELD_CHECK(IS_FATE_SEALED, this._bitField)) return;\n    if (value === this)\n        return this._rejectCallback(makeSelfResolutionError(), false);\n    var maybePromise = tryConvertToPromise(value, this);\n    if (!(maybePromise instanceof Promise)) return this._fulfill(value);\n\n    if (shouldBind) this._propagateFrom(maybePromise, PROPAGATE_BIND);\n\n\n    var promise = maybePromise._target();\n\n    if (promise === this) {\n        this._reject(makeSelfResolutionError());\n        return;\n    }\n\n    var bitField = promise._bitField;\n    if (BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG)) {\n        var len = this._length();\n        if (len > 0) promise._migrateCallback0(this);\n        for (var i = 1; i < len; ++i) {\n            promise._migrateCallbackAt(this, i);\n        }\n        this._setFollowing();\n        this._setLength(0);\n        this._setFollowee(maybePromise);\n    } else if (BIT_FIELD_CHECK(IS_FULFILLED)) {\n        this._fulfill(promise._value());\n    } else if (BIT_FIELD_CHECK(IS_REJECTED)) {\n        this._reject(promise._reason());\n    } else {\n        var reason = new CancellationError(LATE_CANCELLATION_OBSERVER);\n        promise._attachExtraTrace(reason);\n        this._reject(reason);\n    }\n};\n\nPromise.prototype._rejectCallback =\nfunction(reason, synchronous, ignoreNonErrorWarnings) {\n    var trace = util.ensureErrorObject(reason);\n    var hasStack = trace === reason;\n    if (!hasStack && !ignoreNonErrorWarnings && debug.warnings()) {\n        var message = \"a promise was rejected with a non-error: \" +\n            util.classString(reason);\n        this._warn(message, true);\n    }\n    this._attachExtraTrace(trace, synchronous ? hasStack : false);\n    this._reject(reason);\n};\n\nPromise.prototype._resolveFromExecutor = function (executor) {\n    if (executor === INTERNAL) return;\n    ASSERT(typeof executor === \"function\");\n    var promise = this;\n    this._captureStackTrace();\n    this._pushContext();\n    var synchronous = true;\n    var r = this._execute(executor, function(value) {\n        promise._resolveCallback(value);\n    }, function (reason) {\n        promise._rejectCallback(reason, synchronous);\n    });\n    synchronous = false;\n    this._popContext();\n\n    if (r !== undefined) {\n        promise._rejectCallback(r, true);\n    }\n};\n\nPromise.prototype._settlePromiseFromHandler = function (\n    handler, receiver, value, promise\n) {\n    var bitField = promise._bitField;\n    if (BIT_FIELD_CHECK(IS_CANCELLED)) return;\n    promise._pushContext();\n    var x;\n    if (receiver === APPLY) {\n        if (!value || typeof value.length !== \"number\") {\n            x = errorObj;\n            x.e = new TypeError(\"cannot .spread() a non-array: \" +\n                                    util.classString(value));\n        } else {\n            x = tryCatch(handler).apply(this._boundValue(), value);\n        }\n    } else {\n        x = tryCatch(handler).call(receiver, value);\n    }\n    var promiseCreated = promise._popContext();\n    bitField = promise._bitField;\n    if (BIT_FIELD_CHECK(IS_CANCELLED)) return;\n\n    ASSERT(!promise._isFateSealed());\n\n    if (x === NEXT_FILTER) {\n        promise._reject(value);\n    } else if (x === errorObj) {\n        promise._rejectCallback(x.e, false);\n    } else {\n        debug.checkForgottenReturns(x, promiseCreated, \"\",  promise, this);\n        promise._resolveCallback(x);\n    }\n};\n\nPromise.prototype._target = function() {\n    var ret = this;\n    while (ret._isFollowing()) ret = ret._followee();\n    return ret;\n};\n\nPromise.prototype._followee = function() {\n    ASSERT(this._isFollowing());\n    ASSERT(this._rejectionHandler0 instanceof Promise);\n    return this._rejectionHandler0;\n};\n\nPromise.prototype._setFollowee = function(promise) {\n    ASSERT(this._isFollowing());\n    ASSERT(!(this._rejectionHandler0 instanceof Promise));\n    this._rejectionHandler0 = promise;\n};\n\nPromise.prototype._settlePromise = function(promise, handler, receiver, value) {\n    ASSERT(!this._isFollowing());\n    var isPromise = promise instanceof Promise;\n    var bitField = this._bitField;\n    var asyncGuaranteed = BIT_FIELD_CHECK(IS_ASYNC_GUARANTEED);\n    if (BIT_FIELD_CHECK(IS_CANCELLED)) {\n        if (isPromise) promise._invokeInternalOnCancel();\n\n        if (receiver instanceof PassThroughHandlerContext &&\n            receiver.isFinallyHandler()) {\n            receiver.cancelPromise = promise;\n            if (tryCatch(handler).call(receiver, value) === errorObj) {\n                promise._reject(errorObj.e);\n            }\n        } else if (handler === reflectHandler) {\n            promise._fulfill(reflectHandler.call(receiver));\n        } else if (receiver instanceof Proxyable) {\n            receiver._promiseCancelled(promise);\n        } else if (isPromise || promise instanceof PromiseArray) {\n            promise._cancel();\n        } else {\n            receiver.cancel();\n        }\n    } else if (typeof handler === \"function\") {\n        //if promise is not instanceof Promise\n        //it is internally smuggled data\n        if (!isPromise) {\n            handler.call(receiver, value, promise);\n        } else {\n            if (asyncGuaranteed) promise._setAsyncGuaranteed();\n            this._settlePromiseFromHandler(handler, receiver, value, promise);\n        }\n    } else if (receiver instanceof Proxyable) {\n        if (!receiver._isResolved()) {\n            if (BIT_FIELD_CHECK(IS_FULFILLED)) {\n                receiver._promiseFulfilled(value, promise);\n            } else {\n                receiver._promiseRejected(value, promise);\n            }\n        }\n    } else if (isPromise) {\n        if (asyncGuaranteed) promise._setAsyncGuaranteed();\n        if (BIT_FIELD_CHECK(IS_FULFILLED)) {\n            promise._fulfill(value);\n        } else {\n            promise._reject(value);\n        }\n    }\n};\n\nPromise.prototype._settlePromiseLateCancellationObserver = function(ctx) {\n    var handler = ctx.handler;\n    var promise = ctx.promise;\n    var receiver = ctx.receiver;\n    var value = ctx.value;\n    if (typeof handler === \"function\") {\n        if (!(promise instanceof Promise)) {\n            handler.call(receiver, value, promise);\n        } else {\n            this._settlePromiseFromHandler(handler, receiver, value, promise);\n        }\n    } else if (promise instanceof Promise) {\n        promise._reject(value);\n    }\n};\n\nPromise.prototype._settlePromiseCtx = function(ctx) {\n    this._settlePromise(ctx.promise, ctx.handler, ctx.receiver, ctx.value);\n};\n\nPromise.prototype._settlePromise0 = function(handler, value, bitField) {\n    var promise = this._promise0;\n    var receiver = this._receiverAt(0);\n    this._promise0 = undefined;\n    this._receiver0 = undefined;\n    this._settlePromise(promise, handler, receiver, value);\n};\n\nPromise.prototype._clearCallbackDataAtIndex = function(index) {\n    ASSERT(!this._isFollowing());\n    ASSERT(index > 0);\n    var base = index * CALLBACK_SIZE - CALLBACK_SIZE;\n    this[base + CALLBACK_PROMISE_OFFSET] =\n    this[base + CALLBACK_RECEIVER_OFFSET] =\n    this[base + CALLBACK_FULFILL_OFFSET] =\n    this[base + CALLBACK_REJECT_OFFSET] = undefined;\n};\n\nPromise.prototype._fulfill = function (value) {\n    var bitField = this._bitField;\n    if (BIT_FIELD_READ(IS_FATE_SEALED)) return;\n    if (value === this) {\n        var err = makeSelfResolutionError();\n        this._attachExtraTrace(err);\n        return this._reject(err);\n    }\n    this._setFulfilled();\n    this._rejectionHandler0 = value;\n\n    if (BIT_FIELD_READ(LENGTH_MASK) > 0) {\n        if (BIT_FIELD_CHECK(IS_ASYNC_GUARANTEED)) {\n            this._settlePromises();\n        } else {\n            async.settlePromises(this);\n        }\n        this._dereferenceTrace();\n    }\n};\n\nPromise.prototype._reject = function (reason) {\n    var bitField = this._bitField;\n    if (BIT_FIELD_READ(IS_FATE_SEALED)) return;\n    this._setRejected();\n    this._fulfillmentHandler0 = reason;\n\n    if (this._isFinal()) {\n        ASSERT(this._length() === 0);\n        return async.fatalError(reason, util.isNode);\n    }\n\n    if (BIT_FIELD_READ(LENGTH_MASK) > 0) {\n        async.settlePromises(this);\n    } else {\n        this._ensurePossibleRejectionHandled();\n    }\n};\n\nPromise.prototype._fulfillPromises = function (len, value) {\n    for (var i = 1; i < len; i++) {\n        var handler = this._fulfillmentHandlerAt(i);\n        var promise = this._promiseAt(i);\n        var receiver = this._receiverAt(i);\n        this._clearCallbackDataAtIndex(i);\n        this._settlePromise(promise, handler, receiver, value);\n    }\n};\n\nPromise.prototype._rejectPromises = function (len, reason) {\n    for (var i = 1; i < len; i++) {\n        var handler = this._rejectionHandlerAt(i);\n        var promise = this._promiseAt(i);\n        var receiver = this._receiverAt(i);\n        this._clearCallbackDataAtIndex(i);\n        this._settlePromise(promise, handler, receiver, reason);\n    }\n};\n\nPromise.prototype._settlePromises = function () {\n    var bitField = this._bitField;\n    var len = BIT_FIELD_READ(LENGTH_MASK);\n\n    if (len > 0) {\n        if (BIT_FIELD_CHECK(IS_REJECTED_OR_CANCELLED)) {\n            var reason = this._fulfillmentHandler0;\n            this._settlePromise0(this._rejectionHandler0, reason, bitField);\n            this._rejectPromises(len, reason);\n        } else {\n            var value = this._rejectionHandler0;\n            this._settlePromise0(this._fulfillmentHandler0, value, bitField);\n            this._fulfillPromises(len, value);\n        }\n        this._setLength(0);\n    }\n    this._clearCancellationData();\n};\n\nPromise.prototype._settledValue = function() {\n    ASSERT(!this._isFollowing());\n    ASSERT(this._isFateSealed());\n    var bitField = this._bitField;\n    if (BIT_FIELD_CHECK(IS_FULFILLED)) {\n        return this._rejectionHandler0;\n    } else if (BIT_FIELD_CHECK(IS_REJECTED)) {\n        return this._fulfillmentHandler0;\n    }\n    // Implicit undefined for cancelled promise.\n};\n\nif (typeof Symbol !== \"undefined\" && Symbol.toStringTag) {\n    es5.defineProperty(Promise.prototype, Symbol.toStringTag, {\n        get: function () {\n            return \"Object\";\n        }\n    });\n}\n\nfunction deferResolve(v) {this.promise._resolveCallback(v);}\nfunction deferReject(v) {this.promise._rejectCallback(v, false);}\n\nPromise.defer = Promise.pending = function() {\n    debug.deprecated(\"Promise.defer\", \"new Promise\");\n    var promise = new Promise(INTERNAL);\n    return {\n        promise: promise,\n        resolve: deferResolve,\n        reject: deferReject\n    };\n};\n\nutil.notEnumerableProp(Promise,\n                       \"_makeSelfResolutionError\",\n                       makeSelfResolutionError);\n\nrequire(\"./method\")(Promise, INTERNAL, tryConvertToPromise, apiRejection,\n    debug);\nrequire(\"./bind\")(Promise, INTERNAL, tryConvertToPromise, debug);\nrequire(\"./cancel\")(Promise, PromiseArray, apiRejection, debug);\nrequire(\"./direct_resolve\")(Promise);\nrequire(\"./synchronous_inspection\")(Promise);\nrequire(\"./join\")(\n    Promise, PromiseArray, tryConvertToPromise, INTERNAL, async);\nPromise.Promise = Promise;\nPromise.version = \"__VERSION__\";\n};\n"
  },
  {
    "path": "src/promise_array.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise, INTERNAL, tryConvertToPromise,\n    apiRejection, Proxyable) {\nvar ASSERT = require(\"./assert\");\nvar util = require(\"./util\");\nvar isArray = util.isArray;\n\n//To avoid eagerly allocating the objects\n//and also because undefined cannot be smuggled\nfunction toResolutionValue(val) {\n    switch(val) {\n    case RESOLVE_ARRAY: return [];\n    case RESOLVE_OBJECT: return {};\n    case RESOLVE_MAP: return new Map();\n    }\n    ASSERT(false);\n}\n\nfunction PromiseArray(values) {\n    ASSERT(arguments.length === 1);\n    var promise = this._promise = new Promise(INTERNAL);\n    if (values instanceof Promise) {\n        promise._propagateFrom(values, PROPAGATE_ALL);\n        values.suppressUnhandledRejections();\n    }\n    promise._setOnCancel(this);\n    this._values = values;\n    this._length = 0;\n    this._totalResolved = 0;\n    this._init(undefined, RESOLVE_ARRAY);\n}\nutil.inherits(PromiseArray, Proxyable);\n\nPromiseArray.prototype.length = function () {\n    return this._length;\n};\n\nPromiseArray.prototype.promise = function () {\n    return this._promise;\n};\n\nPromiseArray.prototype._init = function init(_, resolveValueIfEmpty) {\n    var values = tryConvertToPromise(this._values, this._promise);\n    if (values instanceof Promise) {\n        values = values._target();\n        var bitField = values._bitField;\n        USE(bitField);\n        this._values = values;\n\n        if (BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG)) {\n            ASSERT(typeof resolveValueIfEmpty === \"number\");\n            ASSERT(resolveValueIfEmpty < 0);\n            this._promise._setAsyncGuaranteed();\n            return values._then(\n                init,\n                this._reject,\n                undefined,\n                this,\n                resolveValueIfEmpty\n           );\n        } else if (BIT_FIELD_CHECK(IS_FULFILLED)) {\n            values = values._value();\n        } else if (BIT_FIELD_CHECK(IS_REJECTED)) {\n            return this._reject(values._reason());\n        } else {\n            return this._cancel();\n        }\n    }\n    values = util.asArray(values);\n    if (values === null) {\n        var err = apiRejection(\n            COLLECTION_ERROR + util.classString(values)).reason();\n        this._promise._rejectCallback(err, false);\n        return;\n    }\n\n    if (values.length === 0) {\n        if (resolveValueIfEmpty === RESOLVE_CALL_METHOD) {\n            this._resolveEmptyArray();\n        }\n        else {\n            this._resolve(toResolutionValue(resolveValueIfEmpty));\n        }\n        return;\n    }\n    this._iterate(values);\n};\n\nPromiseArray.prototype._iterate = function(values) {\n    var len = this.getActualLength(values.length);\n    this._length = len;\n    this._values = this.shouldCopyValues() ? new Array(len) : this._values;\n    var result = this._promise;\n    var isResolved = false;\n    var bitField = null;\n    for (var i = 0; i < len; ++i) {\n        var maybePromise = tryConvertToPromise(values[i], result);\n\n        if (maybePromise instanceof Promise) {\n            maybePromise = maybePromise._target();\n            bitField = maybePromise._bitField;\n        } else {\n            bitField = null;\n        }\n\n        if (isResolved) {\n            if (bitField !== null) {\n                maybePromise.suppressUnhandledRejections();\n            }\n        } else if (bitField !== null) {\n            if (BIT_FIELD_CHECK(IS_PENDING_AND_WAITING_NEG)) {\n                // Optimized for just passing the updates through\n                maybePromise._proxy(this, i);\n                this._values[i] = maybePromise;\n            } else if (BIT_FIELD_CHECK(IS_FULFILLED)) {\n                isResolved = this._promiseFulfilled(maybePromise._value(), i);\n            } else if (BIT_FIELD_CHECK(IS_REJECTED)) {\n                isResolved = this._promiseRejected(maybePromise._reason(), i);\n            } else {\n                isResolved = this._promiseCancelled(i);\n            }\n        } else {\n            isResolved = this._promiseFulfilled(maybePromise, i);\n        }\n        ASSERT(typeof isResolved === \"boolean\");\n    }\n    if (!isResolved) result._setAsyncGuaranteed();\n};\n\nPromiseArray.prototype._isResolved = function () {\n    return this._values === null;\n};\n\nPromiseArray.prototype._resolve = function (value) {\n    ASSERT(!this._isResolved());\n    ASSERT(!(value instanceof Promise));\n    this._values = null;\n    this._promise._fulfill(value);\n};\n\nPromiseArray.prototype._cancel = function() {\n    if (this._isResolved() || !this._promise._isCancellable()) return;\n    this._values = null;\n    this._promise._cancel();\n};\n\nPromiseArray.prototype._reject = function (reason) {\n    ASSERT(!this._isResolved());\n    this._values = null;\n    this._promise._rejectCallback(reason, false);\n};\n\nPromiseArray.prototype._promiseFulfilled = function (value, index) {\n    ASSERT(!this._isResolved());\n    ASSERT(isArray(this._values));\n    ASSERT(typeof index === \"number\");\n    this._values[index] = value;\n    var totalResolved = ++this._totalResolved;\n    if (totalResolved >= this._length) {\n        this._resolve(this._values);\n        return true;\n    }\n    return false;\n};\n\nPromiseArray.prototype._promiseCancelled = function() {\n    this._cancel();\n    return true;\n};\n\nPromiseArray.prototype._promiseRejected = function (reason) {\n    ASSERT(!this._isResolved());\n    ASSERT(isArray(this._values));\n    this._totalResolved++;\n    this._reject(reason);\n    return true;\n};\n\nPromiseArray.prototype._resultCancelled = function() {\n    if (this._isResolved()) return;\n    var values = this._values;\n    this._cancel();\n    if (values instanceof Promise) {\n        values.cancel();\n    } else {\n        for (var i = 0; i < values.length; ++i) {\n            if (values[i] instanceof Promise) {\n                values[i].cancel();\n            }\n        }\n    }\n};\n\nPromiseArray.prototype.shouldCopyValues = function () {\n    return true;\n};\n\nPromiseArray.prototype.getActualLength = function (len) {\n    return len;\n};\n\nreturn PromiseArray;\n};\n"
  },
  {
    "path": "src/promisify.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise, INTERNAL) {\nvar THIS = {};\nvar util = require(\"./util\");\nvar nodebackForPromise = require(\"./nodeback\");\nvar withAppended = util.withAppended;\nvar maybeWrapAsError = util.maybeWrapAsError;\nvar canEvaluate = util.canEvaluate;\nvar ASSERT = require(\"./assert\");\nvar TypeError = require(\"./errors\").TypeError;\nvar defaultSuffix = AFTER_PROMISIFIED_SUFFIX;\nvar defaultPromisified = {__isPromisified__: true};\nvar noCopyProps = [\n    \"arity\", // Firefox 4\n    \"length\",\n    \"name\",\n    \"arguments\",\n    \"caller\",\n    \"callee\",\n    \"prototype\",\n    \"__isPromisified__\"\n];\nvar noCopyPropsPattern = new RegExp(\"^(?:\" + noCopyProps.join(\"|\") + \")$\");\n\nvar defaultFilter = function(name) {\n    return util.isIdentifier(name) &&\n        name.charAt(0) !== \"_\" &&\n        name !== \"constructor\";\n};\n\nfunction propsFilter(key) {\n    return !noCopyPropsPattern.test(key);\n}\n\nfunction isPromisified(fn) {\n    try {\n        return fn.__isPromisified__ === true;\n    }\n    catch (e) {\n        return false;\n    }\n}\n\nfunction hasPromisified(obj, key, suffix) {\n    var val = util.getDataPropertyOrDefault(obj, key + suffix,\n                                            defaultPromisified);\n    return val ? isPromisified(val) : false;\n}\nfunction checkValid(ret, suffix, suffixRegexp) {\n    // Verify that in the list of methods to promisify there is no\n    // method that has a name ending in \"Async\"-suffix while\n    // also having a method with the same name but no Async suffix\n    for (var i = 0; i < ret.length; i += 2) {\n        var key = ret[i];\n        if (suffixRegexp.test(key)) {\n            var keyWithoutAsyncSuffix = key.replace(suffixRegexp, \"\");\n            for (var j = 0; j < ret.length; j += 2) {\n                if (ret[j] === keyWithoutAsyncSuffix) {\n                    throw new TypeError(PROMISIFICATION_NORMAL_METHODS_ERROR\n                        .replace(\"%s\", suffix));\n                }\n            }\n        }\n    }\n}\n\nfunction promisifiableMethods(obj, suffix, suffixRegexp, filter) {\n    var keys = util.inheritedDataKeys(obj);\n    var ret = [];\n    for (var i = 0; i < keys.length; ++i) {\n        var key = keys[i];\n        var value = obj[key];\n        var passesDefaultFilter = filter === defaultFilter\n            ? true : defaultFilter(key, value, obj);\n        if (typeof value === \"function\" &&\n            !isPromisified(value) &&\n            !hasPromisified(obj, key, suffix) &&\n            filter(key, value, obj, passesDefaultFilter)) {\n            ret.push(key, value);\n        }\n    }\n    checkValid(ret, suffix, suffixRegexp);\n    return ret;\n}\n\nvar escapeIdentRegex = function(str) {\n    return str.replace(/([$])/, \"\\\\$\");\n};\n\nvar makeNodePromisifiedEval;\nif (!__BROWSER__) {\n//Gives an optimal sequence of argument count to try given a formal parameter\n//.length for a function\nvar switchCaseArgumentOrder = function(likelyArgumentCount) {\n    var ret = [likelyArgumentCount];\n    var min = Math.max(0, likelyArgumentCount - 1 - PARAM_COUNTS_TO_TRY);\n    for(var i = likelyArgumentCount - 1; i >= min; --i) {\n        ret.push(i);\n    }\n    for(var i = likelyArgumentCount + 1; i <= PARAM_COUNTS_TO_TRY; ++i) {\n        ret.push(i);\n    }\n    return ret;\n};\n\nvar argumentSequence = function(argumentCount) {\n    return util.filledRange(argumentCount, \"_arg\", \"\");\n};\n\nvar parameterDeclaration = function(parameterCount) {\n    return util.filledRange(\n        Math.max(parameterCount, PARAM_COUNTS_TO_TRY), \"_arg\", \"\");\n};\n\nvar parameterCount = function(fn) {\n    if (typeof fn.length === \"number\") {\n        return Math.max(Math.min(fn.length, MAX_PARAM_COUNT + 1), 0);\n    }\n    //Unsupported .length for functions\n    return 0;\n};\n\nmakeNodePromisifiedEval =\nfunction(callback, receiver, originalName, fn, _, multiArgs) {\n                                        //-1 for the callback parameter\n    var newParameterCount = Math.max(0, parameterCount(fn) - 1);\n    var argumentOrder = switchCaseArgumentOrder(newParameterCount);\n    var shouldProxyThis = typeof callback === \"string\" || receiver === THIS;\n\n    function generateCallForArgumentCount(count) {\n        var args = argumentSequence(count).join(\", \");\n        var comma = count > 0 ? \", \" : \"\";\n        var ret;\n        if (shouldProxyThis) {\n            ret = \"ret = callback.call(this, {{args}}, nodeback); break;\\n\";\n        } else {\n            ret = receiver === undefined\n                ? \"ret = callback({{args}}, nodeback); break;\\n\"\n                : \"ret = callback.call(receiver, {{args}}, nodeback); break;\\n\";\n        }\n        return ret.replace(\"{{args}}\", args).replace(\", \", comma);\n    }\n\n    function generateArgumentSwitchCase() {\n        var ret = \"\";\n        for (var i = 0; i < argumentOrder.length; ++i) {\n            ret += \"case \" + argumentOrder[i] +\":\" +\n                generateCallForArgumentCount(argumentOrder[i]);\n        }\n\n        ret += \"                                                             \\n\\\n        default:                                                             \\n\\\n            var args = new Array(len + 1);                                   \\n\\\n            var i = 0;                                                       \\n\\\n            for (var i = 0; i < len; ++i) {                                  \\n\\\n               args[i] = arguments[i];                                       \\n\\\n            }                                                                \\n\\\n            args[i] = nodeback;                                              \\n\\\n            [CodeForCall]                                                    \\n\\\n            break;                                                           \\n\\\n        \".replace(\"[CodeForCall]\", (shouldProxyThis\n                                ? \"ret = callback.apply(this, args);\\n\"\n                                : \"ret = callback.apply(receiver, args);\\n\"));\n        return ret;\n    }\n\n    var getFunctionCode = typeof callback === \"string\"\n                                ? (\"this != null ? this['\"+callback+\"'] : fn\")\n                                : \"fn\";\n    var body = \"'use strict';                                                \\n\\\n        var ret = function (Parameters) {                                    \\n\\\n            'use strict';                                                    \\n\\\n            var len = arguments.length;                                      \\n\\\n            var promise = new Promise(INTERNAL);                             \\n\\\n            promise._captureStackTrace();                                    \\n\\\n            var nodeback = nodebackForPromise(promise, \" + multiArgs + \");   \\n\\\n            var ret;                                                         \\n\\\n            var callback = tryCatch([GetFunctionCode]);                      \\n\\\n            switch(len) {                                                    \\n\\\n                [CodeForSwitchCase]                                          \\n\\\n            }                                                                \\n\\\n            if (ret === errorObj) {                                          \\n\\\n                promise._rejectCallback(maybeWrapAsError(ret.e), true, true);\\n\\\n            }                                                                \\n\\\n            if (!promise._isFateSealed()) promise._setAsyncGuaranteed();     \\n\\\n            return promise;                                                  \\n\\\n        };                                                                   \\n\\\n        notEnumerableProp(ret, '__isPromisified__', true);                   \\n\\\n        return ret;                                                          \\n\\\n    \".replace(\"[CodeForSwitchCase]\", generateArgumentSwitchCase())\n        .replace(\"[GetFunctionCode]\", getFunctionCode);\n    body = body.replace(\"Parameters\", parameterDeclaration(newParameterCount));\n    return new Function(\"Promise\",\n                        \"fn\",\n                        \"receiver\",\n                        \"withAppended\",\n                        \"maybeWrapAsError\",\n                        \"nodebackForPromise\",\n                        \"tryCatch\",\n                        \"errorObj\",\n                        \"notEnumerableProp\",\n                        \"INTERNAL\",\n                        body)(\n                    Promise,\n                    fn,\n                    receiver,\n                    withAppended,\n                    maybeWrapAsError,\n                    nodebackForPromise,\n                    util.tryCatch,\n                    util.errorObj,\n                    util.notEnumerableProp,\n                    INTERNAL);\n};\n}\n\nfunction makeNodePromisifiedClosure(callback, receiver, _, fn, __, multiArgs) {\n    var defaultThis = (function() {return this;})();\n    var method = callback;\n    if (typeof method === \"string\") {\n        callback = fn;\n    }\n    function promisified() {\n        var _receiver = receiver;\n        if (receiver === THIS) _receiver = this;\n        ASSERT(typeof callback === \"function\");\n        var promise = new Promise(INTERNAL);\n        promise._captureStackTrace();\n        var cb = typeof method === \"string\" && this !== defaultThis\n            ? this[method] : callback;\n        var fn = nodebackForPromise(promise, multiArgs);\n        try {\n            cb.apply(_receiver, withAppended(arguments, fn));\n        } catch(e) {\n            promise._rejectCallback(maybeWrapAsError(e), true, true);\n        }\n        if (!promise._isFateSealed()) promise._setAsyncGuaranteed();\n        return promise;\n    }\n    util.notEnumerableProp(promisified, \"__isPromisified__\", true);\n    return promisified;\n}\n\nvar makeNodePromisified = canEvaluate\n    ? makeNodePromisifiedEval\n    : makeNodePromisifiedClosure;\n\nfunction promisifyAll(obj, suffix, filter, promisifier, multiArgs) {\n    ASSERT(typeof suffix === \"string\");\n    ASSERT(typeof filter === \"function\");\n    var suffixRegexp = new RegExp(escapeIdentRegex(suffix) + \"$\");\n    var methods =\n        promisifiableMethods(obj, suffix, suffixRegexp, filter);\n\n    for (var i = 0, len = methods.length; i < len; i+= 2) {\n        var key = methods[i];\n        var fn = methods[i+1];\n        var promisifiedKey = key + suffix;\n        if (promisifier === makeNodePromisified) {\n            obj[promisifiedKey] =\n                makeNodePromisified(key, THIS, key, fn, suffix, multiArgs);\n        } else {\n            var promisified = promisifier(fn, function() {\n                return makeNodePromisified(key, THIS, key,\n                                           fn, suffix, multiArgs);\n            });\n            util.notEnumerableProp(promisified, \"__isPromisified__\", true);\n            obj[promisifiedKey] = promisified;\n        }\n    }\n    util.toFastProperties(obj);\n    return obj;\n}\n\nfunction promisify(callback, receiver, multiArgs) {\n    return makeNodePromisified(callback, receiver, undefined,\n                                callback, null, multiArgs);\n}\n\nPromise.promisify = function (fn, options) {\n    if (typeof fn !== \"function\") {\n        throw new TypeError(FUNCTION_ERROR + util.classString(fn));\n    }\n    if (isPromisified(fn)) {\n        return fn;\n    }\n    options = Object(options);\n    var receiver = options.context === undefined ? THIS : options.context;\n    var multiArgs = !!options.multiArgs;\n    var ret = promisify(fn, receiver, multiArgs);\n    util.copyDescriptors(fn, ret, propsFilter);\n    return ret;\n};\n\nPromise.promisifyAll = function (target, options) {\n    if (typeof target !== \"function\" && typeof target !== \"object\") {\n        throw new TypeError(PROMISIFY_TYPE_ERROR);\n    }\n    options = Object(options);\n    var multiArgs = !!options.multiArgs;\n    var suffix = options.suffix;\n    if (typeof suffix !== \"string\") suffix = defaultSuffix;\n    var filter = options.filter;\n    if (typeof filter !== \"function\") filter = defaultFilter;\n    var promisifier = options.promisifier;\n    if (typeof promisifier !== \"function\") promisifier = makeNodePromisified;\n\n    if (!util.isIdentifier(suffix)) {\n        throw new RangeError(SUFFIX_NOT_IDENTIFIER);\n    }\n\n    var keys = util.inheritedDataKeys(target);\n    for (var i = 0; i < keys.length; ++i) {\n        var value = target[keys[i]];\n        if (keys[i] !== \"constructor\" &&\n            util.isClass(value)) {\n            promisifyAll(value.prototype, suffix, filter, promisifier,\n                multiArgs);\n            promisifyAll(value, suffix, filter, promisifier, multiArgs);\n        }\n    }\n\n    return promisifyAll(target, suffix, filter, promisifier, multiArgs);\n};\n};\n\n"
  },
  {
    "path": "src/props.js",
    "content": "\"use strict\";\nmodule.exports = function(\n    Promise, PromiseArray, tryConvertToPromise, apiRejection) {\nvar ASSERT = require(\"./assert\");\nvar util = require(\"./util\");\nvar isObject = util.isObject;\nvar es5 = require(\"./es5\");\nvar Es6Map;\nif (typeof Map === \"function\") Es6Map = Map;\n\nvar mapToEntries = (function() {\n    var index = 0;\n    var size = 0;\n\n    function extractEntry(value, key) {\n        this[index] = value;\n        this[index + size] = key;\n        index++;\n    }\n\n    return function mapToEntries(map) {\n        size = map.size;\n        index = 0;\n        var ret = new Array(map.size * 2);\n        map.forEach(extractEntry, ret);\n        return ret;\n    };\n})();\n\nvar entriesToMap = function(entries) {\n    var ret = new Es6Map();\n    var length = entries.length / 2 | 0;\n    for (var i = 0; i < length; ++i) {\n        var key = entries[length + i];\n        var value = entries[i];\n        ret.set(key, value);\n    }\n    return ret;\n};\n\nfunction PropertiesPromiseArray(obj) {\n    var isMap = false;\n    var entries;\n    if (Es6Map !== undefined && obj instanceof Es6Map) {\n        entries = mapToEntries(obj);\n        isMap = true;\n    } else {\n        var keys = es5.keys(obj);\n        var len = keys.length;\n        entries = new Array(len * 2);\n        for (var i = 0; i < len; ++i) {\n            var key = keys[i];\n            entries[i] = obj[key];\n            entries[i + len] = key;\n        }\n    }\n    this.constructor$(entries);\n    this._isMap = isMap;\n    this._init$(undefined, isMap ? RESOLVE_MAP : RESOLVE_OBJECT);\n}\nutil.inherits(PropertiesPromiseArray, PromiseArray);\n\n//Override\nPropertiesPromiseArray.prototype._init = function () {};\n\n//Override\nPropertiesPromiseArray.prototype._promiseFulfilled = function (value, index) {\n    ASSERT(!this._isResolved());\n    ASSERT(!(value instanceof Promise));\n    this._values[index] = value;\n    var totalResolved = ++this._totalResolved;\n    if (totalResolved >= this._length) {\n        var val;\n        if (this._isMap) {\n            val = entriesToMap(this._values);\n        } else {\n            val = {};\n            var keyOffset = this.length();\n            for (var i = 0, len = this.length(); i < len; ++i) {\n                val[this._values[i + keyOffset]] = this._values[i];\n            }\n        }\n        this._resolve(val);\n        return true;\n    }\n    return false;\n};\n\n// Override\nPropertiesPromiseArray.prototype.shouldCopyValues = function () {\n    return false;\n};\n\n// Override\nPropertiesPromiseArray.prototype.getActualLength = function (len) {\n    return len >> 1;\n};\n\nfunction props(promises) {\n    var ret;\n    var castValue = tryConvertToPromise(promises);\n\n    if (!isObject(castValue)) {\n        return apiRejection(PROPS_TYPE_ERROR);\n    } else if (castValue instanceof Promise) {\n        ret = castValue._then(\n            Promise.props, undefined, undefined, undefined, undefined);\n    } else {\n        ret = new PropertiesPromiseArray(castValue).promise();\n    }\n\n    if (castValue instanceof Promise) {\n        ret._propagateFrom(castValue, PROPAGATE_BIND);\n    }\n    return ret;\n}\n\nPromise.prototype.props = function () {\n    return props(this);\n};\n\nPromise.props = function (promises) {\n    return props(promises);\n};\n};\n"
  },
  {
    "path": "src/queue.js",
    "content": "\"use strict\";\nvar ASSERT = require(\"./assert\");\nfunction arrayMove(src, srcIndex, dst, dstIndex, len) {\n    for (var j = 0; j < len; ++j) {\n        dst[j + dstIndex] = src[j + srcIndex];\n        src[j + srcIndex] = void 0;\n    }\n}\n\nfunction Queue(capacity) {\n    this._capacity = capacity;\n    this._length = 0;\n    this._front = 0;\n}\n\nQueue.prototype._willBeOverCapacity = function (size) {\n    return this._capacity < size;\n};\n\nQueue.prototype._pushOne = function (arg) {\n    var length = this.length();\n    this._checkCapacity(length + 1);\n    var i = (this._front + length) & (this._capacity - 1);\n    this[i] = arg;\n    this._length = length + 1;\n};\n\nQueue.prototype.push = function (fn, receiver, arg) {\n    ASSERT(arguments.length === 3);\n    ASSERT(typeof fn === \"function\");\n    var length = this.length() + 3;\n    if (this._willBeOverCapacity(length)) {\n        //The fast array copies expect the\n        //underlying array to be filled completely\n        this._pushOne(fn);\n        this._pushOne(receiver);\n        this._pushOne(arg);\n        return;\n    }\n    var j = this._front + length - 3;\n    this._checkCapacity(length);\n    var wrapMask = this._capacity - 1;\n    this[(j + 0) & wrapMask] = fn;\n    this[(j + 1) & wrapMask] = receiver;\n    this[(j + 2) & wrapMask] = arg;\n    this._length = length;\n};\n\nQueue.prototype.shift = function () {\n    ASSERT(this.length() > 0);\n    var front = this._front,\n        ret = this[front];\n\n    this[front] = undefined;\n    this._front = (front + 1) & (this._capacity - 1);\n    this._length--;\n    return ret;\n};\n\nQueue.prototype.length = function () {\n    return this._length;\n};\n\nQueue.prototype._checkCapacity = function (size) {\n    if (this._capacity < size) {\n        this._resizeTo(this._capacity << 1);\n    }\n};\n\nQueue.prototype._resizeTo = function (capacity) {\n    var oldCapacity = this._capacity;\n    this._capacity = capacity;\n    var front = this._front;\n    var length = this._length;\n    var moveItemsCount = (front + length) & (oldCapacity - 1);\n    arrayMove(this, 0, this, oldCapacity, moveItemsCount);\n};\n\nmodule.exports = Queue;\n"
  },
  {
    "path": "src/race.js",
    "content": "\"use strict\";\nmodule.exports = function(\n    Promise, INTERNAL, tryConvertToPromise, apiRejection) {\nvar util = require(\"./util\");\n\nvar raceLater = function (promise) {\n    return promise.then(function(array) {\n        return race(array, promise);\n    });\n};\n\nfunction race(promises, parent) {\n    var maybePromise = tryConvertToPromise(promises);\n\n    if (maybePromise instanceof Promise) {\n        return raceLater(maybePromise);\n    } else {\n        promises = util.asArray(promises);\n        if (promises === null)\n            return apiRejection(COLLECTION_ERROR + util.classString(promises));\n    }\n\n    var ret = new Promise(INTERNAL);\n    if (parent !== undefined) {\n        ret._propagateFrom(parent, PROPAGATE_ALL);\n    }\n    var fulfill = ret._fulfill;\n    var reject = ret._reject;\n    for (var i = 0, len = promises.length; i < len; ++i) {\n        var val = promises[i];\n\n        if (val === undefined && !(i in promises)) {\n            continue;\n        }\n\n        Promise.cast(val)._then(fulfill, reject, undefined, ret, null);\n    }\n    //Yes, if promises were empty, it will be forever pending :-)\n    return ret;\n}\n\nPromise.race = function (promises) {\n    return race(promises, undefined);\n};\n\nPromise.prototype.race = function () {\n    return race(this, undefined);\n};\n\n};\n"
  },
  {
    "path": "src/reduce.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise,\n                          PromiseArray,\n                          apiRejection,\n                          tryConvertToPromise,\n                          INTERNAL,\n                          debug) {\nvar util = require(\"./util\");\nvar tryCatch = util.tryCatch;\n\nfunction ReductionPromiseArray(promises, fn, initialValue, _each) {\n    this.constructor$(promises);\n    var context = Promise._getContext();\n    this._fn = util.contextBind(context, fn);\n    if (initialValue !== undefined) {\n        initialValue = Promise.resolve(initialValue);\n        initialValue._attachCancellationCallback(this);\n    }\n    this._initialValue = initialValue;\n    this._currentCancellable = null;\n    if(_each === INTERNAL) {\n        this._eachValues = Array(this._length);\n    } else if (_each === 0) {\n        this._eachValues = null;\n    } else {\n        this._eachValues = undefined;\n    }\n    this._promise._captureStackTrace();\n    this._init$(undefined, RESOLVE_CALL_METHOD);\n}\nutil.inherits(ReductionPromiseArray, PromiseArray);\n\nReductionPromiseArray.prototype._gotAccum = function(accum) {\n    if (this._eachValues !== undefined &&\n        this._eachValues !== null &&\n        accum !== INTERNAL) {\n        this._eachValues.push(accum);\n    }\n};\n\nReductionPromiseArray.prototype._eachComplete = function(value) {\n    if (this._eachValues !== null) {\n        this._eachValues.push(value);\n    }\n    return this._eachValues;\n};\n\n// Override\nReductionPromiseArray.prototype._init = function() {};\n\n// Override\nReductionPromiseArray.prototype._resolveEmptyArray = function() {\n    this._resolve(this._eachValues !== undefined ? this._eachValues\n                                                 : this._initialValue);\n};\n\n// Override\nReductionPromiseArray.prototype.shouldCopyValues = function () {\n    return false;\n};\n\n// Override\nReductionPromiseArray.prototype._resolve = function(value) {\n    this._promise._resolveCallback(value);\n    this._values = null;\n};\n\n// Override\nReductionPromiseArray.prototype._resultCancelled = function(sender) {\n    if (sender === this._initialValue) return this._cancel();\n    if (this._isResolved()) return;\n    this._resultCancelled$();\n    if (this._currentCancellable instanceof Promise) {\n        this._currentCancellable.cancel();\n    }\n    if (this._initialValue instanceof Promise) {\n        this._initialValue.cancel();\n    }\n};\n\n// Override\nReductionPromiseArray.prototype._iterate = function (values) {\n    this._values = values;\n    var value;\n    var i;\n    var length = values.length;\n    if (this._initialValue !== undefined) {\n        value = this._initialValue;\n        i = 0;\n    } else {\n        value = Promise.resolve(values[0]);\n        i = 1;\n    }\n\n    this._currentCancellable = value;\n\n    for (var j = i; j < length; ++j) {\n        var maybePromise = values[j];\n        if (maybePromise instanceof Promise) {\n            maybePromise.suppressUnhandledRejections();\n        }\n    }\n\n    if (!value.isRejected()) {\n        for (; i < length; ++i) {\n            var ctx = {\n                accum: null,\n                value: values[i],\n                index: i,\n                length: length,\n                array: this\n            };\n\n            value = value._then(gotAccum, undefined, undefined, ctx, undefined);\n\n            // Too many promises chained with asyncGuaranteed will result in\n            // stack overflow. Break up long chains to reset stack.\n            if ((i & 127) === 0) {\n                value._setNoAsyncGuarantee();\n            }\n        }\n    }\n\n    if (this._eachValues !== undefined) {\n        value = value\n            ._then(this._eachComplete, undefined, undefined, this, undefined);\n    }\n    value._then(completed, completed, undefined, value, this);\n};\n\nPromise.prototype.reduce = function (fn, initialValue) {\n    return reduce(this, fn, initialValue, null);\n};\n\nPromise.reduce = function (promises, fn, initialValue, _each) {\n    return reduce(promises, fn, initialValue, _each);\n};\n\nfunction completed(valueOrReason, array) {\n    if (this.isFulfilled()) {\n        array._resolve(valueOrReason);\n    } else {\n        array._reject(valueOrReason);\n    }\n}\n\nfunction reduce(promises, fn, initialValue, _each) {\n    if (typeof fn !== \"function\") {\n        return apiRejection(FUNCTION_ERROR + util.classString(fn));\n    }\n    var array = new ReductionPromiseArray(promises, fn, initialValue, _each);\n    return array.promise();\n}\n\nfunction gotAccum(accum) {\n    this.accum = accum;\n    this.array._gotAccum(accum);\n    var value = tryConvertToPromise(this.value, this.array._promise);\n    if (value instanceof Promise) {\n        this.array._currentCancellable = value;\n        return value._then(gotValue, undefined, undefined, this, undefined);\n    } else {\n        return gotValue.call(this, value);\n    }\n}\n\nfunction gotValue(value) {\n    var array = this.array;\n    var promise = array._promise;\n    var fn = tryCatch(array._fn);\n    promise._pushContext();\n    var ret;\n    if (array._eachValues !== undefined) {\n        ret = fn.call(promise._boundValue(), value, this.index, this.length);\n    } else {\n        ret = fn.call(promise._boundValue(),\n                              this.accum, value, this.index, this.length);\n    }\n    if (ret instanceof Promise) {\n        array._currentCancellable = ret;\n    }\n    var promiseCreated = promise._popContext();\n    debug.checkForgottenReturns(\n        ret,\n        promiseCreated,\n        array._eachValues !== undefined ? \"Promise.each\" : \"Promise.reduce\",\n        promise\n    );\n    return ret;\n}\n};\n"
  },
  {
    "path": "src/schedule.js",
    "content": "\"use strict\";\nvar util = require(\"./util\");\nvar schedule;\nvar noAsyncScheduler = function() {\n    throw new Error(NO_ASYNC_SCHEDULER);\n};\nvar NativePromise = util.getNativePromise();\n// This file figures out which scheduler to use for Bluebird. It normalizes\n// async task scheduling across target platforms. Note that not all JS target\n// platforms come supported. The scheduler is overridable with `setScheduler`.\n\n// Our scheduler for Node.js/io.js is setImmediate for recent\n// versions of node because of macrotask semantics.\n// The `typeof` check is for an edge case with nw.js.\nif (util.isNode && typeof MutationObserver === \"undefined\") {\n    var GlobalSetImmediate = global.setImmediate;\n    var ProcessNextTick = process.nextTick;\n    schedule = util.isRecentNode\n                ? function(fn) { GlobalSetImmediate.call(global, fn); }\n                : function(fn) { ProcessNextTick.call(process, fn); };\n} else if (typeof NativePromise === \"function\" &&\n           typeof NativePromise.resolve === \"function\") {\n    var nativePromise = NativePromise.resolve();\n    schedule = function(fn) {\n        nativePromise.then(fn);\n    };\n// Outside of Node, we're using MutationObservers because they provide low\n// latency. The second check is to guard against iOS standalone apps which\n// do not fire DOM mutation events for some reason on iOS 8.3+ and cordova\n// apps which have the same bug but are not `.navigator.standalone`\n} else if ((typeof MutationObserver !== \"undefined\") &&\n          !(typeof window !== \"undefined\" &&\n            window.navigator &&\n            (window.navigator.standalone || window.cordova)) &&\n          (\"classList\" in document.documentElement)) {\n    schedule = (function() {\n        // Using 2 mutation observers to batch multiple updates into one.\n        var div = document.createElement(\"div\");\n        var opts = {attributes: true};\n        var toggleScheduled = false;\n        var div2 = document.createElement(\"div\");\n        var o2 = new MutationObserver(function() {\n            div.classList.toggle(\"foo\");\n            toggleScheduled = false;\n        });\n        o2.observe(div2, opts);\n\n        var scheduleToggle = function() {\n            if (toggleScheduled) return;\n            toggleScheduled = true;\n            div2.classList.toggle(\"foo\");\n        };\n\n        return function schedule(fn) {\n            var o = new MutationObserver(function() {\n                o.disconnect();\n                fn();\n            });\n            o.observe(div, opts);\n            scheduleToggle();\n        };\n    })();\n// setImmediate has higher latency but is still pretty good. This is useful for\n// cases where MutationObserver is not defined (older IE, for example).\n} else if (typeof setImmediate !== \"undefined\") {\n    schedule = function (fn) {\n        setImmediate(fn);\n    };\n// setTimeout also works, it has the most latency but it does the trick.\n} else if (typeof setTimeout !== \"undefined\") {\n    schedule = function (fn) {\n        setTimeout(fn, 0);\n    };\n} else {\n// Do __Not__ default to a sync scheduler, that would break Promises/A+\n// compliancy and cause race conditions.\n    schedule = noAsyncScheduler;\n}\nmodule.exports = schedule;\n"
  },
  {
    "path": "src/settle.js",
    "content": "\"use strict\";\nmodule.exports =\n    function(Promise, PromiseArray, debug) {\nvar ASSERT = require(\"./assert\");\nvar PromiseInspection = Promise.PromiseInspection;\nvar util = require(\"./util\");\n\nfunction SettledPromiseArray(values) {\n    this.constructor$(values);\n}\nutil.inherits(SettledPromiseArray, PromiseArray);\n\nSettledPromiseArray.prototype._promiseResolved = function (index, inspection) {\n    ASSERT(typeof index === \"number\");\n    this._values[index] = inspection;\n    var totalResolved = ++this._totalResolved;\n    if (totalResolved >= this._length) {\n        this._resolve(this._values);\n        return true;\n    }\n    return false;\n};\n\n//override\nSettledPromiseArray.prototype._promiseFulfilled = function (value, index) {\n    ASSERT(!this._isResolved());\n    ASSERT(typeof index === \"number\");\n    var ret = new PromiseInspection();\n    ret._bitField = IS_FULFILLED;\n    ret._settledValueField = value;\n    return this._promiseResolved(index, ret);\n};\n//override\nSettledPromiseArray.prototype._promiseRejected = function (reason, index) {\n    ASSERT(!this._isResolved());\n    ASSERT(typeof index === \"number\");\n    var ret = new PromiseInspection();\n    ret._bitField = IS_REJECTED;\n    ret._settledValueField = reason;\n    return this._promiseResolved(index, ret);\n};\n\nPromise.settle = function (promises) {\n    debug.deprecated(\".settle()\", \".reflect()\");\n    return new SettledPromiseArray(promises).promise();\n};\n\nPromise.allSettled = function (promises) {\n    return new SettledPromiseArray(promises).promise();\n};\n\nPromise.prototype.settle = function () {\n    return Promise.settle(this);\n};\n};\n"
  },
  {
    "path": "src/some.js",
    "content": "\"use strict\";\nmodule.exports =\nfunction(Promise, PromiseArray, apiRejection) {\nvar ASSERT = require(\"./assert\");\nvar util = require(\"./util\");\nvar RangeError = require(\"./errors\").RangeError;\nvar AggregateError = require(\"./errors\").AggregateError;\nvar isArray = util.isArray;\nvar CANCELLATION = {};\n\n\nfunction SomePromiseArray(values) {\n    this.constructor$(values);\n    this._howMany = 0;\n    this._unwrap = false;\n    this._initialized = false;\n}\nutil.inherits(SomePromiseArray, PromiseArray);\n\nSomePromiseArray.prototype._init = function () {\n    if (!this._initialized) {\n        return;\n    }\n    if (this._howMany === 0) {\n        this._resolve([]);\n        return;\n    }\n    this._init$(undefined, RESOLVE_CALL_METHOD);\n    var isArrayResolved = isArray(this._values);\n    if (!this._isResolved() &&\n        isArrayResolved &&\n        this._howMany > this._canPossiblyFulfill()) {\n        this._reject(this._getRangeError(this.length()));\n    }\n};\n\nSomePromiseArray.prototype.init = function () {\n    this._initialized = true;\n    this._init();\n};\n\nSomePromiseArray.prototype.setUnwrap = function () {\n    this._unwrap = true;\n};\n\nSomePromiseArray.prototype.howMany = function () {\n    return this._howMany;\n};\n\nSomePromiseArray.prototype.setHowMany = function (count) {\n    ASSERT(!this._isResolved());\n    this._howMany = count;\n};\n\n//override\nSomePromiseArray.prototype._promiseFulfilled = function (value) {\n    ASSERT(!this._isResolved());\n    this._addFulfilled(value);\n    if (this._fulfilled() === this.howMany()) {\n        this._values.length = this.howMany();\n        if (this.howMany() === 1 && this._unwrap) {\n            this._resolve(this._values[0]);\n        } else {\n            this._resolve(this._values);\n        }\n        return true;\n    }\n    return false;\n\n};\n//override\nSomePromiseArray.prototype._promiseRejected = function (reason) {\n    ASSERT(!this._isResolved());\n    this._addRejected(reason);\n    return this._checkOutcome();\n};\n\n//override\nSomePromiseArray.prototype._promiseCancelled = function () {\n    if (this._values instanceof Promise || this._values == null) {\n        return this._cancel();\n    }\n    ASSERT(!this._isResolved());\n    this._addRejected(CANCELLATION);\n    return this._checkOutcome();\n};\n\nSomePromiseArray.prototype._checkOutcome = function() {\n    if (this.howMany() > this._canPossiblyFulfill()) {\n        var e = new AggregateError();\n        for (var i = this.length(); i < this._values.length; ++i) {\n            if (this._values[i] !== CANCELLATION) {\n                e.push(this._values[i]);\n            }\n        }\n        if (e.length > 0) {\n            this._reject(e);\n        } else {\n            this._cancel();\n        }\n        return true;\n    }\n    return false;\n};\n\nSomePromiseArray.prototype._fulfilled = function () {\n    return this._totalResolved;\n};\n\nSomePromiseArray.prototype._rejected = function () {\n    return this._values.length - this.length();\n};\n\n//Use the same array past .length() to store rejection reasons\nSomePromiseArray.prototype._addRejected = function (reason) {\n    this._values.push(reason);\n};\n\nSomePromiseArray.prototype._addFulfilled = function (value) {\n    this._values[this._totalResolved++] = value;\n};\n\nSomePromiseArray.prototype._canPossiblyFulfill = function () {\n    return this.length() - this._rejected();\n};\n\nSomePromiseArray.prototype._getRangeError = function (count) {\n    var message = \"Input array must contain at least \" +\n            this._howMany + \" items but contains only \" + count + \" items\";\n    return new RangeError(message);\n};\n\nSomePromiseArray.prototype._resolveEmptyArray = function () {\n    this._reject(this._getRangeError(0));\n};\n\nfunction some(promises, howMany) {\n    if ((howMany | 0) !== howMany || howMany < 0) {\n        return apiRejection(POSITIVE_INTEGER_ERROR);\n    }\n    var ret = new SomePromiseArray(promises);\n    var promise = ret.promise();\n    ASSERT(promise.isPending());\n    ASSERT(ret instanceof SomePromiseArray);\n    ret.setHowMany(howMany);\n    ret.init();\n    return promise;\n}\n\nPromise.some = function (promises, howMany) {\n    return some(promises, howMany);\n};\n\nPromise.prototype.some = function (howMany) {\n    return some(this, howMany);\n};\n\nPromise._SomePromiseArray = SomePromiseArray;\n};\n"
  },
  {
    "path": "src/synchronous_inspection.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise) {\nfunction PromiseInspection(promise) {\n    if (promise !== undefined) {\n        promise = promise._target();\n        this._bitField = promise._bitField;\n        this._settledValueField = promise._isFateSealed()\n            ? promise._settledValue() : undefined;\n    }\n    else {\n        this._bitField = 0;\n        this._settledValueField = undefined;\n    }\n}\n\nPromiseInspection.prototype._settledValue = function() {\n    return this._settledValueField;\n};\n\nvar value = PromiseInspection.prototype.value = function () {\n    if (!this.isFulfilled()) {\n        throw new TypeError(INSPECTION_VALUE_ERROR);\n    }\n    return this._settledValue();\n};\n\nvar reason = PromiseInspection.prototype.error =\nPromiseInspection.prototype.reason = function () {\n    if (!this.isRejected()) {\n        throw new TypeError(INSPECTION_REASON_ERROR);\n    }\n    return this._settledValue();\n};\n\nvar isFulfilled = PromiseInspection.prototype.isFulfilled = function() {\n    return (this._bitField & IS_FULFILLED) !== 0;\n};\n\nvar isRejected = PromiseInspection.prototype.isRejected = function () {\n    return (this._bitField & IS_REJECTED) !== 0;\n};\n\nvar isPending = PromiseInspection.prototype.isPending = function () {\n    return (this._bitField & IS_REJECTED_OR_FULFILLED_OR_CANCELLED) === 0;\n};\n\nvar isResolved = PromiseInspection.prototype.isResolved = function () {\n    return (this._bitField & IS_REJECTED_OR_FULFILLED) !== 0;\n};\n\nPromiseInspection.prototype.isCancelled = function() {\n    return (this._bitField & IS_CANCELLED_OR_WILL_BE_CANCELLED) !== 0;\n};\n\nPromise.prototype.__isCancelled = function() {\n    return (this._bitField & IS_CANCELLED) === IS_CANCELLED;\n};\n\nPromise.prototype._isCancelled = function() {\n    return this._target().__isCancelled();\n};\n\nPromise.prototype.isCancelled = function() {\n    return (this._target()._bitField & IS_CANCELLED_OR_WILL_BE_CANCELLED) !== 0;\n};\n\nPromise.prototype.isPending = function() {\n    return isPending.call(this._target());\n};\n\nPromise.prototype.isRejected = function() {\n    return isRejected.call(this._target());\n};\n\nPromise.prototype.isFulfilled = function() {\n    return isFulfilled.call(this._target());\n};\n\nPromise.prototype.isResolved = function() {\n    return isResolved.call(this._target());\n};\n\nPromise.prototype.value = function() {\n    return value.call(this._target());\n};\n\nPromise.prototype.reason = function() {\n    var target = this._target();\n    target._unsetRejectionIsUnhandled();\n    return reason.call(target);\n};\n\nPromise.prototype._value = function() {\n    return this._settledValue();\n};\n\nPromise.prototype._reason = function() {\n    this._unsetRejectionIsUnhandled();\n    return this._settledValue();\n};\n\nPromise.PromiseInspection = PromiseInspection;\n};\n"
  },
  {
    "path": "src/thenables.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise, INTERNAL) {\nvar ASSERT = require(\"./assert\");\nvar util = require(\"./util\");\nvar errorObj = util.errorObj;\nvar isObject = util.isObject;\n\nfunction tryConvertToPromise(obj, context) {\n    if (isObject(obj)) {\n        if (obj instanceof Promise) return obj;\n        var then = getThen(obj);\n        if (then === errorObj) {\n            if (context) context._pushContext();\n            var ret = Promise.reject(then.e);\n            if (context) context._popContext();\n            return ret;\n        } else if (typeof then === \"function\") {\n            //Make casting from another bluebird fast\n            if (isAnyBluebirdPromise(obj)) {\n                var ret = new Promise(INTERNAL);\n                obj._then(\n                    ret._fulfill,\n                    ret._reject,\n                    undefined,\n                    ret,\n                    null\n                );\n                return ret;\n            }\n            return doThenable(obj, then, context);\n        }\n    }\n    return obj;\n}\n\nfunction doGetThen(obj) {\n    return obj.then;\n}\n\nfunction getThen(obj) {\n    try {\n        return doGetThen(obj);\n    } catch (e) {\n        errorObj.e = e;\n        return errorObj;\n    }\n}\n\nvar hasProp = {}.hasOwnProperty;\nfunction isAnyBluebirdPromise(obj) {\n    try {\n        return hasProp.call(obj, \"_promise0\");\n    } catch (e) {\n        return false;\n    }\n}\n\nfunction doThenable(x, then, context) {\n    ASSERT(typeof then === \"function\");\n    var promise = new Promise(INTERNAL);\n    var ret = promise;\n    if (context) context._pushContext();\n    promise._captureStackTrace();\n    if (context) context._popContext();\n    var synchronous = true;\n    var result = util.tryCatch(then).call(x, resolve, reject);\n    synchronous = false;\n\n    if (promise && result === errorObj) {\n        promise._rejectCallback(result.e, true, true);\n        promise = null;\n    }\n\n    function resolve(value) {\n        if (!promise) return;\n        promise._resolveCallback(value);\n        promise = null;\n    }\n\n    function reject(reason) {\n        if (!promise) return;\n        promise._rejectCallback(reason, synchronous, true);\n        promise = null;\n    }\n    return ret;\n}\n\nreturn tryConvertToPromise;\n};\n"
  },
  {
    "path": "src/timers.js",
    "content": "\"use strict\";\nmodule.exports = function(Promise, INTERNAL, debug) {\nvar util = require(\"./util\");\nvar TimeoutError = Promise.TimeoutError;\n\nfunction HandleWrapper(handle)  {\n    this.handle = handle;\n}\n\nHandleWrapper.prototype._resultCancelled = function() {\n    clearTimeout(this.handle);\n};\n\nvar afterValue = function(value) { return delay(+this).thenReturn(value); };\nvar delay = Promise.delay = function (ms, value) {\n    var ret;\n    var handle;\n    if (value !== undefined) {\n        ret = Promise.resolve(value)\n                ._then(afterValue, null, null, ms, undefined);\n        if (debug.cancellation() && value instanceof Promise) {\n            ret._setOnCancel(value);\n        }\n    } else {\n        ret = new Promise(INTERNAL);\n        handle = setTimeout(function() { ret._fulfill(); }, +ms);\n        if (debug.cancellation()) {\n            ret._setOnCancel(new HandleWrapper(handle));\n        }\n        ret._captureStackTrace();\n    }\n    ret._setAsyncGuaranteed();\n    return ret;\n};\n\nPromise.prototype.delay = function (ms) {\n    return delay(ms, this);\n};\n\nvar afterTimeout = function (promise, message, parent) {\n    var err;\n    if (typeof message !== \"string\") {\n        if (message instanceof Error) {\n            err = message;\n        } else {\n            err = new TimeoutError(TIMEOUT_ERROR);\n        }\n    } else {\n        err = new TimeoutError(message);\n    }\n    util.markAsOriginatingFromRejection(err);\n    promise._attachExtraTrace(err);\n    promise._reject(err);\n\n    if (parent != null) {\n        parent.cancel();\n    }\n};\n\nfunction successClear(value) {\n    clearTimeout(this.handle);\n    return value;\n}\n\nfunction failureClear(reason) {\n    clearTimeout(this.handle);\n    throw reason;\n}\n\nPromise.prototype.timeout = function (ms, message) {\n    ms = +ms;\n    var ret, parent;\n\n    var handleWrapper = new HandleWrapper(setTimeout(function timeoutTimeout() {\n        if (ret.isPending()) {\n            afterTimeout(ret, message, parent);\n        }\n    }, ms));\n\n    if (debug.cancellation()) {\n        parent = this.then();\n        ret = parent._then(successClear, failureClear,\n                            undefined, handleWrapper, undefined);\n        ret._setOnCancel(handleWrapper);\n    } else {\n        ret = this._then(successClear, failureClear,\n                            undefined, handleWrapper, undefined);\n    }\n\n    return ret;\n};\n\n};\n"
  },
  {
    "path": "src/using.js",
    "content": "\"use strict\";\nmodule.exports = function (Promise, apiRejection, tryConvertToPromise,\n    createContext, INTERNAL, debug) {\n    var util = require(\"./util\");\n    var TypeError = require(\"./errors\").TypeError;\n    var inherits = require(\"./util\").inherits;\n    var errorObj = util.errorObj;\n    var tryCatch = util.tryCatch;\n    var NULL = {};\n\n    function thrower(e) {\n        setTimeout(function(){throw e;}, 0);\n    }\n\n    function castPreservingDisposable(thenable) {\n        var maybePromise = tryConvertToPromise(thenable);\n        if (maybePromise !== thenable &&\n            typeof thenable._isDisposable === \"function\" &&\n            typeof thenable._getDisposer === \"function\" &&\n            thenable._isDisposable()) {\n            maybePromise._setDisposable(thenable._getDisposer());\n        }\n        return maybePromise;\n    }\n    function dispose(resources, inspection) {\n        var i = 0;\n        var len = resources.length;\n        var ret = new Promise(INTERNAL);\n        function iterator() {\n            if (i >= len) return ret._fulfill();\n            var maybePromise = castPreservingDisposable(resources[i++]);\n            if (maybePromise instanceof Promise &&\n                maybePromise._isDisposable()) {\n                try {\n                    maybePromise = tryConvertToPromise(\n                        maybePromise._getDisposer().tryDispose(inspection),\n                        resources.promise);\n                } catch (e) {\n                    return thrower(e);\n                }\n                if (maybePromise instanceof Promise) {\n                    return maybePromise._then(iterator, thrower,\n                                              null, null, null);\n                }\n            }\n            iterator();\n        }\n        iterator();\n        return ret;\n    }\n\n    function Disposer(data, promise, context) {\n        this._data = data;\n        this._promise = promise;\n        this._context = context;\n    }\n\n    Disposer.prototype.data = function () {\n        return this._data;\n    };\n\n    Disposer.prototype.promise = function () {\n        return this._promise;\n    };\n\n    Disposer.prototype.resource = function () {\n        if (this.promise().isFulfilled()) {\n            return this.promise().value();\n        }\n        return NULL;\n    };\n\n    Disposer.prototype.tryDispose = function(inspection) {\n        var resource = this.resource();\n        var context = this._context;\n        if (context !== undefined) context._pushContext();\n        var ret = resource !== NULL\n            ? this.doDispose(resource, inspection) : null;\n        if (context !== undefined) context._popContext();\n        this._promise._unsetDisposable();\n        this._data = null;\n        return ret;\n    };\n\n    Disposer.isDisposer = function (d) {\n        return (d != null &&\n                typeof d.resource === \"function\" &&\n                typeof d.tryDispose === \"function\");\n    };\n\n    function FunctionDisposer(fn, promise, context) {\n        this.constructor$(fn, promise, context);\n    }\n    inherits(FunctionDisposer, Disposer);\n\n    FunctionDisposer.prototype.doDispose = function (resource, inspection) {\n        var fn = this.data();\n        return fn.call(resource, resource, inspection);\n    };\n\n    function maybeUnwrapDisposer(value) {\n        if (Disposer.isDisposer(value)) {\n            this.resources[this.index]._setDisposable(value);\n            return value.promise();\n        }\n        return value;\n    }\n\n    function ResourceList(length) {\n        this.length = length;\n        this.promise = null;\n        this[length-1] = null;\n    }\n\n    ResourceList.prototype._resultCancelled = function() {\n        var len = this.length;\n        for (var i = 0; i < len; ++i) {\n            var item = this[i];\n            if (item instanceof Promise) {\n                item.cancel();\n            }\n        }\n    };\n\n    Promise.using = function () {\n        var len = arguments.length;\n        if (len < 2) return apiRejection(\n                        \"you must pass at least 2 arguments to Promise.using\");\n        var fn = arguments[len - 1];\n        if (typeof fn !== \"function\") {\n            return apiRejection(FUNCTION_ERROR + util.classString(fn));\n        }\n        var input;\n        var spreadArgs = true;\n        if (len === 2 && Array.isArray(arguments[0])) {\n            input = arguments[0];\n            len = input.length;\n            spreadArgs = false;\n        } else {\n            input = arguments;\n            len--;\n        }\n        var resources = new ResourceList(len);\n        for (var i = 0; i < len; ++i) {\n            var resource = input[i];\n            if (Disposer.isDisposer(resource)) {\n                var disposer = resource;\n                resource = resource.promise();\n                resource._setDisposable(disposer);\n            } else {\n                var maybePromise = tryConvertToPromise(resource);\n                if (maybePromise instanceof Promise) {\n                    resource =\n                        maybePromise._then(maybeUnwrapDisposer, null, null, {\n                            resources: resources,\n                            index: i\n                    }, undefined);\n                }\n            }\n            resources[i] = resource;\n        }\n\n        var reflectedResources = new Array(resources.length);\n        for (var i = 0; i < reflectedResources.length; ++i) {\n            reflectedResources[i] = Promise.resolve(resources[i]).reflect();\n        }\n\n        var resultPromise = Promise.all(reflectedResources)\n            .then(function(inspections) {\n                for (var i = 0; i < inspections.length; ++i) {\n                    var inspection = inspections[i];\n                    if (inspection.isRejected()) {\n                        errorObj.e = inspection.error();\n                        return errorObj;\n                    } else if (!inspection.isFulfilled()) {\n                        resultPromise.cancel();\n                        return;\n                    }\n                    inspections[i] = inspection.value();\n                }\n                promise._pushContext();\n\n                fn = tryCatch(fn);\n                var ret = spreadArgs\n                    ? fn.apply(undefined, inspections) : fn(inspections);\n                var promiseCreated = promise._popContext();\n                debug.checkForgottenReturns(\n                    ret, promiseCreated, \"Promise.using\", promise);\n                return ret;\n            });\n\n        var promise = resultPromise.lastly(function() {\n            var inspection = new Promise.PromiseInspection(resultPromise);\n            return dispose(resources, inspection);\n        });\n        resources.promise = promise;\n        promise._setOnCancel(resources);\n        return promise;\n    };\n\n    Promise.prototype._setDisposable = function (disposer) {\n        this._bitField = this._bitField | IS_DISPOSABLE;\n        this._disposer = disposer;\n    };\n\n    Promise.prototype._isDisposable = function () {\n        return (this._bitField & IS_DISPOSABLE) > 0;\n    };\n\n    Promise.prototype._getDisposer = function () {\n        return this._disposer;\n    };\n\n    Promise.prototype._unsetDisposable = function () {\n        this._bitField = this._bitField & (~IS_DISPOSABLE);\n        this._disposer = undefined;\n    };\n\n    Promise.prototype.disposer = function (fn) {\n        if (typeof fn === \"function\") {\n            return new FunctionDisposer(fn, this, createContext());\n        }\n        throw new TypeError();\n    };\n\n};\n"
  },
  {
    "path": "src/util.js",
    "content": "\"use strict\";\nvar ASSERT = require(\"./assert\");\nvar es5 = require(\"./es5\");\n// Assume CSP if browser\nvar canEvaluate = typeof navigator == \"undefined\";\n\n//Try catch is not supported in optimizing\n//compiler, so it is isolated\nvar errorObj = {e: {}};\nvar tryCatchTarget;\nvar globalObject = typeof self !== \"undefined\" ? self :\n    typeof window !== \"undefined\" ? window :\n    typeof global !== \"undefined\" ? global :\n    this !== undefined ? this : null;\n\nfunction tryCatcher() {\n    try {\n        var target = tryCatchTarget;\n        tryCatchTarget = null;\n        return target.apply(this, arguments);\n    } catch (e) {\n        errorObj.e = e;\n        return errorObj;\n    }\n}\nfunction tryCatch(fn) {\n    ASSERT(typeof fn === \"function\");\n    tryCatchTarget = fn;\n    return tryCatcher;\n}\n\n//Un-magical enough that using this doesn't prevent\n//extending classes from outside using any convention\nvar inherits = function(Child, Parent) {\n    var hasProp = {}.hasOwnProperty;\n\n    function T() {\n        this.constructor = Child;\n        this.constructor$ = Parent;\n        for (var propertyName in Parent.prototype) {\n            if (hasProp.call(Parent.prototype, propertyName) &&\n                propertyName.charAt(propertyName.length-1) !== \"$\"\n           ) {\n                this[propertyName + \"$\"] = Parent.prototype[propertyName];\n            }\n        }\n    }\n    T.prototype = Parent.prototype;\n    Child.prototype = new T();\n    return Child.prototype;\n};\n\n\nfunction isPrimitive(val) {\n    return val == null || val === true || val === false ||\n        typeof val === \"string\" || typeof val === \"number\";\n\n}\n\nfunction isObject(value) {\n    return typeof value === \"function\" ||\n           typeof value === \"object\" && value !== null;\n}\n\nfunction maybeWrapAsError(maybeError) {\n    if (!isPrimitive(maybeError)) return maybeError;\n\n    return new Error(safeToString(maybeError));\n}\n\nfunction withAppended(target, appendee) {\n    var len = target.length;\n    var ret = new Array(len + 1);\n    var i;\n    for (i = 0; i < len; ++i) {\n        ret[i] = target[i];\n    }\n    ret[i] = appendee;\n    return ret;\n}\n\nfunction getDataPropertyOrDefault(obj, key, defaultValue) {\n    if (es5.isES5) {\n        var desc = Object.getOwnPropertyDescriptor(obj, key);\n\n        if (desc != null) {\n            return desc.get == null && desc.set == null\n                    ? desc.value\n                    : defaultValue;\n        }\n    } else {\n        return {}.hasOwnProperty.call(obj, key) ? obj[key] : undefined;\n    }\n}\n\nfunction notEnumerableProp(obj, name, value) {\n    if (isPrimitive(obj)) return obj;\n    var descriptor = {\n        value: value,\n        configurable: true,\n        enumerable: false,\n        writable: true\n    };\n    es5.defineProperty(obj, name, descriptor);\n    return obj;\n}\n\nfunction thrower(r) {\n    throw r;\n}\n\nvar inheritedDataKeys = (function() {\n    var excludedPrototypes = [\n        Array.prototype,\n        Object.prototype,\n        Function.prototype\n    ];\n\n    var isExcludedProto = function(val) {\n        for (var i = 0; i < excludedPrototypes.length; ++i) {\n            if (excludedPrototypes[i] === val) {\n                return true;\n            }\n        }\n        return false;\n    };\n\n    if (es5.isES5) {\n        var getKeys = Object.getOwnPropertyNames;\n        return function(obj) {\n            var ret = [];\n            var visitedKeys = Object.create(null);\n            while (obj != null && !isExcludedProto(obj)) {\n                var keys;\n                try {\n                    keys = getKeys(obj);\n                } catch (e) {\n                    return ret;\n                }\n                for (var i = 0; i < keys.length; ++i) {\n                    var key = keys[i];\n                    if (visitedKeys[key]) continue;\n                    visitedKeys[key] = true;\n                    var desc = Object.getOwnPropertyDescriptor(obj, key);\n                    if (desc != null && desc.get == null && desc.set == null) {\n                        ret.push(key);\n                    }\n                }\n                obj = es5.getPrototypeOf(obj);\n            }\n            return ret;\n        };\n    } else {\n        var hasProp = {}.hasOwnProperty;\n        return function(obj) {\n            if (isExcludedProto(obj)) return [];\n            var ret = [];\n\n            /*jshint forin:false */\n            enumeration: for (var key in obj) {\n                if (hasProp.call(obj, key)) {\n                    ret.push(key);\n                } else {\n                    for (var i = 0; i < excludedPrototypes.length; ++i) {\n                        if (hasProp.call(excludedPrototypes[i], key)) {\n                            continue enumeration;\n                        }\n                    }\n                    ret.push(key);\n                }\n            }\n            return ret;\n        };\n    }\n\n})();\n\nvar thisAssignmentPattern = /this\\s*\\.\\s*\\S+\\s*=/;\nfunction isClass(fn) {\n    try {\n        if (typeof fn === \"function\") {\n            var keys = es5.names(fn.prototype);\n\n            var hasMethods = es5.isES5 && keys.length > 1;\n            var hasMethodsOtherThanConstructor = keys.length > 0 &&\n                !(keys.length === 1 && keys[0] === \"constructor\");\n            var hasThisAssignmentAndStaticMethods =\n                thisAssignmentPattern.test(fn + \"\") && es5.names(fn).length > 0;\n\n            if (hasMethods || hasMethodsOtherThanConstructor ||\n                hasThisAssignmentAndStaticMethods) {\n                return true;\n            }\n        }\n        return false;\n    } catch (e) {\n        return false;\n    }\n}\n\nvar fastProto = null;\nvar kInlineCacheCutoff = 10;\nfunction FastObject(o) {\n    if (fastProto !== null && typeof fastProto.property) {\n        var result = fastProto;\n        fastProto = FastObject.prototype = null;\n        return result;\n    }\n    fastProto = FastObject.prototype = o == null ? Object.create(null) : o;\n    return new FastObject();\n}\n\n// Initialize the inline property cache of FastObject\nfor(var i = 0; i <= kInlineCacheCutoff; i++) {\n    FastObject({});\n}\n\n\nfunction toFastProperties(obj) {\n    FastObject(obj);\n    ASSERT(\"%HasFastProperties\", true, obj);\n    return obj;\n}\n\nvar rident = /^[a-z$_][a-z$_0-9]*$/i;\nfunction isIdentifier(str) {\n    return rident.test(str);\n}\n\nfunction filledRange(count, prefix, suffix) {\n    var ret = new Array(count);\n    for(var i = 0; i < count; ++i) {\n        ret[i] = prefix + i + suffix;\n    }\n    return ret;\n}\n\nfunction safeToString(obj) {\n    try {\n        return obj + \"\";\n    } catch (e) {\n        return \"[no string representation]\";\n    }\n}\n\nfunction isError(obj) {\n    return obj instanceof Error ||\n        (obj !== null &&\n           typeof obj === \"object\" &&\n           typeof obj.message === \"string\" &&\n           typeof obj.name === \"string\");\n}\n\nfunction markAsOriginatingFromRejection(e) {\n    try {\n        notEnumerableProp(e, OPERATIONAL_ERROR_KEY, true);\n    }\n    catch(ignore) {}\n}\n\nfunction originatesFromRejection(e) {\n    if (e == null) return false;\n    return ((e instanceof Error[BLUEBIRD_ERRORS].OperationalError) ||\n        e[OPERATIONAL_ERROR_KEY] === true);\n}\n\nfunction canAttachTrace(obj) {\n    return isError(obj) && es5.propertyIsWritable(obj, \"stack\");\n}\n\nvar ensureErrorObject = (function() {\n    if (!(\"stack\" in new Error())) {\n        return function(value) {\n            if (canAttachTrace(value)) return value;\n            try {throw new Error(safeToString(value));}\n            catch(err) {return err;}\n        };\n    } else {\n        return function(value) {\n            if (canAttachTrace(value)) return value;\n            return new Error(safeToString(value));\n        };\n    }\n})();\n\nfunction classString(obj) {\n    return {}.toString.call(obj);\n}\n\nfunction copyDescriptors(from, to, filter) {\n    var keys = es5.names(from);\n    for (var i = 0; i < keys.length; ++i) {\n        var key = keys[i];\n        if (filter(key)) {\n            try {\n                es5.defineProperty(to, key, es5.getDescriptor(from, key));\n            } catch (ignore) {}\n        }\n    }\n}\n\nvar asArray = function(v) {\n    if (es5.isArray(v)) {\n        return v;\n    }\n    return null;\n};\n\nif (typeof Symbol !== \"undefined\" && Symbol.iterator) {\n    var ArrayFrom = typeof Array.from === \"function\" ? function(v) {\n        return Array.from(v);\n    } : function(v) {\n        var ret = [];\n        var it = v[Symbol.iterator]();\n        var itResult;\n        while (!((itResult = it.next()).done)) {\n            ret.push(itResult.value);\n        }\n        return ret;\n    };\n\n    asArray = function(v) {\n        if (es5.isArray(v)) {\n            return v;\n        } else if (v != null && typeof v[Symbol.iterator] === \"function\") {\n            return ArrayFrom(v);\n        }\n        return null;\n    };\n}\n\nvar isNode = typeof process !== \"undefined\" &&\n        classString(process).toLowerCase() === \"[object process]\";\n\nvar hasEnvVariables = typeof process !== \"undefined\" &&\n    typeof process.env !== \"undefined\";\n\nfunction env(key) {\n    return hasEnvVariables ? process.env[key] : undefined;\n}\n\nfunction getNativePromise() {\n    if (typeof Promise === \"function\") {\n        try {\n            var promise = new Promise(function(){});\n            if (classString(promise) === \"[object Promise]\") {\n                return Promise;\n            }\n        } catch (e) {}\n    }\n}\n\nvar reflectHandler;\nfunction contextBind(ctx, cb) {\n    if (ctx === null ||\n        typeof cb !== \"function\" ||\n        cb === reflectHandler) {\n        return cb;\n    }\n\n    if (ctx.domain !== null) {\n        cb = ctx.domain.bind(cb);\n    }\n\n    var async = ctx.async;\n    if (async !== null) {\n        var old = cb;\n        cb = function() {\n            INLINE_SLICE_LEFT_PADDED(2, args, arguments);\n            args[0] = old;\n            args[1] = this;\n            return async.runInAsyncScope.apply(async, args);\n        };\n    }\n    return cb;\n}\n\nvar ret = {\n    setReflectHandler: function(fn) {\n        reflectHandler = fn;\n    },\n    isClass: isClass,\n    isIdentifier: isIdentifier,\n    inheritedDataKeys: inheritedDataKeys,\n    getDataPropertyOrDefault: getDataPropertyOrDefault,\n    thrower: thrower,\n    isArray: es5.isArray,\n    asArray: asArray,\n    notEnumerableProp: notEnumerableProp,\n    isPrimitive: isPrimitive,\n    isObject: isObject,\n    isError: isError,\n    canEvaluate: canEvaluate,\n    errorObj: errorObj,\n    tryCatch: tryCatch,\n    inherits: inherits,\n    withAppended: withAppended,\n    maybeWrapAsError: maybeWrapAsError,\n    toFastProperties: toFastProperties,\n    filledRange: filledRange,\n    toString: safeToString,\n    canAttachTrace: canAttachTrace,\n    ensureErrorObject: ensureErrorObject,\n    originatesFromRejection: originatesFromRejection,\n    markAsOriginatingFromRejection: markAsOriginatingFromRejection,\n    classString: classString,\n    copyDescriptors: copyDescriptors,\n    isNode: isNode,\n    hasEnvVariables: hasEnvVariables,\n    env: env,\n    global: globalObject,\n    getNativePromise: getNativePromise,\n    contextBind: contextBind\n};\nret.isRecentNode = ret.isNode && (function() {\n    var version;\n    if (process.versions && process.versions.node) {\n        version = process.versions.node.split(\".\").map(Number);\n    } else if (process.version) {\n        version = process.version.split(\".\").map(Number);\n    }\n    return (version[0] === 0 && version[1] > 10) || (version[0] > 0);\n})();\nret.nodeSupportsAsyncResource = ret.isNode && (function() {\n    var supportsAsync = false;\n    try {\n        var res = require(\"async_hooks\").AsyncResource;\n        supportsAsync = typeof res.prototype.runInAsyncScope === \"function\";\n    } catch (e) {\n        supportsAsync = false;\n    }\n    return supportsAsync;\n})();\n\nif (ret.isNode) ret.toFastProperties(process);\n\ntry {throw new Error(); } catch (e) {ret.lastLineError = e;}\nmodule.exports = ret;\n"
  },
  {
    "path": "test/browser/es5-sham.js",
    "content": "// Copyright 2009-2012 by contributors, MIT License\n// vim: ts=4 sts=4 sw=4 expandtab\n\n// Module systems magic dance\n(function (definition) {\n    // RequireJS\n    if (typeof define == \"function\") {\n        define(definition);\n    // YUI3\n    } else if (typeof YUI == \"function\") {\n        YUI.add(\"es5-sham\", definition);\n    // CommonJS and <script>\n    } else {\n        definition();\n    }\n})(function () {\n\n\nvar call = Function.prototype.call;\nvar prototypeOfObject = Object.prototype;\nvar owns = call.bind(prototypeOfObject.hasOwnProperty);\n\n// If JS engine supports accessors creating shortcuts.\nvar defineGetter;\nvar defineSetter;\nvar lookupGetter;\nvar lookupSetter;\nvar supportsAccessors;\nif ((supportsAccessors = owns(prototypeOfObject, \"__defineGetter__\"))) {\n    defineGetter = call.bind(prototypeOfObject.__defineGetter__);\n    defineSetter = call.bind(prototypeOfObject.__defineSetter__);\n    lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);\n    lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);\n}\n\n// ES5 15.2.3.2\n// http://es5.github.com/#x15.2.3.2\nif (!Object.getPrototypeOf) {\n    // https://github.com/kriskowal/es5-shim/issues#issue/2\n    // http://ejohn.org/blog/objectgetprototypeof/\n    // recommended by fschaefer on github\n    Object.getPrototypeOf = function getPrototypeOf(object) {\n        return object.__proto__ || (\n            object.constructor\n                ? object.constructor.prototype\n                : prototypeOfObject\n        );\n    };\n}\n\n//ES5 15.2.3.3\n//http://es5.github.com/#x15.2.3.3\n\nfunction doesGetOwnPropertyDescriptorWork(object) {\n    try {\n        object.sentinel = 0;\n        return Object.getOwnPropertyDescriptor(\n                object,\n                \"sentinel\"\n        ).value === 0;\n    } catch (exception) {\n        // returns falsy\n    }\n}\n\n//check whether getOwnPropertyDescriptor works if it's given. Otherwise,\n//shim partially.\nif (Object.defineProperty) {\n    var getOwnPropertyDescriptorWorksOnObject =\n        doesGetOwnPropertyDescriptorWork({});\n    var getOwnPropertyDescriptorWorksOnDom = typeof document == \"undefined\" ||\n    doesGetOwnPropertyDescriptorWork(document.createElement(\"div\"));\n    if (!getOwnPropertyDescriptorWorksOnDom ||\n            !getOwnPropertyDescriptorWorksOnObject\n    ) {\n        var getOwnPropertyDescriptorFallback = Object.getOwnPropertyDescriptor;\n    }\n}\n\nif (!Object.getOwnPropertyDescriptor || getOwnPropertyDescriptorFallback) {\n    var ERR_NON_OBJECT = \"Object.getOwnPropertyDescriptor called on a non-object: \";\n\n    Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {\n        if ((typeof object != \"object\" && typeof object != \"function\") || object === null) {\n            throw new TypeError(ERR_NON_OBJECT + object);\n        }\n\n        // make a valiant attempt to use the real getOwnPropertyDescriptor\n        // for I8's DOM elements.\n        if (getOwnPropertyDescriptorFallback) {\n            try {\n                return getOwnPropertyDescriptorFallback.call(Object, object, property);\n            } catch (exception) {\n                // try the shim if the real one doesn't work\n            }\n        }\n\n        // If object does not owns property return undefined immediately.\n        if (!owns(object, property)) {\n            return;\n        }\n\n        // If object has a property then it's for sure both `enumerable` and\n        // `configurable`.\n        var descriptor =  { enumerable: true, configurable: true };\n\n        // If JS engine supports accessor properties then property may be a\n        // getter or setter.\n        if (supportsAccessors) {\n            // Unfortunately `__lookupGetter__` will return a getter even\n            // if object has own non getter property along with a same named\n            // inherited getter. To avoid misbehavior we temporary remove\n            // `__proto__` so that `__lookupGetter__` will return getter only\n            // if it's owned by an object.\n            var prototype = object.__proto__;\n            object.__proto__ = prototypeOfObject;\n\n            var getter = lookupGetter(object, property);\n            var setter = lookupSetter(object, property);\n\n            // Once we have getter and setter we can put values back.\n            object.__proto__ = prototype;\n\n            if (getter || setter) {\n                if (getter) {\n                    descriptor.get = getter;\n                }\n                if (setter) {\n                    descriptor.set = setter;\n                }\n                // If it was accessor property we're done and return here\n                // in order to avoid adding `value` to the descriptor.\n                return descriptor;\n            }\n        }\n\n        // If we got this far we know that object has an own property that is\n        // not an accessor so we set it as a value and return descriptor.\n        descriptor.value = object[property];\n        descriptor.writable = true;\n        return descriptor;\n    };\n}\n\n// ES5 15.2.3.4\n// http://es5.github.com/#x15.2.3.4\nif (!Object.getOwnPropertyNames) {\n    Object.getOwnPropertyNames = function getOwnPropertyNames(object) {\n        return Object.keys(object);\n    };\n}\n\n// ES5 15.2.3.5\n// http://es5.github.com/#x15.2.3.5\nif (!Object.create) {\n\n    // Contributed by Brandon Benvie, October, 2012\n    var createEmpty;\n    var supportsProto = Object.prototype.__proto__ === null;\n    if (supportsProto || typeof document == 'undefined') {\n        createEmpty = function () {\n            return { \"__proto__\": null };\n        };\n    } else {\n        // In old IE __proto__ can't be used to manually set `null`, nor does\n        // any other method exist to make an object that inherits from nothing,\n        // aside from Object.prototype itself. Instead, create a new global\n        // object and *steal* its Object.prototype and strip it bare. This is\n        // used as the prototype to create nullary objects.\n        createEmpty = function () {\n            var iframe = document.createElement('iframe');\n            var parent = document.body || document.documentElement;\n            iframe.style.display = 'none';\n            parent.appendChild(iframe);\n            iframe.src = 'javascript:';\n            var empty = iframe.contentWindow.Object.prototype;\n            parent.removeChild(iframe);\n            iframe = null;\n            delete empty.constructor;\n            delete empty.hasOwnProperty;\n            delete empty.propertyIsEnumerable;\n            delete empty.isPrototypeOf;\n            delete empty.toLocaleString;\n            delete empty.toString;\n            delete empty.valueOf;\n            empty.__proto__ = null;\n\n            function Empty() {}\n            Empty.prototype = empty;\n            // short-circuit future calls\n            createEmpty = function () {\n                return new Empty();\n            };\n            return new Empty();\n        };\n    }\n\n    Object.create = function create(prototype, properties) {\n\n        var object;\n        function Type() {}  // An empty constructor.\n\n        if (prototype === null) {\n            object = createEmpty();\n        } else {\n            if (typeof prototype !== \"object\" && typeof prototype !== \"function\") {\n                // In the native implementation `parent` can be `null`\n                // OR *any* `instanceof Object`  (Object|Function|Array|RegExp|etc)\n                // Use `typeof` tho, b/c in old IE, DOM elements are not `instanceof Object`\n                // like they are in modern browsers. Using `Object.create` on DOM elements\n                // is...err...probably inappropriate, but the native version allows for it.\n                throw new TypeError(\"Object prototype may only be an Object or null\"); // same msg as Chrome\n            }\n            Type.prototype = prototype;\n            object = new Type();\n            // IE has no built-in implementation of `Object.getPrototypeOf`\n            // neither `__proto__`, but this manually setting `__proto__` will\n            // guarantee that `Object.getPrototypeOf` will work as expected with\n            // objects created using `Object.create`\n            object.__proto__ = prototype;\n        }\n\n        if (properties !== void 0) {\n            Object.defineProperties(object, properties);\n        }\n\n        return object;\n    };\n}\n\n// ES5 15.2.3.6\n// http://es5.github.com/#x15.2.3.6\n\n// Patch for WebKit and IE8 standard mode\n// Designed by hax <hax.github.com>\n// related issue: https://github.com/kriskowal/es5-shim/issues#issue/5\n// IE8 Reference:\n//     http://msdn.microsoft.com/en-us/library/dd282900.aspx\n//     http://msdn.microsoft.com/en-us/library/dd229916.aspx\n// WebKit Bugs:\n//     https://bugs.webkit.org/show_bug.cgi?id=36423\n\nfunction doesDefinePropertyWork(object) {\n    try {\n        Object.defineProperty(object, \"sentinel\", {});\n        return \"sentinel\" in object;\n    } catch (exception) {\n        // returns falsy\n    }\n}\n\n// check whether defineProperty works if it's given. Otherwise,\n// shim partially.\nif (Object.defineProperty) {\n    var definePropertyWorksOnObject = doesDefinePropertyWork({});\n    var definePropertyWorksOnDom = typeof document == \"undefined\" ||\n        doesDefinePropertyWork(document.createElement(\"div\"));\n    if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {\n        var definePropertyFallback = Object.defineProperty,\n            definePropertiesFallback = Object.defineProperties;\n    }\n}\n\nif (!Object.defineProperty || definePropertyFallback) {\n    var ERR_NON_OBJECT_DESCRIPTOR = \"Property description must be an object: \";\n    var ERR_NON_OBJECT_TARGET = \"Object.defineProperty called on non-object: \"\n    var ERR_ACCESSORS_NOT_SUPPORTED = \"getters & setters can not be defined \" +\n                                      \"on this javascript engine\";\n\n    Object.defineProperty = function defineProperty(object, property, descriptor) {\n        if ((typeof object != \"object\" && typeof object != \"function\") || object === null) {\n            throw new TypeError(ERR_NON_OBJECT_TARGET + object);\n        }\n        if ((typeof descriptor != \"object\" && typeof descriptor != \"function\") || descriptor === null) {\n            throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);\n        }\n        // make a valiant attempt to use the real defineProperty\n        // for I8's DOM elements.\n        if (definePropertyFallback) {\n            try {\n                return definePropertyFallback.call(Object, object, property, descriptor);\n            } catch (exception) {\n                // try the shim if the real one doesn't work\n            }\n        }\n\n        // If it's a data property.\n        if (owns(descriptor, \"value\")) {\n            // fail silently if \"writable\", \"enumerable\", or \"configurable\"\n            // are requested but not supported\n            /*\n            // alternate approach:\n            if ( // can't implement these features; allow false but not true\n                !(owns(descriptor, \"writable\") ? descriptor.writable : true) ||\n                !(owns(descriptor, \"enumerable\") ? descriptor.enumerable : true) ||\n                !(owns(descriptor, \"configurable\") ? descriptor.configurable : true)\n            )\n                throw new RangeError(\n                    \"This implementation of Object.defineProperty does not \" +\n                    \"support configurable, enumerable, or writable.\"\n                );\n            */\n\n            if (supportsAccessors && (lookupGetter(object, property) ||\n                                      lookupSetter(object, property)))\n            {\n                // As accessors are supported only on engines implementing\n                // `__proto__` we can safely override `__proto__` while defining\n                // a property to make sure that we don't hit an inherited\n                // accessor.\n                var prototype = object.__proto__;\n                object.__proto__ = prototypeOfObject;\n                // Deleting a property anyway since getter / setter may be\n                // defined on object itself.\n                delete object[property];\n                object[property] = descriptor.value;\n                // Setting original `__proto__` back now.\n                object.__proto__ = prototype;\n            } else {\n                object[property] = descriptor.value;\n            }\n        } else {\n            if (!supportsAccessors) {\n                //throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);\n                return object;\n            }\n            // If we got that far then getters and setters can be defined !!\n            if (owns(descriptor, \"get\")) {\n                defineGetter(object, property, descriptor.get);\n            }\n            if (owns(descriptor, \"set\")) {\n                defineSetter(object, property, descriptor.set);\n            }\n        }\n        return object;\n    };\n}\n\n// ES5 15.2.3.7\n// http://es5.github.com/#x15.2.3.7\nif (!Object.defineProperties || definePropertiesFallback) {\n    Object.defineProperties = function defineProperties(object, properties) {\n        // make a valiant attempt to use the real defineProperties\n        if (definePropertiesFallback) {\n            try {\n                return definePropertiesFallback.call(Object, object, properties);\n            } catch (exception) {\n                // try the shim if the real one doesn't work\n            }\n        }\n\n        for (var property in properties) {\n            if (owns(properties, property) && property != \"__proto__\") {\n                Object.defineProperty(object, property, properties[property]);\n            }\n        }\n        return object;\n    };\n}\n\n// ES5 15.2.3.8\n// http://es5.github.com/#x15.2.3.8\nif (!Object.seal) {\n    Object.seal = function seal(object) {\n        // this is misleading and breaks feature-detection, but\n        // allows \"securable\" code to \"gracefully\" degrade to working\n        // but insecure code.\n        return object;\n    };\n}\n\n// ES5 15.2.3.9\n// http://es5.github.com/#x15.2.3.9\nif (!Object.freeze) {\n    Object.freeze = function freeze(object) {\n        // this is misleading and breaks feature-detection, but\n        // allows \"securable\" code to \"gracefully\" degrade to working\n        // but insecure code.\n        return object;\n    };\n}\n\n// detect a Rhino bug and patch it\ntry {\n    Object.freeze(function () {});\n} catch (exception) {\n    Object.freeze = (function freeze(freezeObject) {\n        return function freeze(object) {\n            if (typeof object == \"function\") {\n                return object;\n            } else {\n                return freezeObject(object);\n            }\n        };\n    })(Object.freeze);\n}\n\n// ES5 15.2.3.10\n// http://es5.github.com/#x15.2.3.10\nif (!Object.preventExtensions) {\n    Object.preventExtensions = function preventExtensions(object) {\n        // this is misleading and breaks feature-detection, but\n        // allows \"securable\" code to \"gracefully\" degrade to working\n        // but insecure code.\n        return object;\n    };\n}\n\n// ES5 15.2.3.11\n// http://es5.github.com/#x15.2.3.11\nif (!Object.isSealed) {\n    Object.isSealed = function isSealed(object) {\n        return false;\n    };\n}\n\n// ES5 15.2.3.12\n// http://es5.github.com/#x15.2.3.12\nif (!Object.isFrozen) {\n    Object.isFrozen = function isFrozen(object) {\n        return false;\n    };\n}\n\n// ES5 15.2.3.13\n// http://es5.github.com/#x15.2.3.13\nif (!Object.isExtensible) {\n    Object.isExtensible = function isExtensible(object) {\n        // 1. If Type(O) is not Object throw a TypeError exception.\n        if (Object(object) !== object) {\n            throw new TypeError(); // TODO message\n        }\n        // 2. Return the Boolean value of the [[Extensible]] internal property of O.\n        var name = '';\n        while (owns(object, name)) {\n            name += '?';\n        }\n        object[name] = true;\n        var returnValue = owns(object, name);\n        delete object[name];\n        return returnValue;\n    };\n}\n\n});"
  },
  {
    "path": "test/browser/es5-shim.js",
    "content": "// Copyright 2009-2012 by contributors, MIT License\n// vim: ts=4 sts=4 sw=4 expandtab\n\n// Module systems magic dance\n(function (definition) {\n    // RequireJS\n    if (typeof define == \"function\") {\n        define(definition);\n    // YUI3\n    } else if (typeof YUI == \"function\") {\n        YUI.add(\"es5\", definition);\n    // CommonJS and <script>\n    } else {\n        definition();\n    }\n})(function () {\n\n/**\n * Brings an environment as close to ECMAScript 5 compliance\n * as is possible with the facilities of erstwhile engines.\n *\n * Annotated ES5: http://es5.github.com/ (specific links below)\n * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf\n * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/\n */\n\n//\n// Function\n// ========\n//\n\n// ES-5 15.3.4.5\n// http://es5.github.com/#x15.3.4.5\n\nfunction Empty() {}\n\nif (!Function.prototype.bind) {\n    Function.prototype.bind = function bind(that) { // .length is 1\n        // 1. Let Target be the this value.\n        var target = this;\n        // 2. If IsCallable(Target) is false, throw a TypeError exception.\n        if (typeof target != \"function\") {\n            throw new TypeError(\"Function.prototype.bind called on incompatible \" + target);\n        }\n        // 3. Let A be a new (possibly empty) internal list of all of the\n        //   argument values provided after thisArg (arg1, arg2 etc), in order.\n        // XXX slicedArgs will stand in for \"A\" if used\n        var args = _Array_slice_.call(arguments, 1); // for normal call\n        // 4. Let F be a new native ECMAScript object.\n        // 11. Set the [[Prototype]] internal property of F to the standard\n        //   built-in Function prototype object as specified in 15.3.3.1.\n        // 12. Set the [[Call]] internal property of F as described in\n        //   15.3.4.5.1.\n        // 13. Set the [[Construct]] internal property of F as described in\n        //   15.3.4.5.2.\n        // 14. Set the [[HasInstance]] internal property of F as described in\n        //   15.3.4.5.3.\n        var bound = function () {\n\n            if (this instanceof bound) {\n                // 15.3.4.5.2 [[Construct]]\n                // When the [[Construct]] internal method of a function object,\n                // F that was created using the bind function is called with a\n                // list of arguments ExtraArgs, the following steps are taken:\n                // 1. Let target be the value of F's [[TargetFunction]]\n                //   internal property.\n                // 2. If target has no [[Construct]] internal method, a\n                //   TypeError exception is thrown.\n                // 3. Let boundArgs be the value of F's [[BoundArgs]] internal\n                //   property.\n                // 4. Let args be a new list containing the same values as the\n                //   list boundArgs in the same order followed by the same\n                //   values as the list ExtraArgs in the same order.\n                // 5. Return the result of calling the [[Construct]] internal\n                //   method of target providing args as the arguments.\n\n                var result = target.apply(\n                    this,\n                    args.concat(_Array_slice_.call(arguments))\n                );\n                if (Object(result) === result) {\n                    return result;\n                }\n                return this;\n\n            } else {\n                // 15.3.4.5.1 [[Call]]\n                // When the [[Call]] internal method of a function object, F,\n                // which was created using the bind function is called with a\n                // this value and a list of arguments ExtraArgs, the following\n                // steps are taken:\n                // 1. Let boundArgs be the value of F's [[BoundArgs]] internal\n                //   property.\n                // 2. Let boundThis be the value of F's [[BoundThis]] internal\n                //   property.\n                // 3. Let target be the value of F's [[TargetFunction]] internal\n                //   property.\n                // 4. Let args be a new list containing the same values as the\n                //   list boundArgs in the same order followed by the same\n                //   values as the list ExtraArgs in the same order.\n                // 5. Return the result of calling the [[Call]] internal method\n                //   of target providing boundThis as the this value and\n                //   providing args as the arguments.\n\n                // equiv: target.call(this, ...boundArgs, ...args)\n                return target.apply(\n                    that,\n                    args.concat(_Array_slice_.call(arguments))\n                );\n\n            }\n\n        };\n        if (target.prototype) {\n            Empty.prototype = target.prototype;\n            bound.prototype = new Empty();\n            // Clean up dangling references.\n            Empty.prototype = null;\n        }\n        // XXX bound.length is never writable, so don't even try\n        //\n        // 15. If the [[Class]] internal property of Target is \"Function\", then\n        //     a. Let L be the length property of Target minus the length of A.\n        //     b. Set the length own property of F to either 0 or L, whichever is\n        //       larger.\n        // 16. Else set the length own property of F to 0.\n        // 17. Set the attributes of the length own property of F to the values\n        //   specified in 15.3.5.1.\n\n        // TODO\n        // 18. Set the [[Extensible]] internal property of F to true.\n\n        // TODO\n        // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).\n        // 20. Call the [[DefineOwnProperty]] internal method of F with\n        //   arguments \"caller\", PropertyDescriptor {[[Get]]: thrower, [[Set]]:\n        //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and\n        //   false.\n        // 21. Call the [[DefineOwnProperty]] internal method of F with\n        //   arguments \"arguments\", PropertyDescriptor {[[Get]]: thrower,\n        //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},\n        //   and false.\n\n        // TODO\n        // NOTE Function objects created using Function.prototype.bind do not\n        // have a prototype property or the [[Code]], [[FormalParameters]], and\n        // [[Scope]] internal properties.\n        // XXX can't delete prototype in pure-js.\n\n        // 22. Return F.\n        return bound;\n    };\n}\n\n// Shortcut to an often accessed properties, in order to avoid multiple\n// dereference that costs universally.\n// _Please note: Shortcuts are defined after `Function.prototype.bind` as we\n// us it in defining shortcuts.\nvar call = Function.prototype.call;\nvar prototypeOfArray = Array.prototype;\nvar prototypeOfObject = Object.prototype;\nvar _Array_slice_ = prototypeOfArray.slice;\n// Having a toString local variable name breaks in Opera so use _toString.\nvar _toString = call.bind(prototypeOfObject.toString);\nvar owns = call.bind(prototypeOfObject.hasOwnProperty);\n\n// If JS engine supports accessors creating shortcuts.\nvar defineGetter;\nvar defineSetter;\nvar lookupGetter;\nvar lookupSetter;\nvar supportsAccessors;\nif ((supportsAccessors = owns(prototypeOfObject, \"__defineGetter__\"))) {\n    defineGetter = call.bind(prototypeOfObject.__defineGetter__);\n    defineSetter = call.bind(prototypeOfObject.__defineSetter__);\n    lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);\n    lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);\n}\n\n//\n// Array\n// =====\n//\n\n// ES5 15.4.4.12\n// http://es5.github.com/#x15.4.4.12\n// Default value for second param\n// [bugfix, ielt9, old browsers]\n// IE < 9 bug: [1,2].splice(0).join(\"\") == \"\" but should be \"12\"\nif ([1,2].splice(0).length != 2) {\n    var array_splice = Array.prototype.splice;\n\n    if (function() { // test IE < 9 to splice bug - see issue #138\n        function makeArray(l) {\n            var a = [];\n            while (l--) {\n                a.unshift(l)\n            }\n            return a\n        }\n\n        var array = []\n            , lengthBefore\n        ;\n\n        array.splice.bind(array, 0, 0).apply(null, makeArray(20));\n        array.splice.bind(array, 0, 0).apply(null, makeArray(26));\n\n        lengthBefore = array.length; //20\n        array.splice(5, 0, \"XXX\"); // add one element\n\n        if (lengthBefore + 1 == array.length) {\n            return true;// has right splice implementation without bugs\n        }\n        // else {\n        //    IE8 bug\n        // }\n    }()) {//IE 6/7\n        Array.prototype.splice = function(start, deleteCount) {\n            if (!arguments.length) {\n                return [];\n            } else {\n                return array_splice.apply(this, [\n                    start === void 0 ? 0 : start,\n                    deleteCount === void 0 ? (this.length - start) : deleteCount\n                ].concat(_Array_slice_.call(arguments, 2)))\n            }\n        };\n    }\n    else {//IE8\n        Array.prototype.splice = function(start, deleteCount) {\n            var result\n                , args = _Array_slice_.call(arguments, 2)\n                , addElementsCount = args.length\n            ;\n\n            if (!arguments.length) {\n                return [];\n            }\n\n            if (start === void 0) { // default\n                start = 0;\n            }\n            if (deleteCount === void 0) { // default\n                deleteCount = this.length - start;\n            }\n\n            if (addElementsCount > 0) {\n                if (deleteCount <= 0) {\n                    if (start == this.length) { // tiny optimisation #1\n                        this.push.apply(this, args);\n                        return [];\n                    }\n\n                    if (start == 0) { // tiny optimisation #2\n                        this.unshift.apply(this, args);\n                        return [];\n                    }\n                }\n\n                // Array.prototype.splice implementation\n                result = _Array_slice_.call(this, start, start + deleteCount);// delete part\n                args.push.apply(args, _Array_slice_.call(this, start + deleteCount, this.length));// right part\n                args.unshift.apply(args, _Array_slice_.call(this, 0, start));// left part\n\n                // delete all items from this array and replace it to 'left part' + _Array_slice_.call(arguments, 2) + 'right part'\n                args.unshift(0, this.length);\n\n                array_splice.apply(this, args);\n\n                return result;\n            }\n\n            return array_splice.call(this, start, deleteCount);\n        }\n\n    }\n}\n\n// ES5 15.4.4.12\n// http://es5.github.com/#x15.4.4.13\n// Return len+argCount.\n// [bugfix, ielt8]\n// IE < 8 bug: [].unshift(0) == undefined but should be \"1\"\nif ([].unshift(0) != 1) {\n    var array_unshift = Array.prototype.unshift;\n    Array.prototype.unshift = function() {\n        array_unshift.apply(this, arguments);\n        return this.length;\n    };\n}\n\n// ES5 15.4.3.2\n// http://es5.github.com/#x15.4.3.2\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray\nif (!Array.isArray) {\n    Array.isArray = function isArray(obj) {\n        return _toString(obj) == \"[object Array]\";\n    };\n}\n\n// The IsCallable() check in the Array functions\n// has been replaced with a strict check on the\n// internal class of the object to trap cases where\n// the provided function was actually a regular\n// expression literal, which in V8 and\n// JavaScriptCore is a typeof \"function\".  Only in\n// V8 are regular expression literals permitted as\n// reduce parameters, so it is desirable in the\n// general case for the shim to match the more\n// strict and common behavior of rejecting regular\n// expressions.\n\n// ES5 15.4.4.18\n// http://es5.github.com/#x15.4.4.18\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach\n\n// Check failure of by-index access of string characters (IE < 9)\n// and failure of `0 in boxedString` (Rhino)\nvar boxedString = Object(\"a\"),\n    splitString = boxedString[0] != \"a\" || !(0 in boxedString);\n\nif (!Array.prototype.forEach) {\n    Array.prototype.forEach = function forEach(fun /*, thisp*/) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            thisp = arguments[1],\n            i = -1,\n            length = self.length >>> 0;\n\n        // If no callback function or if callback is not a callable function\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(); // TODO message\n        }\n\n        while (++i < length) {\n            if (i in self) {\n                // Invoke the callback function with call, passing arguments:\n                // context, property value, property key, thisArg object\n                // context\n                fun.call(thisp, self[i], i, object);\n            }\n        }\n    };\n}\n\n// ES5 15.4.4.19\n// http://es5.github.com/#x15.4.4.19\n// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map\nif (!Array.prototype.map) {\n    Array.prototype.map = function map(fun /*, thisp*/) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            length = self.length >>> 0,\n            result = Array(length),\n            thisp = arguments[1];\n\n        // If no callback function or if callback is not a callable function\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self)\n                result[i] = fun.call(thisp, self[i], i, object);\n        }\n        return result;\n    };\n}\n\n// ES5 15.4.4.20\n// http://es5.github.com/#x15.4.4.20\n// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter\nif (!Array.prototype.filter) {\n    Array.prototype.filter = function filter(fun /*, thisp */) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                    object,\n            length = self.length >>> 0,\n            result = [],\n            value,\n            thisp = arguments[1];\n\n        // If no callback function or if callback is not a callable function\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self) {\n                value = self[i];\n                if (fun.call(thisp, value, i, object)) {\n                    result.push(value);\n                }\n            }\n        }\n        return result;\n    };\n}\n\n// ES5 15.4.4.16\n// http://es5.github.com/#x15.4.4.16\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every\nif (!Array.prototype.every) {\n    Array.prototype.every = function every(fun /*, thisp */) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            length = self.length >>> 0,\n            thisp = arguments[1];\n\n        // If no callback function or if callback is not a callable function\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self && !fun.call(thisp, self[i], i, object)) {\n                return false;\n            }\n        }\n        return true;\n    };\n}\n\n// ES5 15.4.4.17\n// http://es5.github.com/#x15.4.4.17\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some\nif (!Array.prototype.some) {\n    Array.prototype.some = function some(fun /*, thisp */) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            length = self.length >>> 0,\n            thisp = arguments[1];\n\n        // If no callback function or if callback is not a callable function\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n\n        for (var i = 0; i < length; i++) {\n            if (i in self && fun.call(thisp, self[i], i, object)) {\n                return true;\n            }\n        }\n        return false;\n    };\n}\n\n// ES5 15.4.4.21\n// http://es5.github.com/#x15.4.4.21\n// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce\nif (!Array.prototype.reduce) {\n    Array.prototype.reduce = function reduce(fun /*, initial*/) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            length = self.length >>> 0;\n\n        // If no callback function or if callback is not a callable function\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n\n        // no value to return if no initial value and an empty array\n        if (!length && arguments.length == 1) {\n            throw new TypeError(\"reduce of empty array with no initial value\");\n        }\n\n        var i = 0;\n        var result;\n        if (arguments.length >= 2) {\n            result = arguments[1];\n        } else {\n            do {\n                if (i in self) {\n                    result = self[i++];\n                    break;\n                }\n\n                // if array contains no values, no initial value to return\n                if (++i >= length) {\n                    throw new TypeError(\"reduce of empty array with no initial value\");\n                }\n            } while (true);\n        }\n\n        for (; i < length; i++) {\n            if (i in self) {\n                result = fun.call(void 0, result, self[i], i, object);\n            }\n        }\n\n        return result;\n    };\n}\n\n// ES5 15.4.4.22\n// http://es5.github.com/#x15.4.4.22\n// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight\nif (!Array.prototype.reduceRight) {\n    Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {\n        var object = toObject(this),\n            self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                object,\n            length = self.length >>> 0;\n\n        // If no callback function or if callback is not a callable function\n        if (_toString(fun) != \"[object Function]\") {\n            throw new TypeError(fun + \" is not a function\");\n        }\n\n        // no value to return if no initial value, empty array\n        if (!length && arguments.length == 1) {\n            throw new TypeError(\"reduceRight of empty array with no initial value\");\n        }\n\n        var result, i = length - 1;\n        if (arguments.length >= 2) {\n            result = arguments[1];\n        } else {\n            do {\n                if (i in self) {\n                    result = self[i--];\n                    break;\n                }\n\n                // if array contains no values, no initial value to return\n                if (--i < 0) {\n                    throw new TypeError(\"reduceRight of empty array with no initial value\");\n                }\n            } while (true);\n        }\n\n        if (i < 0) {\n            return result;\n        }\n\n        do {\n            if (i in this) {\n                result = fun.call(void 0, result, self[i], i, object);\n            }\n        } while (i--);\n\n        return result;\n    };\n}\n\n// ES5 15.4.4.14\n// http://es5.github.com/#x15.4.4.14\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf\nif (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {\n    Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {\n        var self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                toObject(this),\n            length = self.length >>> 0;\n\n        if (!length) {\n            return -1;\n        }\n\n        var i = 0;\n        if (arguments.length > 1) {\n            i = toInteger(arguments[1]);\n        }\n\n        // handle negative indices\n        i = i >= 0 ? i : Math.max(0, length + i);\n        for (; i < length; i++) {\n            if (i in self && self[i] === sought) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\n// ES5 15.4.4.15\n// http://es5.github.com/#x15.4.4.15\n// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf\nif (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {\n    Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {\n        var self = splitString && _toString(this) == \"[object String]\" ?\n                this.split(\"\") :\n                toObject(this),\n            length = self.length >>> 0;\n\n        if (!length) {\n            return -1;\n        }\n        var i = length - 1;\n        if (arguments.length > 1) {\n            i = Math.min(i, toInteger(arguments[1]));\n        }\n        // handle negative indices\n        i = i >= 0 ? i : length - Math.abs(i);\n        for (; i >= 0; i--) {\n            if (i in self && sought === self[i]) {\n                return i;\n            }\n        }\n        return -1;\n    };\n}\n\n//\n// Object\n// ======\n//\n\n// ES5 15.2.3.14\n// http://es5.github.com/#x15.2.3.14\nif (!Object.keys) {\n    // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation\n    var hasDontEnumBug = true,\n        dontEnums = [\n            \"toString\",\n            \"toLocaleString\",\n            \"valueOf\",\n            \"hasOwnProperty\",\n            \"isPrototypeOf\",\n            \"propertyIsEnumerable\",\n            \"constructor\"\n        ],\n        dontEnumsLength = dontEnums.length;\n\n    for (var key in {\"toString\": null}) {\n        hasDontEnumBug = false;\n    }\n\n    Object.keys = function keys(object) {\n\n        if (\n            (typeof object != \"object\" && typeof object != \"function\") ||\n            object === null\n        ) {\n            throw new TypeError(\"Object.keys called on a non-object\");\n        }\n\n        var keys = [];\n        for (var name in object) {\n            if (owns(object, name)) {\n                keys.push(name);\n            }\n        }\n\n        if (hasDontEnumBug) {\n            for (var i = 0, ii = dontEnumsLength; i < ii; i++) {\n                var dontEnum = dontEnums[i];\n                if (owns(object, dontEnum)) {\n                    keys.push(dontEnum);\n                }\n            }\n        }\n        return keys;\n    };\n\n}\n\n//\n// Date\n// ====\n//\n\n// ES5 15.9.5.43\n// http://es5.github.com/#x15.9.5.43\n// This function returns a String value represent the instance in time\n// represented by this Date object. The format of the String is the Date Time\n// string format defined in 15.9.1.15. All fields are present in the String.\n// The time zone is always UTC, denoted by the suffix Z. If the time value of\n// this object is not a finite Number a RangeError exception is thrown.\nvar negativeDate = -62198755200000,\n    negativeYearString = \"-000001\";\nif (\n    !Date.prototype.toISOString ||\n    (new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1)\n) {\n    Date.prototype.toISOString = function toISOString() {\n        var result, length, value, year, month;\n        if (!isFinite(this)) {\n            throw new RangeError(\"Date.prototype.toISOString called on non-finite value.\");\n        }\n\n        year = this.getUTCFullYear();\n\n        month = this.getUTCMonth();\n        // see https://github.com/kriskowal/es5-shim/issues/111\n        year += Math.floor(month / 12);\n        month = (month % 12 + 12) % 12;\n\n        // the date time string format is specified in 15.9.1.15.\n        result = [month + 1, this.getUTCDate(),\n            this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];\n        year = (\n            (year < 0 ? \"-\" : (year > 9999 ? \"+\" : \"\")) +\n            (\"00000\" + Math.abs(year))\n            .slice(0 <= year && year <= 9999 ? -4 : -6)\n        );\n\n        length = result.length;\n        while (length--) {\n            value = result[length];\n            // pad months, days, hours, minutes, and seconds to have two\n            // digits.\n            if (value < 10) {\n                result[length] = \"0\" + value;\n            }\n        }\n        // pad milliseconds to have three digits.\n        return (\n            year + \"-\" + result.slice(0, 2).join(\"-\") +\n            \"T\" + result.slice(2).join(\":\") + \".\" +\n            (\"000\" + this.getUTCMilliseconds()).slice(-3) + \"Z\"\n        );\n    };\n}\n\n\n// ES5 15.9.5.44\n// http://es5.github.com/#x15.9.5.44\n// This function provides a String representation of a Date object for use by\n// JSON.stringify (15.12.3).\nvar dateToJSONIsSupported = false;\ntry {\n    dateToJSONIsSupported = (\n        Date.prototype.toJSON &&\n        new Date(NaN).toJSON() === null &&\n        new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&\n        Date.prototype.toJSON.call({ // generic\n            toISOString: function () {\n                return true;\n            }\n        })\n    );\n} catch (e) {\n}\nif (!dateToJSONIsSupported) {\n    Date.prototype.toJSON = function toJSON(key) {\n        // When the toJSON method is called with argument key, the following\n        // steps are taken:\n\n        // 1.  Let O be the result of calling ToObject, giving it the this\n        // value as its argument.\n        // 2. Let tv be toPrimitive(O, hint Number).\n        var o = Object(this),\n            tv = toPrimitive(o),\n            toISO;\n        // 3. If tv is a Number and is not finite, return null.\n        if (typeof tv === \"number\" && !isFinite(tv)) {\n            return null;\n        }\n        // 4. Let toISO be the result of calling the [[Get]] internal method of\n        // O with argument \"toISOString\".\n        toISO = o.toISOString;\n        // 5. If IsCallable(toISO) is false, throw a TypeError exception.\n        if (typeof toISO != \"function\") {\n            throw new TypeError(\"toISOString property is not callable\");\n        }\n        // 6. Return the result of calling the [[Call]] internal method of\n        //  toISO with O as the this value and an empty argument list.\n        return toISO.call(o);\n\n        // NOTE 1 The argument is ignored.\n\n        // NOTE 2 The toJSON function is intentionally generic; it does not\n        // require that its this value be a Date object. Therefore, it can be\n        // transferred to other kinds of objects for use as a method. However,\n        // it does require that any such object have a toISOString method. An\n        // object is free to use the argument key to filter its\n        // stringification.\n    };\n}\n\n// ES5 15.9.4.2\n// http://es5.github.com/#x15.9.4.2\n// based on work shared by Daniel Friesen (dantman)\n// http://gist.github.com/303249\nif (!Date.parse || \"Date.parse is buggy\") {\n    // XXX global assignment won't work in embeddings that use\n    // an alternate object for the context.\n    Date = (function(NativeDate) {\n\n        // Date.length === 7\n        function Date(Y, M, D, h, m, s, ms) {\n            var length = arguments.length;\n            if (this instanceof NativeDate) {\n                var date = length == 1 && String(Y) === Y ? // isString(Y)\n                    // We explicitly pass it through parse:\n                    new NativeDate(Date.parse(Y)) :\n                    // We have to manually make calls depending on argument\n                    // length here\n                    length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :\n                    length >= 6 ? new NativeDate(Y, M, D, h, m, s) :\n                    length >= 5 ? new NativeDate(Y, M, D, h, m) :\n                    length >= 4 ? new NativeDate(Y, M, D, h) :\n                    length >= 3 ? new NativeDate(Y, M, D) :\n                    length >= 2 ? new NativeDate(Y, M) :\n                    length >= 1 ? new NativeDate(Y) :\n                                  new NativeDate();\n                // Prevent mixups with unfixed Date object\n                date.constructor = Date;\n                return date;\n            }\n            return NativeDate.apply(this, arguments);\n        };\n\n        // 15.9.1.15 Date Time String Format.\n        var isoDateExpression = new RegExp(\"^\" +\n            \"(\\\\d{4}|[\\+\\-]\\\\d{6})\" + // four-digit year capture or sign +\n                                      // 6-digit extended year\n            \"(?:-(\\\\d{2})\" + // optional month capture\n            \"(?:-(\\\\d{2})\" + // optional day capture\n            \"(?:\" + // capture hours:minutes:seconds.milliseconds\n                \"T(\\\\d{2})\" + // hours capture\n                \":(\\\\d{2})\" + // minutes capture\n                \"(?:\" + // optional :seconds.milliseconds\n                    \":(\\\\d{2})\" + // seconds capture\n                    \"(?:(\\\\.\\\\d{1,}))?\" + // milliseconds capture\n                \")?\" +\n            \"(\" + // capture UTC offset component\n                \"Z|\" + // UTC capture\n                \"(?:\" + // offset specifier +/-hours:minutes\n                    \"([-+])\" + // sign capture\n                    \"(\\\\d{2})\" + // hours offset capture\n                    \":(\\\\d{2})\" + // minutes offset capture\n                \")\" +\n            \")?)?)?)?\" +\n        \"$\");\n\n        var months = [\n            0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365\n        ];\n\n        function dayFromMonth(year, month) {\n            var t = month > 1 ? 1 : 0;\n            return (\n                months[month] +\n                Math.floor((year - 1969 + t) / 4) -\n                Math.floor((year - 1901 + t) / 100) +\n                Math.floor((year - 1601 + t) / 400) +\n                365 * (year - 1970)\n            );\n        }\n\n        function toUTC(t) {\n            return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t));\n        }\n\n        // Copy any custom methods a 3rd party library may have added\n        for (var key in NativeDate) {\n            Date[key] = NativeDate[key];\n        }\n\n        // Copy \"native\" methods explicitly; they may be non-enumerable\n        Date.now = NativeDate.now;\n        Date.UTC = NativeDate.UTC;\n        Date.prototype = NativeDate.prototype;\n        Date.prototype.constructor = Date;\n\n        // Upgrade Date.parse to handle simplified ISO 8601 strings\n        Date.parse = function parse(string) {\n            var match = isoDateExpression.exec(string);\n            if (match) {\n                // parse months, days, hours, minutes, seconds, and milliseconds\n                // provide default values if necessary\n                // parse the UTC offset component\n                var year = Number(match[1]),\n                    month = Number(match[2] || 1) - 1,\n                    day = Number(match[3] || 1) - 1,\n                    hour = Number(match[4] || 0),\n                    minute = Number(match[5] || 0),\n                    second = Number(match[6] || 0),\n                    millisecond = Math.floor(Number(match[7] || 0) * 1000),\n                    // When time zone is missed, local offset should be used\n                    // (ES 5.1 bug)\n                    // see https://bugs.ecmascript.org/show_bug.cgi?id=112\n                    isLocalTime = Boolean(match[4] && !match[8]),\n                    signOffset = match[9] === \"-\" ? 1 : -1,\n                    hourOffset = Number(match[10] || 0),\n                    minuteOffset = Number(match[11] || 0),\n                    result;\n                if (\n                    hour < (\n                        minute > 0 || second > 0 || millisecond > 0 ?\n                        24 : 25\n                    ) &&\n                    minute < 60 && second < 60 && millisecond < 1000 &&\n                    month > -1 && month < 12 && hourOffset < 24 &&\n                    minuteOffset < 60 && // detect invalid offsets\n                    day > -1 &&\n                    day < (\n                        dayFromMonth(year, month + 1) -\n                        dayFromMonth(year, month)\n                    )\n                ) {\n                    result = (\n                        (dayFromMonth(year, month) + day) * 24 +\n                        hour +\n                        hourOffset * signOffset\n                    ) * 60;\n                    result = (\n                        (result + minute + minuteOffset * signOffset) * 60 +\n                        second\n                    ) * 1000 + millisecond;\n                    if (isLocalTime) {\n                        result = toUTC(result);\n                    }\n                    if (-8.64e15 <= result && result <= 8.64e15) {\n                        return result;\n                    }\n                }\n                return NaN;\n            }\n            return NativeDate.parse.apply(this, arguments);\n        };\n\n        return Date;\n    })(Date);\n}\n\n// ES5 15.9.4.4\n// http://es5.github.com/#x15.9.4.4\nif (!Date.now) {\n    Date.now = function now() {\n        return new Date().getTime();\n    };\n}\n\n\n//\n// Number\n// ======\n//\n\n// ES5.1 15.7.4.5\n// http://es5.github.com/#x15.7.4.5\nif (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) === '0' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== \"1000000000000000128\") {\n    // Hide these variables and functions\n    (function () {\n        var base, size, data, i;\n\n        base = 1e7;\n        size = 6;\n        data = [0, 0, 0, 0, 0, 0];\n\n        function multiply(n, c) {\n            var i = -1;\n            while (++i < size) {\n                c += n * data[i];\n                data[i] = c % base;\n                c = Math.floor(c / base);\n            }\n        }\n\n        function divide(n) {\n            var i = size, c = 0;\n            while (--i >= 0) {\n                c += data[i];\n                data[i] = Math.floor(c / n);\n                c = (c % n) * base;\n            }\n        }\n\n        function toString() {\n            var i = size;\n            var s = '';\n            while (--i >= 0) {\n                if (s !== '' || i === 0 || data[i] !== 0) {\n                    var t = String(data[i]);\n                    if (s === '') {\n                        s = t;\n                    } else {\n                        s += '0000000'.slice(0, 7 - t.length) + t;\n                    }\n                }\n            }\n            return s;\n        }\n\n        function pow(x, n, acc) {\n            return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));\n        }\n\n        function log(x) {\n            var n = 0;\n            while (x >= 4096) {\n                n += 12;\n                x /= 4096;\n            }\n            while (x >= 2) {\n                n += 1;\n                x /= 2;\n            }\n            return n;\n        }\n\n        Number.prototype.toFixed = function (fractionDigits) {\n            var f, x, s, m, e, z, j, k;\n\n            // Test for NaN and round fractionDigits down\n            f = Number(fractionDigits);\n            f = f !== f ? 0 : Math.floor(f);\n\n            if (f < 0 || f > 20) {\n                throw new RangeError(\"Number.toFixed called with invalid number of decimals\");\n            }\n\n            x = Number(this);\n\n            // Test for NaN\n            if (x !== x) {\n                return \"NaN\";\n            }\n\n            // If it is too big or small, return the string value of the number\n            if (x <= -1e21 || x >= 1e21) {\n                return String(x);\n            }\n\n            s = \"\";\n\n            if (x < 0) {\n                s = \"-\";\n                x = -x;\n            }\n\n            m = \"0\";\n\n            if (x > 1e-21) {\n                // 1e-21 < x < 1e21\n                // -70 < log2(x) < 70\n                e = log(x * pow(2, 69, 1)) - 69;\n                z = (e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1));\n                z *= 0x10000000000000; // Math.pow(2, 52);\n                e = 52 - e;\n\n                // -18 < e < 122\n                // x = z / 2 ^ e\n                if (e > 0) {\n                    multiply(0, z);\n                    j = f;\n\n                    while (j >= 7) {\n                        multiply(1e7, 0);\n                        j -= 7;\n                    }\n\n                    multiply(pow(10, j, 1), 0);\n                    j = e - 1;\n\n                    while (j >= 23) {\n                        divide(1 << 23);\n                        j -= 23;\n                    }\n\n                    divide(1 << j);\n                    multiply(1, 1);\n                    divide(2);\n                    m = toString();\n                } else {\n                    multiply(0, z);\n                    multiply(1 << (-e), 0);\n                    m = toString() + '0.00000000000000000000'.slice(2, 2 + f);\n                }\n            }\n\n            if (f > 0) {\n                k = m.length;\n\n                if (k <= f) {\n                    m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;\n                } else {\n                    m = s + m.slice(0, k - f) + '.' + m.slice(k - f);\n                }\n            } else {\n                m = s + m;\n            }\n\n            return m;\n        }\n    }());\n}\n\n\n//\n// String\n// ======\n//\n\n\n// ES5 15.5.4.14\n// http://es5.github.com/#x15.5.4.14\n\n// [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]\n// Many browsers do not split properly with regular expressions or they\n// do not perform the split correctly under obscure conditions.\n// See http://blog.stevenlevithan.com/archives/cross-browser-split\n// I've tested in many browsers and this seems to cover the deviant ones:\n//    'ab'.split(/(?:ab)*/) should be [\"\", \"\"], not [\"\"]\n//    '.'.split(/(.?)(.?)/) should be [\"\", \".\", \"\", \"\"], not [\"\", \"\"]\n//    'tesst'.split(/(s)*/) should be [\"t\", undefined, \"e\", \"s\", \"t\"], not\n//       [undefined, \"t\", undefined, \"e\", ...]\n//    ''.split(/.?/) should be [], not [\"\"]\n//    '.'.split(/()()/) should be [\".\"], not [\"\", \"\", \".\"]\n\nvar string_split = String.prototype.split;\nif (\n    'ab'.split(/(?:ab)*/).length !== 2 ||\n    '.'.split(/(.?)(.?)/).length !== 4 ||\n    'tesst'.split(/(s)*/)[1] === \"t\" ||\n    ''.split(/.?/).length ||\n    '.'.split(/()()/).length > 1\n) {\n    (function () {\n        var compliantExecNpcg = /()??/.exec(\"\")[1] === void 0; // NPCG: nonparticipating capturing group\n\n        String.prototype.split = function (separator, limit) {\n            var string = this;\n            if (separator === void 0 && limit === 0)\n                return [];\n\n            // If `separator` is not a regex, use native split\n            if (Object.prototype.toString.call(separator) !== \"[object RegExp]\") {\n                return string_split.apply(this, arguments);\n            }\n\n            var output = [],\n                flags = (separator.ignoreCase ? \"i\" : \"\") +\n                        (separator.multiline  ? \"m\" : \"\") +\n                        (separator.extended   ? \"x\" : \"\") + // Proposed for ES6\n                        (separator.sticky     ? \"y\" : \"\"), // Firefox 3+\n                lastLastIndex = 0,\n                // Make `global` and avoid `lastIndex` issues by working with a copy\n                separator = new RegExp(separator.source, flags + \"g\"),\n                separator2, match, lastIndex, lastLength;\n            string += \"\"; // Type-convert\n            if (!compliantExecNpcg) {\n                // Doesn't need flags gy, but they don't hurt\n                separator2 = new RegExp(\"^\" + separator.source + \"$(?!\\\\s)\", flags);\n            }\n            /* Values for `limit`, per the spec:\n             * If undefined: 4294967295 // Math.pow(2, 32) - 1\n             * If 0, Infinity, or NaN: 0\n             * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;\n             * If negative number: 4294967296 - Math.floor(Math.abs(limit))\n             * If other: Type-convert, then use the above rules\n             */\n            limit = limit === void 0 ?\n                -1 >>> 0 : // Math.pow(2, 32) - 1\n                limit >>> 0; // ToUint32(limit)\n            while (match = separator.exec(string)) {\n                // `separator.lastIndex` is not reliable cross-browser\n                lastIndex = match.index + match[0].length;\n                if (lastIndex > lastLastIndex) {\n                    output.push(string.slice(lastLastIndex, match.index));\n                    // Fix browsers whose `exec` methods don't consistently return `undefined` for\n                    // nonparticipating capturing groups\n                    if (!compliantExecNpcg && match.length > 1) {\n                        match[0].replace(separator2, function () {\n                            for (var i = 1; i < arguments.length - 2; i++) {\n                                if (arguments[i] === void 0) {\n                                    match[i] = void 0;\n                                }\n                            }\n                        });\n                    }\n                    if (match.length > 1 && match.index < string.length) {\n                        Array.prototype.push.apply(output, match.slice(1));\n                    }\n                    lastLength = match[0].length;\n                    lastLastIndex = lastIndex;\n                    if (output.length >= limit) {\n                        break;\n                    }\n                }\n                if (separator.lastIndex === match.index) {\n                    separator.lastIndex++; // Avoid an infinite loop\n                }\n            }\n            if (lastLastIndex === string.length) {\n                if (lastLength || !separator.test(\"\")) {\n                    output.push(\"\");\n                }\n            } else {\n                output.push(string.slice(lastLastIndex));\n            }\n            return output.length > limit ? output.slice(0, limit) : output;\n        };\n    }());\n\n// [bugfix, chrome]\n// If separator is undefined, then the result array contains just one String,\n// which is the this value (converted to a String). If limit is not undefined,\n// then the output array is truncated so that it contains no more than limit\n// elements.\n// \"0\".split(undefined, 0) -> []\n} else if (\"0\".split(void 0, 0).length) {\n    String.prototype.split = function(separator, limit) {\n        if (separator === void 0 && limit === 0) return [];\n        return string_split.apply(this, arguments);\n    }\n}\n\n\n// ECMA-262, 3rd B.2.3\n// Note an ECMAScript standard, although ECMAScript 3rd Edition has a\n// non-normative section suggesting uniform semantics and it should be\n// normalized across all browsers\n// [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE\nif (\"\".substr && \"0b\".substr(-1) !== \"b\") {\n    var string_substr = String.prototype.substr;\n    /**\n     *  Get the substring of a string\n     *  @param  {integer}  start   where to start the substring\n     *  @param  {integer}  length  how many characters to return\n     *  @return {string}\n     */\n    String.prototype.substr = function(start, length) {\n        return string_substr.call(\n            this,\n            start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start,\n            length\n        );\n    }\n}\n\n// ES5 15.5.4.20\n// http://es5.github.com/#x15.5.4.20\nvar ws = \"\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\" +\n    \"\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\" +\n    \"\\u2029\\uFEFF\";\nif (!String.prototype.trim || ws.trim()) {\n    // http://blog.stevenlevithan.com/archives/faster-trim-javascript\n    // http://perfectionkills.com/whitespace-deviations/\n    ws = \"[\" + ws + \"]\";\n    var trimBeginRegexp = new RegExp(\"^\" + ws + ws + \"*\"),\n        trimEndRegexp = new RegExp(ws + ws + \"*$\");\n    String.prototype.trim = function trim() {\n        if (this === void 0 || this === null) {\n            throw new TypeError(\"can't convert \"+this+\" to object\");\n        }\n        return String(this)\n            .replace(trimBeginRegexp, \"\")\n            .replace(trimEndRegexp, \"\");\n    };\n}\n\n//\n// Util\n// ======\n//\n\n// ES5 9.4\n// http://es5.github.com/#x9.4\n// http://jsperf.com/to-integer\n\nfunction toInteger(n) {\n    n = +n;\n    if (n !== n) { // isNaN\n        n = 0;\n    } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {\n        n = (n > 0 || -1) * Math.floor(Math.abs(n));\n    }\n    return n;\n}\n\nfunction isPrimitive(input) {\n    var type = typeof input;\n    return (\n        input === null ||\n        type === \"undefined\" ||\n        type === \"boolean\" ||\n        type === \"number\" ||\n        type === \"string\"\n    );\n}\n\nfunction toPrimitive(input) {\n    var val, valueOf, toString;\n    if (isPrimitive(input)) {\n        return input;\n    }\n    valueOf = input.valueOf;\n    if (typeof valueOf === \"function\") {\n        val = valueOf.call(input);\n        if (isPrimitive(val)) {\n            return val;\n        }\n    }\n    toString = input.toString;\n    if (typeof toString === \"function\") {\n        val = toString.call(input);\n        if (isPrimitive(val)) {\n            return val;\n        }\n    }\n    throw new TypeError();\n}\n\n// ES5 9.9\n// http://es5.github.com/#x9.9\nvar toObject = function (o) {\n    if (o == null) { // this matches both null and undefined\n        throw new TypeError(\"can't convert \"+o+\" to object\");\n    }\n    return Object(o);\n};\n\n});\n"
  },
  {
    "path": "test/browser/have_getters.js",
    "content": "var haveGetters = (function(){\n    try {\n        var o ={};\n\n        if( Object.__defineGetter__ ) {\n            o.__defineGetter__( \"fn\", function(){\n                return 3;\n            });\n            return o.fn === 3;\n        }\n        else if( Object.defineProperty ) {\n            Object.defineProperty(o, \"fn\", {get: function(){return 3}});\n            return o.fn === 3;\n        }\n        return false;\n    }\n    catch(e) {\n        return false;\n    }\n})();\n"
  },
  {
    "path": "test/browser/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf8\">\n    <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n    <link href=\"./mocha.css\" rel=\"stylesheet\">\n    <title></title>\n</head>\n<body>\n<div id=\"mocha\"></div>\n<script type=\"text/javascript\" src=\"json.js\"></script>\n<script type=\"text/javascript\" src=\"have_getters.js\"></script>\n<script type=\"text/javascript\" src=\"es5-shim.js\"></script>\n<script type=\"text/javascript\" src=\"es5-sham.js\"></script>\n<script type=\"text/javascript\" src=\"mocha.js\"></script>\n<script type=\"text/javascript\">mocha.setup('bdd')</script>\n<script type=\"text/javascript\" src=\"bundle.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "test/browser/json.js",
    "content": "/*! JSON v3.3.0 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */\n(function(n){function K(p,q){function s(a){if(s[a]!==v)return s[a];var c;if(\"bug-string-char-index\"==a)c=\"a\"!=\"a\"[0];else if(\"json\"==a)c=s(\"json-stringify\")&&s(\"json-parse\");else{var e;if(\"json-stringify\"==a){c=q.stringify;var b=\"function\"==typeof c&&r;if(b){(e=function(){return 1}).toJSON=e;try{b=\"0\"===c(0)&&\"0\"===c(new A)&&'\"\"'==c(new B)&&c(t)===v&&c(v)===v&&c()===v&&\"1\"===c(e)&&\"[1]\"==c([e])&&\"[null]\"==c([v])&&\"null\"==c(null)&&\"[null,null,null]\"==c([v,t,null])&&'{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}'==\nc({a:[e,!0,!1,null,\"\\x00\\b\\n\\f\\r\\t\"]})&&\"1\"===c(null,e)&&\"[\\n 1,\\n 2\\n]\"==c([1,2],null,1)&&'\"-271821-04-20T00:00:00.000Z\"'==c(new D(-864E13))&&'\"+275760-09-13T00:00:00.000Z\"'==c(new D(864E13))&&'\"-000001-01-01T00:00:00.000Z\"'==c(new D(-621987552E5))&&'\"1969-12-31T23:59:59.999Z\"'==c(new D(-1))}catch(f){b=!1}}c=b}if(\"json-parse\"==a){c=q.parse;if(\"function\"==typeof c)try{if(0===c(\"0\")&&!c(!1)){e=c('{\"a\":[1,true,false,null,\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\"]}');var l=5==e.a.length&&1===e.a[0];if(l){try{l=!c('\"\\t\"')}catch(d){}if(l)try{l=\n1!==c(\"01\")}catch(h){}if(l)try{l=1!==c(\"1.\")}catch(m){}}}}catch(X){l=!1}c=l}}return s[a]=!!c}p||(p=n.Object());q||(q=n.Object());var A=p.Number||n.Number,B=p.String||n.String,G=p.Object||n.Object,D=p.Date||n.Date,J=p.SyntaxError||n.SyntaxError,N=p.TypeError||n.TypeError,R=p.Math||n.Math,H=p.JSON||n.JSON;\"object\"==typeof H&&H&&(q.stringify=H.stringify,q.parse=H.parse);var G=G.prototype,t=G.toString,u,C,v,r=new D(-0xc782b5b800cec);try{r=-109252==r.getUTCFullYear()&&0===r.getUTCMonth()&&1===r.getUTCDate()&&\n10==r.getUTCHours()&&37==r.getUTCMinutes()&&6==r.getUTCSeconds()&&708==r.getUTCMilliseconds()}catch(Y){}if(!s(\"json\")){var E=s(\"bug-string-char-index\");if(!r)var w=R.floor,S=[0,31,59,90,120,151,181,212,243,273,304,334],F=function(a,c){return S[c]+365*(a-1970)+w((a-1969+(c=+(1<c)))/4)-w((a-1901+c)/100)+w((a-1601+c)/400)};(u=G.hasOwnProperty)||(u=function(a){var c={},e;(c.__proto__=null,c.__proto__={toString:1},c).toString!=t?u=function(a){var c=this.__proto__;a=a in(this.__proto__=null,this);this.__proto__=\nc;return a}:(e=c.constructor,u=function(a){var c=(this.constructor||e).prototype;return a in this&&!(a in c&&this[a]===c[a])});c=null;return u.call(this,a)});var T={\"boolean\":1,number:1,string:1,undefined:1};C=function(a,c){var e=0,b,f,l;(b=function(){this.valueOf=0}).prototype.valueOf=0;f=new b;for(l in f)u.call(f,l)&&e++;b=f=null;e?C=2==e?function(a,c){var e={},b=\"[object Function]\"==t.call(a),f;for(f in a)b&&\"prototype\"==f||u.call(e,f)||!(e[f]=1)||!u.call(a,f)||c(f)}:function(a,c){var e=\"[object Function]\"==\nt.call(a),b,f;for(b in a)e&&\"prototype\"==b||!u.call(a,b)||(f=\"constructor\"===b)||c(b);(f||u.call(a,b=\"constructor\"))&&c(b)}:(f=\"valueOf toString toLocaleString propertyIsEnumerable isPrototypeOf hasOwnProperty constructor\".split(\" \"),C=function(a,c){var e=\"[object Function]\"==t.call(a),b,g;if(g=!e)if(g=\"function\"!=typeof a.constructor)g=typeof a.hasOwnProperty,g=\"object\"==g?!!a.hasOwnProperty:!T[g];g=g?a.hasOwnProperty:u;for(b in a)e&&\"prototype\"==b||!g.call(a,b)||c(b);for(e=f.length;b=f[--e];g.call(a,\nb)&&c(b));});return C(a,c)};if(!s(\"json-stringify\")){var U={92:\"\\\\\\\\\",34:'\\\\\"',8:\"\\\\b\",12:\"\\\\f\",10:\"\\\\n\",13:\"\\\\r\",9:\"\\\\t\"},x=function(a,c){return(\"000000\"+(c||0)).slice(-a)},O=function(a){for(var c='\"',b=0,g=a.length,f=!E||10<g,l=f&&(E?a.split(\"\"):a);b<g;b++){var d=a.charCodeAt(b);switch(d){case 8:case 9:case 10:case 12:case 13:case 34:case 92:c+=U[d];break;default:if(32>d){c+=\"\\\\u00\"+x(2,d.toString(16));break}c+=f?l[b]:a.charAt(b)}}return c+'\"'},L=function(a,c,b,g,f,l,d){var h,m,k,n,p,q,r,s,y;try{h=\nc[a]}catch(z){}if(\"object\"==typeof h&&h)if(m=t.call(h),\"[object Date]\"!=m||u.call(h,\"toJSON\"))\"function\"==typeof h.toJSON&&(\"[object Number]\"!=m&&\"[object String]\"!=m&&\"[object Array]\"!=m||u.call(h,\"toJSON\"))&&(h=h.toJSON(a));else if(h>-1/0&&h<1/0){if(F){n=w(h/864E5);for(m=w(n/365.2425)+1970-1;F(m+1,0)<=n;m++);for(k=w((n-F(m,0))/30.42);F(m,k+1)<=n;k++);n=1+n-F(m,k);p=(h%864E5+864E5)%864E5;q=w(p/36E5)%24;r=w(p/6E4)%60;s=w(p/1E3)%60;p%=1E3}else m=h.getUTCFullYear(),k=h.getUTCMonth(),n=h.getUTCDate(),\nq=h.getUTCHours(),r=h.getUTCMinutes(),s=h.getUTCSeconds(),p=h.getUTCMilliseconds();h=(0>=m||1E4<=m?(0>m?\"-\":\"+\")+x(6,0>m?-m:m):x(4,m))+\"-\"+x(2,k+1)+\"-\"+x(2,n)+\"T\"+x(2,q)+\":\"+x(2,r)+\":\"+x(2,s)+\".\"+x(3,p)+\"Z\"}else h=null;b&&(h=b.call(c,a,h));if(null===h)return\"null\";m=t.call(h);if(\"[object Boolean]\"==m)return\"\"+h;if(\"[object Number]\"==m)return h>-1/0&&h<1/0?\"\"+h:\"null\";if(\"[object String]\"==m)return O(\"\"+h);if(\"object\"==typeof h){for(a=d.length;a--;)if(d[a]===h)throw N();d.push(h);y=[];c=l;l+=f;if(\"[object Array]\"==\nm){k=0;for(a=h.length;k<a;k++)m=L(k,h,b,g,f,l,d),y.push(m===v?\"null\":m);a=y.length?f?\"[\\n\"+l+y.join(\",\\n\"+l)+\"\\n\"+c+\"]\":\"[\"+y.join(\",\")+\"]\":\"[]\"}else C(g||h,function(a){var c=L(a,h,b,g,f,l,d);c!==v&&y.push(O(a)+\":\"+(f?\" \":\"\")+c)}),a=y.length?f?\"{\\n\"+l+y.join(\",\\n\"+l)+\"\\n\"+c+\"}\":\"{\"+y.join(\",\")+\"}\":\"{}\";d.pop();return a}};q.stringify=function(a,c,b){var g,f,l,d;if(\"function\"==typeof c||\"object\"==typeof c&&c)if(\"[object Function]\"==(d=t.call(c)))f=c;else if(\"[object Array]\"==d){l={};for(var h=0,m=c.length,\nk;h<m;k=c[h++],(d=t.call(k),\"[object String]\"==d||\"[object Number]\"==d)&&(l[k]=1));}if(b)if(\"[object Number]\"==(d=t.call(b))){if(0<(b-=b%1))for(g=\"\",10<b&&(b=10);g.length<b;g+=\" \");}else\"[object String]\"==d&&(g=10>=b.length?b:b.slice(0,10));return L(\"\",(k={},k[\"\"]=a,k),f,l,g,\"\",[])}}if(!s(\"json-parse\")){var V=B.fromCharCode,W={92:\"\\\\\",34:'\"',47:\"/\",98:\"\\b\",116:\"\\t\",110:\"\\n\",102:\"\\f\",114:\"\\r\"},b,I,k=function(){b=I=null;throw J();},z=function(){for(var a=I,c=a.length,e,g,f,l,d;b<c;)switch(d=a.charCodeAt(b),\nd){case 9:case 10:case 13:case 32:b++;break;case 123:case 125:case 91:case 93:case 58:case 44:return e=E?a.charAt(b):a[b],b++,e;case 34:e=\"@\";for(b++;b<c;)if(d=a.charCodeAt(b),32>d)k();else if(92==d)switch(d=a.charCodeAt(++b),d){case 92:case 34:case 47:case 98:case 116:case 110:case 102:case 114:e+=W[d];b++;break;case 117:g=++b;for(f=b+4;b<f;b++)d=a.charCodeAt(b),48<=d&&57>=d||97<=d&&102>=d||65<=d&&70>=d||k();e+=V(\"0x\"+a.slice(g,b));break;default:k()}else{if(34==d)break;d=a.charCodeAt(b);for(g=b;32<=\nd&&92!=d&&34!=d;)d=a.charCodeAt(++b);e+=a.slice(g,b)}if(34==a.charCodeAt(b))return b++,e;k();default:g=b;45==d&&(l=!0,d=a.charCodeAt(++b));if(48<=d&&57>=d){for(48==d&&(d=a.charCodeAt(b+1),48<=d&&57>=d)&&k();b<c&&(d=a.charCodeAt(b),48<=d&&57>=d);b++);if(46==a.charCodeAt(b)){for(f=++b;f<c&&(d=a.charCodeAt(f),48<=d&&57>=d);f++);f==b&&k();b=f}d=a.charCodeAt(b);if(101==d||69==d){d=a.charCodeAt(++b);43!=d&&45!=d||b++;for(f=b;f<c&&(d=a.charCodeAt(f),48<=d&&57>=d);f++);f==b&&k();b=f}return+a.slice(g,b)}l&&\nk();if(\"true\"==a.slice(b,b+4))return b+=4,!0;if(\"false\"==a.slice(b,b+5))return b+=5,!1;if(\"null\"==a.slice(b,b+4))return b+=4,null;k()}return\"$\"},M=function(a){var c,b;\"$\"==a&&k();if(\"string\"==typeof a){if(\"@\"==(E?a.charAt(0):a[0]))return a.slice(1);if(\"[\"==a){for(c=[];;b||(b=!0)){a=z();if(\"]\"==a)break;b&&(\",\"==a?(a=z(),\"]\"==a&&k()):k());\",\"==a&&k();c.push(M(a))}return c}if(\"{\"==a){for(c={};;b||(b=!0)){a=z();if(\"}\"==a)break;b&&(\",\"==a?(a=z(),\"}\"==a&&k()):k());\",\"!=a&&\"string\"==typeof a&&\"@\"==(E?a.charAt(0):\na[0])&&\":\"==z()||k();c[a.slice(1)]=M(z())}return c}k()}return a},Q=function(a,b,e){e=P(a,b,e);e===v?delete a[b]:a[b]=e},P=function(a,b,e){var g=a[b],f;if(\"object\"==typeof g&&g)if(\"[object Array]\"==t.call(g))for(f=g.length;f--;)Q(g,f,e);else C(g,function(a){Q(g,a,e)});return e.call(a,b,g)};q.parse=function(a,c){var e,g;b=0;I=\"\"+a;e=M(z());\"$\"!=z()&&k();b=I=null;return c&&\"[object Function]\"==t.call(c)?P((g={},g[\"\"]=e,g),\"\",c):e}}}q.runInContext=K;return q}var J=typeof define===\"function\"&&define.amd,\nA=\"object\"==typeof global&&global;!A||A.global!==A&&A.window!==A||(n=A);if(\"object\"!=typeof exports||!exports||exports.nodeType||J){var N=n.JSON,B=K(n,n.JSON3={noConflict:function(){n.JSON=N;return B}});n.JSON={parse:B.parse,stringify:B.stringify}}else K(n,exports);J&&define(function(){return B})})(this);\n"
  },
  {
    "path": "test/browser/main.js",
    "content": "adapter.defer = adapter.pending = function() {\n    var ret = {};\n    ret.promise = new Promise(function(resolve, reject) {\n        ret.resolve = ret.fulfill = resolve;\n        ret.reject = reject;\n    });\n    return ret;\n};\n(function() {\n    var currentTime = 0;\n    var timers = {};\n    var currentId = 0;\n    var global = window;\n\n    function checkTimers() {\n        var keys = Object.keys(timers);\n        for (var i = 0; i < keys.length; ++i) {\n            key = keys[i];\n            var timer = timers[key];\n            if (!timer) continue;\n            if (currentTime >= (timer.started + timer.time)) {\n                if (timer.interval) {\n                    timer.started = currentTime;\n                } else {\n                    delete timers[key];\n                }\n                var fn = timer.fn;\n                fn();\n            }\n        }\n    }\n\n    function setInterval(fn, time) {\n        var id = currentId++;\n        time = (+time || 0) | 0;\n        if (time < 0) time = 0;\n        timers[id] = {\n            fn: fn,\n            time: time,\n            started: currentTime,\n            interval: true\n        };\n        return id;\n    }\n\n    function setTimeout(fn, time) {\n        var id = currentId++;\n        time = (+time || 0) | 0;\n        if (time < 0) time = 0;\n        timers[id] = {\n            fn: fn,\n            time: time,\n            started: currentTime,\n            interval: false\n        };\n        return id;\n    }\n\n    function clearTimeout(id) {\n        delete timers[id];\n    }\n    window.oldSetTimeout = window.setTimeout;\n    window.oldClearTimeout = window.clearTimeout;\n    var clearInterval = clearTimeout;\n    window.setInterval(function timerLoop() {\n        currentTime += 10;\n        checkTimers();\n    }, 1);\n    window.setTimeout = setTimeout;\n    window.clearTimeout = clearTimeout;\n    window.setInterval = setInterval;\n    window.clearInterval = clearInterval;\n})();\nwindow.adapter = window.Promise;\nglobal.Promise = global.adapter = window.adapter;\nwindow.assert = require(\"assert\");\n\nvar prev = window.assert.deepEqual;\nvar areDeepEqual = function(a, b) {\n    if (Array.isArray(a) &&\n        Array.isArray(b)) {\n        if (a.length === b.length) {\n            for (var i = 0; i < a.length; ++i) {\n                if (a[i] !== b[i]) {\n                    return false;\n                }\n            }\n            return true;\n        }\n        return false;\n    } else {\n        prev.call(window.assert, a, b);\n        return true;\n    }\n};\nwindow.assert.deepEqual = function(a, b) {\n    if (!areDeepEqual(a, b)) {\n        throw new Error(\"a not equal to b\");\n    }\n};\n\nwindow.setImmediate = function(fn){\n        setTimeout(fn, 0);\n};\n\nwindow.onload = function(){\n    var runner = mocha.run();\n\n    var failedTests = [];\n    runner.on('end', function(){\n        window.mochaResults = runner.stats;\n        window.mochaResults.reports = failedTests;\n        if (window.__coverage__) {\n          postCoverage();\n        }\n    });\n\n    runner.on('fail', logFailure);\n\n    function logFailure(test, err) {\n\n    var flattenTitles = function(test){\n        var titles = [];\n        while (test.parent.title){\n            titles.push(test.parent.title);\n            test = test.parent;\n        }\n        return titles.reverse();\n    };\n\n    failedTests.push({name: test.title, result: false, message: err.message, stack: err.stack, titles: flattenTitles(test) });\n    }\n};\n\nfunction postCoverage() {\n    var json = JSON.stringify(window.__coverage__);\n    var xhr = new XMLHttpRequest();\n    var browser = (navigator.userAgent + \"\").replace(/[^a-zA-Z0-9]/g, \"\");\n    var data = \"json=\" + encodeURIComponent(json) + \"&browser=\" + encodeURIComponent(browser);\n    xhr.open(\"POST\", \"/coverdata\", true);\n    xhr.setRequestHeader(\"Content-type\",\"application/x-www-form-urlencoded\");\n    xhr.send(data);\n}\n"
  },
  {
    "path": "test/browser/mocha.css",
    "content": "@charset \"utf-8\";\n\nbody {\n  margin:0;\n}\n\n#mocha {\n  font: 20px/1.5 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 60px 50px;\n}\n\n#mocha ul,\n#mocha li {\n  margin: 0;\n  padding: 0;\n}\n\n#mocha ul {\n  list-style: none;\n}\n\n#mocha h1,\n#mocha h2 {\n  margin: 0;\n}\n\n#mocha h1 {\n  margin-top: 15px;\n  font-size: 1em;\n  font-weight: 200;\n}\n\n#mocha h1 a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha h1 a:hover {\n  text-decoration: underline;\n}\n\n#mocha .suite .suite h1 {\n  margin-top: 0;\n  font-size: .8em;\n}\n\n#mocha .hidden {\n  display: none;\n}\n\n#mocha h2 {\n  font-size: 12px;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n#mocha .suite {\n  margin-left: 15px;\n}\n\n#mocha .test {\n  margin-left: 15px;\n  overflow: hidden;\n}\n\n#mocha .test.pending:hover h2::after {\n  content: '(pending)';\n  font-family: arial, sans-serif;\n}\n\n#mocha .test.pass.medium .duration {\n  background: #c09853;\n}\n\n#mocha .test.pass.slow .duration {\n  background: #b94a48;\n}\n\n#mocha .test.pass::before {\n  content: '✓';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #00d6b2;\n}\n\n#mocha .test.pass .duration {\n  font-size: 9px;\n  margin-left: 5px;\n  padding: 2px 5px;\n  color: #fff;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  -ms-border-radius: 5px;\n  -o-border-radius: 5px;\n  border-radius: 5px;\n}\n\n#mocha .test.pass.fast .duration {\n  display: none;\n}\n\n#mocha .test.pending {\n  color: #0b97c4;\n}\n\n#mocha .test.pending::before {\n  content: '◦';\n  color: #0b97c4;\n}\n\n#mocha .test.fail {\n  color: #c00;\n}\n\n#mocha .test.fail pre {\n  color: black;\n}\n\n#mocha .test.fail::before {\n  content: '✖';\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: #c00;\n}\n\n#mocha .test pre.error {\n  color: #c00;\n  max-height: 300px;\n  overflow: auto;\n}\n\n/**\n * (1): approximate for browsers not supporting calc\n * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)\n *      ^^ seriously\n */\n#mocha .test pre {\n  display: block;\n  float: left;\n  clear: left;\n  font: 12px/1.5 monaco, monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid #eee;\n  max-width: 85%; /*(1)*/\n  max-width: calc(100% - 42px); /*(2)*/\n  word-wrap: break-word;\n  border-bottom-color: #ddd;\n  -webkit-border-radius: 3px;\n  -webkit-box-shadow: 0 1px 3px #eee;\n  -moz-border-radius: 3px;\n  -moz-box-shadow: 0 1px 3px #eee;\n  border-radius: 3px;\n}\n\n#mocha .test h2 {\n  position: relative;\n}\n\n#mocha .test a.replay {\n  position: absolute;\n  top: 3px;\n  right: 0;\n  text-decoration: none;\n  vertical-align: middle;\n  display: block;\n  width: 15px;\n  height: 15px;\n  line-height: 15px;\n  text-align: center;\n  background: #eee;\n  font-size: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n  -webkit-transition: opacity 200ms;\n  -moz-transition: opacity 200ms;\n  transition: opacity 200ms;\n  opacity: 0.3;\n  color: #888;\n}\n\n#mocha .test:hover a.replay {\n  opacity: 1;\n}\n\n#mocha-report.pass .test.fail {\n  display: none;\n}\n\n#mocha-report.fail .test.pass {\n  display: none;\n}\n\n#mocha-report.pending .test.pass,\n#mocha-report.pending .test.fail {\n  display: none;\n}\n#mocha-report.pending .test.pass.pending {\n  display: block;\n}\n\n#mocha-error {\n  color: #c00;\n  font-size: 1.5em;\n  font-weight: 100;\n  letter-spacing: 1px;\n}\n\n#mocha-stats {\n  position: fixed;\n  top: 15px;\n  right: 10px;\n  font-size: 12px;\n  margin: 0;\n  color: #888;\n  z-index: 1;\n}\n\n#mocha-stats .progress {\n  float: right;\n  padding-top: 0;\n}\n\n#mocha-stats em {\n  color: black;\n}\n\n#mocha-stats a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha-stats a:hover {\n  border-bottom: 1px solid #eee;\n}\n\n#mocha-stats li {\n  display: inline-block;\n  margin: 0 5px;\n  list-style: none;\n  padding-top: 11px;\n}\n\n#mocha-stats canvas {\n  width: 40px;\n  height: 40px;\n}\n\n#mocha code .comment { color: #ddd; }\n#mocha code .init { color: #2f6fad; }\n#mocha code .string { color: #5890ad; }\n#mocha code .keyword { color: #8a6343; }\n#mocha code .number { color: #2f6fad; }\n\n@media screen and (max-device-width: 480px) {\n  #mocha {\n    margin: 60px 0px;\n  }\n\n  #mocha #stats {\n    position: absolute;\n  }\n}\n"
  },
  {
    "path": "test/browser/mocha.js",
    "content": ";(function(){\n\n// CommonJS require()\n\nfunction require(p){\n    var path = require.resolve(p)\n      , mod = require.modules[path];\n    if (!mod) throw new Error('failed to require \"' + p + '\"');\n    if (!mod.exports) {\n      mod.exports = {};\n      mod.call(mod.exports, mod, mod.exports, require.relative(path));\n    }\n    return mod.exports;\n  }\n\nrequire.modules = {};\n\nrequire.resolve = function (path){\n    var orig = path\n      , reg = path + '.js'\n      , index = path + '/index.js';\n    return require.modules[reg] && reg\n      || require.modules[index] && index\n      || orig;\n  };\n\nrequire.register = function (path, fn){\n    require.modules[path] = fn;\n  };\n\nrequire.relative = function (parent) {\n    return function(p){\n      if ('.' != p.charAt(0)) return require(p);\n\n      var path = parent.split('/')\n        , segs = p.split('/');\n      path.pop();\n\n      for (var i = 0; i < segs.length; i++) {\n        var seg = segs[i];\n        if ('..' == seg) path.pop();\n        else if ('.' != seg) path.push(seg);\n      }\n\n      return require(path.join('/'));\n    };\n  };\n\n\nrequire.register(\"browser/debug.js\", function(module, exports, require){\nmodule.exports = function(type){\n  return function(){\n  }\n};\n\n}); // module: browser/debug.js\n\nrequire.register(\"browser/diff.js\", function(module, exports, require){\n/* See LICENSE file for terms of use */\n\n/*\n * Text diff implementation.\n *\n * This library supports the following APIS:\n * JsDiff.diffChars: Character by character diff\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\n * JsDiff.diffLines: Line based diff\n *\n * JsDiff.diffCss: Diff targeted at CSS content\n *\n * These methods are based on the implementation proposed in\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\n */\nvar JsDiff = (function() {\n  /*jshint maxparams: 5*/\n  function clonePath(path) {\n    return { newPos: path.newPos, components: path.components.slice(0) };\n  }\n  function removeEmpty(array) {\n    var ret = [];\n    for (var i = 0; i < array.length; i++) {\n      if (array[i]) {\n        ret.push(array[i]);\n      }\n    }\n    return ret;\n  }\n  function escapeHTML(s) {\n    var n = s;\n    n = n.replace(/&/g, '&amp;');\n    n = n.replace(/</g, '&lt;');\n    n = n.replace(/>/g, '&gt;');\n    n = n.replace(/\"/g, '&quot;');\n\n    return n;\n  }\n\n  var Diff = function(ignoreWhitespace) {\n    this.ignoreWhitespace = ignoreWhitespace;\n  };\n  Diff.prototype = {\n      diff: function(oldString, newString) {\n        // Handle the identity case (this is due to unrolling editLength == 0\n        if (newString === oldString) {\n          return [{ value: newString }];\n        }\n        if (!newString) {\n          return [{ value: oldString, removed: true }];\n        }\n        if (!oldString) {\n          return [{ value: newString, added: true }];\n        }\n\n        newString = this.tokenize(newString);\n        oldString = this.tokenize(oldString);\n\n        var newLen = newString.length, oldLen = oldString.length;\n        var maxEditLength = newLen + oldLen;\n        var bestPath = [{ newPos: -1, components: [] }];\n\n        // Seed editLength = 0\n        var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\n        if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {\n          return bestPath[0].components;\n        }\n\n        for (var editLength = 1; editLength <= maxEditLength; editLength++) {\n          for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {\n            var basePath;\n            var addPath = bestPath[diagonalPath-1],\n                removePath = bestPath[diagonalPath+1];\n            oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\n            if (addPath) {\n              // No one else is going to attempt to use this value, clear it\n              bestPath[diagonalPath-1] = undefined;\n            }\n\n            var canAdd = addPath && addPath.newPos+1 < newLen;\n            var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\n            if (!canAdd && !canRemove) {\n              bestPath[diagonalPath] = undefined;\n              continue;\n            }\n\n            // Select the diagonal that we want to branch from. We select the prior\n            // path whose position in the new string is the farthest from the origin\n            // and does not pass the bounds of the diff graph\n            if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\n              basePath = clonePath(removePath);\n              this.pushComponent(basePath.components, oldString[oldPos], undefined, true);\n            } else {\n              basePath = clonePath(addPath);\n              basePath.newPos++;\n              this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);\n            }\n\n            var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);\n\n            if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {\n              return basePath.components;\n            } else {\n              bestPath[diagonalPath] = basePath;\n            }\n          }\n        }\n      },\n\n      pushComponent: function(components, value, added, removed) {\n        var last = components[components.length-1];\n        if (last && last.added === added && last.removed === removed) {\n          // We need to clone here as the component clone operation is just\n          // as shallow array clone\n          components[components.length-1] =\n            {value: this.join(last.value, value), added: added, removed: removed };\n        } else {\n          components.push({value: value, added: added, removed: removed });\n        }\n      },\n      extractCommon: function(basePath, newString, oldString, diagonalPath) {\n        var newLen = newString.length,\n            oldLen = oldString.length,\n            newPos = basePath.newPos,\n            oldPos = newPos - diagonalPath;\n        while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {\n          newPos++;\n          oldPos++;\n\n          this.pushComponent(basePath.components, newString[newPos], undefined, undefined);\n        }\n        basePath.newPos = newPos;\n        return oldPos;\n      },\n\n      equals: function(left, right) {\n        var reWhitespace = /\\S/;\n        if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {\n          return true;\n        } else {\n          return left === right;\n        }\n      },\n      join: function(left, right) {\n        return left + right;\n      },\n      tokenize: function(value) {\n        return value;\n      }\n  };\n\n  var CharDiff = new Diff();\n\n  var WordDiff = new Diff(true);\n  var WordWithSpaceDiff = new Diff();\n  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/(\\s+|\\b)/));\n  };\n\n  var CssDiff = new Diff(true);\n  CssDiff.tokenize = function(value) {\n    return removeEmpty(value.split(/([{}:;,]|\\s+)/));\n  };\n\n  var LineDiff = new Diff();\n  LineDiff.tokenize = function(value) {\n    return value.split(/^/m);\n  };\n\n  return {\n    Diff: Diff,\n\n    diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },\n    diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },\n    diffWordsWithSpace: function(oldStr, newStr) { return WordWithSpaceDiff.diff(oldStr, newStr); },\n    diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },\n\n    diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },\n\n    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\n      var ret = [];\n\n      ret.push('Index: ' + fileName);\n      ret.push('===================================================================');\n      ret.push('--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\\t' + oldHeader));\n      ret.push('+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\\t' + newHeader));\n\n      var diff = LineDiff.diff(oldStr, newStr);\n      if (!diff[diff.length-1].value) {\n        diff.pop();   // Remove trailing newline add\n      }\n      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier\n\n      function contextLines(lines) {\n        return lines.map(function(entry) { return ' ' + entry; });\n      }\n      function eofNL(curRange, i, current) {\n        var last = diff[diff.length-2],\n            isLast = i === diff.length-2,\n            isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);\n\n        // Figure out if this is the last line for the given file and missing NL\n        if (!/\\n$/.test(current.value) && (isLast || isLastOfType)) {\n          curRange.push('\\\\ No newline at end of file');\n        }\n      }\n\n      var oldRangeStart = 0, newRangeStart = 0, curRange = [],\n          oldLine = 1, newLine = 1;\n      for (var i = 0; i < diff.length; i++) {\n        var current = diff[i],\n            lines = current.lines || current.value.replace(/\\n$/, '').split('\\n');\n        current.lines = lines;\n\n        if (current.added || current.removed) {\n          if (!oldRangeStart) {\n            var prev = diff[i-1];\n            oldRangeStart = oldLine;\n            newRangeStart = newLine;\n\n            if (prev) {\n              curRange = contextLines(prev.lines.slice(-4));\n              oldRangeStart -= curRange.length;\n              newRangeStart -= curRange.length;\n            }\n          }\n          curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?'+':'-') + entry; }));\n          eofNL(curRange, i, current);\n\n          if (current.added) {\n            newLine += lines.length;\n          } else {\n            oldLine += lines.length;\n          }\n        } else {\n          if (oldRangeStart) {\n            // Close out any changes that have been output (or join overlapping)\n            if (lines.length <= 8 && i < diff.length-2) {\n              // Overlapping\n              curRange.push.apply(curRange, contextLines(lines));\n            } else {\n              // end the range and output\n              var contextSize = Math.min(lines.length, 4);\n              ret.push(\n                  '@@ -' + oldRangeStart + ',' + (oldLine-oldRangeStart+contextSize)\n                  + ' +' + newRangeStart + ',' + (newLine-newRangeStart+contextSize)\n                  + ' @@');\n              ret.push.apply(ret, curRange);\n              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\n              if (lines.length <= 4) {\n                eofNL(ret, i, current);\n              }\n\n              oldRangeStart = 0;  newRangeStart = 0; curRange = [];\n            }\n          }\n          oldLine += lines.length;\n          newLine += lines.length;\n        }\n      }\n\n      return ret.join('\\n') + '\\n';\n    },\n\n    applyPatch: function(oldStr, uniDiff) {\n      var diffstr = uniDiff.split('\\n');\n      var diff = [];\n      var remEOFNL = false,\n          addEOFNL = false;\n\n      for (var i = (diffstr[0][0]==='I'?4:0); i < diffstr.length; i++) {\n        if(diffstr[i][0] === '@') {\n          var meh = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\n          diff.unshift({\n            start:meh[3],\n            oldlength:meh[2],\n            oldlines:[],\n            newlength:meh[4],\n            newlines:[]\n          });\n        } else if(diffstr[i][0] === '+') {\n          diff[0].newlines.push(diffstr[i].substr(1));\n        } else if(diffstr[i][0] === '-') {\n          diff[0].oldlines.push(diffstr[i].substr(1));\n        } else if(diffstr[i][0] === ' ') {\n          diff[0].newlines.push(diffstr[i].substr(1));\n          diff[0].oldlines.push(diffstr[i].substr(1));\n        } else if(diffstr[i][0] === '\\\\') {\n          if (diffstr[i-1][0] === '+') {\n            remEOFNL = true;\n          } else if(diffstr[i-1][0] === '-') {\n            addEOFNL = true;\n          }\n        }\n      }\n\n      var str = oldStr.split('\\n');\n      for (var i = diff.length - 1; i >= 0; i--) {\n        var d = diff[i];\n        for (var j = 0; j < d.oldlength; j++) {\n          if(str[d.start-1+j] !== d.oldlines[j]) {\n            return false;\n          }\n        }\n        Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newlines));\n      }\n\n      if (remEOFNL) {\n        while (!str[str.length-1]) {\n          str.pop();\n        }\n      } else if (addEOFNL) {\n        str.push('');\n      }\n      return str.join('\\n');\n    },\n\n    convertChangesToXML: function(changes){\n      var ret = [];\n      for ( var i = 0; i < changes.length; i++) {\n        var change = changes[i];\n        if (change.added) {\n          ret.push('<ins>');\n        } else if (change.removed) {\n          ret.push('<del>');\n        }\n\n        ret.push(escapeHTML(change.value));\n\n        if (change.added) {\n          ret.push('</ins>');\n        } else if (change.removed) {\n          ret.push('</del>');\n        }\n      }\n      return ret.join('');\n    },\n\n    // See: http://code.google.com/p/google-diff-match-patch/wiki/API\n    convertChangesToDMP: function(changes){\n      var ret = [], change;\n      for ( var i = 0; i < changes.length; i++) {\n        change = changes[i];\n        ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);\n      }\n      return ret;\n    }\n  };\n})();\n\nif (typeof module !== 'undefined') {\n    module.exports = JsDiff;\n}\n\n}); // module: browser/diff.js\n\nrequire.register(\"browser/escape-string-regexp.js\", function(module, exports, require){\n'use strict';\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n  if (typeof str !== 'string') {\n    throw new TypeError('Expected a string');\n  }\n\n  return str.replace(matchOperatorsRe,  '\\\\$&');\n};\n\n}); // module: browser/escape-string-regexp.js\n\nrequire.register(\"browser/events.js\", function(module, exports, require){\n/**\n * Module exports.\n */\n\nexports.EventEmitter = EventEmitter;\n\n/**\n * Check if `obj` is an array.\n */\n\nfunction isArray(obj) {\n  return '[object Array]' == {}.toString.call(obj);\n}\n\n/**\n * Event emitter constructor.\n *\n * @api public\n */\n\nfunction EventEmitter(){};\n\n/**\n * Adds a listener.\n *\n * @api public\n */\n\nEventEmitter.prototype.on = function (name, fn) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = fn;\n  } else if (isArray(this.$events[name])) {\n    this.$events[name].push(fn);\n  } else {\n    this.$events[name] = [this.$events[name], fn];\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n/**\n * Adds a volatile listener.\n *\n * @api public\n */\n\nEventEmitter.prototype.once = function (name, fn) {\n  var self = this;\n\n  function on () {\n    self.removeListener(name, on);\n    fn.apply(this, arguments);\n  };\n\n  on.listener = fn;\n  this.on(name, on);\n\n  return this;\n};\n\n/**\n * Removes a listener.\n *\n * @api public\n */\n\nEventEmitter.prototype.removeListener = function (name, fn) {\n  if (this.$events && this.$events[name]) {\n    var list = this.$events[name];\n\n    if (isArray(list)) {\n      var pos = -1;\n\n      for (var i = 0, l = list.length; i < l; i++) {\n        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {\n          pos = i;\n          break;\n        }\n      }\n\n      if (pos < 0) {\n        return this;\n      }\n\n      list.splice(pos, 1);\n\n      if (!list.length) {\n        delete this.$events[name];\n      }\n    } else if (list === fn || (list.listener && list.listener === fn)) {\n      delete this.$events[name];\n    }\n  }\n\n  return this;\n};\n\n/**\n * Removes all listeners for an event.\n *\n * @api public\n */\n\nEventEmitter.prototype.removeAllListeners = function (name) {\n  if (name === undefined) {\n    this.$events = {};\n    return this;\n  }\n\n  if (this.$events && this.$events[name]) {\n    this.$events[name] = null;\n  }\n\n  return this;\n};\n\n/**\n * Gets all listeners for a certain event.\n *\n * @api public\n */\n\nEventEmitter.prototype.listeners = function (name) {\n  if (!this.$events) {\n    this.$events = {};\n  }\n\n  if (!this.$events[name]) {\n    this.$events[name] = [];\n  }\n\n  if (!isArray(this.$events[name])) {\n    this.$events[name] = [this.$events[name]];\n  }\n\n  return this.$events[name];\n};\n\n/**\n * Emits an event.\n *\n * @api public\n */\n\nEventEmitter.prototype.emit = function (name) {\n  if (!this.$events) {\n    return false;\n  }\n\n  var handler = this.$events[name];\n\n  if (!handler) {\n    return false;\n  }\n\n  var args = [].slice.call(arguments, 1);\n\n  if ('function' == typeof handler) {\n    handler.apply(this, args);\n  } else if (isArray(handler)) {\n    var listeners = handler.slice();\n\n    for (var i = 0, l = listeners.length; i < l; i++) {\n      listeners[i].apply(this, args);\n    }\n  } else {\n    return false;\n  }\n\n  return true;\n};\n\n}); // module: browser/events.js\n\nrequire.register(\"browser/fs.js\", function(module, exports, require){\n\n}); // module: browser/fs.js\n\nrequire.register(\"browser/glob.js\", function(module, exports, require){\n\n}); // module: browser/glob.js\n\nrequire.register(\"browser/path.js\", function(module, exports, require){\n\n}); // module: browser/path.js\n\nrequire.register(\"browser/progress.js\", function(module, exports, require){\n/**\n * Expose `Progress`.\n */\n\nmodule.exports = Progress;\n\n/**\n * Initialize a new `Progress` indicator.\n */\n\nfunction Progress() {\n  this.percent = 0;\n  this.size(0);\n  this.fontSize(11);\n  this.font('helvetica, arial, sans-serif');\n}\n\n/**\n * Set progress size to `n`.\n *\n * @param {Number} n\n * @return {Progress} for chaining\n * @api public\n */\n\nProgress.prototype.size = function(n){\n  this._size = n;\n  return this;\n};\n\n/**\n * Set text to `str`.\n *\n * @param {String} str\n * @return {Progress} for chaining\n * @api public\n */\n\nProgress.prototype.text = function(str){\n  this._text = str;\n  return this;\n};\n\n/**\n * Set font size to `n`.\n *\n * @param {Number} n\n * @return {Progress} for chaining\n * @api public\n */\n\nProgress.prototype.fontSize = function(n){\n  this._fontSize = n;\n  return this;\n};\n\n/**\n * Set font `family`.\n *\n * @param {String} family\n * @return {Progress} for chaining\n */\n\nProgress.prototype.font = function(family){\n  this._font = family;\n  return this;\n};\n\n/**\n * Update percentage to `n`.\n *\n * @param {Number} n\n * @return {Progress} for chaining\n */\n\nProgress.prototype.update = function(n){\n  this.percent = n;\n  return this;\n};\n\n/**\n * Draw on `ctx`.\n *\n * @param {CanvasRenderingContext2d} ctx\n * @return {Progress} for chaining\n */\n\nProgress.prototype.draw = function(ctx){\n  try {\n    var percent = Math.min(this.percent, 100)\n      , size = this._size\n      , half = size / 2\n      , x = half\n      , y = half\n      , rad = half - 1\n      , fontSize = this._fontSize;\n\n    ctx.font = fontSize + 'px ' + this._font;\n\n    var angle = Math.PI * 2 * (percent / 100);\n    ctx.clearRect(0, 0, size, size);\n\n    // outer circle\n    ctx.strokeStyle = '#9f9f9f';\n    ctx.beginPath();\n    ctx.arc(x, y, rad, 0, angle, false);\n    ctx.stroke();\n\n    // inner circle\n    ctx.strokeStyle = '#eee';\n    ctx.beginPath();\n    ctx.arc(x, y, rad - 1, 0, angle, true);\n    ctx.stroke();\n\n    // text\n    var text = this._text || (percent | 0) + '%'\n      , w = ctx.measureText(text).width;\n\n    ctx.fillText(\n        text\n      , x - w / 2 + 1\n      , y + fontSize / 2 - 1);\n  } catch (ex) {} //don't fail if we can't render progress\n  return this;\n};\n\n}); // module: browser/progress.js\n\nrequire.register(\"browser/tty.js\", function(module, exports, require){\nexports.isatty = function(){\n  return true;\n};\n\nexports.getWindowSize = function(){\n  if ('innerHeight' in global) {\n    return [global.innerHeight, global.innerWidth];\n  } else {\n    // In a Web Worker, the DOM Window is not available.\n    return [640, 480];\n  }\n};\n\n}); // module: browser/tty.js\n\nrequire.register(\"context.js\", function(module, exports, require){\n/**\n * Expose `Context`.\n */\n\nmodule.exports = Context;\n\n/**\n * Initialize a new `Context`.\n *\n * @api private\n */\n\nfunction Context(){}\n\n/**\n * Set or get the context `Runnable` to `runnable`.\n *\n * @param {Runnable} runnable\n * @return {Context}\n * @api private\n */\n\nContext.prototype.runnable = function(runnable){\n  if (0 == arguments.length) return this._runnable;\n  this.test = this._runnable = runnable;\n  return this;\n};\n\n/**\n * Set test timeout `ms`.\n *\n * @param {Number} ms\n * @return {Context} self\n * @api private\n */\n\nContext.prototype.timeout = function(ms){\n  if (arguments.length === 0) return this.runnable().timeout();\n  this.runnable().timeout(ms);\n  return this;\n};\n\n/**\n * Set test timeout `enabled`.\n *\n * @param {Boolean} enabled\n * @return {Context} self\n * @api private\n */\n\nContext.prototype.enableTimeouts = function (enabled) {\n  this.runnable().enableTimeouts(enabled);\n  return this;\n};\n\n\n/**\n * Set test slowness threshold `ms`.\n *\n * @param {Number} ms\n * @return {Context} self\n * @api private\n */\n\nContext.prototype.slow = function(ms){\n  this.runnable().slow(ms);\n  return this;\n};\n\n/**\n * Inspect the context void of `._runnable`.\n *\n * @return {String}\n * @api private\n */\n\nContext.prototype.inspect = function(){\n  return JSON.stringify(this, function(key, val){\n    if ('_runnable' == key) return;\n    if ('test' == key) return;\n    return val;\n  }, 2);\n};\n\n}); // module: context.js\n\nrequire.register(\"hook.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\n\n/**\n * Expose `Hook`.\n */\n\nmodule.exports = Hook;\n\n/**\n * Initialize a new `Hook` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\n\nfunction Hook(title, fn) {\n  Runnable.call(this, title, fn);\n  this.type = 'hook';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\n\nfunction F(){};\nF.prototype = Runnable.prototype;\nHook.prototype = new F;\nHook.prototype.constructor = Hook;\n\n\n/**\n * Get or set the test `err`.\n *\n * @param {Error} err\n * @return {Error}\n * @api public\n */\n\nHook.prototype.error = function(err){\n  if (0 == arguments.length) {\n    var err = this._error;\n    this._error = null;\n    return err;\n  }\n\n  this._error = err;\n};\n\n}); // module: hook.js\n\nrequire.register(\"interfaces/bdd.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite')\n  , Test = require('../test')\n  , utils = require('../utils')\n  , escapeRe = require('browser/escape-string-regexp');\n\n/**\n * BDD-style interface:\n *\n *      describe('Array', function(){\n *        describe('#indexOf()', function(){\n *          it('should return -1 when not present', function(){\n *\n *          });\n *\n *          it('should return the index when present', function(){\n *\n *          });\n *        });\n *      });\n *\n */\n\nmodule.exports = function(suite){\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha){\n\n    /**\n     * Execute before running tests.\n     */\n\n    context.before = function(name, fn){\n      suites[0].beforeAll(name, fn);\n    };\n\n    /**\n     * Execute after running tests.\n     */\n\n    context.after = function(name, fn){\n      suites[0].afterAll(name, fn);\n    };\n\n    /**\n     * Execute before each test case.\n     */\n\n    context.beforeEach = function(name, fn){\n      suites[0].beforeEach(name, fn);\n    };\n\n    /**\n     * Execute after each test case.\n     */\n\n    context.afterEach = function(name, fn){\n      suites[0].afterEach(name, fn);\n    };\n\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.describe = context.context = function(title, fn){\n      var suite = Suite.create(suites[0], title);\n      suite.file = file;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n      return suite;\n    };\n\n    /**\n     * Pending describe.\n     */\n\n    context.xdescribe =\n    context.xcontext =\n    context.describe.skip = function(title, fn){\n      var suite = Suite.create(suites[0], title);\n      suite.pending = true;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n    };\n\n    /**\n     * Exclusive suite.\n     */\n\n    context.describe.only = function(title, fn){\n      var suite = context.describe(title, fn);\n      mocha.grep(suite.fullTitle());\n      return suite;\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.it = context.specify = function(title, fn){\n      var suite = suites[0];\n      if (suite.pending) fn = null;\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.it.only = function(title, fn){\n      var test = context.it(title, fn);\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\n      mocha.grep(new RegExp(reString));\n      return test;\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.xit =\n    context.xspecify =\n    context.it.skip = function(title){\n      context.it(title);\n    };\n  });\n};\n\n}); // module: interfaces/bdd.js\n\nrequire.register(\"interfaces/exports.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite')\n  , Test = require('../test');\n\n/**\n * TDD-style interface:\n *\n *     exports.Array = {\n *       '#indexOf()': {\n *         'should return -1 when the value is not present': function(){\n *\n *         },\n *\n *         'should return the correct index when the value is present': function(){\n *\n *         }\n *       }\n *     };\n *\n */\n\nmodule.exports = function(suite){\n  var suites = [suite];\n\n  suite.on('require', visit);\n\n  function visit(obj, file) {\n    var suite;\n    for (var key in obj) {\n      if ('function' == typeof obj[key]) {\n        var fn = obj[key];\n        switch (key) {\n          case 'before':\n            suites[0].beforeAll(fn);\n            break;\n          case 'after':\n            suites[0].afterAll(fn);\n            break;\n          case 'beforeEach':\n            suites[0].beforeEach(fn);\n            break;\n          case 'afterEach':\n            suites[0].afterEach(fn);\n            break;\n          default:\n            var test = new Test(key, fn);\n            test.file = file;\n            suites[0].addTest(test);\n        }\n      } else {\n        suite = Suite.create(suites[0], key);\n        suites.unshift(suite);\n        visit(obj[key]);\n        suites.shift();\n      }\n    }\n  }\n};\n\n}); // module: interfaces/exports.js\n\nrequire.register(\"interfaces/index.js\", function(module, exports, require){\nexports.bdd = require('./bdd');\nexports.tdd = require('./tdd');\nexports.qunit = require('./qunit');\nexports.exports = require('./exports');\n\n}); // module: interfaces/index.js\n\nrequire.register(\"interfaces/qunit.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite')\n  , Test = require('../test')\n  , escapeRe = require('browser/escape-string-regexp')\n  , utils = require('../utils');\n\n/**\n * QUnit-style interface:\n *\n *     suite('Array');\n *\n *     test('#length', function(){\n *       var arr = [1,2,3];\n *       ok(arr.length == 3);\n *     });\n *\n *     test('#indexOf()', function(){\n *       var arr = [1,2,3];\n *       ok(arr.indexOf(1) == 0);\n *       ok(arr.indexOf(2) == 1);\n *       ok(arr.indexOf(3) == 2);\n *     });\n *\n *     suite('String');\n *\n *     test('#length', function(){\n *       ok('foo'.length == 3);\n *     });\n *\n */\n\nmodule.exports = function(suite){\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha){\n\n    /**\n     * Execute before running tests.\n     */\n\n    context.before = function(name, fn){\n      suites[0].beforeAll(name, fn);\n    };\n\n    /**\n     * Execute after running tests.\n     */\n\n    context.after = function(name, fn){\n      suites[0].afterAll(name, fn);\n    };\n\n    /**\n     * Execute before each test case.\n     */\n\n    context.beforeEach = function(name, fn){\n      suites[0].beforeEach(name, fn);\n    };\n\n    /**\n     * Execute after each test case.\n     */\n\n    context.afterEach = function(name, fn){\n      suites[0].afterEach(name, fn);\n    };\n\n    /**\n     * Describe a \"suite\" with the given `title`.\n     */\n\n    context.suite = function(title){\n      if (suites.length > 1) suites.shift();\n      var suite = Suite.create(suites[0], title);\n      suite.file = file;\n      suites.unshift(suite);\n      return suite;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.suite.only = function(title, fn){\n      var suite = context.suite(title, fn);\n      mocha.grep(suite.fullTitle());\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function(title, fn){\n      var test = new Test(title, fn);\n      test.file = file;\n      suites[0].addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn){\n      var test = context.test(title, fn);\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\n      mocha.grep(new RegExp(reString));\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.test.skip = function(title){\n      context.test(title);\n    };\n  });\n};\n\n}); // module: interfaces/qunit.js\n\nrequire.register(\"interfaces/tdd.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Suite = require('../suite')\n  , Test = require('../test')\n  , escapeRe = require('browser/escape-string-regexp')\n  , utils = require('../utils');\n\n/**\n * TDD-style interface:\n *\n *      suite('Array', function(){\n *        suite('#indexOf()', function(){\n *          suiteSetup(function(){\n *\n *          });\n *\n *          test('should return -1 when not present', function(){\n *\n *          });\n *\n *          test('should return the index when present', function(){\n *\n *          });\n *\n *          suiteTeardown(function(){\n *\n *          });\n *        });\n *      });\n *\n */\n\nmodule.exports = function(suite){\n  var suites = [suite];\n\n  suite.on('pre-require', function(context, file, mocha){\n\n    /**\n     * Execute before each test case.\n     */\n\n    context.setup = function(name, fn){\n      suites[0].beforeEach(name, fn);\n    };\n\n    /**\n     * Execute after each test case.\n     */\n\n    context.teardown = function(name, fn){\n      suites[0].afterEach(name, fn);\n    };\n\n    /**\n     * Execute before the suite.\n     */\n\n    context.suiteSetup = function(name, fn){\n      suites[0].beforeAll(name, fn);\n    };\n\n    /**\n     * Execute after the suite.\n     */\n\n    context.suiteTeardown = function(name, fn){\n      suites[0].afterAll(name, fn);\n    };\n\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.suite = function(title, fn){\n      var suite = Suite.create(suites[0], title);\n      suite.file = file;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n      return suite;\n    };\n\n    /**\n     * Pending suite.\n     */\n    context.suite.skip = function(title, fn) {\n      var suite = Suite.create(suites[0], title);\n      suite.pending = true;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.suite.only = function(title, fn){\n      var suite = context.suite(title, fn);\n      mocha.grep(suite.fullTitle());\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function(title, fn){\n      var suite = suites[0];\n      if (suite.pending) fn = null;\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function(title, fn){\n      var test = context.test(title, fn);\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\n      mocha.grep(new RegExp(reString));\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.test.skip = function(title){\n      context.test(title);\n    };\n  });\n};\n\n}); // module: interfaces/tdd.js\n\nrequire.register(\"mocha.js\", function(module, exports, require){\n/*!\n * mocha\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n * MIT Licensed\n */\n\n/**\n * Module dependencies.\n */\n\nvar path = require('browser/path')\n  , escapeRe = require('browser/escape-string-regexp')\n  , utils = require('./utils');\n\n/**\n * Expose `Mocha`.\n */\n\nexports = module.exports = Mocha;\n\n/**\n * To require local UIs and reporters when running in node.\n */\n\nif (typeof process !== 'undefined' && typeof process.cwd === 'function') {\n  var join = path.join\n    , cwd = process.cwd();\n  module.paths.push(cwd, join(cwd, 'node_modules'));\n}\n\n/**\n * Expose internals.\n */\n\nexports.utils = utils;\nexports.interfaces = require('./interfaces');\nexports.reporters = require('./reporters');\nexports.Runnable = require('./runnable');\nexports.Context = require('./context');\nexports.Runner = require('./runner');\nexports.Suite = require('./suite');\nexports.Hook = require('./hook');\nexports.Test = require('./test');\n\n/**\n * Return image `name` path.\n *\n * @param {String} name\n * @return {String}\n * @api private\n */\n\nfunction image(name) {\n  return __dirname + '/../images/' + name + '.png';\n}\n\n/**\n * Setup mocha with `options`.\n *\n * Options:\n *\n *   - `ui` name \"bdd\", \"tdd\", \"exports\" etc\n *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`\n *   - `globals` array of accepted globals\n *   - `timeout` timeout in milliseconds\n *   - `bail` bail on the first test failure\n *   - `slow` milliseconds to wait before considering a test slow\n *   - `ignoreLeaks` ignore global leaks\n *   - `grep` string or regexp to filter tests with\n *\n * @param {Object} options\n * @api public\n */\n\nfunction Mocha(options) {\n  options = options || {};\n  this.files = [];\n  this.options = options;\n  this.grep(options.grep);\n  this.suite = new exports.Suite('', new exports.Context);\n  this.ui(options.ui);\n  this.bail(options.bail);\n  this.reporter(options.reporter);\n  if (null != options.timeout) this.timeout(options.timeout);\n  this.useColors(options.useColors)\n  if (options.enableTimeouts !== null) this.enableTimeouts(options.enableTimeouts);\n  if (options.slow) this.slow(options.slow);\n\n  this.suite.on('pre-require', function (context) {\n    exports.afterEach = context.afterEach || context.teardown;\n    exports.after = context.after || context.suiteTeardown;\n    exports.beforeEach = context.beforeEach || context.setup;\n    exports.before = context.before || context.suiteSetup;\n    exports.describe = context.describe || context.suite;\n    exports.it = context.it || context.test;\n    exports.setup = context.setup || context.beforeEach;\n    exports.suiteSetup = context.suiteSetup || context.before;\n    exports.suiteTeardown = context.suiteTeardown || context.after;\n    exports.suite = context.suite || context.describe;\n    exports.teardown = context.teardown || context.afterEach;\n    exports.test = context.test || context.it;\n  });\n}\n\n/**\n * Enable or disable bailing on the first failure.\n *\n * @param {Boolean} [bail]\n * @api public\n */\n\nMocha.prototype.bail = function(bail){\n  if (0 == arguments.length) bail = true;\n  this.suite.bail(bail);\n  return this;\n};\n\n/**\n * Add test `file`.\n *\n * @param {String} file\n * @api public\n */\n\nMocha.prototype.addFile = function(file){\n  this.files.push(file);\n  return this;\n};\n\n/**\n * Set reporter to `reporter`, defaults to \"spec\".\n *\n * @param {String|Function} reporter name or constructor\n * @api public\n */\n\nMocha.prototype.reporter = function(reporter){\n  if ('function' == typeof reporter) {\n    this._reporter = reporter;\n  } else {\n    reporter = reporter || 'spec';\n    var _reporter;\n    try { _reporter = require('./reporters/' + reporter); } catch (err) {};\n    if (!_reporter) try { _reporter = require(reporter); } catch (err) {};\n    if (!_reporter && reporter === 'teamcity')\n      console.warn('The Teamcity reporter was moved to a package named ' +\n        'mocha-teamcity-reporter ' +\n        '(https://npmjs.org/package/mocha-teamcity-reporter).');\n    if (!_reporter) throw new Error('invalid reporter \"' + reporter + '\"');\n    this._reporter = _reporter;\n  }\n  return this;\n};\n\n/**\n * Set test UI `name`, defaults to \"bdd\".\n *\n * @param {String} bdd\n * @api public\n */\n\nMocha.prototype.ui = function(name){\n  name = name || 'bdd';\n  this._ui = exports.interfaces[name];\n  if (!this._ui) try { this._ui = require(name); } catch (err) {};\n  if (!this._ui) throw new Error('invalid interface \"' + name + '\"');\n  this._ui = this._ui(this.suite);\n  return this;\n};\n\n/**\n * Load registered files.\n *\n * @api private\n */\n\nMocha.prototype.loadFiles = function(fn){\n  var self = this;\n  var suite = this.suite;\n  var pending = this.files.length;\n  this.files.forEach(function(file){\n    file = path.resolve(file);\n    suite.emit('pre-require', global, file, self);\n    suite.emit('require', require(file), file, self);\n    suite.emit('post-require', global, file, self);\n    --pending || (fn && fn());\n  });\n};\n\n/**\n * Enable growl support.\n *\n * @api private\n */\n\nMocha.prototype._growl = function(runner, reporter) {\n  var notify = require('growl');\n\n  runner.on('end', function(){\n    var stats = reporter.stats;\n    if (stats.failures) {\n      var msg = stats.failures + ' of ' + runner.total + ' tests failed';\n      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });\n    } else {\n      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {\n          name: 'mocha'\n        , title: 'Passed'\n        , image: image('ok')\n      });\n    }\n  });\n};\n\n/**\n * Add regexp to grep, if `re` is a string it is escaped.\n *\n * @param {RegExp|String} re\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.grep = function(re){\n  this.options.grep = 'string' == typeof re\n    ? new RegExp(escapeRe(re))\n    : re;\n  return this;\n};\n\n/**\n * Invert `.grep()` matches.\n *\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.invert = function(){\n  this.options.invert = true;\n  return this;\n};\n\n/**\n * Ignore global leaks.\n *\n * @param {Boolean} ignore\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.ignoreLeaks = function(ignore){\n  this.options.ignoreLeaks = !!ignore;\n  return this;\n};\n\n/**\n * Enable global leak checking.\n *\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.checkLeaks = function(){\n  this.options.ignoreLeaks = false;\n  return this;\n};\n\n/**\n * Enable growl support.\n *\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.growl = function(){\n  this.options.growl = true;\n  return this;\n};\n\n/**\n * Ignore `globals` array or string.\n *\n * @param {Array|String} globals\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.globals = function(globals){\n  this.options.globals = (this.options.globals || []).concat(globals);\n  return this;\n};\n\n/**\n * Emit color output.\n *\n * @param {Boolean} colors\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.useColors = function(colors){\n  this.options.useColors = arguments.length && colors != undefined\n    ? colors\n    : true;\n  return this;\n};\n\n/**\n * Use inline diffs rather than +/-.\n *\n * @param {Boolean} inlineDiffs\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.useInlineDiffs = function(inlineDiffs) {\n  this.options.useInlineDiffs = arguments.length && inlineDiffs != undefined\n  ? inlineDiffs\n  : false;\n  return this;\n};\n\n/**\n * Set the timeout in milliseconds.\n *\n * @param {Number} timeout\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.timeout = function(timeout){\n  this.suite.timeout(timeout);\n  return this;\n};\n\n/**\n * Set slowness threshold in milliseconds.\n *\n * @param {Number} slow\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.slow = function(slow){\n  this.suite.slow(slow);\n  return this;\n};\n\n/**\n * Enable timeouts.\n *\n * @param {Boolean} enabled\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.enableTimeouts = function(enabled) {\n  this.suite.enableTimeouts(arguments.length && enabled !== undefined\n    ? enabled\n    : true);\n  return this\n};\n\n/**\n * Makes all tests async (accepting a callback)\n *\n * @return {Mocha}\n * @api public\n */\n\nMocha.prototype.asyncOnly = function(){\n  this.options.asyncOnly = true;\n  return this;\n};\n\n/**\n * Disable syntax highlighting (in browser).\n * @returns {Mocha}\n * @api public\n */\nMocha.prototype.noHighlighting = function() {\n  this.options.noHighlighting = true;\n  return this;\n};\n\n/**\n * Run tests and invoke `fn()` when complete.\n *\n * @param {Function} fn\n * @return {Runner}\n * @api public\n */\n\nMocha.prototype.run = function(fn){\n  if (this.files.length) this.loadFiles();\n  var suite = this.suite;\n  var options = this.options;\n  options.files = this.files;\n  var runner = new exports.Runner(suite);\n  var reporter = new this._reporter(runner, options);\n  runner.ignoreLeaks = false !== options.ignoreLeaks;\n  runner.asyncOnly = options.asyncOnly;\n  if (options.grep) runner.grep(options.grep, options.invert);\n  if (options.globals) runner.globals(options.globals);\n  if (options.growl) this._growl(runner, reporter);\n  exports.reporters.Base.useColors = options.useColors;\n  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;\n  return runner.run(fn);\n};\n\n}); // module: mocha.js\n\nrequire.register(\"ms.js\", function(module, exports, require){\n/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function(val, options){\n  options = options || {};\n  if ('string' == typeof val) return parse(val);\n  return options['long'] ? longFormat(val) : shortFormat(val);\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  var match = /^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);\n  if (!match) return;\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'y':\n      return n * y;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 's':\n      return n * s;\n    case 'ms':\n      return n;\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction shortFormat(ms) {\n  if (ms >= d) return Math.round(ms / d) + 'd';\n  if (ms >= h) return Math.round(ms / h) + 'h';\n  if (ms >= m) return Math.round(ms / m) + 'm';\n  if (ms >= s) return Math.round(ms / s) + 's';\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction longFormat(ms) {\n  return plural(ms, d, 'day')\n    || plural(ms, h, 'hour')\n    || plural(ms, m, 'minute')\n    || plural(ms, s, 'second')\n    || ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, n, name) {\n  if (ms < n) return;\n  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;\n  return Math.ceil(ms / n) + ' ' + name + 's';\n}\n\n}); // module: ms.js\n\nrequire.register(\"reporters/base.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar tty = require('browser/tty')\n  , diff = require('browser/diff')\n  , ms = require('../ms')\n  , utils = require('../utils');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date\n  , setTimeout = global.setTimeout\n  , setInterval = global.setInterval\n  , clearTimeout = global.clearTimeout\n  , clearInterval = global.clearInterval;\n\n/**\n * Check if both stdio streams are associated with a tty.\n */\n\nvar isatty = tty.isatty(1) && tty.isatty(2);\n\n/**\n * Expose `Base`.\n */\n\nexports = module.exports = Base;\n\n/**\n * Enable coloring by default.\n */\n\nexports.useColors = isatty || (process.env.MOCHA_COLORS !== undefined);\n\n/**\n * Inline diffs instead of +/-\n */\n\nexports.inlineDiffs = false;\n\n/**\n * Default color map.\n */\n\nexports.colors = {\n    'pass': 90\n  , 'fail': 31\n  , 'bright pass': 92\n  , 'bright fail': 91\n  , 'bright yellow': 93\n  , 'pending': 36\n  , 'suite': 0\n  , 'error title': 0\n  , 'error message': 31\n  , 'error stack': 90\n  , 'checkmark': 32\n  , 'fast': 90\n  , 'medium': 33\n  , 'slow': 31\n  , 'green': 32\n  , 'light': 90\n  , 'diff gutter': 90\n  , 'diff added': 42\n  , 'diff removed': 41\n};\n\n/**\n * Default symbol map.\n */\n\nexports.symbols = {\n  ok: '✓',\n  err: '✖',\n  dot: '․'\n};\n\n// With node.js on Windows: use symbols available in terminal default fonts\nif ('win32' == process.platform) {\n  exports.symbols.ok = '\\u221A';\n  exports.symbols.err = '\\u00D7';\n  exports.symbols.dot = '.';\n}\n\n/**\n * Color `str` with the given `type`,\n * allowing colors to be disabled,\n * as well as user-defined color\n * schemes.\n *\n * @param {String} type\n * @param {String} str\n * @return {String}\n * @api private\n */\n\nvar color = exports.color = function(type, str) {\n  if (!exports.useColors) return str;\n  return '\\u001b[' + exports.colors[type] + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Expose term window size, with some\n * defaults for when stderr is not a tty.\n */\n\nexports.window = {\n  width: isatty\n    ? process.stdout.getWindowSize\n      ? process.stdout.getWindowSize(1)[0]\n      : tty.getWindowSize()[1]\n    : 75\n};\n\n/**\n * Expose some basic cursor interactions\n * that are common among reporters.\n */\n\nexports.cursor = {\n  hide: function(){\n    isatty && process.stdout.write('\\u001b[?25l');\n  },\n\n  show: function(){\n    isatty && process.stdout.write('\\u001b[?25h');\n  },\n\n  deleteLine: function(){\n    isatty && process.stdout.write('\\u001b[2K');\n  },\n\n  beginningOfLine: function(){\n    isatty && process.stdout.write('\\u001b[0G');\n  },\n\n  CR: function(){\n    if (isatty) {\n      exports.cursor.deleteLine();\n      exports.cursor.beginningOfLine();\n    } else {\n      process.stdout.write('\\r');\n    }\n  }\n};\n\n/**\n * Outut the given `failures` as a list.\n *\n * @param {Array} failures\n * @api public\n */\n\nexports.list = function(failures){\n  console.error();\n  failures.forEach(function(test, i){\n    // format\n    var fmt = color('error title', '  %s) %s:\\n')\n      + color('error message', '     %s')\n      + color('error stack', '\\n%s\\n');\n\n    // msg\n    var err = test.err\n      , message = err.message || ''\n      , stack = err.stack || message\n      , index = stack.indexOf(message) + message.length\n      , msg = stack.slice(0, index)\n      , actual = err.actual\n      , expected = err.expected\n      , escape = true;\n\n    // uncaught\n    if (err.uncaught) {\n      msg = 'Uncaught ' + msg;\n    }\n\n    // explicitly show diff\n    if (err.showDiff && sameType(actual, expected)) {\n      escape = false;\n      err.actual = actual = utils.stringify(actual);\n      err.expected = expected = utils.stringify(expected);\n    }\n\n    // actual / expected diff\n    if (err.showDiff && 'string' == typeof actual && 'string' == typeof expected) {\n      fmt = color('error title', '  %s) %s:\\n%s') + color('error stack', '\\n%s\\n');\n      var match = message.match(/^([^:]+): expected/);\n      msg = '\\n      ' + color('error message', match ? match[1] : msg);\n\n      if (exports.inlineDiffs) {\n        msg += inlineDiff(err, escape);\n      } else {\n        msg += unifiedDiff(err, escape);\n      }\n    }\n\n    // indent stack trace without msg\n    stack = stack.slice(index ? index + 1 : index)\n      .replace(/^/gm, '  ');\n\n    console.error(fmt, (i + 1), test.fullTitle(), msg, stack);\n  });\n};\n\n/**\n * Initialize a new `Base` reporter.\n *\n * All other reporters generally\n * inherit from this reporter, providing\n * stats such as test duration, number\n * of tests passed / failed etc.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Base(runner) {\n  var self = this\n    , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }\n    , failures = this.failures = [];\n\n  if (!runner) return;\n  this.runner = runner;\n\n  runner.stats = stats;\n\n  runner.on('start', function(){\n    stats.start = new Date;\n  });\n\n  runner.on('suite', function(suite){\n    stats.suites = stats.suites || 0;\n    suite.root || stats.suites++;\n  });\n\n  runner.on('test end', function(test){\n    stats.tests = stats.tests || 0;\n    stats.tests++;\n  });\n\n  runner.on('pass', function(test){\n    stats.passes = stats.passes || 0;\n\n    var medium = test.slow() / 2;\n    test.speed = test.duration > test.slow()\n      ? 'slow'\n      : test.duration > medium\n        ? 'medium'\n        : 'fast';\n\n    stats.passes++;\n  });\n\n  runner.on('fail', function(test, err){\n    stats.failures = stats.failures || 0;\n    stats.failures++;\n    test.err = err;\n    failures.push(test);\n  });\n\n  runner.on('end', function(){\n    stats.end = new Date;\n    stats.duration = new Date - stats.start;\n  });\n\n  runner.on('pending', function(){\n    stats.pending++;\n  });\n}\n\n/**\n * Output common epilogue used by many of\n * the bundled reporters.\n *\n * @api public\n */\n\nBase.prototype.epilogue = function(){\n  var stats = this.stats;\n  var tests;\n  var fmt;\n\n  console.log();\n\n  // passes\n  fmt = color('bright pass', ' ')\n    + color('green', ' %d passing')\n    + color('light', ' (%s)');\n\n  console.log(fmt,\n    stats.passes || 0,\n    ms(stats.duration));\n\n  // pending\n  if (stats.pending) {\n    fmt = color('pending', ' ')\n      + color('pending', ' %d pending');\n\n    console.log(fmt, stats.pending);\n  }\n\n  // failures\n  if (stats.failures) {\n    fmt = color('fail', '  %d failing');\n\n    console.error(fmt,\n      stats.failures);\n\n    Base.list(this.failures);\n    console.error();\n  }\n\n  console.log();\n};\n\n/**\n * Pad the given `str` to `len`.\n *\n * @param {String} str\n * @param {String} len\n * @return {String}\n * @api private\n */\n\nfunction pad(str, len) {\n  str = String(str);\n  return Array(len - str.length + 1).join(' ') + str;\n}\n\n\n/**\n * Returns an inline diff between 2 strings with coloured ANSI output\n *\n * @param {Error} Error with actual/expected\n * @return {String} Diff\n * @api private\n */\n\nfunction inlineDiff(err, escape) {\n  var msg = errorDiff(err, 'WordsWithSpace', escape);\n\n  // linenos\n  var lines = msg.split('\\n');\n  if (lines.length > 4) {\n    var width = String(lines.length).length;\n    msg = lines.map(function(str, i){\n      return pad(++i, width) + ' |' + ' ' + str;\n    }).join('\\n');\n  }\n\n  // legend\n  msg = '\\n'\n    + color('diff removed', 'actual')\n    + ' '\n    + color('diff added', 'expected')\n    + '\\n\\n'\n    + msg\n    + '\\n';\n\n  // indent\n  msg = msg.replace(/^/gm, '      ');\n  return msg;\n}\n\n/**\n * Returns a unified diff between 2 strings\n *\n * @param {Error} Error with actual/expected\n * @return {String} Diff\n * @api private\n */\n\nfunction unifiedDiff(err, escape) {\n  var indent = '      ';\n  function cleanUp(line) {\n    if (escape) {\n      line = escapeInvisibles(line);\n    }\n    if (line[0] === '+') return indent + colorLines('diff added', line);\n    if (line[0] === '-') return indent + colorLines('diff removed', line);\n    if (line.match(/\\@\\@/)) return null;\n    if (line.match(/\\\\ No newline/)) return null;\n    else return indent + line;\n  }\n  function notBlank(line) {\n    return line != null;\n  }\n  msg = diff.createPatch('string', err.actual, err.expected);\n  var lines = msg.split('\\n').splice(4);\n  return '\\n      '\n         + colorLines('diff added',   '+ expected') + ' '\n         + colorLines('diff removed', '- actual')\n         + '\\n\\n'\n         + lines.map(cleanUp).filter(notBlank).join('\\n');\n}\n\n/**\n * Return a character diff for `err`.\n *\n * @param {Error} err\n * @return {String}\n * @api private\n */\n\nfunction errorDiff(err, type, escape) {\n  var actual   = escape ? escapeInvisibles(err.actual)   : err.actual;\n  var expected = escape ? escapeInvisibles(err.expected) : err.expected;\n  return diff['diff' + type](actual, expected).map(function(str){\n    if (str.added) return colorLines('diff added', str.value);\n    if (str.removed) return colorLines('diff removed', str.value);\n    return str.value;\n  }).join('');\n}\n\n/**\n * Returns a string with all invisible characters in plain text\n *\n * @param {String} line\n * @return {String}\n * @api private\n */\nfunction escapeInvisibles(line) {\n    return line.replace(/\\t/g, '<tab>')\n               .replace(/\\r/g, '<CR>')\n               .replace(/\\n/g, '<LF>\\n');\n}\n\n/**\n * Color lines for `str`, using the color `name`.\n *\n * @param {String} name\n * @param {String} str\n * @return {String}\n * @api private\n */\n\nfunction colorLines(name, str) {\n  return str.split('\\n').map(function(str){\n    return color(name, str);\n  }).join('\\n');\n}\n\n/**\n * Check that a / b have the same type.\n *\n * @param {Object} a\n * @param {Object} b\n * @return {Boolean}\n * @api private\n */\n\nfunction sameType(a, b) {\n  a = Object.prototype.toString.call(a);\n  b = Object.prototype.toString.call(b);\n  return a == b;\n}\n\n}); // module: reporters/base.js\n\nrequire.register(\"reporters/doc.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , utils = require('../utils');\n\n/**\n * Expose `Doc`.\n */\n\nexports = module.exports = Doc;\n\n/**\n * Initialize a new `Doc` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Doc(runner) {\n  Base.call(this, runner);\n\n  var self = this\n    , stats = this.stats\n    , total = runner.total\n    , indents = 2;\n\n  function indent() {\n    return Array(indents).join('  ');\n  }\n\n  runner.on('suite', function(suite){\n    if (suite.root) return;\n    ++indents;\n    console.log('%s<section class=\"suite\">', indent());\n    ++indents;\n    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));\n    console.log('%s<dl>', indent());\n  });\n\n  runner.on('suite end', function(suite){\n    if (suite.root) return;\n    console.log('%s</dl>', indent());\n    --indents;\n    console.log('%s</section>', indent());\n    --indents;\n  });\n\n  runner.on('pass', function(test){\n    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.fn.toString()));\n    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);\n  });\n\n  runner.on('fail', function(test, err){\n    console.log('%s  <dt class=\"error\">%s</dt>', indent(), utils.escape(test.title));\n    var code = utils.escape(utils.clean(test.fn.toString()));\n    console.log('%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>', indent(), code);\n    console.log('%s  <dd class=\"error\">%s</dd>', indent(), utils.escape(err));\n  });\n}\n\n}); // module: reporters/doc.js\n\nrequire.register(\"reporters/dot.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , color = Base.color;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = Dot;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Dot(runner) {\n  Base.call(this, runner);\n\n  var self = this\n    , stats = this.stats\n    , width = Base.window.width * .75 | 0\n    , n = -1;\n\n  runner.on('start', function(){\n    process.stdout.write('\\n  ');\n  });\n\n  runner.on('pending', function(test){\n    if (++n % width == 0) process.stdout.write('\\n  ');\n    process.stdout.write(color('pending', Base.symbols.dot));\n  });\n\n  runner.on('pass', function(test){\n    if (++n % width == 0) process.stdout.write('\\n  ');\n    if ('slow' == test.speed) {\n      process.stdout.write(color('bright yellow', Base.symbols.dot));\n    } else {\n      process.stdout.write(color(test.speed, Base.symbols.dot));\n    }\n  });\n\n  runner.on('fail', function(test, err){\n    if (++n % width == 0) process.stdout.write('\\n  ');\n    process.stdout.write(color('fail', Base.symbols.dot));\n  });\n\n  runner.on('end', function(){\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\n\nfunction F(){};\nF.prototype = Base.prototype;\nDot.prototype = new F;\nDot.prototype.constructor = Dot;\n\n\n}); // module: reporters/dot.js\n\nrequire.register(\"reporters/html-cov.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar JSONCov = require('./json-cov')\n  , fs = require('browser/fs');\n\n/**\n * Expose `HTMLCov`.\n */\n\nexports = module.exports = HTMLCov;\n\n/**\n * Initialize a new `JsCoverage` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction HTMLCov(runner) {\n  var jade = require('jade')\n    , file = __dirname + '/templates/coverage.jade'\n    , str = fs.readFileSync(file, 'utf8')\n    , fn = jade.compile(str, { filename: file })\n    , self = this;\n\n  JSONCov.call(this, runner, false);\n\n  runner.on('end', function(){\n    process.stdout.write(fn({\n        cov: self.cov\n      , coverageClass: coverageClass\n    }));\n  });\n}\n\n/**\n * Return coverage class for `n`.\n *\n * @return {String}\n * @api private\n */\n\nfunction coverageClass(n) {\n  if (n >= 75) return 'high';\n  if (n >= 50) return 'medium';\n  if (n >= 25) return 'low';\n  return 'terrible';\n}\n\n}); // module: reporters/html-cov.js\n\nrequire.register(\"reporters/html.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , utils = require('../utils')\n  , Progress = require('../browser/progress')\n  , escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date\n  , setTimeout = global.setTimeout\n  , setInterval = global.setInterval\n  , clearTimeout = global.clearTimeout\n  , clearInterval = global.clearInterval;\n\n/**\n * Expose `HTML`.\n */\n\nexports = module.exports = HTML;\n\n/**\n * Stats template.\n */\n\nvar statsTemplate = '<ul id=\"mocha-stats\">'\n  + '<li class=\"progress\"><canvas width=\"40\" height=\"40\"></canvas></li>'\n  + '<li class=\"passes\"><a href=\"#\">passes:</a> <em>0</em></li>'\n  + '<li class=\"failures\"><a href=\"#\">failures:</a> <em>0</em></li>'\n  + '<li class=\"duration\">duration: <em>0</em>s</li>'\n  + '</ul>';\n\n/**\n * Initialize a new `HTML` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction HTML(runner) {\n  Base.call(this, runner);\n\n  var self = this\n    , stats = this.stats\n    , total = runner.total\n    , stat = fragment(statsTemplate)\n    , items = stat.getElementsByTagName('li')\n    , passes = items[1].getElementsByTagName('em')[0]\n    , passesLink = items[1].getElementsByTagName('a')[0]\n    , failures = items[2].getElementsByTagName('em')[0]\n    , failuresLink = items[2].getElementsByTagName('a')[0]\n    , duration = items[3].getElementsByTagName('em')[0]\n    , canvas = stat.getElementsByTagName('canvas')[0]\n    , report = fragment('<ul id=\"mocha-report\"></ul>')\n    , stack = [report]\n    , progress\n    , ctx\n    , root = document.getElementById('mocha');\n\n  if (canvas.getContext) {\n    var ratio = window.devicePixelRatio || 1;\n    canvas.style.width = canvas.width;\n    canvas.style.height = canvas.height;\n    canvas.width *= ratio;\n    canvas.height *= ratio;\n    ctx = canvas.getContext('2d');\n    ctx.scale(ratio, ratio);\n    progress = new Progress;\n  }\n\n  if (!root) return error('#mocha div missing, add it to your document');\n\n  // pass toggle\n  on(passesLink, 'click', function(){\n    unhide();\n    var name = /pass/.test(report.className) ? '' : ' pass';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) hideSuitesWithout('test pass');\n  });\n\n  // failure toggle\n  on(failuresLink, 'click', function(){\n    unhide();\n    var name = /fail/.test(report.className) ? '' : ' fail';\n    report.className = report.className.replace(/fail|pass/g, '') + name;\n    if (report.className.trim()) hideSuitesWithout('test fail');\n  });\n\n  root.appendChild(stat);\n  root.appendChild(report);\n\n  if (progress) progress.size(40);\n\n  runner.on('suite', function(suite){\n    if (suite.root) return;\n\n    // suite\n    var url = self.suiteURL(suite);\n    var el = fragment('<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>', url, escape(suite.title));\n\n    // container\n    stack[0].appendChild(el);\n    stack.unshift(document.createElement('ul'));\n    el.appendChild(stack[0]);\n  });\n\n  runner.on('suite end', function(suite){\n    if (suite.root) return;\n    stack.shift();\n  });\n\n  runner.on('fail', function(test, err){\n    if ('hook' == test.type) runner.emit('test end', test);\n  });\n\n  runner.on('test end', function(test){\n    // TODO: add to stats\n    var percent = stats.tests / this.total * 100 | 0;\n    if (progress) progress.update(percent).draw(ctx);\n\n    // update stats\n    var ms = new Date - stats.start;\n    text(passes, stats.passes);\n    text(failures, stats.failures);\n    text(duration, (ms / 1000).toFixed(2));\n\n    // test\n    if ('passed' == test.state) {\n      var url = self.testURL(test);\n      var el = fragment('<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> <a href=\"%s\" class=\"replay\">‣</a></h2></li>', test.speed, test.title, test.duration, url);\n    } else if (test.pending) {\n      var el = fragment('<li class=\"test pass pending\"><h2>%e</h2></li>', test.title);\n    } else {\n      var el = fragment('<li class=\"test fail\"><h2>%e <a href=\"?grep=%e\" class=\"replay\">‣</a></h2></li>', test.title, encodeURIComponent(test.fullTitle()));\n      var str = test.err.stack || test.err.toString();\n\n      // FF / Opera do not add the message\n      if (!~str.indexOf(test.err.message)) {\n        str = test.err.message + '\\n' + str;\n      }\n\n      // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\n      // check for the result of the stringifying.\n      if ('[object Error]' == str) str = test.err.message;\n\n      // Safari doesn't give you a stack. Let's at least provide a source line.\n      if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {\n        str += \"\\n(\" + test.err.sourceURL + \":\" + test.err.line + \")\";\n      }\n\n      el.appendChild(fragment('<pre class=\"error\">%e</pre>', str));\n    }\n\n    // toggle code\n    // TODO: defer\n    if (!test.pending) {\n      var h2 = el.getElementsByTagName('h2')[0];\n\n      on(h2, 'click', function(){\n        pre.style.display = 'none' == pre.style.display\n          ? 'block'\n          : 'none';\n      });\n\n      var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));\n      el.appendChild(pre);\n      pre.style.display = 'none';\n    }\n\n    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\n    if (stack[0]) stack[0].appendChild(el);\n  });\n}\n\n/**\n * Makes a URL, preserving querystring (\"search\") parameters.\n * @param {string} s\n * @returns {string} your new URL\n */\nvar makeUrl = function makeUrl(s) {\n  var search = window.location.search;\n  return (search ? search + '&' : '?' ) + 'grep=' + encodeURIComponent(s);\n};\n\n/**\n * Provide suite URL\n *\n * @param {Object} [suite]\n */\nHTML.prototype.suiteURL = function(suite){\n  return makeUrl(suite.fullTitle());\n};\n\n/**\n * Provide test URL\n *\n * @param {Object} [test]\n */\n\nHTML.prototype.testURL = function(test){\n  return makeUrl(test.fullTitle());\n};\n\n/**\n * Display error `msg`.\n */\n\nfunction error(msg) {\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\n}\n\n/**\n * Return a DOM fragment from `html`.\n */\n\nfunction fragment(html) {\n  var args = arguments\n    , div = document.createElement('div')\n    , i = 1;\n\n  div.innerHTML = html.replace(/%([se])/g, function(_, type){\n    switch (type) {\n      case 's': return String(args[i++]);\n      case 'e': return escape(args[i++]);\n    }\n  });\n\n  return div.firstChild;\n}\n\n/**\n * Check for suites that do not have elements\n * with `classname`, and hide them.\n */\n\nfunction hideSuitesWithout(classname) {\n  var suites = document.getElementsByClassName('suite');\n  for (var i = 0; i < suites.length; i++) {\n    var els = suites[i].getElementsByClassName(classname);\n    if (0 == els.length) suites[i].className += ' hidden';\n  }\n}\n\n/**\n * Unhide .hidden suites.\n */\n\nfunction unhide() {\n  var els = document.getElementsByClassName('suite hidden');\n  for (var i = 0; i < els.length; ++i) {\n    els[i].className = els[i].className.replace('suite hidden', 'suite');\n  }\n}\n\n/**\n * Set `el` text to `str`.\n */\n\nfunction text(el, str) {\n  if (el.textContent) {\n    el.textContent = str;\n  } else {\n    el.innerText = str;\n  }\n}\n\n/**\n * Listen on `event` with callback `fn`.\n */\n\nfunction on(el, event, fn) {\n  if (el.addEventListener) {\n    el.addEventListener(event, fn, false);\n  } else {\n    el.attachEvent('on' + event, fn);\n  }\n}\n\n}); // module: reporters/html.js\n\nrequire.register(\"reporters/index.js\", function(module, exports, require){\nexports.Base = require('./base');\nexports.Dot = require('./dot');\nexports.Doc = require('./doc');\nexports.TAP = require('./tap');\nexports.JSON = require('./json');\nexports.HTML = require('./html');\nexports.List = require('./list');\nexports.Min = require('./min');\nexports.Spec = require('./spec');\nexports.Nyan = require('./nyan');\nexports.XUnit = require('./xunit');\nexports.Markdown = require('./markdown');\nexports.Progress = require('./progress');\nexports.Landing = require('./landing');\nexports.JSONCov = require('./json-cov');\nexports.HTMLCov = require('./html-cov');\nexports.JSONStream = require('./json-stream');\n\n}); // module: reporters/index.js\n\nrequire.register(\"reporters/json-cov.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `JSONCov`.\n */\n\nexports = module.exports = JSONCov;\n\n/**\n * Initialize a new `JsCoverage` reporter.\n *\n * @param {Runner} runner\n * @param {Boolean} output\n * @api public\n */\n\nfunction JSONCov(runner, output) {\n  var self = this\n    , output = 1 == arguments.length ? true : output;\n\n  Base.call(this, runner);\n\n  var tests = []\n    , failures = []\n    , passes = [];\n\n  runner.on('test end', function(test){\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test){\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test){\n    failures.push(test);\n  });\n\n  runner.on('end', function(){\n    var cov = global._$jscoverage || {};\n    var result = self.cov = map(cov);\n    result.stats = self.stats;\n    result.tests = tests.map(clean);\n    result.failures = failures.map(clean);\n    result.passes = passes.map(clean);\n    if (!output) return;\n    process.stdout.write(JSON.stringify(result, null, 2 ));\n  });\n}\n\n/**\n * Map jscoverage data to a JSON structure\n * suitable for reporting.\n *\n * @param {Object} cov\n * @return {Object}\n * @api private\n */\n\nfunction map(cov) {\n  var ret = {\n      instrumentation: 'node-jscoverage'\n    , sloc: 0\n    , hits: 0\n    , misses: 0\n    , coverage: 0\n    , files: []\n  };\n\n  for (var filename in cov) {\n    var data = coverage(filename, cov[filename]);\n    ret.files.push(data);\n    ret.hits += data.hits;\n    ret.misses += data.misses;\n    ret.sloc += data.sloc;\n  }\n\n  ret.files.sort(function(a, b) {\n    return a.filename.localeCompare(b.filename);\n  });\n\n  if (ret.sloc > 0) {\n    ret.coverage = (ret.hits / ret.sloc) * 100;\n  }\n\n  return ret;\n}\n\n/**\n * Map jscoverage data for a single source file\n * to a JSON structure suitable for reporting.\n *\n * @param {String} filename name of the source file\n * @param {Object} data jscoverage coverage data\n * @return {Object}\n * @api private\n */\n\nfunction coverage(filename, data) {\n  var ret = {\n    filename: filename,\n    coverage: 0,\n    hits: 0,\n    misses: 0,\n    sloc: 0,\n    source: {}\n  };\n\n  data.source.forEach(function(line, num){\n    num++;\n\n    if (data[num] === 0) {\n      ret.misses++;\n      ret.sloc++;\n    } else if (data[num] !== undefined) {\n      ret.hits++;\n      ret.sloc++;\n    }\n\n    ret.source[num] = {\n        source: line\n      , coverage: data[num] === undefined\n        ? ''\n        : data[num]\n    };\n  });\n\n  ret.coverage = ret.hits / ret.sloc * 100;\n\n  return ret;\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @param {Object} test\n * @return {Object}\n * @api private\n */\n\nfunction clean(test) {\n  return {\n      title: test.title\n    , fullTitle: test.fullTitle()\n    , duration: test.duration\n  }\n}\n\n}); // module: reporters/json-cov.js\n\nrequire.register(\"reporters/json-stream.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , color = Base.color;\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this\n    , stats = this.stats\n    , total = runner.total;\n\n  runner.on('start', function(){\n    console.log(JSON.stringify(['start', { total: total }]));\n  });\n\n  runner.on('pass', function(test){\n    console.log(JSON.stringify(['pass', clean(test)]));\n  });\n\n  runner.on('fail', function(test, err){\n    test = clean(test);\n    test.err = err.message;\n    console.log(JSON.stringify(['fail', test]));\n  });\n\n  runner.on('end', function(){\n    process.stdout.write(JSON.stringify(['end', self.stats]));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @param {Object} test\n * @return {Object}\n * @api private\n */\n\nfunction clean(test) {\n  return {\n      title: test.title\n    , fullTitle: test.fullTitle()\n    , duration: test.duration\n  }\n}\n\n}); // module: reporters/json-stream.js\n\nrequire.register(\"reporters/json.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , cursor = Base.cursor\n  , color = Base.color;\n\n/**\n * Expose `JSON`.\n */\n\nexports = module.exports = JSONReporter;\n\n/**\n * Initialize a new `JSON` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction JSONReporter(runner) {\n  var self = this;\n  Base.call(this, runner);\n\n  var tests = []\n    , pending = []\n    , failures = []\n    , passes = [];\n\n  runner.on('test end', function(test){\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test){\n    passes.push(test);\n  });\n\n  runner.on('fail', function(test){\n    failures.push(test);\n  });\n\n  runner.on('pending', function(test){\n    pending.push(test);\n  });\n\n  runner.on('end', function(){\n    var obj = {\n      stats: self.stats,\n      tests: tests.map(clean),\n      pending: pending.map(clean),\n      failures: failures.map(clean),\n      passes: passes.map(clean)\n    };\n\n    runner.testResults = obj;\n\n    process.stdout.write(JSON.stringify(obj, null, 2));\n  });\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @param {Object} test\n * @return {Object}\n * @api private\n */\n\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    duration: test.duration,\n    err: errorJSON(test.err || {})\n  }\n}\n\n/**\n * Transform `error` into a JSON object.\n * @param {Error} err\n * @return {Object}\n */\n\nfunction errorJSON(err) {\n  var res = {};\n  Object.getOwnPropertyNames(err).forEach(function(key) {\n    res[key] = err[key];\n  }, err);\n  return res;\n}\n\n}); // module: reporters/json.js\n\nrequire.register(\"reporters/landing.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , cursor = Base.cursor\n  , color = Base.color;\n\n/**\n * Expose `Landing`.\n */\n\nexports = module.exports = Landing;\n\n/**\n * Airplane color.\n */\n\nBase.colors.plane = 0;\n\n/**\n * Airplane crash color.\n */\n\nBase.colors['plane crash'] = 31;\n\n/**\n * Runway color.\n */\n\nBase.colors.runway = 90;\n\n/**\n * Initialize a new `Landing` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Landing(runner) {\n  Base.call(this, runner);\n\n  var self = this\n    , stats = this.stats\n    , width = Base.window.width * .75 | 0\n    , total = runner.total\n    , stream = process.stdout\n    , plane = color('plane', '✈')\n    , crashed = -1\n    , n = 0;\n\n  function runway() {\n    var buf = Array(width).join('-');\n    return '  ' + color('runway', buf);\n  }\n\n  runner.on('start', function(){\n    stream.write('\\n\\n\\n  ');\n    cursor.hide();\n  });\n\n  runner.on('test end', function(test){\n    // check if the plane crashed\n    var col = -1 == crashed\n      ? width * ++n / total | 0\n      : crashed;\n\n    // show the crash\n    if ('failed' == test.state) {\n      plane = color('plane crash', '✈');\n      crashed = col;\n    }\n\n    // render landing strip\n    stream.write('\\u001b['+(width+1)+'D\\u001b[2A');\n    stream.write(runway());\n    stream.write('\\n  ');\n    stream.write(color('runway', Array(col).join('⋅')));\n    stream.write(plane)\n    stream.write(color('runway', Array(width - col).join('⋅') + '\\n'));\n    stream.write(runway());\n    stream.write('\\u001b[0m');\n  });\n\n  runner.on('end', function(){\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\n\nfunction F(){};\nF.prototype = Base.prototype;\nLanding.prototype = new F;\nLanding.prototype.constructor = Landing;\n\n\n}); // module: reporters/landing.js\n\nrequire.register(\"reporters/list.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , cursor = Base.cursor\n  , color = Base.color;\n\n/**\n * Expose `List`.\n */\n\nexports = module.exports = List;\n\n/**\n * Initialize a new `List` test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction List(runner) {\n  Base.call(this, runner);\n\n  var self = this\n    , stats = this.stats\n    , n = 0;\n\n  runner.on('start', function(){\n    console.log();\n  });\n\n  runner.on('test', function(test){\n    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));\n  });\n\n  runner.on('pending', function(test){\n    var fmt = color('checkmark', '  -')\n      + color('pending', ' %s');\n    console.log(fmt, test.fullTitle());\n  });\n\n  runner.on('pass', function(test){\n    var fmt = color('checkmark', '  '+Base.symbols.dot)\n      + color('pass', ' %s: ')\n      + color(test.speed, '%dms');\n    cursor.CR();\n    console.log(fmt, test.fullTitle(), test.duration);\n  });\n\n  runner.on('fail', function(test, err){\n    cursor.CR();\n    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\n\nfunction F(){};\nF.prototype = Base.prototype;\nList.prototype = new F;\nList.prototype.constructor = List;\n\n\n}); // module: reporters/list.js\n\nrequire.register(\"reporters/markdown.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , utils = require('../utils');\n\n/**\n * Expose `Markdown`.\n */\n\nexports = module.exports = Markdown;\n\n/**\n * Initialize a new `Markdown` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Markdown(runner) {\n  Base.call(this, runner);\n\n  var self = this\n    , stats = this.stats\n    , level = 0\n    , buf = '';\n\n  function title(str) {\n    return Array(level).join('#') + ' ' + str;\n  }\n\n  function indent() {\n    return Array(level).join('  ');\n  }\n\n  function mapTOC(suite, obj) {\n    var ret = obj;\n    obj = obj[suite.title] = obj[suite.title] || { suite: suite };\n    suite.suites.forEach(function(suite){\n      mapTOC(suite, obj);\n    });\n    return ret;\n  }\n\n  function stringifyTOC(obj, level) {\n    ++level;\n    var buf = '';\n    var link;\n    for (var key in obj) {\n      if ('suite' == key) continue;\n      if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\\n';\n      if (key) buf += Array(level).join('  ') + link;\n      buf += stringifyTOC(obj[key], level);\n    }\n    --level;\n    return buf;\n  }\n\n  function generateTOC(suite) {\n    var obj = mapTOC(suite, {});\n    return stringifyTOC(obj, 0);\n  }\n\n  generateTOC(runner.suite);\n\n  runner.on('suite', function(suite){\n    ++level;\n    var slug = utils.slug(suite.fullTitle());\n    buf += '<a name=\"' + slug + '\"></a>' + '\\n';\n    buf += title(suite.title) + '\\n';\n  });\n\n  runner.on('suite end', function(suite){\n    --level;\n  });\n\n  runner.on('pass', function(test){\n    var code = utils.clean(test.fn.toString());\n    buf += test.title + '.\\n';\n    buf += '\\n```js\\n';\n    buf += code + '\\n';\n    buf += '```\\n\\n';\n  });\n\n  runner.on('end', function(){\n    process.stdout.write('# TOC\\n');\n    process.stdout.write(generateTOC(runner.suite));\n    process.stdout.write(buf);\n  });\n}\n\n}); // module: reporters/markdown.js\n\nrequire.register(\"reporters/min.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base');\n\n/**\n * Expose `Min`.\n */\n\nexports = module.exports = Min;\n\n/**\n * Initialize a new `Min` minimal test reporter (best used with --watch).\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Min(runner) {\n  Base.call(this, runner);\n\n  runner.on('start', function(){\n    // clear screen\n    process.stdout.write('\\u001b[2J');\n    // set cursor position\n    process.stdout.write('\\u001b[1;3H');\n  });\n\n  runner.on('end', this.epilogue.bind(this));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\n\nfunction F(){};\nF.prototype = Base.prototype;\nMin.prototype = new F;\nMin.prototype.constructor = Min;\n\n\n}); // module: reporters/min.js\n\nrequire.register(\"reporters/nyan.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , color = Base.color;\n\n/**\n * Expose `Dot`.\n */\n\nexports = module.exports = NyanCat;\n\n/**\n * Initialize a new `Dot` matrix test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction NyanCat(runner) {\n  Base.call(this, runner);\n  var self = this\n    , stats = this.stats\n    , width = Base.window.width * .75 | 0\n    , rainbowColors = this.rainbowColors = self.generateColors()\n    , colorIndex = this.colorIndex = 0\n    , numerOfLines = this.numberOfLines = 4\n    , trajectories = this.trajectories = [[], [], [], []]\n    , nyanCatWidth = this.nyanCatWidth = 11\n    , trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)\n    , scoreboardWidth = this.scoreboardWidth = 5\n    , tick = this.tick = 0\n    , n = 0;\n\n  runner.on('start', function(){\n    Base.cursor.hide();\n    self.draw();\n  });\n\n  runner.on('pending', function(test){\n    self.draw();\n  });\n\n  runner.on('pass', function(test){\n    self.draw();\n  });\n\n  runner.on('fail', function(test, err){\n    self.draw();\n  });\n\n  runner.on('end', function(){\n    Base.cursor.show();\n    for (var i = 0; i < self.numberOfLines; i++) write('\\n');\n    self.epilogue();\n  });\n}\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\n\nNyanCat.prototype.draw = function(){\n  this.appendRainbow();\n  this.drawScoreboard();\n  this.drawRainbow();\n  this.drawNyanCat();\n  this.tick = !this.tick;\n};\n\n/**\n * Draw the \"scoreboard\" showing the number\n * of passes, failures and pending tests.\n *\n * @api private\n */\n\nNyanCat.prototype.drawScoreboard = function(){\n  var stats = this.stats;\n  var colors = Base.colors;\n\n  function draw(color, n) {\n    write(' ');\n    write('\\u001b[' + color + 'm' + n + '\\u001b[0m');\n    write('\\n');\n  }\n\n  draw(colors.green, stats.passes);\n  draw(colors.fail, stats.failures);\n  draw(colors.pending, stats.pending);\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Append the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.appendRainbow = function(){\n  var segment = this.tick ? '_' : '-';\n  var rainbowified = this.rainbowify(segment);\n\n  for (var index = 0; index < this.numberOfLines; index++) {\n    var trajectory = this.trajectories[index];\n    if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();\n    trajectory.push(rainbowified);\n  }\n};\n\n/**\n * Draw the rainbow.\n *\n * @api private\n */\n\nNyanCat.prototype.drawRainbow = function(){\n  var self = this;\n\n  this.trajectories.forEach(function(line, index) {\n    write('\\u001b[' + self.scoreboardWidth + 'C');\n    write(line.join(''));\n    write('\\n');\n  });\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw the nyan cat\n *\n * @api private\n */\n\nNyanCat.prototype.drawNyanCat = function() {\n  var self = this;\n  var startWidth = this.scoreboardWidth + this.trajectories[0].length;\n  var color = '\\u001b[' + startWidth + 'C';\n  var padding = '';\n\n  write(color);\n  write('_,------,');\n  write('\\n');\n\n  write(color);\n  padding = self.tick ? '  ' : '   ';\n  write('_|' + padding + '/\\\\_/\\\\ ');\n  write('\\n');\n\n  write(color);\n  padding = self.tick ? '_' : '__';\n  var tail = self.tick ? '~' : '^';\n  var face;\n  write(tail + '|' + padding + this.face() + ' ');\n  write('\\n');\n\n  write(color);\n  padding = self.tick ? ' ' : '  ';\n  write(padding + '\"\"  \"\" ');\n  write('\\n');\n\n  this.cursorUp(this.numberOfLines);\n};\n\n/**\n * Draw nyan cat face.\n *\n * @return {String}\n * @api private\n */\n\nNyanCat.prototype.face = function() {\n  var stats = this.stats;\n  if (stats.failures) {\n    return '( x .x)';\n  } else if (stats.pending) {\n    return '( o .o)';\n  } else if(stats.passes) {\n    return '( ^ .^)';\n  } else {\n    return '( - .-)';\n  }\n};\n\n/**\n * Move cursor up `n`.\n *\n * @param {Number} n\n * @api private\n */\n\nNyanCat.prototype.cursorUp = function(n) {\n  write('\\u001b[' + n + 'A');\n};\n\n/**\n * Move cursor down `n`.\n *\n * @param {Number} n\n * @api private\n */\n\nNyanCat.prototype.cursorDown = function(n) {\n  write('\\u001b[' + n + 'B');\n};\n\n/**\n * Generate rainbow colors.\n *\n * @return {Array}\n * @api private\n */\n\nNyanCat.prototype.generateColors = function(){\n  var colors = [];\n\n  for (var i = 0; i < (6 * 7); i++) {\n    var pi3 = Math.floor(Math.PI / 3);\n    var n = (i * (1.0 / 6));\n    var r = Math.floor(3 * Math.sin(n) + 3);\n    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\n    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\n    colors.push(36 * r + 6 * g + b + 16);\n  }\n\n  return colors;\n};\n\n/**\n * Apply rainbow to the given `str`.\n *\n * @param {String} str\n * @return {String}\n * @api private\n */\n\nNyanCat.prototype.rainbowify = function(str){\n  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\n  this.colorIndex += 1;\n  return '\\u001b[38;5;' + color + 'm' + str + '\\u001b[0m';\n};\n\n/**\n * Stdout helper.\n */\n\nfunction write(string) {\n  process.stdout.write(string);\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\n\nfunction F(){};\nF.prototype = Base.prototype;\nNyanCat.prototype = new F;\nNyanCat.prototype.constructor = NyanCat;\n\n\n}); // module: reporters/nyan.js\n\nrequire.register(\"reporters/progress.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , cursor = Base.cursor\n  , color = Base.color;\n\n/**\n * Expose `Progress`.\n */\n\nexports = module.exports = Progress;\n\n/**\n * General progress bar color.\n */\n\nBase.colors.progress = 90;\n\n/**\n * Initialize a new `Progress` bar test reporter.\n *\n * @param {Runner} runner\n * @param {Object} options\n * @api public\n */\n\nfunction Progress(runner, options) {\n  Base.call(this, runner);\n\n  var self = this\n    , options = options || {}\n    , stats = this.stats\n    , width = Base.window.width * .50 | 0\n    , total = runner.total\n    , complete = 0\n    , max = Math.max\n    , lastN = -1;\n\n  // default chars\n  options.open = options.open || '[';\n  options.complete = options.complete || '▬';\n  options.incomplete = options.incomplete || Base.symbols.dot;\n  options.close = options.close || ']';\n  options.verbose = false;\n\n  // tests started\n  runner.on('start', function(){\n    console.log();\n    cursor.hide();\n  });\n\n  // tests complete\n  runner.on('test end', function(){\n    complete++;\n    var incomplete = total - complete\n      , percent = complete / total\n      , n = width * percent | 0\n      , i = width - n;\n\n    if (lastN === n && !options.verbose) {\n      // Don't re-render the line if it hasn't changed\n      return;\n    }\n    lastN = n;\n\n    cursor.CR();\n    process.stdout.write('\\u001b[J');\n    process.stdout.write(color('progress', '  ' + options.open));\n    process.stdout.write(Array(n).join(options.complete));\n    process.stdout.write(Array(i).join(options.incomplete));\n    process.stdout.write(color('progress', options.close));\n    if (options.verbose) {\n      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));\n    }\n  });\n\n  // tests are complete, output some stats\n  // and the failures if any\n  runner.on('end', function(){\n    cursor.show();\n    console.log();\n    self.epilogue();\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\n\nfunction F(){};\nF.prototype = Base.prototype;\nProgress.prototype = new F;\nProgress.prototype.constructor = Progress;\n\n\n}); // module: reporters/progress.js\n\nrequire.register(\"reporters/spec.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , cursor = Base.cursor\n  , color = Base.color;\n\n/**\n * Expose `Spec`.\n */\n\nexports = module.exports = Spec;\n\n/**\n * Initialize a new `Spec` test reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction Spec(runner) {\n  Base.call(this, runner);\n\n  var self = this\n    , stats = this.stats\n    , indents = 0\n    , n = 0;\n\n  function indent() {\n    return Array(indents).join('  ')\n  }\n\n  runner.on('start', function(){\n    console.log();\n  });\n\n  runner.on('suite', function(suite){\n    ++indents;\n    console.log(color('suite', '%s%s'), indent(), suite.title);\n  });\n\n  runner.on('suite end', function(suite){\n    --indents;\n    if (1 == indents) console.log();\n  });\n\n  runner.on('pending', function(test){\n    var fmt = indent() + color('pending', '  - %s');\n    console.log(fmt, test.title);\n  });\n\n  runner.on('pass', function(test){\n    if ('fast' == test.speed) {\n      var fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s ');\n      cursor.CR();\n      console.log(fmt, test.title);\n    } else {\n      var fmt = indent()\n        + color('checkmark', '  ' + Base.symbols.ok)\n        + color('pass', ' %s ')\n        + color(test.speed, '(%dms)');\n      cursor.CR();\n      console.log(fmt, test.title, test.duration);\n    }\n  });\n\n  runner.on('fail', function(test, err){\n    cursor.CR();\n    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);\n  });\n\n  runner.on('end', self.epilogue.bind(self));\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\n\nfunction F(){};\nF.prototype = Base.prototype;\nSpec.prototype = new F;\nSpec.prototype.constructor = Spec;\n\n\n}); // module: reporters/spec.js\n\nrequire.register(\"reporters/tap.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , cursor = Base.cursor\n  , color = Base.color;\n\n/**\n * Expose `TAP`.\n */\n\nexports = module.exports = TAP;\n\n/**\n * Initialize a new `TAP` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction TAP(runner) {\n  Base.call(this, runner);\n\n  var self = this\n    , stats = this.stats\n    , n = 1\n    , passes = 0\n    , failures = 0;\n\n  runner.on('start', function(){\n    var total = runner.grepTotal(runner.suite);\n    console.log('%d..%d', 1, total);\n  });\n\n  runner.on('test end', function(){\n    ++n;\n  });\n\n  runner.on('pending', function(test){\n    console.log('ok %d %s # SKIP -', n, title(test));\n  });\n\n  runner.on('pass', function(test){\n    passes++;\n    console.log('ok %d %s', n, title(test));\n  });\n\n  runner.on('fail', function(test, err){\n    failures++;\n    console.log('not ok %d %s', n, title(test));\n    if (err.stack) console.log(err.stack.replace(/^/gm, '  '));\n  });\n\n  runner.on('end', function(){\n    console.log('# tests ' + (passes + failures));\n    console.log('# pass ' + passes);\n    console.log('# fail ' + failures);\n  });\n}\n\n/**\n * Return a TAP-safe title of `test`\n *\n * @param {Object} test\n * @return {String}\n * @api private\n */\n\nfunction title(test) {\n  return test.fullTitle().replace(/#/g, '');\n}\n\n}); // module: reporters/tap.js\n\nrequire.register(\"reporters/xunit.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Base = require('./base')\n  , utils = require('../utils')\n  , escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date\n  , setTimeout = global.setTimeout\n  , setInterval = global.setInterval\n  , clearTimeout = global.clearTimeout\n  , clearInterval = global.clearInterval;\n\n/**\n * Expose `XUnit`.\n */\n\nexports = module.exports = XUnit;\n\n/**\n * Initialize a new `XUnit` reporter.\n *\n * @param {Runner} runner\n * @api public\n */\n\nfunction XUnit(runner) {\n  Base.call(this, runner);\n  var stats = this.stats\n    , tests = []\n    , self = this;\n\n  runner.on('pending', function(test){\n    tests.push(test);\n  });\n\n  runner.on('pass', function(test){\n    tests.push(test);\n  });\n\n  runner.on('fail', function(test){\n    tests.push(test);\n  });\n\n  runner.on('end', function(){\n    console.log(tag('testsuite', {\n        name: 'Mocha Tests'\n      , tests: stats.tests\n      , failures: stats.failures\n      , errors: stats.failures\n      , skipped: stats.tests - stats.failures - stats.passes\n      , timestamp: (new Date).toUTCString()\n      , time: (stats.duration / 1000) || 0\n    }, false));\n\n    tests.forEach(test);\n    console.log('</testsuite>');\n  });\n}\n\n/**\n * Inherit from `Base.prototype`.\n */\n\nfunction F(){};\nF.prototype = Base.prototype;\nXUnit.prototype = new F;\nXUnit.prototype.constructor = XUnit;\n\n\n/**\n * Output tag for the given `test.`\n */\n\nfunction test(test) {\n  var attrs = {\n      classname: test.parent.fullTitle()\n    , name: test.title\n    , time: (test.duration / 1000) || 0\n  };\n\n  if ('failed' == test.state) {\n    var err = test.err;\n    console.log(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + \"\\n\" + err.stack))));\n  } else if (test.pending) {\n    console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));\n  } else {\n    console.log(tag('testcase', attrs, true) );\n  }\n}\n\n/**\n * HTML tag helper.\n */\n\nfunction tag(name, attrs, close, content) {\n  var end = close ? '/>' : '>'\n    , pairs = []\n    , tag;\n\n  for (var key in attrs) {\n    pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\n  }\n\n  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;\n  if (content) tag += content + '</' + name + end;\n  return tag;\n}\n\n/**\n * Return cdata escaped CDATA `str`.\n */\n\nfunction cdata(str) {\n  return '<![CDATA[' + escape(str) + ']]>';\n}\n\n}); // module: reporters/xunit.js\n\nrequire.register(\"runnable.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('browser/events').EventEmitter\n  , debug = require('browser/debug')('mocha:runnable')\n  , milliseconds = require('./ms');\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date\n  , setTimeout = global.setTimeout\n  , setInterval = global.setInterval\n  , clearTimeout = global.clearTimeout\n  , clearInterval = global.clearInterval;\n\n/**\n * Object#toString().\n */\n\nvar toString = Object.prototype.toString;\n\n/**\n * Expose `Runnable`.\n */\n\nmodule.exports = Runnable;\n\n/**\n * Initialize a new `Runnable` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\n\nfunction Runnable(title, fn) {\n  this.title = title;\n  this.fn = fn;\n  this.async = fn && fn.length;\n  this.sync = ! this.async;\n  this._timeout = 1000 * 60 * 5;\n  this._slow = 75;\n  this._enableTimeouts = true;\n  this.timedOut = false;\n  this._trace = new Error('done() called multiple times')\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\n\nfunction F(){};\nF.prototype = EventEmitter.prototype;\nRunnable.prototype = new F;\nRunnable.prototype.constructor = Runnable;\n\n\n/**\n * Set & get timeout `ms`.\n *\n * @param {Number|String} ms\n * @return {Runnable|Number} ms or self\n * @api private\n */\n\nRunnable.prototype.timeout = function(ms){\n  if (0 == arguments.length) return this._timeout;\n  if (ms === 0) this._enableTimeouts = false;\n  if ('string' == typeof ms) ms = milliseconds(ms);\n  debug('timeout %d', ms);\n  this._timeout = ms;\n  if (this.timer) this.resetTimeout();\n  return this;\n};\n\n/**\n * Set & get slow `ms`.\n *\n * @param {Number|String} ms\n * @return {Runnable|Number} ms or self\n * @api private\n */\n\nRunnable.prototype.slow = function(ms){\n  if (0 === arguments.length) return this._slow;\n  if ('string' == typeof ms) ms = milliseconds(ms);\n  debug('timeout %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Set and & get timeout `enabled`.\n *\n * @param {Boolean} enabled\n * @return {Runnable|Boolean} enabled or self\n * @api private\n */\n\nRunnable.prototype.enableTimeouts = function(enabled){\n  if (arguments.length === 0) return this._enableTimeouts;\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Return the full title generated by recursively\n * concatenating the parent's full title.\n *\n * @return {String}\n * @api public\n */\n\nRunnable.prototype.fullTitle = function(){\n  return this.parent.fullTitle() + ' ' + this.title;\n};\n\n/**\n * Clear the timeout.\n *\n * @api private\n */\n\nRunnable.prototype.clearTimeout = function(){\n  clearTimeout(this.timer);\n};\n\n/**\n * Inspect the runnable void of private properties.\n *\n * @return {String}\n * @api private\n */\n\nRunnable.prototype.inspect = function(){\n  return JSON.stringify(this, function(key, val){\n    if ('_' == key[0]) return;\n    if ('parent' == key) return '#<Suite>';\n    if ('ctx' == key) return '#<Context>';\n    return val;\n  }, 2);\n};\n\n/**\n * Reset the timeout.\n *\n * @api private\n */\n\nRunnable.prototype.resetTimeout = function(){\n  var self = this;\n  var ms = this.timeout() || 1e9;\n\n  if (!this._enableTimeouts) return;\n  this.clearTimeout();\n\n  this.timer = setTimeout(function(){\n    if (!self._enableTimeouts) return;\n    self.callback(new Error('timeout of ' + ms + 'ms exceeded'));\n    self.timedOut = true;\n  }, ms);\n};\n\n/**\n * Whitelist these globals for this test run\n *\n * @api private\n */\nRunnable.prototype.globals = function(arr){\n  var self = this;\n  this._allowedGlobals = arr;\n};\n\n/**\n * Run the test and invoke `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\n\nRunnable.prototype.run = function(fn){\n  var self = this\n    , start = new Date\n    , ctx = this.ctx\n    , finished\n    , emitted;\n\n  // Some times the ctx exists but it is not runnable\n  if (ctx && ctx.runnable) ctx.runnable(this);\n\n  // called multiple times\n  function multiple(err) {\n    if (emitted) return;\n    emitted = true;\n    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));\n  }\n\n  // finished\n  function done(err) {\n    var ms = self.timeout();\n    if (self.timedOut) return;\n    if (finished) return multiple(err || self._trace);\n    self.clearTimeout();\n    self.duration = new Date - start;\n    finished = true;\n    if (!err && self.duration > ms && self._enableTimeouts) err = new Error('timeout of ' + ms + 'ms exceeded');\n    fn(err);\n  }\n\n  // for .resetTimeout()\n  this.callback = done;\n\n  // explicit async with `done` argument\n  if (this.async) {\n    this.resetTimeout();\n\n    try {\n      this.fn.call(ctx, function(err){\n        if (err instanceof Error || toString.call(err) === \"[object Error]\") return done(err);\n        if (null != err) {\n          if (Object.prototype.toString.call(err) === '[object Object]') {\n            return done(new Error('done() invoked with non-Error: ' + JSON.stringify(err)));\n          } else {\n            return done(new Error('done() invoked with non-Error: ' + err));\n          }\n        }\n        done();\n      });\n    } catch (err) {\n      done(err);\n    }\n    return;\n  }\n\n  if (this.asyncOnly) {\n    return done(new Error('--async-only option in use without declaring `done()`'));\n  }\n\n  // sync or promise-returning\n  try {\n    if (this.pending) {\n      done();\n    } else {\n      callFn(this.fn);\n    }\n  } catch (err) {\n    done(err);\n  }\n\n  function callFn(fn) {\n    var result = fn.call(ctx);\n    if (result && typeof result.then === 'function') {\n      self.resetTimeout();\n      result\n        .then(function() {\n          done()\n        },\n        function(reason) {\n          done(reason || new Error('Promise rejected with no or falsy reason'))\n        });\n    } else {\n      done();\n    }\n  }\n};\n\n}); // module: runnable.js\n\nrequire.register(\"runner.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('browser/events').EventEmitter\n  , debug = require('browser/debug')('mocha:runner')\n  , Test = require('./test')\n  , utils = require('./utils')\n  , filter = utils.filter\n  , keys = utils.keys;\n\n/**\n * Non-enumerable globals.\n */\n\nvar globals = [\n  'setTimeout',\n  'clearTimeout',\n  'setInterval',\n  'clearInterval',\n  'XMLHttpRequest',\n  'Date'\n];\n\n/**\n * Expose `Runner`.\n */\n\nmodule.exports = Runner;\n\n/**\n * Initialize a `Runner` for the given `suite`.\n *\n * Events:\n *\n *   - `start`  execution started\n *   - `end`  execution complete\n *   - `suite`  (suite) test suite execution started\n *   - `suite end`  (suite) all tests (and sub-suites) have finished\n *   - `test`  (test) test execution started\n *   - `test end`  (test) test completed\n *   - `hook`  (hook) hook execution started\n *   - `hook end`  (hook) hook complete\n *   - `pass`  (test) test passed\n *   - `fail`  (test, err) test failed\n *   - `pending`  (test) test pending\n *\n * @api public\n */\n\nfunction Runner(suite) {\n  var self = this;\n  this._globals = [];\n  this._abort = false;\n  this.suite = suite;\n  this.total = suite.total();\n  this.failures = 0;\n  this.on('test end', function(test){ self.checkGlobals(test); });\n  this.on('hook end', function(hook){ self.checkGlobals(hook); });\n  this.grep(/.*/);\n  this.globals(this.globalProps().concat(extraGlobals()));\n}\n\n/**\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\n *\n * @param {Function} fn\n * @api private\n */\n\nRunner.immediately = global.setImmediate || process.nextTick;\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\n\nfunction F(){};\nF.prototype = EventEmitter.prototype;\nRunner.prototype = new F;\nRunner.prototype.constructor = Runner;\n\n\n/**\n * Run tests with full titles matching `re`. Updates runner.total\n * with number of tests matched.\n *\n * @param {RegExp} re\n * @param {Boolean} invert\n * @return {Runner} for chaining\n * @api public\n */\n\nRunner.prototype.grep = function(re, invert){\n  debug('grep %s', re);\n  this._grep = re;\n  this._invert = invert;\n  this.total = this.grepTotal(this.suite);\n  return this;\n};\n\n/**\n * Returns the number of tests matching the grep search for the\n * given suite.\n *\n * @param {Suite} suite\n * @return {Number}\n * @api public\n */\n\nRunner.prototype.grepTotal = function(suite) {\n  var self = this;\n  var total = 0;\n\n  suite.eachTest(function(test){\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) match = !match;\n    if (match) total++;\n  });\n\n  return total;\n};\n\n/**\n * Return a list of global properties.\n *\n * @return {Array}\n * @api private\n */\n\nRunner.prototype.globalProps = function() {\n  var props = utils.keys(global);\n\n  // non-enumerables\n  for (var i = 0; i < globals.length; ++i) {\n    if (~utils.indexOf(props, globals[i])) continue;\n    props.push(globals[i]);\n  }\n\n  return props;\n};\n\n/**\n * Allow the given `arr` of globals.\n *\n * @param {Array} arr\n * @return {Runner} for chaining\n * @api public\n */\n\nRunner.prototype.globals = function(arr){\n  if (0 == arguments.length) return this._globals;\n  debug('globals %j', arr);\n  this._globals = this._globals.concat(arr);\n  return this;\n};\n\n/**\n * Check for global variable leaks.\n *\n * @api private\n */\n\nRunner.prototype.checkGlobals = function(test){\n  if (this.ignoreLeaks) return;\n  var ok = this._globals;\n\n  var globals = this.globalProps();\n  var leaks;\n\n  if (test) {\n    ok = ok.concat(test._allowedGlobals || []);\n  }\n\n  if(this.prevGlobalsLength == globals.length) return;\n  this.prevGlobalsLength = globals.length;\n\n  leaks = filterLeaks(ok, globals);\n  this._globals = this._globals.concat(leaks);\n\n  if (leaks.length > 1) {\n    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));\n  } else if (leaks.length) {\n    this.fail(test, new Error('global leak detected: ' + leaks[0]));\n  }\n};\n\n/**\n * Fail the given `test`.\n *\n * @param {Test} test\n * @param {Error} err\n * @api private\n */\n\nRunner.prototype.fail = function(test, err){\n  ++this.failures;\n  test.state = 'failed';\n\n  if ('string' == typeof err) {\n    err = new Error('the string \"' + err + '\" was thrown, throw an Error :)');\n  }\n\n  this.emit('fail', test, err);\n};\n\n/**\n * Fail the given `hook` with `err`.\n *\n * Hook failures work in the following pattern:\n * - If bail, then exit\n * - Failed `before` hook skips all tests in a suite and subsuites,\n *   but jumps to corresponding `after` hook\n * - Failed `before each` hook skips remaining tests in a\n *   suite and jumps to corresponding `after each` hook,\n *   which is run only once\n * - Failed `after` hook does not alter\n *   execution order\n * - Failed `after each` hook skips remaining tests in a\n *   suite and subsuites, but executes other `after each`\n *   hooks\n *\n * @param {Hook} hook\n * @param {Error} err\n * @api private\n */\n\nRunner.prototype.failHook = function(hook, err){\n  this.fail(hook, err);\n  if (this.suite.bail()) {\n    this.emit('end');\n  }\n};\n\n/**\n * Run hook `name` callbacks and then invoke `fn()`.\n *\n * @param {String} name\n * @param {Function} function\n * @api private\n */\n\nRunner.prototype.hook = function(name, fn){\n  var suite = this.suite\n    , hooks = suite['_' + name]\n    , self = this\n    , timer;\n\n  function next(i) {\n    var hook = hooks[i];\n    if (!hook) return fn();\n    if (self.failures && suite.bail()) return fn();\n    self.currentRunnable = hook;\n\n    hook.ctx.currentTest = self.test;\n\n    self.emit('hook', hook);\n\n    hook.on('error', function(err){\n      self.failHook(hook, err);\n    });\n\n    hook.run(function(err){\n      hook.removeAllListeners('error');\n      var testError = hook.error();\n      if (testError) self.fail(self.test, testError);\n      if (err) {\n        self.failHook(hook, err);\n\n        // stop executing hooks, notify callee of hook err\n        return fn(err);\n      }\n      self.emit('hook end', hook);\n      delete hook.ctx.currentTest;\n      next(++i);\n    });\n  }\n\n  Runner.immediately(function(){\n    next(0);\n  });\n};\n\n/**\n * Run hook `name` for the given array of `suites`\n * in order, and callback `fn(err, errSuite)`.\n *\n * @param {String} name\n * @param {Array} suites\n * @param {Function} fn\n * @api private\n */\n\nRunner.prototype.hooks = function(name, suites, fn){\n  var self = this\n    , orig = this.suite;\n\n  function next(suite) {\n    self.suite = suite;\n\n    if (!suite) {\n      self.suite = orig;\n      return fn();\n    }\n\n    self.hook(name, function(err){\n      if (err) {\n        var errSuite = self.suite;\n        self.suite = orig;\n        return fn(err, errSuite);\n      }\n\n      next(suites.pop());\n    });\n  }\n\n  next(suites.pop());\n};\n\n/**\n * Run hooks from the top level down.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\n\nRunner.prototype.hookUp = function(name, fn){\n  var suites = [this.suite].concat(this.parents()).reverse();\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Run hooks from the bottom up.\n *\n * @param {String} name\n * @param {Function} fn\n * @api private\n */\n\nRunner.prototype.hookDown = function(name, fn){\n  var suites = [this.suite].concat(this.parents());\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Return an array of parent Suites from\n * closest to furthest.\n *\n * @return {Array}\n * @api private\n */\n\nRunner.prototype.parents = function(){\n  var suite = this.suite\n    , suites = [];\n  while (suite = suite.parent) suites.push(suite);\n  return suites;\n};\n\n/**\n * Run the current test and callback `fn(err)`.\n *\n * @param {Function} fn\n * @api private\n */\n\nRunner.prototype.runTest = function(fn){\n  var test = this.test\n    , self = this;\n\n  if (this.asyncOnly) test.asyncOnly = true;\n\n  try {\n    test.on('error', function(err){\n      self.fail(test, err);\n    });\n    test.run(fn);\n  } catch (err) {\n    fn(err);\n  }\n};\n\n/**\n * Run tests in the given `suite` and invoke\n * the callback `fn()` when complete.\n *\n * @param {Suite} suite\n * @param {Function} fn\n * @api private\n */\n\nRunner.prototype.runTests = function(suite, fn){\n  var self = this\n    , tests = suite.tests.slice()\n    , test;\n\n\n  function hookErr(err, errSuite, after) {\n    // before/after Each hook for errSuite failed:\n    var orig = self.suite;\n\n    // for failed 'after each' hook start from errSuite parent,\n    // otherwise start from errSuite itself\n    self.suite = after ? errSuite.parent : errSuite;\n\n    if (self.suite) {\n      // call hookUp afterEach\n      self.hookUp('afterEach', function(err2, errSuite2) {\n        self.suite = orig;\n        // some hooks may fail even now\n        if (err2) return hookErr(err2, errSuite2, true);\n        // report error suite\n        fn(errSuite);\n      });\n    } else {\n      // there is no need calling other 'after each' hooks\n      self.suite = orig;\n      fn(errSuite);\n    }\n  }\n\n  function next(err, errSuite) {\n    // if we bail after first err\n    if (self.failures && suite._bail) return fn();\n\n    if (self._abort) return fn();\n\n    if (err) return hookErr(err, errSuite, true);\n\n    // next test\n    test = tests.shift();\n\n    // all done\n    if (!test) return fn();\n\n    // grep\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) match = !match;\n    if (!match) return next();\n\n    // pending\n    if (test.pending) {\n      self.emit('pending', test);\n      self.emit('test end', test);\n      return next();\n    }\n\n    // execute test and hook(s)\n    self.emit('test', self.test = test);\n    self.hookDown('beforeEach', function(err, errSuite){\n\n      if (err) return hookErr(err, errSuite, false);\n\n      self.currentRunnable = self.test;\n      self.runTest(function(err){\n        test = self.test;\n\n        if (err) {\n          self.fail(test, err);\n          self.emit('test end', test);\n          return self.hookUp('afterEach', next);\n        }\n\n        test.state = 'passed';\n        self.emit('pass', test);\n        self.emit('test end', test);\n        self.hookUp('afterEach', next);\n      });\n    });\n  }\n\n  this.next = next;\n  next();\n};\n\n/**\n * Run the given `suite` and invoke the\n * callback `fn()` when complete.\n *\n * @param {Suite} suite\n * @param {Function} fn\n * @api private\n */\n\nRunner.prototype.runSuite = function(suite, fn){\n  var total = this.grepTotal(suite)\n    , self = this\n    , i = 0;\n\n  debug('run suite %s', suite.fullTitle());\n\n  if (!total) return fn();\n\n  this.emit('suite', this.suite = suite);\n\n  function next(errSuite) {\n    if (errSuite) {\n      // current suite failed on a hook from errSuite\n      if (errSuite == suite) {\n        // if errSuite is current suite\n        // continue to the next sibling suite\n        return done();\n      } else {\n        // errSuite is among the parents of current suite\n        // stop execution of errSuite and all sub-suites\n        return done(errSuite);\n      }\n    }\n\n    if (self._abort) return done();\n\n    var curr = suite.suites[i++];\n    if (!curr) return done();\n    self.runSuite(curr, next);\n  }\n\n  function done(errSuite) {\n    self.suite = suite;\n    self.hook('afterAll', function(){\n      self.emit('suite end', suite);\n      fn(errSuite);\n    });\n  }\n\n  this.hook('beforeAll', function(err){\n    if (err) return done();\n    self.runTests(suite, next);\n  });\n};\n\n/**\n * Handle uncaught exceptions.\n *\n * @param {Error} err\n * @api private\n */\n\nRunner.prototype.uncaught = function(err){\n  if (err) {\n    debug('uncaught exception %s', err !== function () {\n      return this;\n    }.call(err) ? err : ( err.message || err ));\n  } else {\n    debug('uncaught undefined exception');\n    err = new Error('Caught undefined error, did you throw without specifying what?');\n  }\n  err.uncaught = true;\n\n  var runnable = this.currentRunnable;\n  if (!runnable) return;\n\n  var wasAlreadyDone = runnable.state;\n  this.fail(runnable, err);\n\n  runnable.clearTimeout();\n\n  if (wasAlreadyDone) return;\n\n  // recover from test\n  if ('test' == runnable.type) {\n    this.emit('test end', runnable);\n    this.hookUp('afterEach', this.next);\n    return;\n  }\n\n  // bail on hooks\n  this.emit('end');\n};\n\n/**\n * Run the root suite and invoke `fn(failures)`\n * on completion.\n *\n * @param {Function} fn\n * @return {Runner} for chaining\n * @api public\n */\n\nRunner.prototype.run = function(fn){\n  var self = this\n    , fn = fn || function(){};\n\n  function uncaught(err){\n    self.uncaught(err);\n  }\n\n  debug('start');\n\n  // callback\n  this.on('end', function(){\n    debug('end');\n    process.removeListener('uncaughtException', uncaught);\n    fn(self.failures);\n  });\n\n  // run suites\n  this.emit('start');\n  this.runSuite(this.suite, function(){\n    debug('finished running');\n    self.emit('end');\n  });\n\n  // uncaught exception\n  process.on('uncaughtException', uncaught);\n\n  return this;\n};\n\n/**\n * Cleanly abort execution\n *\n * @return {Runner} for chaining\n * @api public\n */\nRunner.prototype.abort = function(){\n  debug('aborting');\n  this._abort = true;\n};\n\n/**\n * Filter leaks with the given globals flagged as `ok`.\n *\n * @param {Array} ok\n * @param {Array} globals\n * @return {Array}\n * @api private\n */\n\nfunction filterLeaks(ok, globals) {\n  return filter(globals, function(key){\n    // Firefox and Chrome exposes iframes as index inside the window object\n    if (/^d+/.test(key)) return false;\n\n    // in firefox\n    // if runner runs in an iframe, this iframe's window.getInterface method not init at first\n    // it is assigned in some seconds\n    if (global.navigator && /^getInterface/.test(key)) return false;\n\n    // an iframe could be approached by window[iframeIndex]\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\n    if (global.navigator && /^\\d+/.test(key)) return false;\n\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\n    if (/^mocha-/.test(key)) return false;\n\n    var matched = filter(ok, function(ok){\n      if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);\n      return key == ok;\n    });\n    return matched.length == 0 && (!global.navigator || 'onerror' !== key);\n  });\n}\n\n/**\n * Array of globals dependent on the environment.\n *\n * @return {Array}\n * @api private\n */\n\n function extraGlobals() {\n  if (typeof(process) === 'object' &&\n      typeof(process.version) === 'string') {\n\n    var nodeVersion = process.version.split('.').reduce(function(a, v) {\n      return a << 8 | v;\n    });\n\n    // 'errno' was renamed to process._errno in v0.9.11.\n\n    if (nodeVersion < 0x00090B) {\n      return ['errno'];\n    }\n  }\n\n  return [];\n }\n\n}); // module: runner.js\n\nrequire.register(\"suite.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar EventEmitter = require('browser/events').EventEmitter\n  , debug = require('browser/debug')('mocha:suite')\n  , milliseconds = require('./ms')\n  , utils = require('./utils')\n  , Hook = require('./hook');\n\n/**\n * Expose `Suite`.\n */\n\nexports = module.exports = Suite;\n\n/**\n * Create a new `Suite` with the given `title`\n * and parent `Suite`. When a suite with the\n * same title is already present, that suite\n * is returned to provide nicer reporter\n * and more flexible meta-testing.\n *\n * @param {Suite} parent\n * @param {String} title\n * @return {Suite}\n * @api public\n */\n\nexports.create = function(parent, title){\n  var suite = new Suite(title, parent.ctx);\n  suite.parent = parent;\n  if (parent.pending) suite.pending = true;\n  title = suite.fullTitle();\n  parent.addSuite(suite);\n  return suite;\n};\n\n/**\n * Initialize a new `Suite` with the given\n * `title` and `ctx`.\n *\n * @param {String} title\n * @param {Context} ctx\n * @api private\n */\n\nfunction Suite(title, parentContext) {\n  this.title = title;\n  var context = function() {};\n  context.prototype = parentContext;\n  this.ctx = new context();\n  this.suites = [];\n  this.tests = [];\n  this.pending = false;\n  this._beforeEach = [];\n  this._beforeAll = [];\n  this._afterEach = [];\n  this._afterAll = [];\n  this.root = !title;\n  this._timeout = 1000 * 60 * 5;\n  this._enableTimeouts = true;\n  this._slow = 75;\n  this._bail = false;\n}\n\n/**\n * Inherit from `EventEmitter.prototype`.\n */\n\nfunction F(){};\nF.prototype = EventEmitter.prototype;\nSuite.prototype = new F;\nSuite.prototype.constructor = Suite;\n\n\n/**\n * Return a clone of this `Suite`.\n *\n * @return {Suite}\n * @api private\n */\n\nSuite.prototype.clone = function(){\n  var suite = new Suite(this.title);\n  debug('clone');\n  suite.ctx = this.ctx;\n  suite.timeout(this.timeout());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  return suite;\n};\n\n/**\n * Set timeout `ms` or short-hand such as \"2s\".\n *\n * @param {Number|String} ms\n * @return {Suite|Number} for chaining\n * @api private\n */\n\nSuite.prototype.timeout = function(ms){\n  if (0 == arguments.length) return this._timeout;\n  if (ms === 0) this._enableTimeouts = false;\n  if ('string' == typeof ms) ms = milliseconds(ms);\n  debug('timeout %d', ms);\n  this._timeout = parseInt(ms, 10);\n  return this;\n};\n\n/**\n  * Set timeout `enabled`.\n  *\n  * @param {Boolean} enabled\n  * @return {Suite|Boolean} self or enabled\n  * @api private\n  */\n\nSuite.prototype.enableTimeouts = function(enabled){\n  if (arguments.length === 0) return this._enableTimeouts;\n  debug('enableTimeouts %s', enabled);\n  this._enableTimeouts = enabled;\n  return this;\n};\n\n/**\n * Set slow `ms` or short-hand such as \"2s\".\n *\n * @param {Number|String} ms\n * @return {Suite|Number} for chaining\n * @api private\n */\n\nSuite.prototype.slow = function(ms){\n  if (0 === arguments.length) return this._slow;\n  if ('string' == typeof ms) ms = milliseconds(ms);\n  debug('slow %d', ms);\n  this._slow = ms;\n  return this;\n};\n\n/**\n * Sets whether to bail after first error.\n *\n * @parma {Boolean} bail\n * @return {Suite|Number} for chaining\n * @api private\n */\n\nSuite.prototype.bail = function(bail){\n  if (0 == arguments.length) return this._bail;\n  debug('bail %s', bail);\n  this._bail = bail;\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before running tests.\n *\n * @param {Function} fn\n * @return {Suite} for chaining\n * @api private\n */\n\nSuite.prototype.beforeAll = function(title, fn){\n  if (this.pending) return this;\n  if ('function' === typeof title) {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeAll.push(hook);\n  this.emit('beforeAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after running tests.\n *\n * @param {Function} fn\n * @return {Suite} for chaining\n * @api private\n */\n\nSuite.prototype.afterAll = function(title, fn){\n  if (this.pending) return this;\n  if ('function' === typeof title) {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after all\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterAll.push(hook);\n  this.emit('afterAll', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` before each test case.\n *\n * @param {Function} fn\n * @return {Suite} for chaining\n * @api private\n */\n\nSuite.prototype.beforeEach = function(title, fn){\n  if (this.pending) return this;\n  if ('function' === typeof title) {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"before each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._beforeEach.push(hook);\n  this.emit('beforeEach', hook);\n  return this;\n};\n\n/**\n * Run `fn(test[, done])` after each test case.\n *\n * @param {Function} fn\n * @return {Suite} for chaining\n * @api private\n */\n\nSuite.prototype.afterEach = function(title, fn){\n  if (this.pending) return this;\n  if ('function' === typeof title) {\n    fn = title;\n    title = fn.name;\n  }\n  title = '\"after each\" hook' + (title ? ': ' + title : '');\n\n  var hook = new Hook(title, fn);\n  hook.parent = this;\n  hook.timeout(this.timeout());\n  hook.enableTimeouts(this.enableTimeouts());\n  hook.slow(this.slow());\n  hook.ctx = this.ctx;\n  this._afterEach.push(hook);\n  this.emit('afterEach', hook);\n  return this;\n};\n\n/**\n * Add a test `suite`.\n *\n * @param {Suite} suite\n * @return {Suite} for chaining\n * @api private\n */\n\nSuite.prototype.addSuite = function(suite){\n  suite.parent = this;\n  suite.timeout(this.timeout());\n  suite.enableTimeouts(this.enableTimeouts());\n  suite.slow(this.slow());\n  suite.bail(this.bail());\n  this.suites.push(suite);\n  this.emit('suite', suite);\n  return this;\n};\n\n/**\n * Add a `test` to this suite.\n *\n * @param {Test} test\n * @return {Suite} for chaining\n * @api private\n */\n\nSuite.prototype.addTest = function(test){\n  test.parent = this;\n  test.timeout(this.timeout());\n  test.enableTimeouts(this.enableTimeouts());\n  test.slow(this.slow());\n  test.ctx = this.ctx;\n  this.tests.push(test);\n  this.emit('test', test);\n  return this;\n};\n\n/**\n * Return the full title generated by recursively\n * concatenating the parent's full title.\n *\n * @return {String}\n * @api public\n */\n\nSuite.prototype.fullTitle = function(){\n  if (this.parent) {\n    var full = this.parent.fullTitle();\n    if (full) return full + ' ' + this.title;\n  }\n  return this.title;\n};\n\n/**\n * Return the total number of tests.\n *\n * @return {Number}\n * @api public\n */\n\nSuite.prototype.total = function(){\n  return utils.reduce(this.suites, function(sum, suite){\n    return sum + suite.total();\n  }, 0) + this.tests.length;\n};\n\n/**\n * Iterates through each suite recursively to find\n * all tests. Applies a function in the format\n * `fn(test)`.\n *\n * @param {Function} fn\n * @return {Suite}\n * @api private\n */\n\nSuite.prototype.eachTest = function(fn){\n  utils.forEach(this.tests, fn);\n  utils.forEach(this.suites, function(suite){\n    suite.eachTest(fn);\n  });\n  return this;\n};\n\n}); // module: suite.js\n\nrequire.register(\"test.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar Runnable = require('./runnable');\n\n/**\n * Expose `Test`.\n */\n\nmodule.exports = Test;\n\n/**\n * Initialize a new `Test` with the given `title` and callback `fn`.\n *\n * @param {String} title\n * @param {Function} fn\n * @api private\n */\n\nfunction Test(title, fn) {\n  Runnable.call(this, title, fn);\n  this.pending = !fn;\n  this.type = 'test';\n}\n\n/**\n * Inherit from `Runnable.prototype`.\n */\n\nfunction F(){};\nF.prototype = Runnable.prototype;\nTest.prototype = new F;\nTest.prototype.constructor = Test;\n\n\n}); // module: test.js\n\nrequire.register(\"utils.js\", function(module, exports, require){\n/**\n * Module dependencies.\n */\n\nvar fs = require('browser/fs')\n  , path = require('browser/path')\n  , basename = path.basename\n  , exists = fs.existsSync || path.existsSync\n  , glob = require('browser/glob')\n  , join = path.join\n  , debug = require('browser/debug')('mocha:watch');\n\n/**\n * Ignored directories.\n */\n\nvar ignore = ['node_modules', '.git'];\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param  {String} html\n * @return {String}\n * @api private\n */\n\nexports.escape = function(html){\n  return String(html)\n    .replace(/&/g, '&amp;')\n    .replace(/\"/g, '&quot;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n};\n\n/**\n * Array#forEach (<=IE8)\n *\n * @param {Array} array\n * @param {Function} fn\n * @param {Object} scope\n * @api private\n */\n\nexports.forEach = function(arr, fn, scope){\n  for (var i = 0, l = arr.length; i < l; i++)\n    fn.call(scope, arr[i], i);\n};\n\n/**\n * Array#map (<=IE8)\n *\n * @param {Array} array\n * @param {Function} fn\n * @param {Object} scope\n * @api private\n */\n\nexports.map = function(arr, fn, scope){\n  var result = [];\n  for (var i = 0, l = arr.length; i < l; i++)\n    result.push(fn.call(scope, arr[i], i));\n  return result;\n};\n\n/**\n * Array#indexOf (<=IE8)\n *\n * @parma {Array} arr\n * @param {Object} obj to find index of\n * @param {Number} start\n * @api private\n */\n\nexports.indexOf = function(arr, obj, start){\n  for (var i = start || 0, l = arr.length; i < l; i++) {\n    if (arr[i] === obj)\n      return i;\n  }\n  return -1;\n};\n\n/**\n * Array#reduce (<=IE8)\n *\n * @param {Array} array\n * @param {Function} fn\n * @param {Object} initial value\n * @api private\n */\n\nexports.reduce = function(arr, fn, val){\n  var rval = val;\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    rval = fn(rval, arr[i], i, arr);\n  }\n\n  return rval;\n};\n\n/**\n * Array#filter (<=IE8)\n *\n * @param {Array} array\n * @param {Function} fn\n * @api private\n */\n\nexports.filter = function(arr, fn){\n  var ret = [];\n\n  for (var i = 0, l = arr.length; i < l; i++) {\n    var val = arr[i];\n    if (fn(val, i, arr)) ret.push(val);\n  }\n\n  return ret;\n};\n\n/**\n * Object.keys (<=IE8)\n *\n * @param {Object} obj\n * @return {Array} keys\n * @api private\n */\n\nexports.keys = Object.keys || function(obj) {\n  var keys = []\n    , has = Object.prototype.hasOwnProperty // for `window` on <=IE8\n\n  for (var key in obj) {\n    if (has.call(obj, key)) {\n      keys.push(key);\n    }\n  }\n\n  return keys;\n};\n\n/**\n * Watch the given `files` for changes\n * and invoke `fn(file)` on modification.\n *\n * @param {Array} files\n * @param {Function} fn\n * @api private\n */\n\nexports.watch = function(files, fn){\n  var options = { interval: 100 };\n  files.forEach(function(file){\n    debug('file %s', file);\n    fs.watchFile(file, options, function(curr, prev){\n      if (prev.mtime < curr.mtime) fn(file);\n    });\n  });\n};\n\n/**\n * Ignored files.\n */\n\nfunction ignored(path){\n  return !~ignore.indexOf(path);\n}\n\n/**\n * Lookup files in the given `dir`.\n *\n * @return {Array}\n * @api private\n */\n\nexports.files = function(dir, ext, ret){\n  ret = ret || [];\n  ext = ext || ['js'];\n\n  var re = new RegExp('\\\\.(' + ext.join('|') + ')$');\n\n  fs.readdirSync(dir)\n  .filter(ignored)\n  .forEach(function(path){\n    path = join(dir, path);\n    if (fs.statSync(path).isDirectory()) {\n      exports.files(path, ext, ret);\n    } else if (path.match(re)) {\n      ret.push(path);\n    }\n  });\n\n  return ret;\n};\n\n/**\n * Compute a slug from the given `str`.\n *\n * @param {String} str\n * @return {String}\n * @api private\n */\n\nexports.slug = function(str){\n  return str\n    .toLowerCase()\n    .replace(/ +/g, '-')\n    .replace(/[^-\\w]/g, '');\n};\n\n/**\n * Strip the function definition from `str`,\n * and re-indent for pre whitespace.\n */\n\nexports.clean = function(str) {\n  str = str\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, \"\\n\").replace(/^\\uFEFF/, '')\n    .replace(/^function *\\(.*\\) *{|\\(.*\\) *=> *{?/, '')\n    .replace(/\\s+\\}$/, '');\n\n  var spaces = str.match(/^\\n?( *)/)[1].length\n    , tabs = str.match(/^\\n?(\\t*)/)[1].length\n    , re = new RegExp('^\\n?' + (tabs ? '\\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');\n\n  str = str.replace(re, '');\n\n  return exports.trim(str);\n};\n\n/**\n * Trim the given `str`.\n *\n * @param {String} str\n * @return {String}\n * @api private\n */\n\nexports.trim = function(str){\n  return str.replace(/^\\s+|\\s+$/g, '');\n};\n\n/**\n * Parse the given `qs`.\n *\n * @param {String} qs\n * @return {Object}\n * @api private\n */\n\nexports.parseQuery = function(qs){\n  return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){\n    var i = pair.indexOf('=')\n      , key = pair.slice(0, i)\n      , val = pair.slice(++i);\n\n    obj[key] = decodeURIComponent(val);\n    return obj;\n  }, {});\n};\n\n/**\n * Highlight the given string of `js`.\n *\n * @param {String} js\n * @return {String}\n * @api private\n */\n\nfunction highlight(js) {\n  return js\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/\\bnew[ \\t]+(\\w+)/gm, '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>')\n    .replace(/\\b(function|new|throw|return|var|if|else)\\b/gm, '<span class=\"keyword\">$1</span>')\n}\n\n/**\n * Highlight the contents of tag `name`.\n *\n * @param {String} name\n * @api private\n */\n\nexports.highlightTags = function(name) {\n  var code = document.getElementById('mocha').getElementsByTagName(name);\n  for (var i = 0, len = code.length; i < len; ++i) {\n    code[i].innerHTML = highlight(code[i].innerHTML);\n  }\n};\n\n\n/**\n * Stringify `obj`.\n *\n * @param {Object} obj\n * @return {String}\n * @api private\n */\n\nexports.stringify = function(obj) {\n  if (obj instanceof RegExp) return obj.toString();\n  return JSON.stringify(exports.canonicalize(obj), null, 2).replace(/,(\\n|$)/g, '$1');\n};\n\n/**\n * Return a new object that has the keys in sorted order.\n * @param {Object} obj\n * @param {Array} [stack]\n * @return {Object}\n * @api private\n */\n\nexports.canonicalize = function(obj, stack) {\n  stack = stack || [];\n\n  if (exports.indexOf(stack, obj) !== -1) return '[Circular]';\n\n  var canonicalizedObj;\n\n  if ({}.toString.call(obj) === '[object Array]') {\n    stack.push(obj);\n    canonicalizedObj = exports.map(obj, function (item) {\n      return exports.canonicalize(item, stack);\n    });\n    stack.pop();\n  } else if (typeof obj === 'object' && obj !== null) {\n    stack.push(obj);\n    canonicalizedObj = {};\n    exports.forEach(exports.keys(obj).sort(), function (key) {\n      canonicalizedObj[key] = exports.canonicalize(obj[key], stack);\n    });\n    stack.pop();\n  } else {\n    canonicalizedObj = obj;\n  }\n\n  return canonicalizedObj;\n };\n\n/**\n * Lookup file names at the given `path`.\n */\nexports.lookupFiles = function lookupFiles(path, extensions, recursive) {\n  var files = [];\n  var re = new RegExp('\\\\.(' + extensions.join('|') + ')$');\n\n  if (!exists(path)) {\n    if (exists(path + '.js')) {\n      path += '.js';\n    } else {\n      files = glob.sync(path);\n      if (!files.length) throw new Error(\"cannot resolve path (or pattern) '\" + path + \"'\");\n      return files;\n    }\n  }\n\n  try {\n    var stat = fs.statSync(path);\n    if (stat.isFile()) return path;\n  }\n  catch (ignored) {\n    return;\n  }\n\n  fs.readdirSync(path).forEach(function(file){\n    file = join(path, file);\n    try {\n      var stat = fs.statSync(file);\n      if (stat.isDirectory()) {\n        if (recursive) {\n          files = files.concat(lookupFiles(file, extensions, recursive));\n        }\n        return;\n      }\n    }\n    catch (ignored) {\n      return;\n    }\n    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') return;\n    files.push(file);\n  });\n\n  return files;\n};\n\n}); // module: utils.js\n// The global object is \"self\" in Web Workers.\nvar global = (function() { return this; })();\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n\n/**\n * Node shims.\n *\n * These are meant only to allow\n * mocha.js to run untouched, not\n * to allow running node code in\n * the browser.\n */\n\nvar process = {};\nprocess.exit = function(status){};\nprocess.stdout = {};\n\nvar uncaughtExceptionHandlers = [];\n\nvar originalOnerrorHandler = global.onerror;\n\n/**\n * Remove uncaughtException listener.\n * Revert to original onerror handler if previously defined.\n */\n\nprocess.removeListener = function(e, fn){\n  if ('uncaughtException' == e) {\n    if (originalOnerrorHandler) {\n      global.onerror = originalOnerrorHandler;\n    } else {\n      global.onerror = function() {};\n    }\n    var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);\n    if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); }\n  }\n};\n\n/**\n * Implements uncaughtException listener.\n */\n\nprocess.on = function(e, fn){\n  if ('uncaughtException' == e) {\n    global.onerror = function(err, url, line){\n      fn(new Error(err + ' (' + url + ':' + line + ')'));\n      return true;\n    };\n    uncaughtExceptionHandlers.push(fn);\n  }\n};\n\n/**\n * Expose mocha.\n */\n\nvar Mocha = global.Mocha = require('mocha'),\n    mocha = global.mocha = new Mocha({ reporter: 'html' });\n\n// The BDD UI is registered by default, but no UI will be functional in the\n// browser without an explicit call to the overridden `mocha.ui` (see below).\n// Ensure that this default UI does not expose its methods to the global scope.\nmocha.suite.removeAllListeners('pre-require');\n\nvar immediateQueue = []\n  , immediateTimeout;\n\nfunction timeslice() {\n  var immediateStart = new Date().getTime();\n  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {\n    immediateQueue.shift()();\n  }\n  if (immediateQueue.length) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  } else {\n    immediateTimeout = null;\n  }\n}\n\n/**\n * High-performance override of Runner.immediately.\n */\n\nMocha.Runner.immediately = function(callback) {\n  immediateQueue.push(callback);\n  if (!immediateTimeout) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  }\n};\n\n/**\n * Function to allow assertion libraries to throw errors directly into mocha.\n * This is useful when running tests in a browser because window.onerror will\n * only receive the 'message' attribute of the Error.\n */\nmocha.throwError = function(err) {\n  Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) {\n    fn(err);\n  });\n  throw err;\n};\n\n/**\n * Override ui to ensure that the ui functions are initialized.\n * Normally this would happen in Mocha.prototype.loadFiles.\n */\n\nmocha.ui = function(ui){\n  Mocha.prototype.ui.call(this, ui);\n  this.suite.emit('pre-require', global, null, this);\n  return this;\n};\n\n/**\n * Setup mocha with the given setting options.\n */\n\nmocha.setup = function(opts){\n  if ('string' == typeof opts) opts = { ui: opts };\n  for (var opt in opts) this[opt](opts[opt]);\n  return this;\n};\n\n/**\n * Run mocha, returning the Runner.\n */\n\nmocha.run = function(fn){\n  var options = mocha.options;\n  mocha.globals('location');\n\n  var query = Mocha.utils.parseQuery(global.location.search || '');\n  if (query.grep) mocha.grep(query.grep);\n  if (query.invert) mocha.invert();\n\n  return Mocha.prototype.run.call(mocha, function(err){\n    // The DOM Document is not available in Web Workers.\n    var document = global.document;\n    if (document && document.getElementById('mocha') && options.noHighlighting !== true) {\n      Mocha.utils.highlightTags('code');\n    }\n    if (fn) fn(err);\n  });\n};\n\n/**\n * Expose the process shim.\n */\n\nMocha.process = process;\n})();\n"
  },
  {
    "path": "test/browser/package.json",
    "content": "{\n  \"name\": \"bluebird-nw\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.html\"\n}\n"
  },
  {
    "path": "test/browser/promise_debug.js",
    "content": "var Promise = require(\"../../js/browser/bluebird.min.js\");\nPromise.longStackTraces();\nPromise.config({cancellation:true});\nself.Promise = Promise;\nself.adapter = Promise;\n"
  },
  {
    "path": "test/browser/promise_instrumented.js",
    "content": "var Promise = require(\"../../js/instrumented/bluebird.js\");\nwindow.Promise = Promise;\nwindow.adapter = Promise;\nPromise.config({cancellation:true});\n"
  },
  {
    "path": "test/browser/worker.js",
    "content": "self.importScripts(\"./worker_bundle.js\");\n\nvar currentPromise;\n\nfunction handler(ev) {\n    ev.preventDefault();\n    self.postMessage(ev.type);\n    if (ev.type === \"unhandledrejection\") {\n        currentPromise.catch(function () {});\n    }\n}\n\nself.addEventListener(\"unhandledrejection\", handler);\nself.addEventListener(\"rejectionhandled\", handler);\n\nself.onmessage = function onmessage(ev) {\n    if (ev.data === \"reject\") {\n        currentPromise = Promise.reject(new Error(\"rejected\"));\n    }\n};\n"
  },
  {
    "path": "test/mocha/2.1.2.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\n\nvar adapter = global.adapter;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\n\ndescribe(\"2.1.2.1: When fulfilled, a promise: must not transition to any other state.\", function () {\n    testFulfilled(dummy, function (promise, done) {\n        var onFulfilledCalled = false;\n\n        promise.then(function onFulfilled() {\n            onFulfilledCalled = true;\n        }, function onRejected() {\n            assert.strictEqual(onFulfilledCalled, false);\n            done();\n        });\n\n        setTimeout(function(){done();}, 100);\n    });\n\n    specify(\"trying to fulfill then immediately reject\", function (done) {\n        var tuple = pending();\n        var onFulfilledCalled = false;\n\n        tuple.promise.then(function onFulfilled() {\n            onFulfilledCalled = true;\n        }, function onRejected() {\n            assert.strictEqual(onFulfilledCalled, false);\n            done();\n        });\n\n        tuple.fulfill(dummy);\n        tuple.reject(dummy);\n        setTimeout(function(){done();}, 100);\n    });\n\n    specify(\"trying to fulfill then reject, delayed\", function (done) {\n        var tuple = pending();\n        var onFulfilledCalled = false;\n\n        tuple.promise.then(function onFulfilled() {\n            onFulfilledCalled = true;\n        }, function onRejected() {\n            assert.strictEqual(onFulfilledCalled, false);\n            done();\n        });\n\n        setTimeout(function () {\n            tuple.fulfill(dummy);\n            tuple.reject(dummy);\n        }, 50);\n        setTimeout(function(){done();}, 100);\n    });\n\n    specify(\"trying to fulfill immediately then reject delayed\", function (done) {\n        var tuple = pending();\n        var onFulfilledCalled = false;\n\n        tuple.promise.then(function onFulfilled() {\n            onFulfilledCalled = true;\n        }, function onRejected() {\n            assert.strictEqual(onFulfilledCalled, false);\n            done();\n        });\n\n        tuple.fulfill(dummy);\n        setTimeout(function () {\n            tuple.reject(dummy);\n        }, 50);\n        setTimeout(function(){done();}, 100);\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.1.3.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\nvar adapter = global.adapter;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\n\ndescribe(\"2.1.3.1: When rejected, a promise: must not transition to any other state.\", function () {\n    testRejected(dummy, function (promise, done) {\n        var onRejectedCalled = false;\n\n        promise.then(function onFulfilled() {\n            assert.strictEqual(onRejectedCalled, false);\n            done();\n        }, function onRejected() {\n            onRejectedCalled = true;\n        });\n\n        setTimeout(function(){done();}, 100);\n    });\n\n    specify(\"trying to reject then immediately fulfill\", function (done) {\n        var tuple = pending();\n        var onRejectedCalled = false;\n\n        tuple.promise.then(function onFulfilled() {\n            assert.strictEqual(onRejectedCalled, false);\n            done();\n        }, function onRejected() {\n            onRejectedCalled = true;\n        });\n\n        tuple.reject(dummy);\n        tuple.fulfill(dummy);\n        setTimeout(function(){done();}, 100);\n    });\n\n    specify(\"trying to reject then fulfill, delayed\", function (done) {\n        var tuple = pending();\n        var onRejectedCalled = false;\n\n        tuple.promise.then(function onFulfilled() {\n            assert.strictEqual(onRejectedCalled, false);\n            done();\n        }, function onRejected() {\n            onRejectedCalled = true;\n        });\n\n        setTimeout(function () {\n            tuple.reject(dummy);\n            tuple.fulfill(dummy);\n        }, 50);\n        setTimeout(function(){done();}, 100);\n    });\n\n    specify(\"trying to reject immediately then fulfill delayed\", function (done) {\n        var tuple = pending();\n        var onRejectedCalled = false;\n\n        tuple.promise.then(function onFulfilled() {\n            assert.strictEqual(onRejectedCalled, false);\n            done();\n        }, function onRejected() {\n            onRejectedCalled = true;\n        });\n\n        tuple.reject(dummy);\n        setTimeout(function () {\n            tuple.fulfill(dummy);\n        }, 50);\n        setTimeout(function(){done();}, 100);\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.2.1.js",
    "content": "\"use strict\";\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\n\ndescribe(\"2.2.1: Both `onFulfilled` and `onRejected` are optional arguments.\", function () {\n    describe(\"2.2.1.1: If `onFulfilled` is not a function, it must be ignored.\", function () {\n        function testNonFunction(nonFunction, stringRepresentation) {\n            specify(\"`onFulfilled` is \" + stringRepresentation, function (done) {\n                rejected(dummy).then(nonFunction, function () {\n                    done();\n                });\n            });\n        }\n\n        testNonFunction(undefined, \"`undefined`\");\n        testNonFunction(null, \"`null`\");\n        testNonFunction(false, \"`false`\");\n        testNonFunction(5, \"`5`\");\n        testNonFunction({}, \"an object\");\n    });\n\n    describe(\"2.2.1.2: If `onRejected` is not a function, it must be ignored.\", function () {\n        function testNonFunction(nonFunction, stringRepresentation) {\n            specify(\"`onRejected` is \" + stringRepresentation, function (done) {\n                fulfilled(dummy).then(function () {\n                    done();\n                }, nonFunction);\n            });\n        }\n\n        testNonFunction(undefined, \"`undefined`\");\n        testNonFunction(null, \"`null`\");\n        testNonFunction(false, \"`false`\");\n        testNonFunction(5, \"`5`\");\n        testNonFunction({}, \"an object\");\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.2.2.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\nvar sentinel = { sentinel: \"sentinel\" }; // a sentinel fulfillment value to test for with strict equality\n\ndescribe(\"2.2.2: If `onFulfilled` is a function,\", function () {\n    describe(\"2.2.2.1: it must be called after `promise` is fulfilled, with `promise`’s fulfillment value as its \" +\n             \"first argument.\", function () {\n        testFulfilled(sentinel, function (promise, done) {\n            promise.then(function onFulfilled(value) {\n                assert.strictEqual(value, sentinel);\n                done();\n            });\n        });\n    });\n\n    describe(\"2.2.2.2: it must not be called before `promise` is fulfilled\", function () {\n        specify(\"fulfilled after a delay\", function (done) {\n            var tuple = pending();\n            var isFulfilled = false;\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(isFulfilled, true);\n                done();\n            });\n\n            setTimeout(function () {\n                tuple.fulfill(dummy);\n                isFulfilled = true;\n            }, 50);\n        });\n\n        specify(\"never fulfilled\", function (done) {\n            var tuple = pending();\n            var onFulfilledCalled = false;\n\n            tuple.promise.then(function onFulfilled() {\n                onFulfilledCalled = true;\n                done();\n            });\n\n            setTimeout(function () {\n                assert.strictEqual(onFulfilledCalled, false);\n                done();\n            }, 150);\n        });\n    });\n\n    describe(\"2.2.2.3: it must not be called more than once.\", function () {\n        specify(\"already-fulfilled\", function (done) {\n            var timesCalled = 0;\n\n            fulfilled(dummy).then(function onFulfilled() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n        });\n\n        specify(\"trying to fulfill a pending promise more than once, immediately\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            tuple.fulfill(dummy);\n            tuple.fulfill(dummy);\n        });\n\n        specify(\"trying to fulfill a pending promise more than once, delayed\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            setTimeout(function () {\n                tuple.fulfill(dummy);\n                tuple.fulfill(dummy);\n            }, 50);\n        });\n\n        specify(\"trying to fulfill a pending promise more than once, immediately then delayed\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            tuple.fulfill(dummy);\n            setTimeout(function () {\n                tuple.fulfill(dummy);\n            }, 50);\n        });\n\n        specify(\"when multiple `then` calls are made, spaced apart in time\", function (done) {\n            var tuple = pending();\n            var timesCalled = [0, 0, 0];\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled[0], 1);\n            });\n\n            setTimeout(function () {\n                tuple.promise.then(function onFulfilled() {\n                    assert.strictEqual(++timesCalled[1], 1);\n                });\n            }, 50);\n\n            setTimeout(function () {\n                tuple.promise.then(function onFulfilled() {\n                    assert.strictEqual(++timesCalled[2], 1);\n                    done();\n                });\n            }, 100);\n\n            setTimeout(function () {\n                tuple.fulfill(dummy);\n            }, 150);\n        });\n\n        specify(\"when `then` is interleaved with fulfillment\", function (done) {\n            var tuple = pending();\n            var timesCalled = [0, 0];\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled[0], 1);\n            });\n\n            tuple.fulfill(dummy);\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled[1], 1);\n                done();\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.2.3.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\nvar adapter = global.adapter;\nvar rejected = adapter.rejected;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\nvar sentinel = { sentinel: \"sentinel\" }; // a sentinel fulfillment value to test for with strict equality\n\ndescribe(\"2.2.3: If `onRejected` is a function,\", function () {\n    describe(\"2.2.3.1: it must be called after `promise` is rejected, with `promise`’s rejection reason as its \" +\n             \"first argument.\", function () {\n        testRejected(sentinel, function (promise, done) {\n            promise.then(null, function onRejected(reason) {\n                assert.strictEqual(reason, sentinel);\n                done();\n            });\n        });\n    });\n\n    describe(\"2.2.3.2: it must not be called before `promise` is rejected\", function () {\n        specify(\"rejected after a delay\", function (done) {\n            var tuple = pending();\n            var isRejected = false;\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(isRejected, true);\n                done();\n            });\n\n            setTimeout(function () {\n                tuple.reject(dummy);\n                isRejected = true;\n            }, 50);\n        });\n\n        specify(\"never rejected\", function (done) {\n            var tuple = pending();\n            var onRejectedCalled = false;\n\n            tuple.promise.then(null, function onRejected() {\n                onRejectedCalled = true;\n                done();\n            });\n\n            setTimeout(function () {\n                assert.strictEqual(onRejectedCalled, false);\n                done();\n            }, 150);\n        });\n    });\n\n    describe(\"2.2.3.3: it must not be called more than once.\", function () {\n        specify(\"already-rejected\", function (done) {\n            var timesCalled = 0;\n\n            rejected(dummy).then(null, function onRejected() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n        });\n\n        specify(\"trying to reject a pending promise more than once, immediately\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            tuple.reject(dummy);\n            tuple.reject(dummy);\n        });\n\n        specify(\"trying to reject a pending promise more than once, delayed\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            setTimeout(function () {\n                tuple.reject(dummy);\n                tuple.reject(dummy);\n            }, 50);\n        });\n\n        specify(\"trying to reject a pending promise more than once, immediately then delayed\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            tuple.reject(dummy);\n            setTimeout(function () {\n                tuple.reject(dummy);\n            }, 50);\n        });\n\n        specify(\"when multiple `then` calls are made, spaced apart in time\", function (done) {\n            var tuple = pending();\n            var timesCalled = [0, 0, 0];\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled[0], 1);\n            });\n\n            setTimeout(function () {\n                tuple.promise.then(null, function onRejected() {\n                    assert.strictEqual(++timesCalled[1], 1);\n                });\n            }, 50);\n\n            setTimeout(function () {\n                tuple.promise.then(null, function onRejected() {\n                    assert.strictEqual(++timesCalled[2], 1);\n                    done();\n                });\n            }, 100);\n\n            setTimeout(function () {\n                tuple.reject(dummy);\n            }, 150);\n        });\n\n        specify(\"when `then` is interleaved with rejection\", function (done) {\n            var tuple = pending();\n            var timesCalled = [0, 0];\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled[0], 1);\n            });\n\n            tuple.reject(dummy);\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled[1], 1);\n                done();\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.2.4.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\n\ndescribe(\"2.2.4: `onFulfilled` or `onRejected` must not be called until the execution context stack contains only \" +\n         \"platform code.\", function () {\n    describe(\"`then` returns before the promise becomes fulfilled or rejected\", function () {\n        testFulfilled(dummy, function (promise, done) {\n            var thenHasReturned = false;\n\n            promise.then(function onFulfilled() {\n                assert.strictEqual(thenHasReturned, true);\n                done();\n            });\n\n            thenHasReturned = true;\n        });\n        testRejected(dummy, function (promise, done) {\n            var thenHasReturned = false;\n\n            promise.then(null, function onRejected() {\n                assert.strictEqual(thenHasReturned, true);\n                done();\n            });\n\n            thenHasReturned = true;\n        });\n    });\n\n    describe(\"Clean-stack execution ordering tests (fulfillment case)\", function () {\n        specify(\"when `onFulfilled` is added immediately before the promise is fulfilled\",\n                function () {\n            var tuple = pending();\n            var onFulfilledCalled = false;\n\n            tuple.promise.then(function onFulfilled() {\n                onFulfilledCalled = true;\n            });\n\n            tuple.fulfill(dummy);\n\n            assert.strictEqual(onFulfilledCalled, false);\n        });\n\n        specify(\"when `onFulfilled` is added immediately after the promise is fulfilled\",\n                function () {\n            var tuple = pending();\n            var onFulfilledCalled = false;\n\n            tuple.fulfill(dummy);\n\n            tuple.promise.then(function onFulfilled() {\n                onFulfilledCalled = true;\n            });\n\n            assert.strictEqual(onFulfilledCalled, false);\n        });\n\n        specify(\"when one `onFulfilled` is added inside another `onFulfilled`\", function (done) {\n            var promise = fulfilled();\n            var firstOnFulfilledFinished = false;\n\n            promise.then(function () {\n                promise.then(function () {\n                    assert.strictEqual(firstOnFulfilledFinished, true);\n                    done();\n                });\n                firstOnFulfilledFinished = true;\n            });\n        });\n\n        specify(\"when `onFulfilled` is added inside an `onRejected`\", function (done) {\n            var promise = rejected();\n            var promise2 = fulfilled();\n            var firstOnRejectedFinished = false;\n\n            promise.then(null, function () {\n                promise2.then(function () {\n                    assert.strictEqual(firstOnRejectedFinished, true);\n                    done();\n                });\n                firstOnRejectedFinished = true;\n            });\n        });\n\n        specify(\"when the promise is fulfilled asynchronously\", function (done) {\n            var tuple = pending();\n            var firstStackFinished = false;\n\n            setTimeout(function () {\n                tuple.fulfill(dummy);\n                firstStackFinished = true;\n            }, 0);\n\n            tuple.promise.then(function () {\n                assert.strictEqual(firstStackFinished, true);\n                done();\n            });\n        });\n    });\n\n    describe(\"Clean-stack execution ordering tests (rejection case)\", function () {\n        specify(\"when `onRejected` is added immediately before the promise is rejected\",\n                function () {\n            var tuple = pending();\n            var onRejectedCalled = false;\n\n            tuple.promise.then(null, function onRejected() {\n                onRejectedCalled = true;\n            });\n\n            tuple.reject(dummy);\n\n            assert.strictEqual(onRejectedCalled, false);\n        });\n\n        specify(\"when `onRejected` is added immediately after the promise is rejected\",\n                function () {\n            var tuple = pending();\n            var onRejectedCalled = false;\n\n            tuple.reject(dummy);\n\n            tuple.promise.then(null, function onRejected() {\n                onRejectedCalled = true;\n            });\n\n            assert.strictEqual(onRejectedCalled, false);\n        });\n\n        specify(\"when `onRejected` is added inside an `onFulfilled`\", function (done) {\n            var promise = fulfilled();\n            var promise2 = rejected();\n            var firstOnFulfilledFinished = false;\n\n            promise.then(function () {\n                promise2.then(null, function () {\n                    assert.strictEqual(firstOnFulfilledFinished, true);\n                    done();\n                });\n                firstOnFulfilledFinished = true;\n            });\n        });\n\n        specify(\"when one `onRejected` is added inside another `onRejected`\", function (done) {\n            var promise = rejected();\n            var firstOnRejectedFinished = false;\n\n            promise.then(null, function () {\n                promise.then(null, function () {\n                    assert.strictEqual(firstOnRejectedFinished, true);\n                    done();\n                });\n                firstOnRejectedFinished = true;\n            });\n        });\n\n        specify(\"when the promise is rejected asynchronously\", function (done) {\n            var tuple = pending();\n            var firstStackFinished = false;\n\n            setTimeout(function () {\n                tuple.reject(dummy);\n                firstStackFinished = true;\n            }, 0);\n\n            tuple.promise.then(null, function () {\n                assert.strictEqual(firstStackFinished, true);\n                done();\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.2.5.js",
    "content": "/*jshint strict: false */\n\nvar assert = require(\"assert\");\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\n\nvar undefinedThisStrict = (function() {\n    \"use strict\";\n    return this;\n})();\n\nvar undefinedThisSloppy = (function() {\n    return this;\n})();\n\ndescribe(\"2.2.5 `onFulfilled` and `onRejected` must be called as functions (i.e. with no `this` value).\", function () {\n    describe(\"strict mode\", function () {\n        specify(\"fulfilled\", function (done) {\n            fulfilled(dummy).then(function onFulfilled() {\n                \"use strict\";\n\n                assert(this === undefinedThisStrict ||\n                       this === undefinedThisSloppy);\n                done();\n            });\n        });\n\n        specify(\"rejected\", function (done) {\n            rejected(dummy).then(null, function onRejected() {\n                \"use strict\";\n\n                assert(this === undefinedThisStrict ||\n                       this === undefinedThisSloppy);\n                done();\n            });\n        });\n    });\n\n    describe(\"sloppy mode\", function () {\n        specify(\"fulfilled\", function (done) {\n            fulfilled(dummy).then(function onFulfilled() {\n                assert.strictEqual(this, undefinedThisSloppy);\n                done();\n            });\n        });\n\n        specify(\"rejected\", function (done) {\n            rejected(dummy).then(null, function onRejected() {\n                assert.strictEqual(this, undefinedThisSloppy);\n                done();\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.2.6.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar sinon = require(\"sinon\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\nvar other = { other: \"other\" }; // a value we don't want to be strict equal to\nvar sentinel = { sentinel: \"sentinel\" }; // a sentinel fulfillment value to test for with strict equality\nvar sentinel2 = { sentinel2: \"sentinel2\" };\nvar sentinel3 = { sentinel3: \"sentinel3\" };\n\nfunction callbackAggregator(times, ultimateCallback) {\n    var soFar = 0;\n    return function () {\n        if (++soFar === times) {\n            ultimateCallback();\n        }\n    };\n}\n\ndescribe(\"2.2.6: `then` may be called multiple times on the same promise.\", function () {\n    describe(\"2.2.6.1: If/when `promise` is fulfilled, all respective `onFulfilled` callbacks must execute in the \" +\n             \"order of their originating calls to `then`.\", function () {\n        describe(\"multiple boring fulfillment handlers\", function () {\n            testFulfilled(sentinel, function (promise, done) {\n                var handler1 = sinon.stub().returns(other);\n                var handler2 = sinon.stub().returns(other);\n                var handler3 = sinon.stub().returns(other);\n\n                var spy = sinon.spy();\n                promise.then(handler1, spy);\n                promise.then(handler2, spy);\n                promise.then(handler3, spy);\n\n                promise.then(function (value) {\n                    assert.strictEqual(value, sentinel);\n\n                    sinon.assert.calledWith(handler1, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler2, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler3, sinon.match.same(sentinel));\n                    sinon.assert.notCalled(spy);\n\n                    done();\n                });\n            });\n        });\n\n        describe(\"multiple fulfillment handlers, one of which throws\", function () {\n            testFulfilled(sentinel, function (promise, done) {\n                var handler1 = sinon.stub().returns(other);\n                var handler2 = sinon.stub().throws(other);\n                var handler3 = sinon.stub().returns(other);\n\n                var spy = sinon.spy();\n                promise.then(handler1, spy);\n                promise.then(handler2, spy).caught(function(){});\n                promise.then(handler3, spy);\n\n                promise.then(function (value) {\n                    assert.strictEqual(value, sentinel);\n\n                    sinon.assert.calledWith(handler1, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler2, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler3, sinon.match.same(sentinel));\n                    sinon.assert.notCalled(spy);\n\n                    done();\n                });\n            });\n        });\n\n        describe(\"results in multiple branching chains with their own fulfillment values\", function () {\n            testFulfilled(dummy, function (promise, done) {\n                var semiDone = callbackAggregator(3, done);\n\n                promise.then(function () {\n                    return sentinel;\n                }).then(function (value) {\n                    assert.strictEqual(value, sentinel);\n                    semiDone();\n                });\n\n                promise.then(function () {\n                    throw sentinel2;\n                }).then(null, function (reason) {\n                    assert.strictEqual(reason, sentinel2);\n                    semiDone();\n                });\n\n                promise.then(function () {\n                    return sentinel3;\n                }).then(function (value) {\n                    assert.strictEqual(value, sentinel3);\n                    semiDone();\n                });\n            });\n        });\n\n        describe(\"`onFulfilled` handlers are called in the original order\", function () {\n            testFulfilled(dummy, function (promise, done) {\n                var handler1 = sinon.spy(function handler1() {});\n                var handler2 = sinon.spy(function handler2() {});\n                var handler3 = sinon.spy(function handler3() {});\n\n                promise.then(handler1);\n                promise.then(handler2);\n                promise.then(handler3);\n\n                promise.then(function () {\n                    sinon.assert.callOrder(handler1, handler2, handler3);\n                    done();\n                });\n            });\n\n            describe(\"even when one handler is added inside another handler\", function () {\n                testFulfilled(dummy, function (promise, done) {\n                    var handler1 = sinon.spy(function handler1() {});\n                    var handler2 = sinon.spy(function handler2() {});\n                    var handler3 = sinon.spy(function handler3() {});\n\n                    promise.then(function () {\n                        handler1();\n                        promise.then(handler3);\n                    });\n                    promise.then(handler2);\n\n                    promise.then(function () {\n                        // Give implementations a bit of extra time to flush their internal queue, if necessary.\n                        setTimeout(function () {\n                            sinon.assert.callOrder(handler1, handler2, handler3);\n                            done();\n                        }, 15);\n                    });\n                });\n            });\n        });\n    });\n\n    describe(\"2.2.6.2: If/when `promise` is rejected, all respective `onRejected` callbacks must execute in the \" +\n             \"order of their originating calls to `then`.\", function () {\n        describe(\"multiple boring rejection handlers\", function () {\n            testRejected(sentinel, function (promise, done) {\n                var handler1 = sinon.stub().returns(other);\n                var handler2 = sinon.stub().returns(other);\n                var handler3 = sinon.stub().returns(other);\n\n                var spy = sinon.spy();\n                promise.then(spy, handler1);\n                promise.then(spy, handler2);\n                promise.then(spy, handler3);\n\n                promise.then(null, function (reason) {\n                    assert.strictEqual(reason, sentinel);\n\n                    sinon.assert.calledWith(handler1, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler2, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler3, sinon.match.same(sentinel));\n                    sinon.assert.notCalled(spy);\n\n                    done();\n                });\n            });\n        });\n\n        describe(\"multiple rejection handlers, one of which throws\", function () {\n            testRejected(sentinel, function (promise, done) {\n                var handler1 = sinon.stub().returns(other);\n                var handler2 = sinon.stub().throws(other);\n                var handler3 = sinon.stub().returns(other);\n\n                var spy = sinon.spy();\n                promise.then(spy, handler1);\n                promise.then(spy, handler2).caught(function(){});\n                promise.then(spy, handler3);\n\n                promise.then(null, function (reason) {\n                    assert.strictEqual(reason, sentinel);\n\n                    sinon.assert.calledWith(handler1, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler2, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler3, sinon.match.same(sentinel));\n                    sinon.assert.notCalled(spy);\n\n                    done();\n                });\n            });\n        });\n\n        describe(\"results in multiple branching chains with their own fulfillment values\", function () {\n            testRejected(sentinel, function (promise, done) {\n                var semiDone = callbackAggregator(3, done);\n\n                promise.then(null, function () {\n                    return sentinel;\n                }).then(function (value) {\n                    assert.strictEqual(value, sentinel);\n                    semiDone();\n                });\n\n                promise.then(null, function () {\n                    throw sentinel2;\n                }).then(null, function (reason) {\n                    assert.strictEqual(reason, sentinel2);\n                    semiDone();\n                });\n\n                promise.then(null, function () {\n                    return sentinel3;\n                }).then(function (value) {\n                    assert.strictEqual(value, sentinel3);\n                    semiDone();\n                });\n            });\n        });\n\n        describe(\"`onRejected` handlers are called in the original order\", function () {\n            testRejected(dummy, function (promise, done) {\n                var handler1 = sinon.spy(function handler1() {});\n                var handler2 = sinon.spy(function handler2() {});\n                var handler3 = sinon.spy(function handler3() {});\n\n                promise.then(null, handler1);\n                promise.then(null, handler2);\n                promise.then(null, handler3);\n\n                promise.then(null, function () {\n                    sinon.assert.callOrder(handler1, handler2, handler3);\n                    done();\n                });\n            });\n\n            describe(\"even when one handler is added inside another handler\", function () {\n                testRejected(dummy, function (promise, done) {\n                    var handler1 = sinon.spy(function handler1() {});\n                    var handler2 = sinon.spy(function handler2() {});\n                    var handler3 = sinon.spy(function handler3() {});\n\n                    promise.then(null, function () {\n                        handler1();\n                        promise.then(null, handler3);\n                    });\n                    promise.then(null, handler2);\n\n                    promise.then(null, function () {\n                        // Give implementations a bit of extra time to flush their internal queue, if necessary.\n                        setTimeout(function () {\n                            sinon.assert.callOrder(handler1, handler2, handler3);\n                            done();\n                        }, 15);\n                    });\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.2.7.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\nvar reasons = require(\"./helpers/reasons\");\n\nvar adapter = global.adapter;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\nvar sentinel = { sentinel: \"sentinel\" }; // a sentinel fulfillment value to test for with strict equality\nvar other = { other: \"other\" }; // a value we don't want to be strict equal to\n\ndescribe(\"2.2.7: `then` must return a promise: `promise2 = promise1.then(onFulfilled, onRejected)`\", function () {\n    specify(\"is a promise\", function () {\n        var promise1 = pending().promise;\n        var promise2 = promise1.then();\n\n        assert(typeof promise2 === \"object\" || typeof promise2 === \"function\");\n        assert.notStrictEqual(promise2, null);\n        assert.strictEqual(typeof promise2.then, \"function\");\n    });\n\n    describe(\"2.2.7.1: If either `onFulfilled` or `onRejected` returns a value `x`, run the Promise Resolution \" +\n             \"Procedure `[[Resolve]](promise2, x)`\", function () {\n        specify(\"see separate 3.3 tests\", function () { });\n    });\n\n    describe(\"2.2.7.2: If either `onFulfilled` or `onRejected` throws an exception `e`, `promise2` must be rejected \" +\n             \"with `e` as the reason.\", function () {\n        function testReason(expectedReason, stringRepresentation) {\n            describe(\"The reason is \" + stringRepresentation, function () {\n                testFulfilled(dummy, function (promise1, done) {\n                    var promise2 = promise1.then(function onFulfilled() {\n                        throw expectedReason;\n                    });\n\n                    promise2.then(null, function onPromise2Rejected(actualReason) {\n                        assert.strictEqual(actualReason, expectedReason);\n                        done();\n                    });\n                });\n                testRejected(dummy, function (promise1, done) {\n                    var promise2 = promise1.then(null, function onRejected() {\n                        throw expectedReason;\n                    });\n\n                    promise2.then(null, function onPromise2Rejected(actualReason) {\n                        assert.strictEqual(actualReason, expectedReason);\n                        done();\n                    });\n                });\n            });\n        }\n\n        Object.keys(reasons).forEach(function (stringRepresentation) {\n            testReason(reasons[stringRepresentation], stringRepresentation);\n        });\n    });\n\n    describe(\"2.2.7.3: If `onFulfilled` is not a function and `promise1` is fulfilled, `promise2` must be fulfilled \" +\n             \"with the same value.\", function () {\n\n        function testNonFunction(nonFunction, stringRepresentation) {\n            describe(\"`onFulfilled` is \" + stringRepresentation, function () {\n                testFulfilled(sentinel, function (promise1, done) {\n                    var promise2 = promise1.then(nonFunction);\n\n                    promise2.then(function onPromise2Fulfilled(value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n        }\n\n        testNonFunction(undefined, \"`undefined`\");\n        testNonFunction(null, \"`null`\");\n        testNonFunction(false, \"`false`\");\n        testNonFunction(5, \"`5`\");\n        testNonFunction({}, \"an object\");\n        testNonFunction([function () { return other; }], \"an array containing a function\");\n    });\n\n    describe(\"2.2.7.4: If `onRejected` is not a function and `promise1` is rejected, `promise2` must be rejected \" +\n             \"with the same reason.\", function () {\n\n        function testNonFunction(nonFunction, stringRepresentation) {\n            describe(\"`onRejected` is \" + stringRepresentation, function () {\n                testRejected(sentinel, function (promise1, done) {\n                    var promise2 = promise1.then(null, nonFunction);\n\n                    promise2.then(null, function onPromise2Rejected(reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n        }\n\n        testNonFunction(undefined, \"`undefined`\");\n        testNonFunction(null, \"`null`\");\n        testNonFunction(false, \"`false`\");\n        testNonFunction(5, \"`5`\");\n        testNonFunction({}, \"an object\");\n        testNonFunction([function () { return other; }], \"an array containing a function\");\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.3.1.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\n\ndescribe(\"2.3.1: If `promise` and `x` refer to the same object, reject `promise` with a `TypeError' as the reason.\",\n         function () {\n    specify(\"via return from a fulfilled promise\", function (done) {\n        var promise = fulfilled(dummy).then(function () {\n            return promise;\n        });\n\n        promise.then(null, function (reason) {\n            assert(reason instanceof adapter.TypeError);\n            done();\n        });\n    });\n\n    specify(\"via return from a rejected promise\", function (done) {\n        var promise = rejected(dummy).then(null, function () {\n            return promise;\n        });\n\n        promise.then(null, function (reason) {\n            assert(reason instanceof adapter.TypeError);\n            done();\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.3.2.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\nvar sentinel = { sentinel: \"sentinel\" }; // a sentinel fulfillment value to test for with strict equality\n\nfunction testPromiseResolution(xFactory, test) {\n    specify(\"via return from a fulfilled promise\", function (done) {\n        var promise = fulfilled(dummy).then(function onBasePromiseFulfilled() {\n            return xFactory();\n        });\n\n        test(promise, done);\n    });\n\n    specify(\"via return from a rejected promise\", function (done) {\n        var promise = rejected(dummy).then(null, function onBasePromiseRejected() {\n            return xFactory();\n        });\n\n        test(promise, done);\n    });\n}\n\ndescribe(\"2.3.2: If `x` is a promise, adopt its state\", function () {\n    describe(\"2.3.2.1: If `x` is pending, `promise` must remain pending until `x` is fulfilled or rejected.\",\n             function () {\n        function xFactory() {\n            return pending().promise;\n        }\n\n        testPromiseResolution(xFactory, function (promise, done) {\n            var wasFulfilled = false;\n            var wasRejected = false;\n\n            promise.then(\n                function onPromiseFulfilled() {\n                    wasFulfilled = true;\n                },\n                function onPromiseRejected() {\n                    wasRejected = true;\n                }\n            );\n\n            setTimeout(function () {\n                assert.strictEqual(wasFulfilled, false);\n                assert.strictEqual(wasRejected, false);\n                done();\n            }, 100);\n        });\n    });\n\n    describe(\"2.3.2.2: If/when `x` is fulfilled, fulfill `promise` with the same value.\", function () {\n        describe(\"`x` is already-fulfilled\", function () {\n            function xFactory() {\n                return fulfilled(sentinel);\n            }\n\n            testPromiseResolution(xFactory, function (promise, done) {\n                promise.then(function onPromiseFulfilled(value) {\n                    assert.strictEqual(value, sentinel);\n                    done();\n                });\n            });\n        });\n\n        describe(\"`x` is eventually-fulfilled\", function () {\n            var tuple = null;\n\n            function xFactory() {\n                tuple = pending();\n                setTimeout(function () {\n                    tuple.fulfill(sentinel);\n                }, 50);\n                return tuple.promise;\n            }\n\n            testPromiseResolution(xFactory, function (promise, done) {\n                promise.then(function onPromiseFulfilled(value) {\n                    assert.strictEqual(value, sentinel);\n                    done();\n                });\n            });\n        });\n    });\n\n    describe(\"2.3.2.3: If/when `x` is rejected, reject `promise` with the same reason.\", function () {\n        describe(\"`x` is already-rejected\", function () {\n            function xFactory() {\n                return rejected(sentinel);\n            }\n\n            testPromiseResolution(xFactory, function (promise, done) {\n                promise.then(null, function onPromiseRejected(reason) {\n                    assert.strictEqual(reason, sentinel);\n                    done();\n                });\n            });\n        });\n\n        describe(\"`x` is eventually-rejected\", function () {\n            var tuple = null;\n\n            function xFactory() {\n                tuple = pending();\n                setTimeout(function () {\n                    tuple.reject(sentinel);\n                }, 50);\n                return tuple.promise;\n            }\n\n            testPromiseResolution(xFactory, function (promise, done) {\n                promise.then(null, function onPromiseRejected(reason) {\n                    assert.strictEqual(reason, sentinel);\n                    done();\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.3.3.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar thenables = require(\"./helpers/thenables\");\nvar reasons = require(\"./helpers/reasons\");\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\nvar sentinel = { sentinel: \"sentinel\" }; // a sentinel fulfillment value to test for with strict equality\nvar other = { other: \"other\" }; // a value we don't want to be strict equal to\nvar sentinelArray = [sentinel]; // a sentinel fulfillment value to test when we need an array\n\nfunction testPromiseResolution(xFactory, test) {\n    specify(\"via return from a fulfilled promise\", function (done) {\n        var promise = fulfilled(dummy).then(function onBasePromiseFulfilled() {\n            return xFactory();\n        });\n\n        test(promise, done);\n    });\n\n    specify(\"via return from a rejected promise\", function (done) {\n        var promise = rejected(dummy).then(null, function onBasePromiseRejected() {\n            return xFactory();\n        });\n\n        test(promise, done);\n    });\n}\n\nfunction testCallingResolvePromise(yFactory, stringRepresentation, test) {\n    describe(\"`y` is \" + stringRepresentation, function () {\n        describe(\"`then` calls `resolvePromise` synchronously\", function () {\n            function xFactory() {\n                return {\n                    then: function (resolvePromise) {\n                        resolvePromise(yFactory());\n                    }\n                };\n            }\n\n            testPromiseResolution(xFactory, test);\n        });\n\n        describe(\"`then` calls `resolvePromise` asynchronously\", function () {\n            function xFactory() {\n                return {\n                    then: function (resolvePromise) {\n                        setTimeout(function () {\n                            resolvePromise(yFactory());\n                        }, 0);\n                    }\n                };\n            }\n\n            testPromiseResolution(xFactory, test);\n        });\n    });\n}\n\nfunction testCallingRejectPromise(r, stringRepresentation, test) {\n    describe(\"`r` is \" + stringRepresentation, function () {\n        describe(\"`then` calls `rejectPromise` synchronously\", function () {\n            function xFactory() {\n                return {\n                    then: function (resolvePromise, rejectPromise) {\n                        rejectPromise(r);\n                    }\n                };\n            }\n\n            testPromiseResolution(xFactory, test);\n        });\n\n        describe(\"`then` calls `rejectPromise` asynchronously\", function () {\n            function xFactory() {\n                return {\n                    then: function (resolvePromise, rejectPromise) {\n                        setTimeout(function () {\n                            rejectPromise(r);\n                        }, 0);\n                    }\n                };\n            }\n\n            testPromiseResolution(xFactory, test);\n        });\n    });\n}\n\nfunction testCallingResolvePromiseFulfillsWith(yFactory, stringRepresentation, fulfillmentValue) {\n    testCallingResolvePromise(yFactory, stringRepresentation, function (promise, done) {\n\n        promise.then(function onPromiseFulfilled(value) {\n            assert.strictEqual(value, fulfillmentValue);\n            done();\n        });\n    });\n}\n\nfunction testCallingResolvePromiseRejectsWith(yFactory, stringRepresentation, rejectionReason) {\n    testCallingResolvePromise(yFactory, stringRepresentation, function (promise, done) {\n\n        promise.then(null, function onPromiseRejected(reason) {\n            assert.strictEqual(reason, rejectionReason);\n            done();\n        });\n    });\n}\n\nfunction testCallingRejectPromiseRejectsWith(reason, stringRepresentation) {\n    testCallingRejectPromise(reason, stringRepresentation, function (promise, done) {\n\n        promise.then(null, function onPromiseRejected(rejectionReason) {\n            assert.strictEqual(rejectionReason, reason);\n            done();\n        });\n    });\n}\n\ndescribe(\"2.3.3: Otherwise, if `x` is an object or function,\", function () {\n    describe(\"2.3.3.1: Let `then` be `x.then`\", function () {\n        describe(\"`x` is an object with null prototype\", function () {\n            var numberOfTimesThenWasRetrieved = null;\n\n            beforeEach(function () {\n                numberOfTimesThenWasRetrieved = 0;\n            });\n\n            function xFactory() {\n                return Object.create(null, {\n                    then: {\n                        get: function () {\n                            ++numberOfTimesThenWasRetrieved;\n                            return function thenMethodForX(onFulfilled) {\n                                onFulfilled();\n                            };\n                        }\n                    }\n                });\n            }\n\n            testPromiseResolution(xFactory, function (promise, done) {\n\n                promise.then(function () {\n                    assert.strictEqual(numberOfTimesThenWasRetrieved, 1);\n                    done();\n                });\n            });\n        });\n\n        describe(\"`x` is an object with normal Object.prototype\", function () {\n            var numberOfTimesThenWasRetrieved = null;\n\n            beforeEach(function () {\n                numberOfTimesThenWasRetrieved = 0;\n            });\n\n            function xFactory() {\n                return Object.create(Object.prototype, {\n                    then: {\n                        get: function () {\n                            ++numberOfTimesThenWasRetrieved;\n                            return function thenMethodForX(onFulfilled) {\n                                onFulfilled();\n                            };\n                        }\n                    }\n                });\n            }\n\n            testPromiseResolution(xFactory, function (promise, done) {\n\n                promise.then(function () {\n                    assert.strictEqual(numberOfTimesThenWasRetrieved, 1);\n                    done();\n                });\n            });\n        });\n\n        describe(\"`x` is a function\", function () {\n            var numberOfTimesThenWasRetrieved = null;\n\n            beforeEach(function () {\n                numberOfTimesThenWasRetrieved = 0;\n            });\n\n            function xFactory() {\n                function x() { }\n\n                Object.defineProperty(x, \"then\", {\n                    get: function () {\n                        ++numberOfTimesThenWasRetrieved;\n                        return function thenMethodForX(onFulfilled) {\n                            onFulfilled();\n                        };\n                    }\n                });\n\n                return x;\n            }\n\n            testPromiseResolution(xFactory, function (promise, done) {\n\n                promise.then(function () {\n                    assert.strictEqual(numberOfTimesThenWasRetrieved, 1);\n                    done();\n                });\n            });\n        });\n    });\n\n    describe(\"2.3.3.2: If retrieving the property `x.then` results in a thrown exception `e`, reject `promise` with \" +\n             \"`e` as the reason.\", function () {\n        function testRejectionViaThrowingGetter(e, stringRepresentation) {\n            function xFactory() {\n                return Object.create(Object.prototype, {\n                    then: {\n                        get: function () {\n                            throw e;\n                        }\n                    }\n                });\n            }\n\n            describe(\"`e` is \" + stringRepresentation, function () {\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(null, function (reason) {\n                        assert.strictEqual(reason, e);\n                        done();\n                    });\n                });\n            });\n        }\n\n        Object.keys(reasons).forEach(function (stringRepresentation) {\n            testRejectionViaThrowingGetter(reasons[stringRepresentation], stringRepresentation);\n        });\n    });\n\n    describe(\"2.3.3.3: If `then` is a function, call it with `x` as `this`, first argument `resolvePromise`, and \" +\n             \"second argument `rejectPromise`\", function () {\n        describe(\"Calls with `x` as `this` and two function arguments\", function () {\n            function xFactory() {\n                var x = {\n                    then: function (onFulfilled, onRejected) {\n                        assert.strictEqual(this, x);\n                        assert.strictEqual(typeof onFulfilled, \"function\");\n                        assert.strictEqual(typeof onRejected, \"function\");\n                        onFulfilled();\n                    }\n                };\n                return x;\n            }\n\n            testPromiseResolution(xFactory, function (promise, done) {\n\n                promise.then(function () {\n                    done();\n                });\n            });\n        });\n\n        describe(\"Uses the original value of `then`\", function () {\n            var numberOfTimesThenWasRetrieved = null;\n\n            beforeEach(function () {\n                numberOfTimesThenWasRetrieved = 0;\n            });\n\n            function xFactory() {\n                return Object.create(Object.prototype, {\n                    then: {\n                        get: function () {\n                            if (numberOfTimesThenWasRetrieved === 0) {\n                                return function (onFulfilled) {\n                                    onFulfilled();\n                                };\n                            }\n                            return null;\n                        }\n                    }\n                });\n            }\n\n            testPromiseResolution(xFactory, function (promise, done) {\n\n                promise.then(function () {\n                    done();\n                });\n            });\n        });\n\n        describe(\"2.3.3.3.1: If/when `resolvePromise` is called with value `y`, run `[[Resolve]](promise, y)`\",\n                 function () {\n            describe(\"`y` is not a thenable\", function () {\n                testCallingResolvePromiseFulfillsWith(function () { return undefined; }, \"`undefined`\", undefined);\n                testCallingResolvePromiseFulfillsWith(function () { return null; }, \"`null`\", null);\n                testCallingResolvePromiseFulfillsWith(function () { return false; }, \"`false`\", false);\n                testCallingResolvePromiseFulfillsWith(function () { return 5; }, \"`5`\", 5);\n                testCallingResolvePromiseFulfillsWith(function () { return sentinel; }, \"an object\", sentinel);\n                testCallingResolvePromiseFulfillsWith(function () { return sentinelArray; }, \"an array\", sentinelArray);\n            });\n\n            describe(\"`y` is a thenable\", function () {\n                Object.keys(thenables.fulfilled).forEach(function (stringRepresentation) {\n                    function yFactory() {\n                        return thenables.fulfilled[stringRepresentation](sentinel);\n                    }\n\n                    testCallingResolvePromiseFulfillsWith(yFactory, stringRepresentation, sentinel);\n                });\n\n                Object.keys(thenables.rejected).forEach(function (stringRepresentation) {\n                    function yFactory() {\n                        return thenables.rejected[stringRepresentation](sentinel);\n                    }\n\n                    testCallingResolvePromiseRejectsWith(yFactory, stringRepresentation, sentinel);\n                });\n            });\n\n            describe(\"`y` is a thenable for a thenable\", function () {\n                Object.keys(thenables.fulfilled).forEach(function (outerStringRepresentation) {\n                    var outerThenableFactory = thenables.fulfilled[outerStringRepresentation];\n\n                    Object.keys(thenables.fulfilled).forEach(function (innerStringRepresentation) {\n                        var innerThenableFactory = thenables.fulfilled[innerStringRepresentation];\n\n                        var stringRepresentation = outerStringRepresentation + \" for \" + innerStringRepresentation;\n\n                        function yFactory() {\n                            return outerThenableFactory(innerThenableFactory(sentinel));\n                        }\n\n                        testCallingResolvePromiseFulfillsWith(yFactory, stringRepresentation, sentinel);\n                    });\n\n                    Object.keys(thenables.rejected).forEach(function (innerStringRepresentation) {\n                        var innerThenableFactory = thenables.rejected[innerStringRepresentation];\n\n                        var stringRepresentation = outerStringRepresentation + \" for \" + innerStringRepresentation;\n\n                        function yFactory() {\n                            return outerThenableFactory(innerThenableFactory(sentinel));\n                        }\n\n                        testCallingResolvePromiseRejectsWith(yFactory, stringRepresentation, sentinel);\n                    });\n                });\n            });\n        });\n\n        describe(\"2.3.3.3.2: If/when `rejectPromise` is called with reason `r`, reject `promise` with `r`\",\n                 function () {\n            Object.keys(reasons).forEach(function (stringRepresentation) {\n                testCallingRejectPromiseRejectsWith(reasons[stringRepresentation], stringRepresentation);\n            });\n        });\n\n        describe(\"2.3.3.3.3: If both `resolvePromise` and `rejectPromise` are called, or multiple calls to the same \" +\n                 \"argument are made, the first call takes precedence, and any further calls are ignored.\",\n                 function () {\n            describe(\"calling `resolvePromise` then `rejectPromise`, both synchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            resolvePromise(sentinel);\n                            rejectPromise(other);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(function (value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `resolvePromise` synchronously then `rejectPromise` asynchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            resolvePromise(sentinel);\n\n                            setTimeout(function () {\n                                rejectPromise(other);\n                            }, 0);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(function (value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `resolvePromise` then `rejectPromise`, both asynchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            setTimeout(function () {\n                                resolvePromise(sentinel);\n                            }, 0);\n\n                            setTimeout(function () {\n                                rejectPromise(other);\n                            }, 0);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(function (value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `resolvePromise` with an asynchronously-fulfilled promise, then calling \" +\n                     \"`rejectPromise`, both synchronously\", function () {\n                function xFactory() {\n                    var tuple = pending();\n                    setTimeout(function () {\n                        tuple.fulfill(sentinel);\n                    }, 50);\n\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            resolvePromise(tuple.promise);\n                            rejectPromise(other);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(function (value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `resolvePromise` with an asynchronously-rejected promise, then calling \" +\n                     \"`rejectPromise`, both synchronously\", function () {\n                function xFactory() {\n                    var tuple = pending();\n                    setTimeout(function () {\n                        tuple.reject(sentinel);\n                    }, 50);\n\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            resolvePromise(tuple.promise);\n                            rejectPromise(other);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n                    promise.then(null, function (reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `rejectPromise` then `resolvePromise`, both synchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            rejectPromise(sentinel);\n                            resolvePromise(other);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(null, function (reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `rejectPromise` synchronously then `resolvePromise` asynchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            rejectPromise(sentinel);\n\n                            setTimeout(function () {\n                                resolvePromise(other);\n                            }, 0);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(null, function (reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `rejectPromise` then `resolvePromise`, both asynchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            setTimeout(function () {\n                                rejectPromise(sentinel);\n                            }, 0);\n\n                            setTimeout(function () {\n                                resolvePromise(other);\n                            }, 0);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(null, function (reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `resolvePromise` twice synchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise) {\n                            resolvePromise(sentinel);\n                            resolvePromise(other);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(function (value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `resolvePromise` twice, first synchronously then asynchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise) {\n                            resolvePromise(sentinel);\n\n                            setTimeout(function () {\n                                resolvePromise(other);\n                            }, 0);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(function (value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `resolvePromise` twice, both times asynchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise) {\n                            setTimeout(function () {\n                                resolvePromise(sentinel);\n                            }, 0);\n\n                            setTimeout(function () {\n                                resolvePromise(other);\n                            }, 0);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(function (value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `resolvePromise` with an asynchronously-fulfilled promise, then calling it again, both \" +\n                     \"times synchronously\", function () {\n                function xFactory() {\n                    var tuple = pending();\n                    setTimeout(function () {\n                        tuple.fulfill(sentinel);\n                    }, 50);\n\n                    return {\n                        then: function (resolvePromise) {\n                            resolvePromise(tuple.promise);\n                            resolvePromise(other);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(function (value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `resolvePromise` with an asynchronously-rejected promise, then calling it again, both \" +\n                     \"times synchronously\", function () {\n                function xFactory() {\n                    var tuple = pending();\n                    setTimeout(function () {\n                        tuple.reject(sentinel);\n                    }, 50);\n\n                    return {\n                        then: function (resolvePromise) {\n                            resolvePromise(tuple.promise);\n                            resolvePromise(other);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n\n                    promise.then(null, function (reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `rejectPromise` twice synchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            rejectPromise(sentinel);\n                            rejectPromise(other);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n                    promise.then(null, function (reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `rejectPromise` twice, first synchronously then asynchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            rejectPromise(sentinel);\n\n                            setTimeout(function () {\n                                resolvePromise(other);\n                            }, 0);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n                    promise.then(null, function (reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"calling `rejectPromise` twice, both times asynchronously\", function () {\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            setTimeout(function () {\n                                rejectPromise(sentinel);\n                            }, 0);\n\n                            setTimeout(function () {\n                                resolvePromise(other);\n                            }, 0);\n                        }\n                    };\n                }\n\n                testPromiseResolution(xFactory, function (promise, done) {\n                    promise.then(null, function (reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n\n            describe(\"saving and abusing `resolvePromise` and `rejectPromise`\", function () {\n                var savedResolvePromise, savedRejectPromise;\n\n                function xFactory() {\n                    return {\n                        then: function (resolvePromise, rejectPromise) {\n                            savedResolvePromise = resolvePromise;\n                            savedRejectPromise = rejectPromise;\n                        }\n                    };\n                }\n\n                beforeEach(function () {\n                    savedResolvePromise = null;\n                    savedRejectPromise = null;\n                });\n\n                testPromiseResolution(xFactory, function (promise, done) {\n                    var timesFulfilled = 0;\n                    var timesRejected = 0;\n\n                    promise.then(\n                        function () {\n                            ++timesFulfilled;\n                        },\n                        function () {\n                            ++timesRejected;\n                        }\n                    );\n\n                    if (savedResolvePromise && savedRejectPromise) {\n                        savedResolvePromise(dummy);\n                        savedResolvePromise(dummy);\n                        savedRejectPromise(dummy);\n                        savedRejectPromise(dummy);\n                    }\n\n                    setTimeout(function () {\n                        savedResolvePromise(dummy);\n                        savedResolvePromise(dummy);\n                        savedRejectPromise(dummy);\n                        savedRejectPromise(dummy);\n                    }, 4);\n\n                    setTimeout(function () {\n                        assert.strictEqual(timesFulfilled, 1);\n                        assert.strictEqual(timesRejected, 0);\n                        done();\n                    }, 60);\n                });\n            });\n        });\n\n        describe(\"2.3.3.3.4: If calling `then` throws an exception `e`,\", function () {\n            describe(\"2.3.3.3.4.1: If `resolvePromise` or `rejectPromise` have been called, ignore it.\", function () {\n                describe(\"`resolvePromise` was called with a non-thenable\", function () {\n                    function xFactory() {\n                        return {\n                            then: function (resolvePromise) {\n                                resolvePromise(sentinel);\n                                throw other;\n                            }\n                        };\n                    }\n\n                    testPromiseResolution(xFactory, function (promise, done) {\n                        promise.then(function (value) {\n                            assert.strictEqual(value, sentinel);\n                            done();\n                        });\n                    });\n                });\n\n                describe(\"`resolvePromise` was called with an asynchronously-fulfilled promise\", function () {\n                    function xFactory() {\n                        var tuple = pending();\n                        setTimeout(function () {\n                            tuple.fulfill(sentinel);\n                        }, 50);\n\n                        return {\n                            then: function (resolvePromise) {\n                                resolvePromise(tuple.promise);\n                                throw other;\n                            }\n                        };\n                    }\n\n                    testPromiseResolution(xFactory, function (promise, done) {\n                        promise.then(function (value) {\n                            assert.strictEqual(value, sentinel);\n                            done();\n                        });\n                    });\n                });\n\n                describe(\"`resolvePromise` was called with an asynchronously-rejected promise\", function () {\n                    function xFactory() {\n                        var tuple = pending();\n                        setTimeout(function () {\n                            tuple.reject(sentinel);\n                        }, 50);\n\n                        return {\n                            then: function (resolvePromise) {\n                                resolvePromise(tuple.promise);\n                                throw other;\n                            }\n                        };\n                    }\n\n                    testPromiseResolution(xFactory, function (promise, done) {\n                        promise.then(null, function (reason) {\n                            assert.strictEqual(reason, sentinel);\n                            done();\n                        });\n                    });\n                });\n\n                describe(\"`rejectPromise` was called\", function () {\n                    function xFactory() {\n                        return {\n                            then: function (resolvePromise, rejectPromise) {\n                                rejectPromise(sentinel);\n                                throw other;\n                            }\n                        };\n                    }\n\n                    testPromiseResolution(xFactory, function (promise, done) {\n                        promise.then(null, function (reason) {\n                            assert.strictEqual(reason, sentinel);\n                            done();\n                        });\n                    });\n                });\n\n                describe(\"`resolvePromise` then `rejectPromise` were called\", function () {\n                    function xFactory() {\n                        return {\n                            then: function (resolvePromise, rejectPromise) {\n                                resolvePromise(sentinel);\n                                rejectPromise(other);\n                                throw other;\n                            }\n                        };\n                    }\n\n                    testPromiseResolution(xFactory, function (promise, done) {\n                        promise.then(function (value) {\n                            assert.strictEqual(value, sentinel);\n                            done();\n                        });\n                    });\n                });\n\n                describe(\"`rejectPromise` then `resolvePromise` were called\", function () {\n                    function xFactory() {\n                        return {\n                            then: function (resolvePromise, rejectPromise) {\n                                rejectPromise(sentinel);\n                                resolvePromise(other);\n                                throw other;\n                            }\n                        };\n                    }\n\n                    testPromiseResolution(xFactory, function (promise, done) {\n                        promise.then(null, function (reason) {\n                            assert.strictEqual(reason, sentinel);\n                            done();\n                        });\n                    });\n                });\n            });\n\n            describe(\"2.3.3.3.4.2: Otherwise, reject `promise` with `e` as the reason.\", function () {\n                describe(\"straightforward case\", function () {\n                    function xFactory() {\n                        return {\n                            then: function () {\n                                throw sentinel;\n                            }\n                        };\n                    }\n\n                    testPromiseResolution(xFactory, function (promise, done) {\n                        promise.then(null, function (reason) {\n                            assert.strictEqual(reason, sentinel);\n                            done();\n                        });\n                    });\n                });\n\n                describe(\"`resolvePromise` is called asynchronously before the `throw`\", function () {\n                    function xFactory() {\n                        return {\n                            then: function (resolvePromise) {\n                                setTimeout(function () {\n                                    resolvePromise(other);\n                                }, 0);\n                                throw sentinel;\n                            }\n                        };\n                    }\n\n                    testPromiseResolution(xFactory, function (promise, done) {\n                        promise.then(null, function (reason) {\n                            assert.strictEqual(reason, sentinel);\n                            done();\n                        });\n                    });\n                });\n\n                describe(\"`rejectPromise` is called asynchronously before the `throw`\", function () {\n                    function xFactory() {\n                        return {\n                            then: function (resolvePromise, rejectPromise) {\n                                setTimeout(function () {\n                                    rejectPromise(other);\n                                }, 0);\n                                throw sentinel;\n                            }\n                        };\n                    }\n\n                    testPromiseResolution(xFactory, function (promise, done) {\n                        promise.then(null, function (reason) {\n                            assert.strictEqual(reason, sentinel);\n                            done();\n                        });\n                    });\n                });\n            });\n        });\n    });\n\n    describe(\"2.3.3.4: If `then` is not a function, fulfill promise with `x`\", function () {\n        function testFulfillViaNonFunction(then, stringRepresentation) {\n            var x = null;\n\n            beforeEach(function () {\n                x = { then: then };\n            });\n\n            function xFactory() {\n                return x;\n            }\n\n            describe(\"`then` is \" + stringRepresentation, function () {\n                testPromiseResolution(xFactory, function (promise, done) {\n                    promise.then(function (value) {\n                        assert.strictEqual(value, x);\n                        done();\n                    });\n                });\n            });\n        }\n\n        testFulfillViaNonFunction(5, \"`5`\");\n        testFulfillViaNonFunction({}, \"an object\");\n        testFulfillViaNonFunction([function () { }], \"an array containing a function\");\n        testFulfillViaNonFunction(/a-b/i, \"a regular expression\");\n        testFulfillViaNonFunction(Object.create(Function.prototype), \"an object inheriting from `Function.prototype`\");\n\n\n\n    });\n});\n"
  },
  {
    "path": "test/mocha/2.3.4.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\n\ndescribe(\"2.3.4: If `x` is not an object or function, fulfill `promise` with `x`\", function () {\n    function testValue(expectedValue, stringRepresentation, beforeEachHook, afterEachHook) {\n        describe(\"The value is \" + stringRepresentation, function () {\n            if (typeof beforeEachHook === \"function\") {\n                beforeEach(beforeEachHook);\n            }\n            if (typeof afterEachHook === \"function\") {\n                afterEach(afterEachHook);\n            }\n\n            testFulfilled(dummy, function (promise1, done) {\n                var promise2 = promise1.then(function onFulfilled() {\n                    return expectedValue;\n                });\n\n                promise2.then(function onPromise2Fulfilled(actualValue) {\n                    assert.strictEqual(actualValue, expectedValue);\n                    done();\n                });\n            });\n            testRejected(dummy, function (promise1, done) {\n                var promise2 = promise1.then(null, function onRejected() {\n                    return expectedValue;\n                });\n\n                promise2.then(function onPromise2Fulfilled(actualValue) {\n                    assert.strictEqual(actualValue, expectedValue);\n                    done();\n                });\n            });\n        });\n    }\n\n    testValue(undefined, \"`undefined`\");\n    testValue(null, \"`null`\");\n    testValue(false, \"`false`\");\n    testValue(true, \"`true`\");\n    testValue(0, \"`0`\");\n\n    testValue(\n        true,\n        \"`true` with `Boolean.prototype` modified to have a `then` method\",\n        function () {\n            Boolean.prototype.then = function () {};\n        },\n        function () {\n            delete Boolean.prototype.then;\n        }\n    );\n\n    testValue(\n        1,\n        \"`1` with `Number.prototype` modified to have a `then` method\",\n        function () {\n            Number.prototype.then = function () {};\n        },\n        function () {\n            delete Number.prototype.then;\n        }\n    );\n});\n"
  },
  {
    "path": "test/mocha/3.2.1.js",
    "content": "\"use strict\";\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\n\ndescribe(\"3.2.1: Both `onFulfilled` and `onRejected` are optional arguments.\", function () {\n    describe(\"3.2.1.1: If `onFulfilled` is not a function, it must be ignored.\", function () {\n        function testNonFunction(nonFunction, stringRepresentation) {\n            specify(\"`onFulfilled` is \" + stringRepresentation, function (done) {\n                rejected(dummy).then(nonFunction, function () {\n                    done();\n                });\n            });\n        }\n\n        testNonFunction(undefined, \"`undefined`\");\n        testNonFunction(null, \"`null`\");\n        testNonFunction(false, \"`false`\");\n        testNonFunction(5, \"`5`\");\n        testNonFunction({}, \"an object\");\n    });\n\n    describe(\"3.2.1.2: If `onRejected` is not a function, it must be ignored.\", function () {\n        function testNonFunction(nonFunction, stringRepresentation) {\n            specify(\"`onRejected` is \" + stringRepresentation, function (done) {\n                fulfilled(dummy).then(function () {\n                    done();\n                }, nonFunction);\n            });\n        }\n\n        testNonFunction(undefined, \"`undefined`\");\n        testNonFunction(null, \"`null`\");\n        testNonFunction(false, \"`false`\");\n        testNonFunction(5, \"`5`\");\n        testNonFunction({}, \"an object\");\n    });\n});\n"
  },
  {
    "path": "test/mocha/3.2.2.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\nvar sentinel = { sentinel: \"sentinel\" }; // a sentinel fulfillment value to test for with strict equality\n\ndescribe(\"3.2.2: If `onFulfilled` is a function,\", function () {\n    describe(\"3.2.2.1: it must be called after `promise` is fulfilled, with `promise`’s fulfillment value as its \" +\n             \"first argument.\", function () {\n        testFulfilled(sentinel, function (promise, done) {\n            promise.then(function onFulfilled(value) {\n                assert.strictEqual(value, sentinel);\n                done();\n            });\n        });\n    });\n\n    describe(\"3.2.2.2: it must not be called more than once.\", function () {\n        specify(\"already-fulfilled\", function (done) {\n            var timesCalled = 0;\n\n            fulfilled(dummy).then(function onFulfilled() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n        });\n\n        specify(\"trying to fulfill a pending promise more than once, immediately\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            tuple.fulfill(dummy);\n            tuple.fulfill(dummy);\n        });\n\n        specify(\"trying to fulfill a pending promise more than once, delayed\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            setTimeout(function () {\n                tuple.fulfill(dummy);\n                tuple.fulfill(dummy);\n            }, 50);\n        });\n\n        specify(\"trying to fulfill a pending promise more than once, immediately then delayed\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            tuple.fulfill(dummy);\n            setTimeout(function () {\n                tuple.fulfill(dummy);\n            }, 50);\n        });\n\n        specify(\"when multiple `then` calls are made, spaced apart in time\", function (done) {\n            var tuple = pending();\n            var timesCalled = [0, 0, 0];\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled[0], 1);\n            });\n\n            setTimeout(function () {\n                tuple.promise.then(function onFulfilled() {\n                    assert.strictEqual(++timesCalled[1], 1);\n                });\n            }, 50);\n\n            setTimeout(function () {\n                tuple.promise.then(function onFulfilled() {\n                    assert.strictEqual(++timesCalled[2], 1);\n                    done();\n                });\n            }, 100);\n\n            setTimeout(function () {\n                tuple.fulfill(dummy);\n            }, 150);\n        });\n\n        specify(\"when `then` is interleaved with fulfillment\", function (done) {\n            var tuple = pending();\n            var timesCalled = [0, 0];\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled[0], 1);\n            });\n\n            tuple.fulfill(dummy);\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(++timesCalled[1], 1);\n                done();\n            });\n        });\n    });\n\n    describe(\"3.2.2.3: it must not be called if `onRejected` has been called.\", function () {\n        testRejected(dummy, function (promise, done) {\n            var onRejectedCalled = false;\n\n            promise.then(function onFulfilled() {\n                assert.strictEqual(onRejectedCalled, false);\n                done();\n            }, function onRejected() {\n                onRejectedCalled = true;\n            });\n\n            setTimeout(function(){done();}, 100);\n        });\n\n        specify(\"trying to reject then immediately fulfill\", function (done) {\n            var tuple = pending();\n            var onRejectedCalled = false;\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(onRejectedCalled, false);\n                done();\n            }, function onRejected() {\n                onRejectedCalled = true;\n            });\n\n            tuple.reject(dummy);\n            tuple.fulfill(dummy);\n            setTimeout(function(){done();}, 100);\n        });\n\n        specify(\"trying to reject then fulfill, delayed\", function (done) {\n            var tuple = pending();\n            var onRejectedCalled = false;\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(onRejectedCalled, false);\n                done();\n            }, function onRejected() {\n                onRejectedCalled = true;\n            });\n\n            setTimeout(function () {\n                tuple.reject(dummy);\n                tuple.fulfill(dummy);\n            }, 50);\n            setTimeout(function(){done();}, 100);\n        });\n\n        specify(\"trying to reject immediately then fulfill delayed\", function (done) {\n            var tuple = pending();\n            var onRejectedCalled = false;\n\n            tuple.promise.then(function onFulfilled() {\n                assert.strictEqual(onRejectedCalled, false);\n                done();\n            }, function onRejected() {\n                onRejectedCalled = true;\n            });\n\n            tuple.reject(dummy);\n            setTimeout(function () {\n                tuple.fulfill(dummy);\n            }, 50);\n            setTimeout(function(){done();}, 100);\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/3.2.3.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\nvar adapter = global.adapter;\nvar rejected = adapter.rejected;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\nvar sentinel = { sentinel: \"sentinel\" }; // a sentinel fulfillment value to test for with strict equality\n\ndescribe(\"3.2.3: If `onRejected` is a function,\", function () {\n    describe(\"3.2.3.1: it must be called after `promise` is rejected, with `promise`’s rejection reason as its \" +\n             \"first argument.\", function () {\n        testRejected(sentinel, function (promise, done) {\n            promise.then(null, function onRejected(reason) {\n                assert.strictEqual(reason, sentinel);\n                done();\n            });\n        });\n    });\n\n    describe(\"3.2.3.2: it must not be called more than once.\", function () {\n        specify(\"already-rejected\", function (done) {\n            var timesCalled = 0;\n\n            rejected(dummy).then(null, function onRejected() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n        });\n\n        specify(\"trying to reject a pending promise more than once, immediately\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            tuple.reject(dummy);\n            tuple.reject(dummy);\n        });\n\n        specify(\"trying to reject a pending promise more than once, delayed\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            setTimeout(function () {\n                tuple.reject(dummy);\n                tuple.reject(dummy);\n            }, 50);\n        });\n\n        specify(\"trying to reject a pending promise more than once, immediately then delayed\", function (done) {\n            var tuple = pending();\n            var timesCalled = 0;\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled, 1);\n                done();\n            });\n\n            tuple.reject(dummy);\n            setTimeout(function () {\n                tuple.reject(dummy);\n            }, 50);\n        });\n\n        specify(\"when multiple `then` calls are made, spaced apart in time\", function (done) {\n            var tuple = pending();\n            var timesCalled = [0, 0, 0];\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled[0], 1);\n            });\n\n            setTimeout(function () {\n                tuple.promise.then(null, function onRejected() {\n                    assert.strictEqual(++timesCalled[1], 1);\n                });\n            }, 50);\n\n            setTimeout(function () {\n                tuple.promise.then(null, function onRejected() {\n                    assert.strictEqual(++timesCalled[2], 1);\n                    done();\n                });\n            }, 100);\n\n            setTimeout(function () {\n                tuple.reject(dummy);\n            }, 150);\n        });\n\n        specify(\"when `then` is interleaved with rejection\", function (done) {\n            var tuple = pending();\n            var timesCalled = [0, 0];\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled[0], 1);\n            });\n\n            tuple.reject(dummy);\n\n            tuple.promise.then(null, function onRejected() {\n                assert.strictEqual(++timesCalled[1], 1);\n                done();\n            });\n        });\n    });\n\n    describe(\"3.2.3.3: it must not be called if `onFulfilled` has been called.\", function () {\n        testFulfilled(dummy, function (promise, done) {\n            var onFulfilledCalled = false;\n\n            promise.then(function onFulfilled() {\n                onFulfilledCalled = true;\n            }, function onRejected() {\n                assert.strictEqual(onFulfilledCalled, false);\n                done();\n            });\n\n            setTimeout(function(){done();}, 100);\n        });\n\n        specify(\"trying to fulfill then immediately reject\", function (done) {\n            var tuple = pending();\n            var onFulfilledCalled = false;\n\n            tuple.promise.then(function onFulfilled() {\n                onFulfilledCalled = true;\n            }, function onRejected() {\n                assert.strictEqual(onFulfilledCalled, false);\n                done();\n            });\n\n            tuple.fulfill(dummy);\n            tuple.reject(dummy);\n            setTimeout(function(){done();}, 100);\n        });\n\n        specify(\"trying to fulfill then reject, delayed\", function (done) {\n            var tuple = pending();\n            var onFulfilledCalled = false;\n\n            tuple.promise.then(function onFulfilled() {\n                onFulfilledCalled = true;\n            }, function onRejected() {\n                assert.strictEqual(onFulfilledCalled, false);\n                done();\n            });\n\n            setTimeout(function () {\n                tuple.fulfill(dummy);\n                tuple.reject(dummy);\n            }, 50);\n            setTimeout(function(){done();}, 100);\n        });\n\n        specify(\"trying to fulfill immediately then reject delayed\", function (done) {\n            var tuple = pending();\n            var onFulfilledCalled = false;\n\n            tuple.promise.then(function onFulfilled() {\n                onFulfilledCalled = true;\n            }, function onRejected() {\n                assert.strictEqual(onFulfilledCalled, false);\n                done();\n            });\n\n            tuple.fulfill(dummy);\n            setTimeout(function () {\n                tuple.reject(dummy);\n            }, 50);\n            setTimeout(function(){done();}, 100);\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/3.2.4.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\n\ndescribe(\"3.2.4: `then` must return before `onFulfilled` or `onRejected` is called\", function () {\n    testFulfilled(dummy, function (promise, done) {\n        var thenHasReturned = false;\n\n        promise.then(function onFulfilled() {\n            assert(thenHasReturned);\n            done();\n        });\n\n        thenHasReturned = true;\n    });\n\n    testRejected(dummy, function (promise, done) {\n        var thenHasReturned = false;\n\n        promise.then(null, function onRejected() {\n            assert(thenHasReturned);\n            done();\n        });\n\n        thenHasReturned = true;\n    });\n});\n"
  },
  {
    "path": "test/mocha/3.2.5.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar sinon = require(\"sinon\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\nvar other = { other: \"other\" }; // a value we don't want to be strict equal to\nvar sentinel = { sentinel: \"sentinel\" }; // a sentinel fulfillment value to test for with strict equality\nvar sentinel2 = { sentinel2: \"sentinel2\" };\nvar sentinel3 = { sentinel3: \"sentinel3\" };\n\nfunction callbackAggregator(times, ultimateCallback) {\n    var soFar = 0;\n    return function () {\n        if (++soFar === times) {\n            ultimateCallback();\n        }\n    };\n}\n\ndescribe(\"3.2.5: `then` may be called multiple times on the same promise.\", function () {\n    describe(\"3.2.5.1: If/when `promise` is fulfilled, respective `onFulfilled` callbacks must execute in the order \" +\n             \"of their originating calls to `then`.\", function () {\n        describe(\"multiple boring fulfillment handlers\", function () {\n            testFulfilled(sentinel, function (promise, done) {\n                var handler1 = sinon.stub().returns(other);\n                var handler2 = sinon.stub().returns(other);\n                var handler3 = sinon.stub().returns(other);\n\n                var spy = sinon.spy();\n                promise.then(handler1, spy);\n                promise.then(handler2, spy);\n                promise.then(handler3, spy);\n\n                promise.then(function (value) {\n                    assert.strictEqual(value, sentinel);\n\n                    sinon.assert.calledWith(handler1, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler2, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler3, sinon.match.same(sentinel));\n                    sinon.assert.notCalled(spy);\n\n                    done();\n                });\n            });\n        });\n\n        describe(\"multiple fulfillment handlers, one of which throws\", function () {\n            testFulfilled(sentinel, function (promise, done) {\n                var handler1 = sinon.stub().returns(other);\n                var handler2 = sinon.stub().throws(other);\n                var handler3 = sinon.stub().returns(other);\n\n                var spy = sinon.spy();\n                promise.then(handler1, spy);\n                promise.then(handler2, spy).caught(function(){});\n                promise.then(handler3, spy);\n\n                promise.then(function (value) {\n                    assert.strictEqual(value, sentinel);\n\n                    sinon.assert.calledWith(handler1, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler2, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler3, sinon.match.same(sentinel));\n                    sinon.assert.notCalled(spy);\n\n                    done();\n                });\n            });\n        });\n\n        describe(\"results in multiple branching chains with their own fulfillment values\", function () {\n            testFulfilled(dummy, function (promise, done) {\n                var semiDone = callbackAggregator(3, done);\n\n                promise.then(function () {\n                    return sentinel;\n                }).then(function (value) {\n                    assert.strictEqual(value, sentinel);\n                    semiDone();\n                });\n\n                promise.then(function () {\n                    throw sentinel2;\n                }).then(null, function (reason) {\n                    assert.strictEqual(reason, sentinel2);\n                    semiDone();\n                });\n\n                promise.then(function () {\n                    return sentinel3;\n                }).then(function (value) {\n                    assert.strictEqual(value, sentinel3);\n                    semiDone();\n                });\n            });\n        });\n\n        describe(\"`onFulfilled` handlers are called in the original order\", function () {\n            testFulfilled(dummy, function (promise, done) {\n                var handler1 = sinon.spy(function handler1() {});\n                var handler2 = sinon.spy(function handler2() {});\n                var handler3 = sinon.spy(function handler3() {});\n\n                promise.then(handler1);\n                promise.then(handler2);\n                promise.then(handler3);\n\n                promise.then(function () {\n                    sinon.assert.callOrder(handler1, handler2, handler3);\n                    done();\n                });\n            });\n\n            describe(\"even when one handler is added inside another handler\", function () {\n                testFulfilled(dummy, function (promise, done) {\n                    var handler1 = sinon.spy(function handler1() {});\n                    var handler2 = sinon.spy(function handler2() {});\n                    var handler3 = sinon.spy(function handler3() {});\n\n                    promise.then(function () {\n                        handler1();\n                        promise.then(handler3);\n                    });\n                    promise.then(handler2);\n\n                    promise.then(function () {\n                        // Give implementations a bit of extra time to flush their internal queue, if necessary.\n                        setTimeout(function () {\n                            sinon.assert.callOrder(handler1, handler2, handler3);\n                            done();\n                        }, 15);\n                    });\n                });\n            });\n        });\n    });\n\n    describe(\"3.2.5.2: If/when `promise` is rejected, respective `onRejected` callbacks must execute in the order \" +\n             \"of their originating calls to `then`.\", function () {\n        describe(\"multiple boring rejection handlers\", function () {\n            testRejected(sentinel, function (promise, done) {\n                var handler1 = sinon.stub().returns(other);\n                var handler2 = sinon.stub().returns(other);\n                var handler3 = sinon.stub().returns(other);\n\n                var spy = sinon.spy();\n                promise.then(spy, handler1);\n                promise.then(spy, handler2);\n                promise.then(spy, handler3);\n\n                promise.then(null, function (reason) {\n                    assert.strictEqual(reason, sentinel);\n\n                    sinon.assert.calledWith(handler1, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler2, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler3, sinon.match.same(sentinel));\n                    sinon.assert.notCalled(spy);\n\n                    done();\n                });\n            });\n        });\n\n        describe(\"multiple rejection handlers, one of which throws\", function () {\n            testRejected(sentinel, function (promise, done) {\n                var handler1 = sinon.stub().returns(other);\n                var handler2 = sinon.stub().throws(other);\n                var handler3 = sinon.stub().returns(other);\n\n                var spy = sinon.spy();\n                promise.then(spy, handler1);\n                promise.then(spy, handler2).caught(function(){});\n                promise.then(spy, handler3);\n\n                promise.then(null, function (reason) {\n                    assert.strictEqual(reason, sentinel);\n\n                    sinon.assert.calledWith(handler1, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler2, sinon.match.same(sentinel));\n                    sinon.assert.calledWith(handler3, sinon.match.same(sentinel));\n                    sinon.assert.notCalled(spy);\n\n                    done();\n                });\n            });\n        });\n\n        describe(\"results in multiple branching chains with their own fulfillment values\", function () {\n            testRejected(sentinel, function (promise, done) {\n                var semiDone = callbackAggregator(3, done);\n\n                promise.then(null, function () {\n                    return sentinel;\n                }).then(function (value) {\n                    assert.strictEqual(value, sentinel);\n                    semiDone();\n                });\n\n                promise.then(null, function () {\n                    throw sentinel2;\n                }).then(null, function (reason) {\n                    assert.strictEqual(reason, sentinel2);\n                    semiDone();\n                });\n\n                promise.then(null, function () {\n                    return sentinel3;\n                }).then(function (value) {\n                    assert.strictEqual(value, sentinel3);\n                    semiDone();\n                });\n            });\n        });\n\n        describe(\"`onRejected` handlers are called in the original order\", function () {\n            testRejected(dummy, function (promise, done) {\n                var handler1 = sinon.spy(function handler1() {});\n                var handler2 = sinon.spy(function handler2() {});\n                var handler3 = sinon.spy(function handler3() {});\n\n                promise.then(null, handler1);\n                promise.then(null, handler2);\n                promise.then(null, handler3);\n\n                promise.then(null, function () {\n                    sinon.assert.callOrder(handler1, handler2, handler3);\n                    done();\n                });\n            });\n\n            describe(\"even when one handler is added inside another handler\", function () {\n                testRejected(dummy, function (promise, done) {\n                    var handler1 = sinon.spy(function handler1() {});\n                    var handler2 = sinon.spy(function handler2() {});\n                    var handler3 = sinon.spy(function handler3() {});\n\n                    promise.then(null, function () {\n                        handler1();\n                        promise.then(null, handler3);\n                    });\n                    promise.then(null, handler2);\n\n                    promise.then(null, function () {\n                        // Give implementations a bit of extra time to flush their internal queue, if necessary.\n                        setTimeout(function () {\n                            sinon.assert.callOrder(handler1, handler2, handler3);\n                            done();\n                        }, 15);\n                    });\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/3.2.6.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\nvar pending = adapter.pending;\n\nvar dummy = { dummy: \"dummy\" }; // we fulfill or reject with this when we don't intend to test against it\nvar sentinel = { sentinel: \"sentinel\" }; // a sentinel fulfillment value to test for with strict equality\nvar other = { other: \"other\" }; // a value we don't want to be strict equal to\n\ndescribe(\"3.2.6: `then` must return a promise: `promise2 = promise1.then(onFulfilled, onRejected)`\", function () {\n    specify(\"is a promise\", function () {\n        var promise1 = pending().promise;\n        var promise2 = promise1.then();\n\n        assert(typeof promise2 === \"object\" || typeof promise2 === \"function\");\n        assert.notStrictEqual(promise2, null);\n        assert.strictEqual(typeof promise2.then, \"function\");\n    });\n\n    describe(\"3.2.6.1: If either `onFulfilled` or `onRejected` returns a value that is not a promise, `promise2` \" +\n             \"must be fulfilled with that value.\", function () {\n        function testValue(expectedValue, stringRepresentation) {\n            describe(\"The value is \" + stringRepresentation, function () {\n                testFulfilled(dummy, function (promise1, done) {\n                    var promise2 = promise1.then(function onFulfilled() {\n                        return expectedValue;\n                    });\n\n                    promise2.then(function onPromise2Fulfilled(actualValue) {\n                        assert.strictEqual(actualValue, expectedValue);\n                        done();\n                    });\n                });\n                testRejected(dummy, function (promise1, done) {\n                    var promise2 = promise1.then(null, function onRejected() {\n                        return expectedValue;\n                    });\n\n                    promise2.then(function onPromise2Fulfilled(actualValue) {\n                        assert.strictEqual(actualValue, expectedValue);\n                        done();\n                    });\n                });\n            });\n        }\n\n        testValue(undefined, \"`undefined`\");\n        testValue(null, \"`null`\");\n        testValue(false, \"`false`\");\n        testValue(0, \"`0`\");\n        testValue(new Error(), \"an error\");\n        testValue(new Date(), \"a date\");\n        testValue({}, \"an object\");\n        testValue({ then: 5 }, \"an object with a non-function `then` property\");\n    });\n\n    describe(\"3.2.6.2: If either `onFulfilled` or `onRejected` throws an exception, `promise2` \" +\n             \"must be rejected with the thrown exception as the reason.\", function () {\n        function testReason(expectedReason, stringRepresentation) {\n            describe(\"The reason is \" + stringRepresentation, function () {\n                testFulfilled(dummy, function (promise1, done) {\n                    var promise2 = promise1.then(function onFulfilled() {\n                        throw expectedReason;\n                    });\n\n                    promise2.then(null, function onPromise2Rejected(actualReason) {\n                        assert.strictEqual(actualReason, expectedReason);\n                        done();\n                    });\n                });\n                testRejected(dummy, function (promise1, done) {\n                    var promise2 = promise1.then(null, function onRejected() {\n                        throw expectedReason;\n                    });\n\n                    promise2.then(null, function onPromise2Rejected(actualReason) {\n                        assert.strictEqual(actualReason, expectedReason);\n                        done();\n                    });\n                });\n            });\n        }\n\n        testReason(undefined, \"`undefined`\");\n        testReason(null, \"`null`\");\n        testReason(false, \"`false`\");\n        testReason(0, \"`0`\");\n        testReason(new Error(), \"an error\");\n        testReason(new Date(), \"a date\");\n        testReason({}, \"an object\");\n        testReason({ then: function () { } }, \"a promise-alike\");\n        testReason(fulfilled(dummy), \"a fulfilled promise\");\n        var promise = rejected(dummy); promise.caught(function(){});\n        testReason(promise, \"a rejected promise\");\n    });\n\n    describe(\"3.2.6.3: If either `onFulfilled` or `onRejected` returns a promise (call it `returnedPromise`), \" +\n             \"`promise2` must assume the state of `returnedPromise`\", function () {\n        describe(\"3.2.6.3.1: If `returnedPromise` is pending, `promise2` must remain pending until `returnedPromise` \" +\n                 \"is fulfilled or rejected.\", function () {\n            testFulfilled(dummy, function (promise1, done) {\n                var wasFulfilled = false;\n                var wasRejected = false;\n\n                var promise2 = promise1.then(function onFulfilled() {\n                    var returnedPromise = pending().promise;\n                    return returnedPromise;\n                });\n\n                promise2.then(\n                    function onPromise2Fulfilled() {\n                        wasFulfilled = true;\n                    },\n                    function onPromise2Rejected() {\n                        wasRejected = true;\n                    }\n                );\n\n                setTimeout(function () {\n                    assert.strictEqual(wasFulfilled, false);\n                    assert.strictEqual(wasRejected, false);\n                    done();\n                }, 100);\n            });\n\n            testRejected(dummy, function (promise1, done) {\n                var wasFulfilled = false;\n                var wasRejected = false;\n\n                var promise2 = promise1.then(null, function onRejected() {\n                    var returnedPromise = pending().promise;\n                    return returnedPromise;\n                });\n\n                promise2.then(\n                    function onPromise2Fulfilled() {\n                        wasFulfilled = true;\n                    },\n                    function onPromise2Rejected() {\n                        wasRejected = true;\n                    }\n                );\n\n                setTimeout(function () {\n                    assert.strictEqual(wasFulfilled, false);\n                    assert.strictEqual(wasRejected, false);\n                    done();\n                }, 100);\n            });\n        });\n\n        describe(\"3.2.6.3.2: If/when `returnedPromise` is fulfilled, `promise2` must be fulfilled with the same value.\",\n                 function () {\n            describe(\"`promise1` is fulfilled, and `returnedPromise` is:\", function () {\n                testFulfilled(sentinel, function (returnedPromise, done) {\n                    var promise1 = fulfilled(dummy);\n                    var promise2 = promise1.then(function onFulfilled() {\n                        return returnedPromise;\n                    });\n\n                    promise2.then(function onPromise2Fulfilled(value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n\n                specify(\"a pseudo-promise\", function (done) {\n                    var promise1 = fulfilled(dummy);\n                    var promise2 = promise1.then(function onFulfilled() {\n                        return {\n                            then: function (f) { f(sentinel); }\n                        };\n                    });\n\n                    promise2.then(function onPromise2Fulfilled(value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n            describe(\"`promise1` is rejected, and `returnedPromise` is:\", function () {\n                testFulfilled(sentinel, function (returnedPromise, done) {\n                    var promise1 = rejected(dummy);\n                    var promise2 = promise1.then(null, function onRejected() {\n                        return returnedPromise;\n                    });\n\n                    promise2.then(function onPromise2Fulfilled(value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n\n                specify(\"a pseudo-promise\", function (done) {\n                    var promise1 = rejected(dummy);\n                    var promise2 = promise1.then(null, function onRejected() {\n                        return {\n                            then: function (f) { f(sentinel); }\n                        };\n                    });\n\n                    promise2.then(function onPromise2Fulfilled(value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n        });\n\n        describe(\"3.2.6.3.3: If/when `returnedPromise` is rejected, `promise2` must be rejected with the same reason.\",\n                 function () {\n            describe(\"`promise1` is fulfilled, and `returnedPromise` is:\", function () {\n                testRejected(sentinel, function (returnedPromise, done) {\n                    var promise1 = fulfilled(dummy);\n                    var promise2 = promise1.then(function onFulfilled() {\n                        return returnedPromise;\n                    });\n\n                    promise2.then(null, function onPromise2Rejected(reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n\n                specify(\"a pseudo-promise\", function (done) {\n                    var promise1 = fulfilled(dummy);\n                    var promise2 = promise1.then(function onFulfilled() {\n                        return {\n                            then: function (f, r) { r(sentinel); }\n                        };\n                    });\n\n                    promise2.then(null, function onPromise2Rejected(reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n            describe(\"`promise1` is rejected, and `returnedPromise` is:\", function () {\n                testRejected(sentinel, function (returnedPromise, done) {\n                    var promise1 = rejected(dummy);\n                    var promise2 = promise1.then(null, function onRejected() {\n                        return returnedPromise;\n                    });\n\n                    promise2.then(null, function onPromise2Rejected(reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n\n                specify(\"a pseudo-promise\", function (done) {\n                    var promise1 = rejected(dummy);\n                    var promise2 = promise1.then(null, function onRejected() {\n                        return {\n                            then: function (f, r) { r(sentinel); }\n                        };\n                    });\n\n                    promise2.then(null, function onPromise2Rejected(reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n        });\n    });\n\n    describe(\"3.2.6.4: If `onFulfilled` is not a function and `promise1` is fulfilled, `promise2` must be fulfilled \" +\n             \"with the same value.\", function () {\n\n        function testNonFunction(nonFunction, stringRepresentation) {\n            describe(\"`onFulfilled` is \" + stringRepresentation, function () {\n                testFulfilled(sentinel, function (promise1, done) {\n                    var promise2 = promise1.then(nonFunction);\n\n                    promise2.then(function onPromise2Fulfilled(value) {\n                        assert.strictEqual(value, sentinel);\n                        done();\n                    });\n                });\n            });\n        }\n\n        testNonFunction(undefined, \"`undefined`\");\n        testNonFunction(null, \"`null`\");\n        testNonFunction(false, \"`false`\");\n        testNonFunction(5, \"`5`\");\n        testNonFunction({}, \"an object\");\n        testNonFunction([function () { return other; }], \"an array containing a function\");\n    });\n\n    describe(\"3.2.6.5: If `onRejected` is not a function and `promise1` is rejected, `promise2` must be rejected \" +\n             \"with the same reason.\", function () {\n\n        function testNonFunction(nonFunction, stringRepresentation) {\n            describe(\"`onRejected` is \" + stringRepresentation, function () {\n                testRejected(sentinel, function (promise1, done) {\n                    var promise2 = promise1.then(null, nonFunction);\n\n                    promise2.then(null, function onPromise2Rejected(reason) {\n                        assert.strictEqual(reason, sentinel);\n                        done();\n                    });\n                });\n            });\n        }\n\n        testNonFunction(undefined, \"`undefined`\");\n        testNonFunction(null, \"`null`\");\n        testNonFunction(false, \"`false`\");\n        testNonFunction(5, \"`5`\");\n        testNonFunction({}, \"an object\");\n        testNonFunction([function () { return other; }], \"an array containing a function\");\n    });\n});\n"
  },
  {
    "path": "test/mocha/any.js",
    "content": "\"use strict\";\n/*\nBased on When.js tests\n\nOpen Source Initiative OSI - The MIT License\n\nhttp://www.opensource.org/licenses/mit-license.php\n\nCopyright (c) 2011 Brian Cavalier\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar sentinel = {};\nvar other = {};\nvar RangeError = Promise.RangeError;\n\ndescribe(\"Promise.any-test\", function () {\n\n    specify(\"should reject on empty input array\", function() {\n        var a = [];\n        return Promise.any(a)\n            .caught(RangeError, testUtils.returnToken)\n            .then(testUtils.assertToken);\n    });\n\n    specify(\"should resolve with an input value\", function() {\n        var input = [1, 2, 3];\n        return Promise.any(input).then(\n            function(result) {\n                assert(testUtils.contains(input, result));\n            }, assert.fail\n        );\n    });\n\n    specify(\"should resolve with a promised input value\", function() {\n        var input = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];\n        return Promise.any(input).then(\n            function(result) {\n                assert(testUtils.contains([1, 2, 3], result));\n            }, assert.fail\n        );\n    });\n\n    specify(\"should reject with all rejected input values if all inputs are rejected\", function() {\n        var input = [Promise.reject(1), Promise.reject(2), Promise.reject(3)];\n        var promise = Promise.any(input);\n\n        return promise.then(\n            assert.fail,\n            function(result) {\n                //Cannot use deep equality in IE8 because non-enumerable properties are not\n                //supported\n                assert(result[0] === 1);\n                assert(result[1] === 2);\n                assert(result[2] === 3);\n            }\n        );\n    });\n\n    specify(\"should accept a promise for an array\", function() {\n        var expected, input;\n\n        expected = [1, 2, 3];\n        input = Promise.resolve(expected);\n\n        return Promise.any(input).then(\n            function(result) {\n                assert.notDeepEqual(expected.indexOf(result), -1);\n            }, assert.fail\n        );\n    });\n\n    specify(\"should allow zero handlers\", function() {\n        var input = [1, 2, 3];\n        return Promise.any(input).then(\n            function(result) {\n                assert(testUtils.contains(input, result));\n            }, assert.fail\n        );\n    });\n\n    specify(\"should resolve to empty array when input promise does not resolve to array\", function() {\n        return Promise.any(Promise.resolve(1))\n            .caught(TypeError, testUtils.returnToken)\n            .then(testUtils.assertToken);\n    });\n\n    specify(\"should reject when given immediately rejected promise\", function() {\n        var err = new Error();\n        return Promise.any(Promise.reject(err)).then(assert.fail, function(e) {\n            assert.strictEqual(err, e);\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/api_exceptions.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\nfunction assertErrorHasLongTraces(e) {\n    assert(e.stack.indexOf(\"From previous event:\") > -1);\n}\n\nfunction testCollection(name, a1, a2, a3) {\n\n    function getPromise(obj, val) {\n        return obj === void 0\n            ? Promise.resolve(val)[name](a1, a2, a3)\n            : Promise[name](val, a1, a2, a3);\n    }\n\n    function thenable(obj) {\n        var o = {\n            then: function(f) {\n                setTimeout(function(){\n                    f(3);\n                }, 1);\n            }\n        }\n        specify(\"thenable for non-collection value\", function() {\n            return getPromise(obj, o)\n                .then(assert.fail)\n                .caught(Promise.TypeError, testUtils.returnToken)\n                .then(testUtils.assertToken)\n        });\n    };\n\n    function immediate(obj) {\n        specify(\"immediate for non-collection value\", function(){\n            return getPromise(obj, 3)\n                .then(assert.fail)\n                .caught(Promise.TypeError, testUtils.returnToken)\n                .then(testUtils.assertToken)\n        });\n    }\n\n    function promise(obj) {\n        var d = Promise.defer();\n        setTimeout(function(){\n            d.resolve(3);\n        }, 1);\n        specify(\"promise for non-collection value\", function() {\n            return getPromise(obj, d.promise)\n                .then(assert.fail)\n                .caught(Promise.TypeError, testUtils.returnToken)\n                .then(testUtils.assertToken)\n        });\n    }\n\n    describe(\"When passing non-collection argument to Promise.\"+name + \"() it should reject\", function() {\n        immediate(Promise);\n        thenable(Promise);\n        promise(Promise);\n    });\n\n    describe(\"When calling .\"+name + \"() on a promise that resolves to a non-collection it should reject\", function() {\n        immediate();\n        thenable();\n        promise();\n    });\n}\n\nif (Promise.hasLongStackTraces()) {\n\n\n    describe(\"runtime API misuse should result in rejections\", function(){\n        specify(\"returning promises circularly\", function() {\n            var d = Promise.defer();\n            var p = d.promise;\n\n            var c = p.then(function(){\n                return c;\n            });\n            d.fulfill(3);\n            return c.then(assert.fail, function(e){\n                assert(e instanceof Promise.TypeError);\n            });\n        });\n\n        specify(\"using illegal catchfilter\", function() {\n\n            var d = Promise.defer();\n            var p = d.promise;\n            d.fulfill(3);\n            return p.caught(null, function(){\n\n            }).then(assert.fail, function(e){\n                assert(e instanceof Promise.TypeError);\n            });\n        });\n\n        specify(\"non-function to map\", function() {\n\n            return Promise.map([], []).then(assert.fail, function(e){\n                assert(e instanceof Promise.TypeError);\n            });\n        });\n\n\n        specify(\"non-function to map inside then\", function() {\n\n            return Promise.resolve().then(function(){\n                return Promise.map([], []);\n            }).then(assert.fail, function(e){\n                assert(e instanceof Promise.TypeError);\n                assertErrorHasLongTraces(e);\n            });\n        });\n\n\n        specify(\"non-function to reduce\", function() {\n\n            return Promise.reduce([], []).then(assert.fail, function(e){\n                assert(e instanceof Promise.TypeError);\n            });\n        });\n\n\n        specify(\"non-function to reduce inside then\", function() {\n\n            return Promise.resolve().then(function(){\n                return Promise.reduce([], []);\n            }).then(assert.fail, function(e){\n                assert(e instanceof Promise.TypeError);\n                assertErrorHasLongTraces(e);\n            });\n        });\n\n\n        specify(\"non-integer to some\", function() {\n\n            return Promise.some([], \"asd\").then(assert.fail, function(e){\n                assert(e instanceof Promise.TypeError);\n            });\n        });\n\n\n        specify(\"non-integer to some inside then\", function() {\n\n            return Promise.resolve().then(function(){\n                return Promise.some([], \"asd\")\n            }).then(assert.fail, function(e){\n                assert(e instanceof Promise.TypeError);\n                assertErrorHasLongTraces(e);\n            });\n        });\n\n        specify(\"non-array to all\", function() {\n\n            Promise.all(3, 3).then(assert.fail, function(e){\n                assert(e instanceof Promise.TypeError);\n            });\n        });\n\n\n        specify(\"non-array to all inside then\", function() {\n\n            return Promise.resolve().then(function(){\n                return Promise.all(3, 3);\n            }).then(assert.fail, function(e) {\n                assert(e instanceof Promise.TypeError);\n                assertErrorHasLongTraces(e);\n            });\n        });\n\n    });\n\n\n    describe(\"static API misuse should just throw right away\", function(){\n\n        specify(\"non-function to promise constructor\", function() {\n            try {\n                new Promise();\n                assert.fail();\n            }\n            catch (e) {\n                assert(e instanceof Promise.TypeError);\n            }\n        });\n\n        specify(\"non-function to coroutine\", function() {\n            try {\n                Promise.coroutine();\n                assert.fail();\n            }\n            catch (e) {\n                assert(e instanceof Promise.TypeError);\n            }\n        });\n\n\n        specify(\"non-object to promisifyAll\", function() {\n            try {\n                Promise.promisifyAll();\n                assert.fail();\n            }\n            catch (e) {\n                assert(e instanceof Promise.TypeError);\n            }\n        });\n\n\n        specify(\"non-function to promisify\", function() {\n            try {\n                Promise.promisify();\n                assert.fail();\n            }\n            catch (e) {\n                assert(e instanceof Promise.TypeError);\n            }\n        });\n\n    });\n\n    testCollection(\"race\");\n    testCollection(\"all\");\n    testCollection(\"settle\");\n    testCollection(\"any\");\n    testCollection(\"some\", 1);\n    testCollection(\"map\", function(){});\n    testCollection(\"reduce\", function(){});\n    testCollection(\"filter\", function(){});\n    testCollection(\"props\", function(){});\n}\n"
  },
  {
    "path": "test/mocha/async.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\ndescribe(\"Async requirement\", function() {\n\n    var arr = [];\n\n    function a() {\n        arr.push(1);\n    }\n\n    function b() {\n        arr.push(2);\n    }\n\n    function c() {\n        arr.push(3);\n    }\n\n\n    function assertArr() {\n        assert.deepEqual(arr, [1,2,3]);\n        arr.length = 0;\n    }\n\n    beforeEach(function() {\n        arr = [];\n    });\n\n    specify(\"Basic\", function() {\n        var p = new Promise(function(resolve) {\n            resolve();\n        });\n        a();\n        p.then(c);\n        b();\n        return p.then(assertArr);\n    });\n\n    specify(\"Resolve-Before-Then\", function() {\n        var resolveP;\n        var p = new Promise(function(resolve) {\n            resolveP = resolve;\n        });\n\n        a();\n        resolveP();\n        p.then(c);\n        b();\n        return p.then(assertArr);\n    });\n\n    specify(\"Resolve-After-Then\", function() {\n        var resolveP;\n        var p = new Promise(function(resolve) {\n            resolveP = resolve;\n        });\n\n        a();\n        p.then(c);\n        resolveP();\n        b();\n        return p.then(assertArr);\n    });\n\n    specify(\"Then-Inside-Then\", function() {\n        var fulfilledP = Promise.resolve();\n        return fulfilledP.then(function() {\n            a();\n            var ret = fulfilledP.then(c).then(assertArr);\n            b();\n            return ret;\n        });\n    });\n\n    if (typeof Error.captureStackTrace === \"function\") {\n        describe(\"Should not grow the stack and cause eventually stack overflow.\", function(){\n            var lim;\n            beforeEach(function() {\n                lim = Error.stackTraceLimit;\n                Error.stackTraceLimit = 10000;\n            });\n\n            afterEach(function() {\n                Error.stackTraceLimit = lim;\n            });\n\n            function assertStackIsNotGrowing(stack) {\n                assert(stack.split(\"\\n\").length > 5);\n                assert(stack.split(\"\\n\").length < 15);\n            }\n\n            specify(\"Already fulfilled.\", function() {\n                function test(i){\n                    if (i <= 0){\n                       return Promise.resolve(new Error().stack);\n                   } else {\n                       return Promise.resolve(i-1).then(test)\n                   }\n                }\n                return test(100).then(function(stack) {\n                    assertStackIsNotGrowing(stack);\n                });\n            });\n\n            specify(\"Already rejected\", function() {\n                function test(i){\n                    if (i <= 0){\n                       return Promise.reject(new Error().stack);\n                   } else {\n                       return Promise.reject(i-1).then(assert.fail, test)\n                   }\n                }\n                return test(100).then(assert.fail, function(stack) {\n                    assertStackIsNotGrowing(stack);\n                });\n            });\n\n            specify(\"Immediately fulfilled\", function() {\n                function test(i){\n                    var deferred = Promise.defer();\n                    if (i <= 0){\n                       deferred.fulfill(new Error().stack);\n                       return deferred.promise;\n                   } else {\n                       deferred.fulfill(i-1);\n                       return deferred.promise.then(test)\n                   }\n                }\n                return test(100).then(function(stack) {\n                    assertStackIsNotGrowing(stack);\n                });\n            });\n\n            specify(\"Immediately rejected\", function() {\n                function test(i){\n                    var deferred = Promise.defer();\n                    if (i <= 0){\n                       deferred.reject(new Error().stack);\n                       return deferred.promise;\n                   } else {\n                       deferred.reject(i-1);\n                       return deferred.promise.then(assert.fail, test)\n                   }\n                }\n                return test(10).then(assert.fail, function(stack) {\n                    assertStackIsNotGrowing(stack);\n                });\n            });\n        });\n    }\n\n    if (testUtils.isRecentNode) {\n        describe(\"Frees memory of old values in promise chains\", function () {\n            function getHeapUsed() {\n                global.gc();\n                return process.memoryUsage().heapUsed;\n            }\n\n            var initialHeapUsed;\n\n            before(function () {\n                if (typeof global.gc !== \"function\") {\n                    throw new Error(\"These tests require the --expose-gc flag\");\n                }\n                initialHeapUsed = getHeapUsed();\n            });\n\n            specify(\".then\", function () {\n                return Promise.resolve()\n                    .then(function () {\n                        assert.ok(\n                            getHeapUsed() < initialHeapUsed * 1.1,\n                            \"Promise.resolve uses minimal memory\"\n                        );\n                        var rows = [];\n                        for (var i = 0; i < 1e6; i++) {\n                            rows.push([\"Example \" + i, i, i * 2]);\n                        }\n                        return rows;\n                    })\n                    .then(function (rows) {\n                        assert.ok(\n                            getHeapUsed() > initialHeapUsed * 12,\n                            \"large array uses a large amount of memory\"\n                        );\n                        return { len: rows.length };\n                    })\n                    .then(function (x) {\n                        // work around cancellation retaining previous result\n                        return x;\n                    })\n                    .then(function (summaryResult) {\n                        assert.ok(\n                            getHeapUsed() < initialHeapUsed * 1.1,\n                            \"memory used by large array is freed\"\n                        );\n                        assert.strictEqual(summaryResult.len, 1e6, \"result\");\n                    });\n            });\n\n            specify(\".catch\", function () {\n                return Promise.reject(new Error(\"error 1\"))\n                    .catch(function () {\n                        assert.ok(\n                            getHeapUsed() < initialHeapUsed * 1.1,\n                            \"Promise.reject uses minimal memory\"\n                        );\n                        var rows = [];\n                        for (var i = 0; i < 1e6; i++) {\n                            rows.push([\"Example \" + i, i, i * 2]);\n                        }\n                        var error = new Error(\"error 2\");\n                        error.result = rows;\n                        throw error;\n                    })\n                    .catch(function (err) {\n                        assert.ok(\n                            getHeapUsed() > initialHeapUsed * 12,\n                            \"large array uses a large amount of memory\"\n                        );\n                        var rows = err.result;\n                        var error = new Error(\"error 3\");\n                        error.result = { len: rows.length };\n                        throw error;\n                    })\n                    .catch(function (err) {\n                        // work around cancellation retaining previous result\n                        throw err;\n                    })\n                    .catch(function (err) {\n                        assert.ok(\n                            getHeapUsed() < initialHeapUsed * 1.1,\n                            \"memory used by large array is freed\"\n                        );\n                        var summaryResult = err.result;\n                        assert.strictEqual(summaryResult.len, 1e6, \"result\");\n                    });\n            });\n        });\n    }\n});\n"
  },
  {
    "path": "test/mocha/async_hooks.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\n\nvar getContextFn = Promise._getContext;\nPromise.config({ asyncHooks: true });\nvar supportsAsync = Promise._getContext !== getContextFn;\nPromise.config({ asyncHooks: false });\nif (supportsAsync) {\n    runTests();\n}\n\nfunction runTests() {\n    var async_hooks = require('async_hooks');\n\n    var tree = new Set();\n    var hook = async_hooks.createHook({\n        init: function(asyncId, type, triggerId) {\n            if (tree.has(triggerId)) {\n                tree.add(asyncId);\n            }\n        }\n    });\n\n    var currentId = async_hooks.executionAsyncId;\n\n    function getAsyncPromise() {\n        return new Promise(function(resolve, reject) {\n            setTimeout(function() {\n                setTimeout(resolve, 1);\n            }, 1);\n        });\n    }\n\n    describe(\"async_hooks\", function() {\n        beforeEach(function() {\n            Promise.config({ asyncHooks: true });\n        })\n        afterEach(function()  {\n            tree.clear();\n            hook.disable();\n            Promise.config({ asyncHooks: false });\n        });\n\n        it('should preserve async context when using fromNode', function() {\n            hook.enable()\n            tree.add(currentId());\n\n            return new Promise(function(resolve) {\n                var globalResolve;\n                setImmediate(function() {\n                    hook.enable()\n                    tree.add(currentId());\n                    resolve(\n                        new Promise(function(resolve) { globalResolve = resolve; })\n                        .then(function() {\n                            assert.ok(tree.has(currentId()));\n                        })\n                    );\n                })\n\n                setTimeout(function() {\n                    globalResolve();\n                }, 10);\n            })\n        });\n\n        it('should preserve async context when using .map', function() {\n            hook.enable()\n            tree.add(currentId());\n            var d1 = getAsyncPromise();\n\n            return new Promise(function(resolve, reject) {\n                resolve(Promise.map([d1, null, Promise.resolve(1), Promise.delay(1)], function() {\n                    return currentId();\n                }).then(function(asyncIds) {\n                    for (var i = 0; i < asyncIds.length; ++i) {\n                        assert.ok(tree.has(asyncIds[i]));\n                    }\n                }));\n            });\n        });\n\n        it('should preserve async context when using .filter', function() {\n            hook.enable()\n            tree.add(currentId());\n            var d1 = getAsyncPromise();\n\n            return new Promise(function(resolve, reject) {\n                resolve(Promise.filter([d1, null, Promise.resolve(1), Promise.delay(1)], function() {\n                    assert.ok(tree.has(currentId()));\n                }));\n            });\n        });\n\n        it('should preserve async context when using .reduce', function() {\n            hook.enable()\n            tree.add(currentId());\n            var d1 = getAsyncPromise();\n\n            return new Promise(function(resolve, reject) {\n                resolve(Promise.reduce([d1, null, Promise.resolve(1), Promise.delay(1)], function() {\n                    assert.ok(tree.has(currentId()));\n                }));\n            });\n        });\n\n        it('should preserve async context when using .join', function() {\n            hook.enable()\n            tree.add(currentId());\n            var d1 = getAsyncPromise();\n\n            return new Promise(function(resolve, reject) {\n                resolve(Promise.join(d1, Promise.delay(1), function() {\n                    assert.ok(tree.has(currentId()));\n                }));\n            });\n        });\n\n        it('should preserve async context when using .each', function() {\n            hook.enable()\n            tree.add(currentId());\n            var d1 = getAsyncPromise();\n\n            return new Promise(function(resolve, reject) {\n                resolve(Promise.each([d1, null, Promise.resolve(1), Promise.delay(1)], function() {\n                    assert.ok(tree.has(currentId()));\n                }));\n            });\n        });\n\n        it('should be able to disable AsyncResource usage', function() {\n            Promise.config({ asyncHooks: false });\n            hook.enable()\n            tree.add(currentId());\n            var d1 = getAsyncPromise();\n\n            return new Promise(function(resolve, reject) {\n                resolve(d1.then(function() {\n                    assert.ok(!tree.has(currentId()));\n                }));\n            });\n        });\n    });\n}\n"
  },
  {
    "path": "test/mocha/bind.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar defaultThis = function() {return this}();\n\nfunction timedThenableOf(value) {\n    return {\n        then: function(onFulfilled) {\n            setTimeout(function() {\n                onFulfilled(value);\n            }, 1);\n        }\n    };\n}\n\nfunction timedPromiseOf(value) {\n    return Promise.delay(1, value);\n}\n\nfunction immediatePromiseOf(value) {\n    return Promise.resolve(value);\n}\n\nfunction immediateThenableOf(value) {\n    return {\n        then: function(onFulfilled) {\n            onFulfilled(value);\n        }\n    };\n}\n\nfunction timedRejectedThenableOf(value) {\n    return {\n        then: function(onFulfilled, onRejected) {\n            setTimeout(function() {\n                onRejected(value);\n            }, 1);\n        }\n    };\n}\n\nfunction timedRejectedPromiseOf(value) {\n    return Promise.delay(1).then(function() {\n        throw value;\n    });\n}\n\nfunction immediateRejectedPromiseOf(value) {\n    return Promise.reject(value);\n}\n\nfunction immediateRejectedThenableOf(value) {\n    return {\n        then: function(onFulfilled, onRejected) {\n            onRejected(value);\n        }\n    };\n}\n\nfunction toValue(valueOrPromise) {\n    if (valueOrPromise && typeof valueOrPromise.value === \"function\") {\n        return valueOrPromise.value();\n    }\n    return valueOrPromise\n}\n\nvar THIS = {name: \"this\"};\n\nfunction CustomError1() {}\nCustomError1.prototype = Object.create(Error.prototype);\nfunction CustomError2() {}\nCustomError2.prototype = Object.create(Error.prototype);\n\n\ndescribe(\"when using .bind\", function() {\n    describe(\"with finally\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"in straight-forward handler\", function() {\n                return Promise.resolve().bind(THIS).lastly(function(){\n                    assert(this === THIS);\n                });\n            });\n\n            specify(\"after promise returned from finally resolves\", function() {\n                var d = Promise.defer();\n                var promise = d.promise;\n                var waited = false;\n\n                setTimeout(function(){\n                    waited = true;\n                    d.fulfill();\n                }, 1);\n\n                return Promise.resolve().bind(THIS).lastly(function(){\n                    return promise;\n                }).lastly(function(){\n                    assert(waited);\n                    assert(this === THIS);\n                });\n            });\n        })\n\n    });\n\n    describe(\"with tap\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"in straight-forward handler\", function() {\n                return Promise.resolve().bind(THIS).tap(function(){\n                    assert(this === THIS);\n                });\n            });\n\n            specify(\"after promise returned from tap resolves\", function() {\n                var d = Promise.defer();\n                var promise = d.promise;\n                var waited = false;\n                setTimeout(function(){\n                    waited = true;\n                    d.fulfill();\n                }, 1);\n\n                return Promise.resolve().bind(THIS).tap(function(){\n                    return promise;\n                }).tap(function(){\n                    assert(waited);\n                    assert(this === THIS);\n                });\n            });\n        })\n\n    });\n\n    describe(\"with timeout\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"in straight-forward handler\", function() {\n                return Promise.resolve(3).bind(THIS).timeout(500).then(function(v) {\n                    assert(v === 3);\n                    assert(this === THIS);\n                });\n            });\n            specify(\"in rejected handler\", function() {\n                return Promise.reject(3).bind(THIS).timeout(500).then(assert.fail, function(v){\n                    assert(v === 3);\n                    assert(this === THIS);\n                });\n            });\n\n            specify(\"in rejected handler after timeout\", function() {\n                return new Promise(function(){})\n                    .bind(THIS).timeout(10).caught(Promise.TimeoutError, function(err){\n                    assert(this === THIS);\n                });\n            });\n        })\n\n    });\n\n    describe(\"With catch filters\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"in an immediately trapped catch handler\", function() {\n                return Promise.resolve().bind(THIS).then(function(){\n                    assert(THIS === this);\n                    var a;\n                    a.b();\n                }).caught(Error, function(e){\n                    assert(THIS === this);\n                });\n            });\n            specify(\"in a later trapped catch handler\", function() {\n                return Promise.resolve().bind(THIS).then(function(){\n                   throw new CustomError1();\n                }).caught(CustomError2, assert.fail)\n                .caught(CustomError1, function(e){\n                    assert(THIS === this);\n                });\n            });\n        });\n    });\n\n    describe(\"With .get promises\", function(){\n        specify(\"this should refer to the bound object\", function() {\n            return Promise.resolve({key: \"value\"}).bind(THIS).get(\"key\").then(function(val){\n                assert(val === \"value\");\n                assert(this === THIS);\n            });\n        });\n    });\n\n    describe(\"With .call promises\", function(){\n        specify(\"this should refer to the bound object\", function() {\n            return Promise.resolve({key: function(){return \"value\";}}).bind(THIS).call(\"key\").then(function(val){\n                assert(val === \"value\");\n                assert(this === THIS);\n            });\n        });\n    });\n\n\n    describe(\"With .done promises\", function(){\n\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"when rejected\", function() {\n                return Promise.reject().bind(THIS).done(assert.fail, function(){\n                    assert(this === THIS);\n                });\n            });\n            specify(\"when fulfilled\", function() {\n                return Promise.resolve().bind(THIS).done(function(){\n                    assert(this === THIS);\n                });\n            });\n        });\n    });\n\n    describe(\"With .spread promises\", function(){\n\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"when spreading immediate array\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).spread(function(a, b, c){\n                    assert(c === 3);\n                    assert(this === THIS);\n                });\n            });\n            specify(\"when spreading eventual array\", function() {\n                var d = Promise.defer();\n                var promise = d.promise;\n\n                setTimeout(function(){\n                    d.fulfill([1,2,3]);\n                }, 1);\n\n                return promise.bind(THIS).spread(function(a, b, c){\n                    assert(c === 3);\n                    assert(this === THIS);\n                });\n            });\n\n            specify(\"when spreading eventual array of eventual values\", function() {\n                var d = Promise.defer();\n                var promise = d.promise;\n                setTimeout(function(){\n                    var d1 = Promise.defer();\n                    var p1 = d1.promise;\n\n                    var d2 = Promise.defer();\n                    var p2 = d2.promise;\n\n                    var d3 = Promise.defer();\n                    var p3 = d3.promise;\n                    d.fulfill([p1, p2, p3]);\n\n                    setTimeout(function(){\n                        d1.fulfill(1);\n                        d2.fulfill(2);\n                        d3.fulfill(3);\n                    }, 3);\n                }, 1);\n                return promise.bind(THIS).all().spread(function(a, b, c){\n                    assert(c === 3);\n                    assert(this === THIS);\n                });\n\n            });\n        });\n    });\n\n    describe(\"With nodeify\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"when the callback succeeeds\", function() {\n                var spy = testUtils.getSpy();\n                Promise.resolve(3).bind(THIS).nodeify(spy(function(err, success){\n                    assert(success === 3);\n                    assert(this === THIS);\n                }));\n                return spy.promise;\n            });\n            specify(\"when the callback errs\", function() {\n                var spy = testUtils.getSpy();\n                Promise.reject(3).bind(THIS).nodeify(spy(function(err, success){\n                    assert(err === 3);\n                    assert(this === THIS);\n                }));\n                return spy.promise;\n            });\n        });\n    });\n\n\n    describe(\"With map\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"inside the mapper with immediate values\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).map(function(v, i){\n                    if (i === 2) {\n                        assert(this === THIS);\n                    }\n                });\n            });\n            specify(\"inside the mapper with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).map(function(v, i){\n                    if (i === 2) {\n                        assert(this === THIS);\n                    }\n                });\n            });\n\n            specify(\"after the mapper with immediate values\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).map(function(){\n                    return 1;\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n\n            specify(\"after the mapper with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).map(function(){\n                    return 1;\n                }).then(function(){\n                    assert(this === THIS);\n                });\n\n\n            });\n\n            specify(\"after the mapper with immediate values when the map returns promises\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).map(function(){\n                    return p1;\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n        });\n\n        describe(\"this should not refer to the bound object\", function() {\n            specify(\"in the promises created within the handler\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).map(function(){\n                    return p1.then(function(){\n                        assert(this !== THIS);\n                        return 1;\n                    })\n                }).then(function(){\n                    assert(this === THIS);\n                });\n\n            });\n        });\n    });\n\n    describe(\"With reduce\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"inside the reducer with immediate values\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).reduce(function(prev, v, i){\n                    if (i === 2) {\n                        assert(this === THIS);\n                    }\n                });\n            });\n            specify(\"inside the reducer with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).reduce(function(prev, v, i){\n                    if (i === 2) {\n                        assert(this === THIS);\n                    }\n                });\n            });\n\n            specify(\"after the reducer with immediate values\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).reduce(function(){\n                    return 1;\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n\n            specify(\"after the reducer with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n                return Promise.resolve([p1, p2, p3]).bind(THIS).reduce(function(){\n                    return 1;\n                }).then(function(){\n                    assert(this === THIS);\n                });\n\n            });\n\n            specify(\"after the reducer with immediate values when the reducer returns promise\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).reduce(function(){\n                    return p1;\n                }).then(function(){\n                    assert(this === THIS);\n                });\n\n\n            });\n        });\n\n        describe(\"this should not refer to the bound object\", function() {\n            specify(\"in the promises created within the handler\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).reduce(function(){\n                    return p1.then(function(){\n                        assert(this !== THIS);\n                        return 1;\n                    })\n                }).then(function(){\n                    assert(this === THIS);\n                });\n\n\n            });\n        });\n    });\n\n\n    describe(\"With filter\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"inside the filterer with immediate values\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).filter(function(v, i){\n                    if (i === 2) {\n                        assert(this === THIS);\n                    }\n                });\n            });\n            specify(\"inside the filterer with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).filter(function(v, i){\n                    if (i === 2) {\n                        assert(this === THIS);\n                    }\n                });\n            });\n\n            specify(\"after the filterer with immediate values\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).filter(function(){\n                    return 1;\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n\n            specify(\"after the filterer with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).filter(function(){\n                    return 1;\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n\n            specify(\"after the filterer with immediate values when the filterer returns promises\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).filter(function(){\n                    return p1;\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n        });\n\n        describe(\"this should not refer to the bound object\", function() {\n            specify(\"in the promises created within the handler\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).filter(function(){\n                    return p1.then(function(){\n                        assert(this !== THIS);\n                        return 1;\n                    })\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n        });\n    });\n\n    describe(\"With all\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"after all with immediate values\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).all().then(function(v){\n                    assert(v.length === 3);\n                    assert(this === THIS);\n                });\n            });\n            specify(\"after all with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).all().then(function(v){\n                    assert(v.length === 3);\n                    assert(this === THIS);\n                });\n            });\n        });\n\n        describe(\"this should not refer to the bound object\", function() {\n            specify(\"in the promises created within the handler\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).filter(function(){\n                    return Promise.all([p1]).then(function(){\n                        assert(this !== THIS);\n                        return 1;\n                    })\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n        });\n    });\n\n    describe(\"With any\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"after any with immediate values\", function() {\n                Promise.resolve([1,2,3]).bind(THIS).any().then(function(v){\n                    assert(v === 1);\n                    assert(this === THIS);\n                });\n            });\n            specify(\"after any with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).any().then(function(v){\n                    assert(v === 1);\n                    assert(this === THIS);\n                });\n            });\n        });\n\n        describe(\"this should not refer to the bound object\", function() {\n            specify(\"in the promises created within the handler\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).filter(function(){\n                    return Promise.any([p1]).then(function(){\n                        assert(this !== THIS);\n                        return 1;\n                    })\n                }).then(function(){\n                    assert(this === THIS);\n                });\n\n            });\n        });\n    });\n\n\n    describe(\"With race\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"after race with immediate values\", function() {\n                Promise.resolve([1,2,3]).bind(THIS).race().then(function(v){\n                    assert(v === 1);\n                    assert(this === THIS);\n                });\n            });\n            specify(\"after race with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).race().then(function(v){\n                    assert(v === 1);\n                    assert(this === THIS);\n                });\n            });\n        });\n\n        describe(\"this should not refer to the bound object\", function() {\n            specify(\"in the promises created within the handler\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).filter(function(){\n                    return Promise.race([p1]).then(function(){\n                        assert(this !== THIS);\n                        return 1;\n                    })\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n        });\n    });\n\n    describe(\"With delay\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"after race with immediate values\", function() {\n                Promise.resolve([1,2,3]).bind(THIS).delay(1).then(function(v){\n                    assert(v[0] === 1);\n                    assert(this === THIS);\n                });\n            });\n            specify(\"after race with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).delay(1).all().then(function(v){\n                    assert(v[0] === 1);\n                    assert(this === THIS);\n                });\n            });\n        });\n\n        describe(\"this should not refer to the bound object\", function() {\n            specify(\"in the promises created within the handler\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).delay(1).bind(THIS).delay(1).filter(function(){\n                    assert(this === THIS);\n                    return Promise.delay(1).then(function(){\n                        assert(this !== THIS);\n                        return 1;\n                    })\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n        });\n    });\n\n    describe(\"With settle\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"after settle with immediate values\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).settle().then(function(v){\n                    assert(v.length === 3);\n                    assert(this === THIS);\n                });\n            });\n            specify(\"after settle with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).settle().then(function(v){\n                    assert(v.length === 3);\n                    assert(this === THIS);\n                });\n            });\n        });\n\n        describe(\"this should not refer to the bound object\", function() {\n            specify(\"in the promises created within the handler\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).filter(function(){\n                    return Promise.settle([p1]).then(function(){\n                        assert(this !== THIS);\n                        return 1;\n                    })\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n        });\n    });\n\n    describe(\"With some\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"after some with immediate values\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).some(2).then(function(v){\n                    assert.deepEqual(v, [1,2]);\n                    assert(this === THIS);\n                });\n            });\n            specify(\"after some with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).some(2).then(function(v){\n                    assert.deepEqual(v, [1,2]);\n                    assert(this === THIS);\n                });\n            });\n\n            specify(\"after some with eventual array for eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                var dArray = Promise.defer();\n                var arrayPromise = dArray.promise;\n\n                setTimeout(function(){\n                    dArray.fulfill([p1, p2, p3]);\n                    setTimeout(function(){\n                        d1.fulfill(1);\n                        d2.fulfill(2);\n                        d3.fulfill(3);\n                    }, 1);\n                }, 1);\n\n                return arrayPromise.bind(THIS).some(2).then(function(v){\n                    assert.deepEqual(v, [1,2]);\n                    assert(this === THIS);\n                });\n            });\n        });\n\n        describe(\"this should not refer to the bound object\", function() {\n            specify(\"in the promises created within the handler\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n\n                return Promise.resolve([1,2,3]).bind(THIS).filter(function(){\n                    return Promise.some([p1], 1).then(function(){\n                        assert(this !== THIS);\n                        return 1;\n                    })\n                }).then(function(){\n                    assert(this === THIS);\n                });\n            });\n        });\n    });\n\n\n\n    describe(\"With props\", function() {\n        describe(\"this should refer to the bound object\", function() {\n            specify(\"after props with immediate values\", function() {\n                return Promise.resolve([1,2,3]).bind(THIS).props().then(function(v){\n                    assert(v[2] === 3);\n                    assert(this === THIS);\n                });\n            });\n            specify(\"after props with eventual values\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n\n                var d2 = Promise.defer();\n                var p2 = d2.promise;\n\n                var d3 = Promise.defer();\n                var p3 = d3.promise;\n\n                setTimeout(function(){\n                    d1.fulfill(1);\n                    d2.fulfill(2);\n                    d3.fulfill(3);\n                }, 1);\n\n                return Promise.resolve([p1, p2, p3]).bind(THIS).props().then(function(v){\n                    assert(v[2] === 3);\n                    assert(this === THIS);\n                });\n            });\n        });\n\n        describe(\"this should not refer to the bound object\", function() {\n            specify(\"in the promises created within the handler\", function() {\n                var d1 = Promise.defer();\n                var p1 = d1.promise;\n                setTimeout(function(){\n                    d1.fulfill(1);\n                }, 1);\n                return Promise.resolve([1,2,3]).bind(THIS).props(function(){\n                    return Promise.settle([p1]).then(function(){\n                        assert(this !== THIS);\n                        return 1;\n                    })\n                }).then(function(){\n                    assert(this === THIS);\n                });\n\n\n            });\n        });\n    });\n\n});\n\ndescribe(\"When using .bind to gratuitously rebind\", function() {\n    var a = {value: 1};\n    var b = {value: 2};\n    var c = {value: 3};\n\n    function makeTest(a, b, c) {\n        return function() {\n            return Promise.bind(a).then(function(){\n                assert(this.value === 1);\n            }).bind(b).then(function(){\n                assert(this.value === 2);\n            }).bind(c).then(function(){\n                assert(this.value === 3);\n            });\n        }\n    }\n\n    specify(\"should not get confused immediately\", makeTest(a, b, c));\n    specify(\"should not get confused immediate thenable\",\n        makeTest(immediateThenableOf(a), immediateThenableOf(b), immediateThenableOf(c)));\n    specify(\"should not get confused immediate promise\",\n        makeTest(immediatePromiseOf(a), immediatePromiseOf(b), immediatePromiseOf(c)));\n    specify(\"should not get confused timed thenable\",\n        makeTest(timedThenableOf(a), timedThenableOf(b), timedThenableOf(c)));\n    specify(\"should not get confused timed promise\",\n        makeTest(timedPromiseOf(a), timedPromiseOf(b), timedPromiseOf(c)));\n});\n\ndescribe(\"Promised thisArg\", function() {\n\n    var e = {value: 1};\n\n    specify(\"basic case, this first\", function(done) {\n        var thisPromise = Promise.delay(1, 1);\n        var promise = thisPromise.delay(1).thenReturn(2);\n        promise.bind(thisPromise).then(function(val) {\n            assert(+this === 1);\n            assert(+val === 2);\n            done();\n        });\n    });\n\n    specify(\"bound value is not changed by returned promise\", function() {\n        return Promise.resolve().then(function() {\n          return new Promise(function(resolve) {\n            resolve();\n          }).bind(THIS).then(function() {});\n        }).then(function() {\n            assert.strictEqual(this, defaultThis);\n        });\n    });\n\n    specify(\"basic case, main promise first\", function() {\n        var promise = Promise.delay(1, 2);\n        var thisPromise = promise.thenReturn(1);\n        return promise.bind(thisPromise).then(function(val) {\n            assert.strictEqual(+this, 1);\n            assert.strictEqual(+val, 2);\n        });\n    });\n\n    specify(\"both reject, this rejects first\", function(done) {\n        var e1 = new Error();\n        var e2 = new Error();\n        var thisPromise = Promise.delay(1, 0).thenThrow(e1);\n        var promise = Promise.delay(2, 56).thenThrow(e2);\n        promise.bind(thisPromise).then(null, function(reason) {\n            assert(this === defaultThis);\n            assert(reason === e1);\n            done();\n        });\n    });\n\n    specify(\"both reject, main promise rejects first\", function(done) {\n        var e1 = new Error(\"first\");\n        var e2 = new Error(\"second\");\n        var thisPromise = Promise.delay(56, 1).thenThrow(e1);\n        var promise = Promise.delay(2, 0).thenThrow(e2);\n        promise.bind(thisPromise).then(null, function(reason) {\n            assert(this === defaultThis);\n            assert(reason === e2);\n            done();\n        });\n    });\n\n    specify(\"Immediate value waits for deferred this\", function() {\n        var t = Promise.delay(1, THIS);\n        var t2 = {};\n        return Promise.resolve(t2).bind(t).then(function(value) {\n            assert.strictEqual(this, THIS);\n            assert.strictEqual(t2, value);\n        });\n    });\n\n\n    specify(\"Immediate error waits for deferred this\", function() {\n        var t = Promise.delay(1, THIS);\n        var err = new Error();\n        return Promise.reject(err).bind(t).then(assert.fail, function(e) {\n            assert.strictEqual(this, THIS);\n            assert.strictEqual(err, e);\n        });\n    });\n\n    function makeThisArgRejectedTest(reason) {\n        return function() {\n            return Promise.bind(reason()).then(assert.fail, function(e) {\n                assert(this === defaultThis);\n                assert(e.value === 1);\n            })\n        };\n    }\n\n    specify(\"if thisArg is rejected timed promise, returned promise is rejected\",\n        makeThisArgRejectedTest(function() { return timedRejectedPromiseOf(e); }));\n    specify(\"if thisArg is rejected immediate promise, returned promise is rejected\",\n        makeThisArgRejectedTest(function() { return immediateRejectedPromiseOf(e); }));\n    specify(\"if thisArg is rejected timed thenable, returned promise is rejected\",\n        makeThisArgRejectedTest(function() { return timedRejectedThenableOf(e); }));\n    specify(\"if thisArg is rejected immediate thenable, returned promise is rejected\",\n        makeThisArgRejectedTest(function() { return immediateRejectedThenableOf(e); }));\n\n    function makeThisArgRejectedTestMethod(reason) {\n        return function() {\n\n            return Promise.resolve().bind(reason()).then(assert.fail, function(e) {\n                assert(this === defaultThis);\n                assert(e.value === 1);\n            })\n        };\n    }\n\n    specify(\"if thisArg is rejected timed promise, returned promise is rejected\",\n        makeThisArgRejectedTestMethod(function() { return timedRejectedPromiseOf(e); }));\n    specify(\"if thisArg is rejected immediate promise, returned promise is rejected\",\n        makeThisArgRejectedTestMethod(function() { return immediateRejectedPromiseOf(e); }));\n    specify(\"if thisArg is rejected timed thenable, returned promise is rejected\",\n        makeThisArgRejectedTestMethod(function() { return timedRejectedThenableOf(e); }));\n    specify(\"if thisArg is rejected immediate thenable, returned promise is rejected\",\n        makeThisArgRejectedTestMethod(function() { return immediateRejectedThenableOf(e); }));\n});\n\ndescribe(\"github issue\", function() {\n    specify(\"gh-426\", function() {\n        return Promise.all([Promise.delay(10)]).bind(THIS).spread(function() {\n            assert.equal(this, THIS);\n        });\n    });\n\n    specify(\"gh-702-1\", function() {\n        return Promise.bind(Promise.delay(1, THIS)).then(function() {\n            assert.equal(this, THIS);\n        }).then(function() {\n            assert.equal(this, THIS);\n        });\n    });\n\n    specify(\"gh-702-2\", function() {\n        return Promise.resolve().bind(Promise.delay(1, THIS)).then(function() {\n            assert.equal(this, THIS);\n        }).then(function() {\n            assert.equal(this, THIS);\n        });\n    });\n});\n\n\ndescribe(\"promised bind\", function() {\n    specify(\"works after following\", function() {\n        return Promise.bind(Promise.delay(1, THIS)).then(function() {\n            assert.equal(this, THIS);\n            return Promise.delay(1);\n        }).then(function() {\n            assert.equal(this, THIS);\n            return Promise.delay(1);\n        }).then(function() {\n            assert.equal(this, THIS);\n        });\n    });\n\n    specify(\"works with spread\", function() {\n        return Promise.bind(Promise.delay(1, THIS), [1,2,3]).spread(function() {\n            assert.equal(this, THIS);\n            assert.deepEqual([1,2,3], [].slice.call(arguments));\n            return Promise.delay(1, [].slice.call(arguments));\n        }).spread(function() {\n            assert.deepEqual([1,2,3], [].slice.call(arguments));\n            assert.equal(this, THIS);\n            return Promise.delay(1, [].slice.call(arguments));\n        }).spread(function() {\n            assert.deepEqual([1,2,3], [].slice.call(arguments));\n            assert.equal(this, THIS);\n        });\n    });\n\n    specify(\"works with immediate finally\", function() {\n        return Promise.bind(Promise.delay(1, THIS), [1,2,3]).lastly(function() {\n            assert.equal(this, THIS);\n        }).then(function() {\n            assert.equal(this, THIS);\n        });\n    });\n\n    specify(\"works with delayed finally\", function() {\n        return Promise.bind(Promise.delay(1, THIS), [1,2,3]).lastly(function() {\n            assert.equal(this, THIS);\n            return Promise.delay(1);\n        }).then(function() {\n            assert.equal(this, THIS);\n        });\n    });\n\n    specify(\"works with immediate tap\", function() {\n        return Promise.bind(Promise.delay(1, THIS), [1,2,3]).tap(function() {\n            assert.equal(this, THIS);\n        }).then(function() {\n            assert.equal(this, THIS);\n        });\n    });\n\n    specify(\"works with delayed tap\", function() {\n        return Promise.bind(Promise.delay(1, THIS), [1,2,3]).tap(function() {\n            assert.equal(this, THIS);\n            return Promise.delay(1);\n        }).then(function() {\n            assert.equal(this, THIS);\n        });\n    });\n});\n\n\n"
  },
  {
    "path": "test/mocha/bluebird-multiple-instances.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar isNodeJS = testUtils.isNodeJS;\nvar OldPromise = require(\"./helpers/bluebird0_7_0.js\");\n\nif (isNodeJS) {\n    var Promise1 = testUtils.addDeferred(require(\"../../js/debug/promise.js\")());\n    var Promise2 = testUtils.addDeferred(require(\"../../js/debug/promise.js\")());\n\n    var err1 = new Error();\n    var err2 = new Error();\n\n    describe(\"Separate instances of bluebird\", function() {\n\n        specify(\"Should have identical Error types\", function() {\n            assert(Promise1.CancellationError === Promise2.CancellationError);\n            assert(Promise1.RejectionError === Promise2.RejectionError);\n            assert(Promise1.TimeoutError === Promise2.TimeoutError);\n        });\n\n        specify(\"Should not be identical\", function() {\n            assert(Promise1.onPossiblyUnhandledRejection !==\n                    Promise2.onPossiblyUnhandledRejection);\n            assert(Promise1 !== Promise2);\n        });\n\n        specify(\"Should have different unhandled rejection handlers\", function() {\n            var spy1 = testUtils.getSpy();\n            var spy2 = testUtils.getSpy();\n\n            Promise1.onPossiblyUnhandledRejection(spy1(function(e, promise) {\n                assert(promise instanceof Promise1);\n                assert(!(promise instanceof Promise2));\n                assert(e === err1);\n            }));\n\n            Promise2.onPossiblyUnhandledRejection(spy2(function(e, promise) {\n                assert(promise instanceof Promise2);\n                assert(!(promise instanceof Promise1));\n                assert(e === err2);\n            }));\n            assert(Promise1.onPossiblyUnhandledRejection !==\n                    Promise2.onPossiblyUnhandledRejection);\n\n            var d1 = Promise1.defer();\n            var d2 = Promise2.defer();\n\n            d1.promise.then(function(){\n                throw err1;\n            });\n\n            d2.promise.then(function(){\n                throw err2;\n            });\n\n            setTimeout(function(){\n                d1.fulfill();\n                d2.fulfill();\n                setTimeout(function() {\n                    Promise1._unhandledRejectionCheck();\n                    Promise2._unhandledRejectionCheck();\n                }, 100);\n            }, 1);\n            return Promise.all([spy1.promise, spy2.promise]);\n        });\n\n        specify(\"Should use fast cast\", function() {\n            var a = Promise1.defer();\n            var b = Promise2.cast(a.promise);\n            assert(a.promise._receiver0 === b);\n        });\n\n        specify(\"Should use fast cast with very old version\", function() {\n            var a = OldPromise.pending();\n            var b = Promise1.cast(a.promise);\n            assert(a.promise._receiver0 === b);\n        });\n\n        specify(\"Should return 2 from very old promise\", function() {\n            return Promise1.resolve().then(\n                function(){ return OldPromise.cast(0).then(function(){return 2});\n            }).then(function(two){\n                assert.equal(two, 2);\n            });\n        });\n\n        specify(\"Should reject primitive from fast cast\", function() {\n            var a = OldPromise.pending();\n            var b = Promise.resolve(a.promise);\n            a.reject(1);\n            return b.then(assert.fail, function(e) {\n                assert.strictEqual(e, 1);\n            });\n        });\n        specify(\"Should reject object from fast cast\", function() {\n            var err = new Error();\n            var a = OldPromise.pending();\n            var b = Promise.resolve(a.promise);\n            a.reject(err);\n            return b.then(assert.fail, function(e) {\n                assert.strictEqual(e, err);\n            });\n        });\n    });\n\n}\n"
  },
  {
    "path": "test/mocha/call.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\nvar c = {\n    val: 3,\n    method: function() {\n        return [].slice.call(arguments).concat(this.val);\n    }\n};\n\ndescribe(\"call\", function() {\n    specify(\"0 args\", function() {\n        return Promise.resolve(c).call(\"method\").then(function(res) {\n            assert.deepEqual([3], res);\n        });\n    });\n    specify(\"1 args\", function() {\n        return Promise.resolve(c).call(\"method\", 1).then(function(res) {\n            assert.deepEqual([1, 3], res);\n        });\n    });\n    specify(\"2 args\", function() {\n        return Promise.resolve(c).call(\"method\", 1, 2).then(function(res) {\n            assert.deepEqual([1, 2, 3], res);\n        });\n    });\n    specify(\"3 args\", function() {\n        return Promise.resolve(c).call(\"method\", 1, 2, 3).then(function(res) {\n            assert.deepEqual([1, 2, 3, 3], res);\n        });\n    });\n    specify(\"10 args\", function() {\n        return Promise.resolve(c).call(\"method\", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10).then(function(res) {\n            assert.deepEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3], res);\n        });\n    });\n    specify(\"method not found\", function() {\n        var promises = [\n          Promise.resolve([]).call(\"abc\").then(assert.fail, testUtils.noop),\n          Promise.resolve([]).call(\"abc\", 1, 2, 3, 4, 5, 6, 7).then(assert.fail, testUtils.noop),\n          Promise.resolve([]).call(\"abc \").then(assert.fail, testUtils.noop),\n          Promise.resolve(null).call(\"abc\", 1, 2, 3, 4, 5, 6, 7).then(assert.fail, testUtils.noop),\n          Promise.resolve(null).call(\"abc\").then(assert.fail, testUtils.noop),\n          Promise.resolve(null).call(\"abc \").then(assert.fail, testUtils.noop)\n        ];\n\n        return Promise.all(promises).then(function(errors) {\n            for (var i = 0; i < errors.length; ++i) {\n                var message = errors[i].message || errors[i].toString();\n                assert(message.indexOf(\"has no method\") >= 0);\n            }\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/cancel.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar awaitLateQueue = testUtils.awaitLateQueue;\n\ndescribe(\"Cancellation\", function() {\n    specify(\"requires a function\", function() {\n        return new Promise(function(_, __, onCancel) {\n            onCancel();\n        }).then(assert.fail, function(e) {\n            assert(e instanceof Promise.TypeError);\n        });\n    });\n\n    specify(\"can register multiple on same promise\", function() {\n        var cancelled = 0;\n        var p = new Promise(function(_, __, onCancel) {\n            onCancel(function() {cancelled++});\n            onCancel(function() {cancelled++});\n            onCancel(function() {cancelled++});\n            onCancel(function() {cancelled++});\n        });\n\n        p.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(4, cancelled);\n        });\n    });\n\n    specify(\"follower promises' handlers are not called, registered before\", function() {\n        var cancelled = 0;\n        var p = new Promise(function(_, __, onCancel) {\n            onCancel(function() {cancelled++});\n        });\n\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p);\n            onCancel(function() {cancelled++});\n        });\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p);\n            onCancel(function() {cancelled++});\n        });\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p);\n            onCancel(function() {cancelled++});\n        });\n        p.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(1, cancelled);\n        });\n    });\n\n    specify(\"follower promises' handlers are not called, registered after\", function() {\n        var cancelled = 0;\n        var p = new Promise(function(_, __, onCancel) {\n            onCancel(function() {cancelled++});\n        });\n\n        p.cancel();\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p);\n            onCancel(function() {cancelled++});\n        }).suppressUnhandledRejections();\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p);\n            onCancel(function() {cancelled++});\n        }).suppressUnhandledRejections();\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p);\n            onCancel(function() {cancelled++});\n        }).suppressUnhandledRejections();\n        return awaitLateQueue(function() {\n            assert.equal(1, cancelled);\n        });\n    });\n\n    specify(\"downstream follower promises' handlers are not called, registered before\", function() {\n        var cancelled = 0;\n        var p = new Promise(function(_, __, onCancel) {\n            onCancel(function() {cancelled++});\n        });\n\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p.then());\n            onCancel(function() {cancelled++});\n        });\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p.then());\n            onCancel(function() {cancelled++});\n        });\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p.then());\n            onCancel(function() {cancelled++});\n        });\n\n        p.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(1, cancelled);\n        });\n    });\n\n    specify(\"downstream follower promises' handlers are called, registered after\", function() {\n        var cancelled = 0;\n        var p = new Promise(function(_, __, onCancel) {\n            onCancel(function() {cancelled++});\n        });\n\n        p.cancel();\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p.then());\n            onCancel(function() {cancelled++});\n        }).suppressUnhandledRejections();\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p.then());\n            onCancel(function() {cancelled++});\n        }).suppressUnhandledRejections();\n        new Promise(function(resolve, _, onCancel) {\n            resolve(p.then());\n            onCancel(function() {cancelled++});\n        }).suppressUnhandledRejections();\n        return awaitLateQueue(function() {\n            assert.equal(1, cancelled);\n        });\n    });\n\n    specify(\"immediately rejected promise immediately cancelled with then in-between\", function() {\n        var error = new Error();\n        var resolve;\n        var result = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n        var p = Promise.reject(error).then().lastly(resolve);\n        p.cancel();\n        p.caught(function() {});\n        return result;\n    });\n\n    specify(\"callback is called asynchronously but fate is sealed synchronously\", function() {\n        var called = false;\n        var promiseResolve;\n        var promise = new Promise(function(resolve, reject, onCancel) {\n            promiseResolve = resolve;\n            onCancel(function() {\n                called = true;\n            });\n        });\n        return awaitLateQueue(function() {\n            promise.cancel();\n            promiseResolve();\n            return Promise.resolve().then(function() {\n                assert(called);\n                assert(!promise.isFulfilled());\n            });\n        });\n    });\n\n    if (testUtils.isNodeJS) {\n        specify(\"throws in process if callback throws\", function() {\n            var e = new Error();\n            var promise = new Promise(function(resolve, reject, onCancel) {\n                onCancel(function onCancel() {\n                    throw e;\n                });\n            });\n            promise.cancel();\n            return testUtils.awaitGlobalException(function(err) {\n                assert.equal(e, err);\n            });\n        });\n    }\n\n    specify(\"cancels the promise chain\", function() {\n        var called = false;\n        var thens = 0;\n        var resolveChain;\n        var root = new Promise(function(resolve, reject, onCancel) {\n            resolveChain = resolve;\n            onCancel(function() {\n                called = true;\n            });\n        }).then(function() {\n            thens++;\n        }).then(function() {\n            thens++;\n        }).then(function() {\n            thens++;\n        });\n\n        root.cancel();\n        resolveChain();\n        return awaitLateQueue(function() {\n            assert.equal(0, thens);\n            assert(called);\n        });\n    });\n\n    specify(\"calls finally handlers\", function() {\n        var called = false;\n        var thens = 0;\n        var resolveChain;\n        var root = new Promise(function(resolve, reject, onCancel) {\n            resolveChain = resolve;\n            onCancel(function() {\n                called = true;\n            });\n        });\n        var chain = root.lastly(function() {\n            thens++;\n        }).lastly(function() {\n            thens++;\n        }).lastly(function() {\n            thens++;\n        });\n\n        chain.cancel();\n        resolveChain();\n        return awaitLateQueue(function() {\n            assert.equal(3, thens);\n            assert(called);\n        });\n    });\n\n    specify(\"cancels the followee\", function() {\n        var called = false;\n        var finalled = false;\n        var promise = new Promise(function(_, __, onCancel) {\n            onCancel(function() {\n                called = true;\n            });\n        });\n        var promise2 = new Promise(function(resolve, reject, onCancel) {\n            resolve(promise);\n        });\n        var promise3 = new Promise(function(resolve, reject, onCancel) {\n            resolve(promise2);\n        }).lastly(function() {\n            finalled = true;\n        });\n\n        promise3.cancel();\n        return awaitLateQueue(function() {\n            assert(called);\n            assert(finalled);\n        });\n    });\n\n    specify(\"cancels the followee, calling all callbacks and finally handlers\", function() {\n        var called = 0;\n        var finalled = 0;\n\n        var promise = new Promise(function(_, __, onCancel) {\n            onCancel(function() {\n                called++;\n            });\n        }).lastly(function() {\n            finalled++;\n        });\n\n        var promise2 = new Promise(function(resolve, reject, onCancel) {\n            resolve(promise);\n            onCancel(function() {\n                called++;\n            });\n        }).lastly(function() {\n            finalled++;\n        });\n\n        var promise3 = new Promise(function(resolve, reject, onCancel) {\n            resolve(promise2);\n            onCancel(function() {\n                called++;\n            });\n        }).lastly(function() {\n            finalled++;\n        });\n\n        promise3.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(3, called);\n            assert.equal(3, finalled);\n        });\n    });\n\n    specify(\"cancels the followee, calling all onCancel callbacks\", function() {\n        var called = 0;\n\n        var promise = new Promise(function(_, __, onCancel) {\n            onCancel(function() {\n                called++;\n            });\n        })\n\n        var promise2 = new Promise(function(resolve, reject, onCancel) {\n            resolve(promise);\n            onCancel(function() {\n                called++;\n            });\n        });\n\n        var promise3 = new Promise(function(resolve, reject, onCancel) {\n            resolve(promise2);\n            onCancel(function() {\n                called++;\n            });\n        });\n\n        promise3.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(3, called);\n        });\n    });\n\n    specify(\"can be used for breaking chains early\", function() {\n        var called = false;\n        var p = Promise.resolve(1)\n            .then(function(data) {\n                p[\"break\"]();\n            })\n            .then(function() {\n                called = true;\n            });\n        return awaitLateQueue(function() {\n            assert(!called);\n        });\n    });\n\n    specify(\"multiple cancel calls have no effect\", function() {\n        var called = 0;\n        var finalled = 0;\n        var req1 = new Promise(function(resolve, _, onCancel) {\n            resolve();\n            onCancel(function() {\n                called++;\n            });\n        });\n\n        var ret = req1.then(function() {\n            return new Promise(function(_, __, onCancel) {\n                onCancel(function() {\n                    called++;\n                });\n            });\n        }).then(function() {\n            return new Promise(function(_, __, onCancel) {\n                onCancel(function() {\n                    called++;\n                });\n            });\n        }).lastly(function() {\n            finalled++;\n        });\n\n        req1.then(function() {\n            ret.cancel();\n            ret.cancel();\n            ret.cancel();\n        });\n\n        return awaitLateQueue(function() {\n            assert.equal(1, called);\n            assert.equal(1, finalled);\n        });\n    });\n\n    specify(\"throwing in finally turns into a rejection\", function() {\n        var e = new Error(\"\");\n        var promise = new Promise(function(_, __, onCancel) {})\n            .lastly(function() {\n                throw e;\n            })\n            .caught(function(err) {\n                assert.equal(err, e);\n            });\n        promise.cancel();\n        return promise;\n    });\n\n    specify(\"returning an immediately rejected promise in finally turns into a rejection\", function() {\n        var e = new Error(\"\");\n        var promise = new Promise(function(_, __, onCancel) {})\n            .lastly(function() {\n                return Promise.reject(e);\n            })\n            .caught(function(err) {\n                assert.equal(err, e);\n            });\n        promise.cancel();\n        return promise;\n    });\n    specify(\"returning an eventually rejected promise in finally turns into a rejection\", function() {\n        var e = new Error(\"\");\n        var promise = new Promise(function(_, __, onCancel) {})\n            .lastly(function() {\n                return new Promise(function(resolve, reject, onCancel) {\n                    Promise.delay(1).then(function() {\n                        reject(e);\n                    });\n                });\n            })\n            .caught(function(err) {\n                assert.equal(err, e);\n            });\n        promise.cancel();\n        return promise;\n    });\n\n    specify(\"finally handler returned promises are awaited for\", function() {\n        var awaited = 0;\n        var resolve;\n        var result = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n        var promise = new Promise(function(_, __, onCancel) {})\n            .lastly(function() {\n                return Promise.delay(1).then(function() {\n                    awaited++;\n                });\n            })\n            .lastly(function() {\n                return Promise.delay(1).then(function() {\n                    awaited++;\n                });\n            })\n            .lastly(function() {\n                return Promise.delay(1).then(function() {\n                    awaited++;\n                });\n            })\n            .lastly(function() {\n                resolve();\n            })\n        promise.cancel();\n        return result.then(function() {\n            assert.equal(3, awaited);\n        });\n    });\n\n    specify(\"finally handler returned promises are skipped if they are cancelled\", function() {\n        var cancelled = 0;\n        var resolve;\n        var result = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n        var promise = new Promise(function(_, __, onCancel) {})\n            .lastly(function() {\n                var ret = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                ret.cancel();\n                return ret;\n            })\n            .lastly(function() {\n                var ret = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                ret.cancel();\n                return ret;\n            })\n            .lastly(function() {\n                var ret = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                ret.cancel();\n                return ret;\n            })\n            .lastly(function() {\n                resolve();\n            })\n        promise.suppressUnhandledRejections();\n        promise.cancel();\n        return result.then(function() {\n            assert.equal(3, cancelled);\n        });\n    });\n\n    specify(\"finally handler returned promises are skipped if they are eventually cancelled\", function() {\n        var cancelled = 0;\n        var resolve;\n        var result = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n        var promise = new Promise(function(_, __, onCancel) {})\n            .lastly(function() {\n                var ret = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                Promise.delay(1).then(function() {\n                    ret.cancel();\n                });\n                return ret;\n            })\n            .lastly(function() {\n                var ret = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                Promise.delay(1).then(function() {\n                    ret.cancel();\n                });\n                return ret;\n            })\n            .lastly(function() {\n                var ret = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                Promise.delay(1).then(function() {\n                    ret.cancel();\n                });\n                return ret;\n            })\n            .lastly(function() {\n                resolve();\n            })\n        promise.cancel();\n        return result.then(function() {\n            assert.equal(3, cancelled);\n        });\n    });\n\n    specify(\"finally handler returned promises are skipped if theiy are eventually cancelled while following\", function() {\n        var cancelled = 0;\n        var resolve;\n        var result = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n        var promise = new Promise(function(_, __, onCancel) {})\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                Promise.delay(1).then(function() {\n                    ret.cancel();\n                });\n                return ret;\n            })\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                Promise.delay(1).then(function() {\n                    ret.cancel();\n                });\n                return ret;\n            })\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                Promise.delay(1).then(function() {\n                    ret.cancel();\n                });\n                return ret;\n            })\n            .lastly(function() {\n                resolve();\n            })\n        promise.cancel();\n        return result.then(function() {\n            assert.equal(6, cancelled);\n        });\n    });\n\n    specify(\"finally handler returned promises are skipped if theiy are immediately cancelled while following\", function() {\n        var cancelled = 0;\n        var resolve;\n        var result = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n        var promise = new Promise(function(_, __, onCancel) {})\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                ret.cancel();\n                return ret;\n            })\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                ret.cancel();\n                return ret;\n            })\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                ret.cancel();\n                return ret;\n            })\n            .lastly(function() {\n                resolve();\n            });\n        promise.suppressUnhandledRejections();\n        promise.cancel();\n        return result.then(function() {\n            assert.equal(6, cancelled);\n        });\n    });\n\n    specify(\"finally handler returned promises target are skipped if their follower is eventually cancelled\", function() {\n        var cancelled = 0;\n        var resolve;\n        var result = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n        var promise = new Promise(function(_, __, onCancel) {})\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                Promise.delay(1).then(function() {\n                    ret.cancel();\n                });\n                return p;\n            })\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                Promise.delay(1).then(function() {\n                    ret.cancel();\n                });\n                return p;\n            })\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                Promise.delay(1).then(function() {\n                    ret.cancel();\n                });\n                return p;\n            })\n            .lastly(function() {\n                resolve();\n            })\n        promise.cancel();\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(6, cancelled);\n            });\n        });\n    });\n\n    specify(\"finally handler returned promises target are skipped if their follower is immediately cancelled\", function() {\n        var cancelled = 0;\n        var resolve;\n        var result = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n        var promise = new Promise(function(_, __, onCancel) {})\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                ret.cancel();\n                return p;\n            })\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                ret.cancel();\n                return p;\n            })\n            .lastly(function() {\n                var p = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); });\n                var ret = new Promise(function(resolve, _, onCancel) {\n                    resolve(p);\n                    onCancel(function() {\n                        cancelled++;\n                    });\n                });\n                ret.cancel();\n                return p;\n            })\n            .lastly(function() {\n                resolve();\n            })\n        promise.cancel();\n        promise.suppressUnhandledRejections();\n        return result.then(function() {\n            assert.equal(6, cancelled);\n        });\n    });\n\n    specify(\"attaching handler on already cancelled promise\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n        return awaitLateQueue(function() {\n            p.lastly(resolve);\n            return result;\n        });\n    });\n\n    specify(\"if onCancel callback causes synchronous rejection, it is ignored and cancellation wins\", function() {\n        var promisifiedXhr = function() {\n            var xhrReject;\n            var xhr = {\n                then: function(resolve, reject) {\n                    xhrReject = reject;\n                },\n                abort: function() {\n                    xhrReject(new Error(\"\"));\n                }\n            };\n            return new Promise(function(resolve, _, onCancel) {\n                resolve(xhr);\n                onCancel(function() {\n                    xhr.abort();\n                });\n            });\n        };\n\n        var req = promisifiedXhr().lastly(function() {\n            resolve();\n        });\n        req.cancel();\n        var resolve;\n        return new Promise(function(_, __, onCancel) {resolve = arguments[0]});\n    });\n\n    specify(\"isCancelled() synchronously returns true after calling cancel() on pending promise\", function() {\n        var promise = new Promise(function () {});\n        promise.cancel();\n        assert(promise.isCancelled());\n    });\n\n    specify(\"isCancelled() synchronously returns true after calling cancel() on promise created from .then()\", function() {\n        var promise = new Promise(function () {});\n        var thenPromise = promise.then();\n        thenPromise.cancel();\n        assert(thenPromise.isCancelled());\n    });\n\n    specify(\"gh-166\", function() {\n        var f1 = false, f2 = false, f3 = false, f4 = false;\n        var a = Promise.resolve();\n        a = a.then(function() {\n            f1 = true;\n            return Promise.delay(1);\n        });\n\n        a = a.then(function() {\n            f2 = true;\n            return Promise.delay(1);\n        });\n\n        a = a.then(function() {\n            f3 = true;\n            return Promise.delay(1);\n        }).then(function() {\n            assert(a.isCancellable());\n            a.cancel();\n        }).delay(100);\n\n\n        a = a.then(function() {\n            f4 = true;\n        });\n\n        var waitingForLongDelay = a;\n\n        a = a.lastly(function() {\n            assert(f1); assert(f2); assert(f3);\n            assert(!f4);\n            assert(waitingForLongDelay.isCancelled());\n            resolve();\n        });\n\n        assert(a.isCancellable());\n        var resolve;\n        var p = new Promise(function(_, __, onCancel) {resolve = arguments[0]});\n        return p;\n    });\n\n    specify(\"gh-1187\", function() {\n        var a = Promise.delay(300).lastly(function() {});\n        a.cancel();\n        assert(a.isCancelled());\n        assert(!a.isCancellable());\n    })\n});\n\ndescribe(\"Cancellation with .all\", function() {\n    specify(\"immediately cancelled input\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n        Promise.all(p).lastly(resolve);\n        return result;\n    });\n\n    specify(\"eventually cancelled input\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        Promise.all(p).lastly(resolve);\n        return awaitLateQueue(function() {\n            p.cancel();\n            return result;\n        });\n    });\n\n    specify(\"immediately cancelled input inside array\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n        Promise.all([1,2,p]).lastly(resolve);\n        return result;\n    });\n\n    specify(\"eventually cancelled input inside array\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        Promise.all([1,2,p]).lastly(resolve);\n        return awaitLateQueue(function() {\n            p.cancel();\n            return result;\n        });\n    });\n\n    specify(\"immediately cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n\n        var all = Promise.all(inputs)\n            .lastly(function() {finalled++; resolve(); });\n\n        all.cancel();\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n\n        var all = Promise.all(inputs)\n            .lastly(function() {finalled++; resolve(); });\n\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        Promise.delay(1).then(function() {\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n            });\n        });\n    });\n\n    specify(\"immediately cancelled output while waiting on promise-for-input\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var input = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); }).lastly(function() {\n            finalled++;\n        });\n\n        var all = Promise.all(input)\n            .lastly(function() {finalled++; resolve(); });\n\n        all.cancel();\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 1);\n                assert.equal(finalled, 2);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output while waiting on promise-for-input\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var input = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); }).lastly(function() {\n            finalled++;\n        });\n\n        var all = Promise.all(input).lastly(function() {finalled++; resolve(); });\n\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        Promise.delay(1).then(function() {\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 1);\n                assert.equal(finalled, 2);\n            });\n        });\n    });\n});\n\ndescribe(\"Cancellation with .props\", function() {\n    specify(\"immediately cancelled input\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n        Promise.props(p).lastly(resolve).suppressUnhandledRejections();\n        return result;\n    });\n\n    specify(\"eventually cancelled input\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        Promise.props(p).lastly(resolve);\n        return awaitLateQueue(function() {\n            p.cancel();\n            return result;\n        });\n    });\n\n    specify(\"immediately cancelled input inside array\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n        Promise.props([1,2,p]).lastly(resolve);\n        return result;\n    });\n\n    specify(\"eventually cancelled input inside array\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        Promise.props([1,2,p]).lastly(resolve);\n        return awaitLateQueue(function() {\n            p.cancel();\n            return result;\n        });\n    });\n\n    specify(\"immediately cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n\n        var all = Promise.props(inputs).lastly(function() {finalled++; resolve(); });\n\n        all.cancel();\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n\n        var all = Promise.props(inputs).lastly(function() {finalled++; resolve(); });\n\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        Promise.delay(1).then(function() {\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n            });\n        });\n    });\n\n    specify(\"immediately cancelled output while waiting on promise-for-input\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var input = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); }).lastly(function() {\n            finalled++;\n        });\n\n        var all = Promise.props(input).lastly(function() {finalled++; resolve(); });\n\n        all.cancel();\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 1);\n                assert.equal(finalled, 2);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output while waiting on promise-for-input\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var input = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); }).lastly(function() {\n            finalled++;\n        });\n\n        var all = Promise.props(input)\n            .lastly(function() {finalled++; resolve(); });\n\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        Promise.delay(1).then(function() {\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 1);\n                assert.equal(finalled, 2);\n            });\n        });\n    });\n});\n\ndescribe(\"Cancellation with .some\", function() {\n    specify(\"immediately cancelled input\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n        Promise.some(p, 1).lastly(resolve);\n        return result;\n    });\n\n    specify(\"eventually cancelled input\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        Promise.some(p, 1).lastly(resolve);\n        return awaitLateQueue(function() {\n            p.cancel();\n            return result;\n        });\n    });\n\n    specify(\"immediately cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n\n        var all = Promise.some(inputs, 1)\n            .lastly(function() {finalled++; resolve(); });\n\n        all.cancel();\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n\n        var all = Promise.some(inputs, 1)\n            .lastly(function() {finalled++; resolve(); });\n\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        Promise.delay(1).then(function() {\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n            });\n        });\n    });\n\n\n    specify(\"immediately cancelled output while waiting on promise-for-input\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var input = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); }).lastly(function() {\n            finalled++;\n        });\n\n        var all = Promise.some(input, 1)\n            .lastly(function() {finalled++; resolve(); });\n\n        all.cancel();\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 1);\n                assert.equal(finalled, 2);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output while waiting on promise-for-input\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var input = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); }).lastly(function() {\n            finalled++;\n        });\n\n        var all = Promise.some(input, 1)\n            .lastly(function() {finalled++; resolve(); });\n\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        Promise.delay(1).then(function() {\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 1);\n                assert.equal(finalled, 2);\n            });\n        });\n    });\n\n    specify(\"some promises are cancelled immediately\", function() {\n        var resolve;\n        var p1 = new Promise(function(_, __, onCancel) {});\n        var p2 = new Promise(function(_, __, onCancel) {});\n        var p3 = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n\n        p1.cancel();\n        p2.cancel();\n        resolve(1);\n        return Promise.some([p1, p2, p3], 1).then(function(result) {\n            assert.deepEqual([1], result);\n        });\n    });\n\n    specify(\"some promises are cancelled eventually\", function() {\n        var resolve;\n        var p1 = new Promise(function(_, __, onCancel) {});\n        var p2 = new Promise(function(_, __, onCancel) {});\n        var p3 = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n\n        Promise.delay(1).then(function() {\n            p1.cancel();\n            p2.cancel();\n            return Promise.delay(1).then(function() {\n                resolve(1);\n            });\n        });\n        return Promise.some([p1, p2, p3], 1).then(function(result) {\n            assert.deepEqual([1], result);\n        });\n    });\n\n    specify(\"promise for some promises that are cancelled immediately\", function() {\n        var resolve;\n        var p1 = new Promise(function(_, __, onCancel) {});\n        var p2 = new Promise(function(_, __, onCancel) {});\n        var p3 = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n\n        p1.cancel();\n        p2.cancel();\n        resolve(1);\n        var promise = Promise.delay(1, [p1, p2, p3]);\n        return Promise.some(promise, 1).then(function(result) {\n            assert.deepEqual([1], result);\n        });\n    });\n\n    specify(\"promise for some promises that are cancelled eventually\", function() {\n        var resolve;\n        var p1 = new Promise(function(_, __, onCancel) {});\n        var p2 = new Promise(function(_, __, onCancel) {});\n        var p3 = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n\n        Promise.delay(1).then(function() {\n            p1.cancel();\n            p2.cancel();\n            return Promise.delay(1).then(function() {\n                resolve(1);\n            });\n        });\n        var promise = Promise.delay(1, [p1, p2, p3]);\n        return Promise.some(promise, 1).then(function(result) {\n            assert.deepEqual([1], result);\n        });\n    });\n\n\n    specify(\"all promises cancel, not enough for fulfillment - immediately\", function() {\n        var resolve;\n        var p1 = new Promise(function(_, __, onCancel) {});\n        var p2 = new Promise(function(_, __, onCancel) {});\n        var p3 = new Promise(function(_, __, onCancel) {});\n        var result = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n\n        p1.cancel();\n        p2.cancel();\n        p3.cancel();\n        Promise.some([p1, p2, p3], 1).then(assert.fail, function(e) {\n            assert(e instanceof Promise.CancellationError);\n            resolve();\n        });\n        return result;\n    });\n\n    specify(\"all promises cancel, not enough for fulfillment - eventually\", function() {\n        var resolve;\n        var p1 = new Promise(function(_, __, onCancel) {});\n        var p2 = new Promise(function(_, __, onCancel) {});\n        var p3 = new Promise(function(_, __, onCancel) {});\n        var result = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n\n        Promise.delay(1).then(function() {\n            p1.cancel();\n            p2.cancel();\n            return Promise.delay(1).then(function() {\n                p3.cancel();\n            });\n        });\n        Promise.some([p1, p2, p3], 1).then(assert.fail, assert.fail).lastly(resolve);\n        return result;\n    });\n\n    specify(\"some promises cancel, some reject, not enough for fulfillment - immediately\", function() {\n        var error = new Error();\n        var reject;\n        var p1 = new Promise(function(_, __, onCancel) {});\n        var p2 = new Promise(function(_, __, onCancel) {});\n        var p3 = new Promise(function(_, __, onCancel) {reject = arguments[1];});\n\n        p1.cancel();\n        p2.cancel();\n        reject(error);\n        return Promise.some([p1, p2, p3], 1).then(assert.fail, function(result) {\n            assert(result instanceof Promise.AggregateError);\n            assert.equal(1, result.length);\n            assert.equal(error, result[0]);\n        });\n    });\n\n    specify(\"some promises cancel, some reject, not enough for fulfillment - eventually\", function() {\n        var error = new Error();\n        var reject;\n        var p1 = new Promise(function(_, __, onCancel) {});\n        var p2 = new Promise(function(_, __, onCancel) {});\n        var p3 = new Promise(function(_, __, onCancel) {reject = arguments[1];});\n\n        Promise.delay(1).then(function() {\n            p1.cancel();\n            p2.cancel();\n            return Promise.delay(1).then(function() {\n                reject(error);\n            });\n        });\n        return Promise.some([p1, p2, p3], 1).then(assert.fail, function(result) {\n            assert(result instanceof Promise.AggregateError);\n            assert.equal(1, result.length);\n            assert.equal(error, result[0]);\n        });\n    });\n});\n\ndescribe(\"Cancellation with .reduce\", function() {\n    specify(\"initialValue immediately cancelled immediate input\", function() {\n        var initialValue = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        initialValue.cancel();\n        Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            assert.equal(2, finalled);\n            assert.equal(1, cancelled);\n        });\n    });\n\n    specify(\"initialValue eventually cancelled immediate input\", function() {\n        var initialValue = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            initialValue.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(2, finalled);\n                    assert.equal(1, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"initialValue eventually cancelled eventual input\", function() {\n        var initialValue = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = new Promise(function(_, __, onCancel) {});\n        Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            initialValue.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(2, finalled);\n                    assert.equal(1, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"initialValue immediately cancelled eventual input\", function() {\n        var initialValue = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = new Promise(function(_, __, onCancel) {});\n        initialValue.cancel();\n        Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            assert.equal(2, finalled);\n            assert.equal(1, cancelled);\n        });\n    });\n\n    specify(\"returned promise cancels immediately\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [1, 2,\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        Promise.reduce(inputs, function(a, b) {\n            finalled++;\n            var ret = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++});\n            ret.cancel();\n            return ret;\n        }).lastly(function() {\n            finalled++;\n        });\n\n        return awaitLateQueue(function() {\n            assert.equal(3, finalled);\n            assert.equal(1, cancelled);\n        });\n    });\n\n    specify(\"returned promise cancels eventually\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [1, 2,\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        Promise.reduce(inputs, function(a, b) {\n            finalled++;\n            var ret = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++});\n            awaitLateQueue(function() {\n                ret.cancel();\n            });\n            return ret;\n        }).lastly(function() {\n            finalled++;\n        });\n\n        return awaitLateQueue(function() {\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(3, finalled);\n                    assert.equal(1, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"input immediately cancelled while waiting initialValue\", function() {\n        var initialValue = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = new Promise(function(_, __, onCancel) {});\n        inputs.cancel();\n        Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            assert.equal(1, finalled);\n            assert.equal(0, cancelled);\n        });\n    });\n\n    specify(\"input eventually cancelled while waiting initialValue\", function() {\n        var initialValue = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = new Promise(function(_, __, onCancel) {});\n        Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            inputs.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(1, finalled);\n                    assert.equal(0, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"output immediately cancelled while waiting inputs\", function() {\n        var initialValue = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n            .lastly(function() {finalled++});\n\n        var all = Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        all.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(3, finalled);\n            assert.equal(2, cancelled);\n        });\n    });\n\n    specify(\"output immediately cancelled while waiting initialValue\", function() {\n        var initialValue = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        var all = Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        all.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(5, finalled);\n            assert.equal(4, cancelled);\n        });\n    });\n\n    specify(\"output immediately cancelled while waiting firstValue\", function() {\n        var initialValue = 1;\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        var all = Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        all.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(4, finalled);\n            assert.equal(3, cancelled);\n        });\n    });\n\n    specify(\"output immediately cancelled while waiting firstValue and secondValue\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        var all = Promise.reduce(inputs, function(){\n            finalled++;\n        }).lastly(function() {\n            finalled++;\n        });\n        all.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(4, finalled);\n            assert.equal(3, cancelled);\n        });\n    });\n\n    specify(\"output immediately cancelled while waiting for a result\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [1, 2,\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        var all = Promise.reduce(inputs, function(a, b) {\n            finalled++;\n            return new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++});\n        }).lastly(function() {\n            finalled++;\n        });\n        all.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(4, finalled);\n            assert.equal(2, cancelled);\n        });\n    });\n\n    specify(\"output eventually cancelled while waiting inputs\", function() {\n        var initialValue = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n            .lastly(function() {finalled++});\n\n        var all = Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            all.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(3, finalled);\n                    assert.equal(2, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"output eventually cancelled while waiting initialValue\", function() {\n        var initialValue = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        var all = Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            all.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(5, finalled);\n                    assert.equal(4, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"output eventually cancelled while waiting firstValue\", function() {\n        var initialValue = 1;\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        var all = Promise.reduce(inputs, function(){\n            finalled++;\n        }, initialValue).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            all.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(4, finalled);\n                    assert.equal(3, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"output eventually cancelled while waiting firstValue and secondValue\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        var all = Promise.reduce(inputs, function(){\n            finalled++;\n        }).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            all.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(4, finalled);\n                    assert.equal(3, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"output eventually cancelled while waiting for a result\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [1, 2,\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n        var all = Promise.reduce(inputs, function(a, b) {\n            finalled++;\n            return new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++});\n        }).lastly(function() {\n            finalled++;\n        });\n\n        return awaitLateQueue(function() {\n            all.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(4, finalled);\n                    assert.equal(2, cancelled);\n                });\n            });\n        });\n    });\n});\n\ndescribe(\"Cancellation with .map\", function() {\n    specify(\"immediately cancelled input\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n        Promise.map(p, function(){}).lastly(resolve);\n        return result;\n    });\n\n    specify(\"eventually cancelled input\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        Promise.map(p, function(){}).lastly(resolve);\n        return awaitLateQueue(function() {\n            p.cancel();\n            return result;\n        });\n    });\n\n    specify(\"immediately cancelled input inside array\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n        Promise.map([1,2,p], function(){}).lastly(resolve);\n        return result;\n    });\n\n    specify(\"eventually cancelled input inside array\", function() {\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        var p = new Promise(function(_, __, onCancel) {});\n        Promise.map([1,2,p], function(){}).lastly(resolve);\n        return awaitLateQueue(function() {\n            p.cancel();\n            return result;\n        });\n    });\n\n    specify(\"immediately cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n\n        var all = Promise.map(inputs, function(){})\n            .lastly(function() {finalled++; resolve(); });\n\n        all.cancel();\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n\n        var all = Promise.map(inputs, function(){})\n            .lastly(function() {finalled++; resolve(); });\n\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        Promise.delay(1).then(function() {\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n            });\n        });\n    });\n\n    specify(\"immediately cancelled output while waiting on promise-for-input\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var input = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); }).lastly(function() {\n            finalled++;\n        });\n\n        var all = Promise.map(input, function(){})\n            .lastly(function() {finalled++; resolve(); });\n\n        all.cancel();\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 1);\n                assert.equal(finalled, 2);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output while waiting on promise-for-input\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var input = new Promise(function(_, __, onCancel) { onCancel(function(){ cancelled++; }); }).lastly(function() {\n            finalled++;\n        });\n\n        var all = Promise.map(input, function(){})\n            .lastly(function() {finalled++; resolve(); });\n\n        var resolve;\n        var result = new Promise(function() {resolve = arguments[0]});\n        Promise.delay(1).then(function() {\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 1);\n                assert.equal(finalled, 2);\n            });\n        });\n    });\n\n    specify(\"result cancelled immediately while there are in-flight returned promises\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n\n        var all = Promise.map([1, 2, 3], function(value, index) {\n            return new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        }).lastly(function() {\n            finalled++;\n        });\n        all.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(4, finalled);\n            assert.equal(3, cancelled);\n        });\n    });\n\n    specify(\"result cancelled eventually while there are in-flight returned promises\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n\n        var all = Promise.map([1, 2, 3], function(value, index) {\n            return new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        }).lastly(function() {\n            finalled++;\n        });\n\n        return awaitLateQueue(function() {\n            all.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(4, finalled);\n                    assert.equal(3, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"returned promise cancelled immediately while there are in-flight returned promises\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n\n        Promise.map([1, 2, 3], function(value, index) {\n            var ret = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++});\n            if (index === 2) {\n                ret.cancel();\n            }\n            return ret;\n        }).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            assert.equal(2, finalled);\n            assert.equal(1, cancelled);\n        });\n    });\n\n    specify(\"returned promise  cancelled eventually while there are in-flight returned promises\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n\n        Promise.map([1, 2, 3], function(value, index) {\n            var ret = new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++});\n            if (index === 2) {\n                awaitLateQueue(function() {\n                    ret.cancel();\n                });\n            }\n            return ret;\n        }).lastly(function() {\n            finalled++;\n        });\n\n        return awaitLateQueue(function() {\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(2, finalled);\n                    assert.equal(1, cancelled);\n                });\n            });\n        });\n    });\n});\ndescribe(\"Cancellation with .bind\", function() {\n    specify(\"immediately cancelled promise passed as ctx\", function() {\n        var finalled = 0;\n        var cancelled = 0;\n        var ctx = new Promise(function(_, __, onCancel) {});\n        ctx.cancel();\n        Promise.bind(ctx).lastly(function() {\n            finalled++;\n        }).suppressUnhandledRejections();\n        return awaitLateQueue(function() {\n            assert.equal(1, finalled);\n            assert.equal(0, cancelled);\n        });\n    });\n\n    specify(\"eventually cancelled promise passed as ctx\", function() {\n        var finalled = 0;\n        var cancelled = 0;\n        var ctx = new Promise(function(_, __, onCancel) {});\n        Promise.bind(ctx).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            ctx.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(1, finalled);\n                    assert.equal(0, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"main promise is immediately cancelled while waiting on binding\", function() {\n        var finalled = 0;\n        var cancelled = 0;\n        var resolve;\n        var ctx = new Promise(function(_, __, onCancel) {resolve = arguments[0];});\n        var main = new Promise(function(_, __, onCancel) {});\n        main.cancel();\n        main.bind(ctx).lastly(function() {\n            finalled++;\n        }).suppressUnhandledRejections();\n        return awaitLateQueue(function() {\n            resolve();\n            return ctx;\n        }).then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(1, finalled);\n                assert.equal(0, cancelled);\n            });\n        });\n    });\n\n    specify(\"main promise is eventually cancelled while waiting on binding\", function() {\n        var finalled = 0;\n        var cancelled = 0;\n        var ctx = new Promise(function(_, __, onCancel) {});\n        var main = new Promise(function(_, __, onCancel) {});\n\n        main.bind(ctx).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            main.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(1, finalled);\n                    assert.equal(0, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"main promise is immediately cancelled with immediate binding\", function() {\n        var finalled = 0;\n        var cancelled = 0;\n        var ctx = {};\n        var main = new Promise(function(_, __, onCancel) {});\n        main.bind(ctx).lastly(function() {\n            assert.equal(this, ctx);\n            finalled++;\n        });\n        main.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(1, finalled);\n            assert.equal(0, cancelled);\n        });\n    });\n\n    specify(\"main promise is eventually cancelled with immediate binding\", function() {\n        var finalled = 0;\n        var cancelled = 0;\n        var ctx = {};\n        var main = new Promise(function(_, __, onCancel) {});\n        main.bind(ctx).lastly(function() {\n            assert.equal(this, ctx);\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            main.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(1, finalled);\n                    assert.equal(0, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"result is immediately cancelled while waiting for binding\", function() {\n        var finalled = 0;\n        var cancelled = 0;\n        var ctx = new Promise(function(_, __, onCancel) {\n            onCancel(function() {\n                cancelled++;\n            });\n        }).lastly(function() {\n            finalled++;\n        });\n        var result = Promise.bind(ctx).lastly(function() {\n            finalled++;\n        });\n        result.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(2, finalled);\n            assert.equal(1, cancelled);\n        });\n    });\n\n    specify(\"result is eventually cancelled while waiting for binding\", function() {\n        var finalled = 0;\n        var cancelled = 0;\n        var ctx = new Promise(function(_, __, onCancel) {\n            onCancel(function() {\n                cancelled++;\n            });\n        }).lastly(function() {\n            finalled++;\n        });\n\n        var result = Promise.bind(ctx).lastly(function() {\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            result.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(2, finalled);\n                    assert.equal(1, cancelled);\n                });\n            });\n        });\n    });\n\n    specify(\"result is immediately cancelled while waiting for main promise\", function() {\n        var finalled = 0;\n        var cancelled = 0;\n        var ctx = {};\n        var main = new Promise(function(_, __, onCancel) {\n            onCancel(function() {\n                cancelled++;\n            });\n        }).lastly(function() {\n            finalled++;\n        });\n\n        var result = main.bind(ctx).lastly(function() {\n            assert.equal(this, ctx);\n            finalled++;\n        });\n        result.cancel();\n        return awaitLateQueue(function() {\n            assert.equal(2, finalled);\n            assert.equal(1, cancelled);\n        });\n    });\n\n    specify(\"result is eventually cancelled while waiting for main promise\", function() {\n        var finalled = 0;\n        var cancelled = 0;\n        var ctx = {};\n        var main = new Promise(function(_, __, onCancel) {\n            onCancel(function() {\n                cancelled++;\n            });\n        }).lastly(function() {\n            finalled++;\n        });\n\n        var result = main.bind(ctx).lastly(function() {\n            assert.equal(this, ctx);\n            finalled++;\n        });\n        return awaitLateQueue(function() {\n            result.cancel();\n            return Promise.resolve().then(function() {\n                return awaitLateQueue(function() {\n                    assert.equal(2, finalled);\n                    assert.equal(1, cancelled);\n                });\n            });\n        });\n    });\n});\n\ndescribe(\"Cancellation with .join\", function() {\n    specify(\"immediately cancelled input inside array\", function() {\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n        Promise.join(1,2,p, assert.fail).then(reject, function(e) {\n            assert(e instanceof Promise.CancellationError);\n            resolve();\n        });\n        return result;\n    });\n\n    specify(\"eventually cancelled input inside array\", function() {\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        var p = new Promise(function(_, __, onCancel) {});\n        Promise.join(1,2,p, assert.fail).then(reject, reject).lastly(resolve);\n        return awaitLateQueue(function() {\n            p.cancel();\n            return result;\n        });\n    });\n\n    specify(\"immediately cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n\n        var all = Promise.join(inputs[0], inputs[1], inputs[2], assert.fail)\n            .then(reject, reject)\n            .lastly(function() {finalled++; resolve(); });\n\n        all.cancel();\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++}),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n        ];\n\n        var all = Promise.join(inputs[0], inputs[1], inputs[2], assert.fail)\n            .then(reject, reject)\n            .lastly(function() {finalled++; resolve(); });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        Promise.delay(1).then(function() {\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n            });\n        });\n    });\n});\n\ndescribe(\"Cancellation with .reflect\", function() {\n    specify(\"immediately cancelled\", function() {\n        var promise = new Promise(function(_, __, onCancel) {});\n        promise.cancel();\n        return promise.reflect().then(function(value) {\n            assert(!value.isFulfilled());\n            assert(!value.isRejected());\n            assert(!value.isPending());\n            assert(value.isCancelled());\n        });\n    });\n\n    specify(\"eventually cancelled\", function() {\n        var promise = new Promise(function(_, __, onCancel) {});\n\n        var ret = promise.reflect().then(function(value) {\n            assert(!value.isFulfilled());\n            assert(!value.isRejected());\n            assert(!value.isPending());\n            assert(value.isCancelled());\n        });\n\n        Promise.delay(1).then(function() {\n            promise.cancel();\n        });\n        return ret;\n    });\n});\n\ndescribe(\"Cancellation with .using\", function() {\n    specify(\"immediately cancelled input\", function() {\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n\n        var disposerCalled = false;\n        var disposable = new Promise(function(_, __, onCancel) {\n            setTimeout(arguments[0], 1);\n        }).disposer(function() {\n            disposerCalled = true;\n        });\n\n        Promise.using(1, disposable, p, assert.fail).then(reject, function(e) {\n            assert(e instanceof Promise.CancellationError);\n            assert(disposerCalled);\n            resolve();\n        });\n\n        return result;\n    });\n\n    specify(\"eventually cancelled input\", function() {\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        var p = new Promise(function(_, __, onCancel) {});\n\n        var disposerCalled = false;\n        var disposable = new Promise(function(_, __, onCancel) {\n            setTimeout(arguments[0], 1);\n        }).disposer(function() {\n            disposerCalled = true;\n        });\n\n        Promise.using(1, disposable, p, assert.fail).then(reject, reject).lastly(function() {\n            assert(disposerCalled);\n            resolve();\n        });\n\n        return awaitLateQueue(function() {\n            p.cancel();\n            return result;\n        });\n    });\n\n    specify(\"eventually cancelled input with 1 fulfilled disposer\", function() {\n        var resolve, reject;\n        var fulfillResource;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        var p = new Promise(function(_, __, onCancel) {});\n\n        var disposerCalled = false;\n        var disposable = new Promise(function(_, __, onCancel) {fulfillResource = arguments[0];}).disposer(function() {\n            disposerCalled = true;\n        });\n\n        Promise.using(1,disposable,p, assert.fail).then(reject, reject).lastly(function() {\n            assert(disposerCalled);\n            resolve();\n        });\n\n        return awaitLateQueue(function() {\n            fulfillResource({});\n            p.cancel();\n            return result;\n        });\n    });\n\n    specify(\"immediately cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var disposerCalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n                .disposer(function() {\n                    disposerCalled++;\n                }),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n                .disposer(function() {\n                    disposerCalled++;\n                }),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n                .disposer(function() {\n                    disposerCalled++;\n                })\n        ];\n\n        var all = Promise.using(inputs[0], inputs[1], inputs[2], assert.fail)\n            .then(reject, reject)\n            .lastly(function() {finalled++; resolve(); });\n\n        all.cancel();\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n                assert.equal(disposerCalled, 0);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var disposerCalled = 0;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n                .disposer(function() {\n                    disposerCalled++;\n                }),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n                .disposer(function() {\n                    disposerCalled++;\n                }),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n                .disposer(function() {\n                    disposerCalled++;\n                })\n        ];\n\n        var all = Promise.using(inputs[0], inputs[1], inputs[2], assert.fail)\n            .then(reject, reject)\n            .lastly(function() {finalled++; resolve(); });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        Promise.delay(1).then(function() {\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 3);\n                assert.equal(finalled, 4);\n                assert.equal(disposerCalled, 0);\n            });\n        });\n    });\n\n    specify(\"eventually cancelled output with 1 disposer fulfilled\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var disposerCalled = 0;\n        var fulfillResource;\n        var inputs = [\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n                .disposer(function() {\n                    disposerCalled++;\n                }),\n            new Promise(function(_, __, onCancel) {fulfillResource = arguments[0];})\n                .disposer(function() {\n                    disposerCalled++;\n                }),\n            new Promise(function(_, __, onCancel) { onCancel(function() { cancelled++; }); })\n                .lastly(function() {finalled++})\n                .disposer(function() {\n                    disposerCalled++;\n                })\n        ];\n\n        var all = Promise.using(inputs[0], inputs[1], inputs[2], assert.fail)\n            .then(reject, reject)\n            .lastly(function() {finalled++; resolve(); });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        Promise.delay(1).then(function() {\n            fulfillResource({})\n            all.cancel();\n        });\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 2);\n                assert.equal(finalled, 3);\n                assert.equal(disposerCalled, 1);\n            });\n        });\n    });\n\n    specify(\"result immediately cancelled when inside handler\", function() {\n        var disposerCalled = 0;\n        var cancelled = 0;\n        var finalled = 0;\n        var resource1 = Promise.resolve().disposer(function() {\n            disposerCalled++;\n        });\n\n        var resource2 = Promise.resolve().disposer(function() {\n            disposerCalled++;\n        });\n\n        var all = Promise.using(resource1, resource2, function(res1, res2) {\n            var ret = new Promise(function(_, __, onCancel) {});\n            all.cancel();\n            return ret;\n        }).then(reject, reject)\n           .lastly(function() {finalled++; resolve(); });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 0);\n                assert.equal(finalled, 1);\n                assert.equal(disposerCalled, 2);\n            });\n        });\n    });\n\n    specify(\"result eventually cancelled when inside handler\", function() {\n        var disposerCalled = 0;\n        var cancelled = 0;\n        var finalled = 0;\n        var resource1 = Promise.resolve().disposer(function() {\n            disposerCalled++;\n        });\n\n        var resource2 = Promise.resolve().disposer(function() {\n            disposerCalled++;\n        });\n\n        var all = Promise.using(resource1, resource2, function(res1, res2) {\n            var ret = new Promise(function(_, __, onCancel) {});\n            Promise.delay(1).then(function() {\n                all.cancel();\n            });\n            return ret;\n        }).then(reject, reject)\n           .lastly(function() {finalled++; resolve(); });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 0);\n                assert.equal(finalled, 1);\n                assert.equal(disposerCalled, 2);\n            });\n        });\n    });\n\n    specify(\"promise returned from handler immediately cancelled\", function() {\n        var disposerCalled = 0;\n        var cancelled = 0;\n        var finalled = 0;\n        var resource1 = Promise.resolve().disposer(function() {\n            disposerCalled++;\n        });\n\n        var resource2 = Promise.resolve().disposer(function() {\n            disposerCalled++;\n        });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n\n        var all = Promise.using(resource1, resource2, function(res1, res2) {\n            var ret = new Promise(function(_, __, onCancel) {});\n            ret.cancel();\n            return ret;\n        }).then(reject, function(e) {\n            if(!(e instanceof Promise.CancellationError)) reject(new Error());\n        }).lastly(function() {finalled++; resolve(); });\n\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 0);\n                assert.equal(finalled, 1);\n                assert.equal(disposerCalled, 2);\n            });\n        });\n    });\n\n    specify(\"promise returned from handler eventually cancelled\", function() {\n        var disposerCalled = 0;\n        var cancelled = 0;\n        var finalled = 0;\n        var resource1 = Promise.resolve().disposer(function() {\n            disposerCalled++;\n        });\n\n        var resource2 = Promise.resolve().disposer(function() {\n            disposerCalled++;\n        });\n\n        var all = Promise.using(resource1, resource2, function(res1, res2) {\n            var ret = new Promise(function(_, __, onCancel) {});\n            Promise.delay(1).then(function() {\n                ret.cancel();\n            });\n            return ret;\n        }).then(reject, reject)\n           .lastly(function() {finalled++; resolve(); });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(cancelled, 0);\n                assert.equal(finalled, 1);\n                assert.equal(disposerCalled, 2);\n            });\n        });\n    });\n});\n\ndescribe(\"Multi-branch cancellation\", function() {\n    specify(\"3 branches, 1 cancels\", function() {\n        var successCalls = 0;\n        var rootGotCancelled = false;\n        var resolveRoot;\n        var root = new Promise(function(resolve, __, onCancel) {\n            onCancel(function() {\n                rootGotCancelled = true;\n            });\n            resolveRoot = resolve;\n        });\n\n        var a = root.then(function() {\n            successCalls++;\n        });\n        var b = root.then(function() {\n            successCalls++;\n        });\n        var c = root.then(function() {\n            successCalls++;\n        });\n\n        return awaitLateQueue(function() {\n            b.cancel();\n        }).then(function() {\n            return awaitLateQueue(resolveRoot);\n        }).then(function() {\n            return awaitLateQueue(function() {\n                assert(!rootGotCancelled);\n                assert.equal(2, successCalls);\n            });\n        });\n    });\n\n    specify(\"3 branches, 3 cancels\", function() {\n        var successCalls = 0;\n        var rootGotCancelled = false;\n        var resolveRoot;\n        var root = new Promise(function(resolve, __, onCancel) {\n            onCancel(function() {\n                rootGotCancelled = true;\n            });\n            resolveRoot = resolve;\n        });\n\n        var a = root.then(function() {\n            successCalls++;\n        });\n        var b = root.then(function() {\n            successCalls++;\n        });\n        var c = root.then(function() {\n            successCalls++;\n        });\n\n        return awaitLateQueue(function() {\n            a.cancel();\n            b.cancel();\n            c.cancel();\n        }).then(function() {\n            return awaitLateQueue(resolveRoot);\n        }).then(function() {\n            return awaitLateQueue(function() {\n                assert(rootGotCancelled);\n                assert.equal(0, successCalls);\n            });\n        });\n    });\n\n    specify(\"3 branches, root cancels\", function() {\n        var successCalls = 0;\n        var rootGotCancelled = false;\n        var resolveRoot;\n        var root = new Promise(function(resolve, __, onCancel) {\n            onCancel(function() {\n                rootGotCancelled = true;\n            });\n            resolveRoot = resolve;\n        });\n\n        var a = root.then(function() {\n            successCalls++;\n        });\n        var b = root.then(function() {\n            successCalls++;\n        });\n        var c = root.then(function() {\n            successCalls++;\n        });\n\n        return awaitLateQueue(function() {\n            root.cancel();\n        }).then(function() {\n            return awaitLateQueue(resolveRoot);\n        }).then(function() {\n            return awaitLateQueue(function() {\n                assert(rootGotCancelled);\n                assert.equal(0, successCalls);\n            });\n        });\n    });\n\n    specify(\"3 branches, each have 3 branches, all children of b cancel\", function() {\n        var successCalls = 0;\n        var rootGotCancelled = false;\n        var resolveRoot;\n        var root = new Promise(function(resolve, __, onCancel) {\n            onCancel(function() {\n                rootGotCancelled = true;\n            });\n            resolveRoot = resolve;\n        });\n\n        var a = root.then(function() {\n            successCalls++;\n        });\n\n        var a1 = a.then(function() {\n            successCalls++;\n        });\n\n        var a2 = a.then(function() {\n            successCalls++;\n        });\n\n        var a3 = a.then(function() {\n            successCalls++;\n        });\n\n        var b = root.then(function() {\n            successCalls++;\n        });\n\n        var b1 = b.then(function() {\n            successCalls++;\n        });\n\n        var b2 = b.then(function() {\n            successCalls++;\n        });\n\n        var b3 = b.then(function() {\n            successCalls++;\n        });\n\n        var c = root.then(function() {\n            successCalls++;\n        });\n\n        var c1 = c.then(function() {\n            successCalls++;\n        });\n\n        var c2 = c.then(function() {\n            successCalls++;\n        });\n\n        var c3 = c.then(function() {\n            successCalls++;\n        });\n\n        return awaitLateQueue(function() {\n            b1.cancel();\n            b2.cancel();\n            b3.cancel();\n        }).then(function() {\n            return awaitLateQueue(resolveRoot);\n        }).then(function() {\n            return awaitLateQueue(function() {\n                assert(!rootGotCancelled);\n                assert.equal(8, successCalls);\n                assert(b.isCancelled());\n                assert(b1.isCancelled());\n                assert(b2.isCancelled());\n                assert(b3.isCancelled());\n            });\n        });\n    });\n\n    specify(\"3 branches, each have 3 branches, all grand children cancel\", function() {\n        var successCalls = 0;\n        var rootGotCancelled = false;\n        var resolveRoot;\n        var root = new Promise(function(resolve, __, onCancel) {\n            onCancel(function() {\n                rootGotCancelled = true;\n            });\n            resolveRoot = resolve;\n        });\n\n        var a = root.then(function() {\n            successCalls++;\n        });\n\n        var a1 = a.then(function() {\n            successCalls++;\n        });\n\n        var a2 = a.then(function() {\n            successCalls++;\n        });\n\n        var a3 = a.then(function() {\n            successCalls++;\n        });\n\n        var b = root.then(function() {\n            successCalls++;\n        });\n\n        var b1 = b.then(function() {\n            successCalls++;\n        });\n\n        var b2 = b.then(function() {\n            successCalls++;\n        });\n\n        var b3 = b.then(function() {\n            successCalls++;\n        });\n\n        var c = root.then(function() {\n            successCalls++;\n        });\n\n        var c1 = c.then(function() {\n            successCalls++;\n        });\n\n        var c2 = c.then(function() {\n            successCalls++;\n        });\n\n        var c3 = c.then(function() {\n            successCalls++;\n        });\n\n        return awaitLateQueue(function() {\n            a1.cancel();\n            a2.cancel();\n            a3.cancel();\n            b1.cancel();\n            b2.cancel();\n            b3.cancel();\n            c1.cancel();\n            c2.cancel();\n            c3.cancel();\n        }).then(function() {\n            return awaitLateQueue(resolveRoot);\n        }).then(function() {\n            return awaitLateQueue(function() {\n                assert(rootGotCancelled);\n                assert.equal(0, successCalls);\n                assert(a.isCancelled());\n                assert(a1.isCancelled());\n                assert(a2.isCancelled());\n                assert(a3.isCancelled());\n                assert(b.isCancelled());\n                assert(b1.isCancelled());\n                assert(b2.isCancelled());\n                assert(b3.isCancelled());\n                assert(c.isCancelled());\n                assert(c1.isCancelled());\n                assert(c2.isCancelled());\n                assert(c3.isCancelled());\n            });\n        });\n    });\n});\n\n\n\nif (testUtils.isNodeJS) {\n    describe(\"issues\", function() {\n        specify(\"cancels the promise chain within a domain GH963\", function() {\n            var called = 0;\n            var thens = 0;\n            var resolveChain;\n            var Domain = require(\"domain\");\n            var domain = Domain.create();\n\n            domain.enter();\n\n            var root = new Promise(function(resolve, reject, onCancel) {\n                resolveChain = resolve;\n                onCancel(function() {\n                    called++;\n                });\n            }).then(function() {\n                thens++;\n            }).then(function() {\n                thens++;\n            }).then(function() {\n                thens++;\n            }).lastly(function() {\n                called++;\n            });\n\n            root.cancel();\n            resolveChain();\n            return awaitLateQueue(function() {\n                assert.equal(0, thens);\n                assert.equal(2, called);\n                domain.exit();\n            });\n        });\n    });\n\n    describe(\"GH926\", function() {\n        var clear, set;\n        var clears = 0;\n        before(function() {\n            clears = 0;\n            set = setTimeout;\n            clear = clearTimeout;\n            setTimeout = function() {\n                return set.apply(this, arguments);\n            };\n            clearTimeout = function() {\n                clears++;\n                return clear.apply(this, arguments);\n            };\n        });\n\n        after(function() {\n            clears = 0;\n            setTimeout = set;\n            clearTimeout = clear;\n        });\n\n        specify(\"GH926\", function() {\n            var calls = 0;\n            var p = new Promise(function(resolve, reject, onCancel) {\n                onCancel(function() { calls++; });\n              })\n              .timeout(10000000)\n              .lastly(function() {\n                calls++;\n              });\n\n            p.cancel();\n\n            return awaitLateQueue(function() {\n                assert.equal(2, calls);\n                assert.equal(1, clears);\n            });\n        });\n    });\n\n    describe(\"GH1000\", function() {\n        var clear, set;\n        var clears = 0, sets = 0;\n        beforeEach(function() {\n            clears = 0;\n            sets = 0;\n            set = setTimeout;\n            clear = clearTimeout;\n            setTimeout = function() {\n                sets++;\n                return set.apply(this, arguments);\n            };\n            clearTimeout = function() {\n                clears++;\n                return clear.apply(this, arguments);\n            };\n        });\n\n        afterEach(function() {\n            clears = 0;\n            sets   = 0;\n            setTimeout = set;\n            clearTimeout = clear;\n        });\n\n        specify(\"delay\", function() {\n            var calls = 0,\n                never = 0;\n            var p = Promise\n              .delay(10000000)\n              .then(function () {\n                never++;\n              });\n\n            p.lastly(function() {\n                if (p.isCancelled()) {\n                    calls++;\n                }\n            });\n\n            p.cancel();\n\n            return awaitLateQueue(function() {\n                assert.equal(0, never);\n                assert.equal(1, calls);\n                assert.equal(1, clears);\n            });\n        });\n\n        specify(\"delay with value\", function() {\n            var calls = 0,\n                never = 0;\n\n            var p = Promise\n              .delay(10000000, true)\n              .then(function () {\n                never++;\n              });\n\n            p.lastly(function() {\n                if (p.isCancelled()) {\n                    calls++;\n                }\n            });\n\n\n\n            return Promise.delay(10)\n                .then(function () {\n                    p.cancel();\n                    return awaitLateQueue(function() {\n                            assert.equal(0, never);\n                            assert.equal(1, calls);\n                            assert.equal(1, clears);\n                        });\n                });\n        });\n\n        specify(\"cancel delay cancels inner promise\", function() {\n            var calls = 0,\n                never = 0;\n            var pInner = Promise.delay(1000)\n                    .then(function () {\n                        never++;\n                    });\n\n            pInner.lastly(function() {\n                if (pInner.isCancelled()) {\n                    calls++;\n                }\n            });\n\n            var pOuter = Promise\n              .delay(10000000, pInner)\n              .then(function () {\n                never++;\n              });\n\n            pOuter.lastly(function() {\n                if (pOuter.isCancelled()) {\n                    calls++;\n                }\n            });\n\n\n\n            pOuter.cancel();\n            return awaitLateQueue(function() {\n                assert.equal(0, never);\n                assert.equal(2, calls);\n            });\n        });\n\n        specify(\"cancel inner promise cancels delay\", function() {\n            var calls = 0,\n                never = 0;\n            var pInner = Promise.delay(1000)\n                    .then(function () {\n                        never++;\n                    });\n\n            pInner.lastly(function() {\n                if (pInner.isCancelled()) {\n                    calls++;\n                }\n            });\n\n            var pOuter = Promise\n              .delay(10000000, pInner)\n              .then(function () {\n                never++;\n              });\n\n            pOuter.lastly(function() {\n                if (pOuter.isCancelled()) {\n                    calls++;\n                }\n            });\n\n\n\n            pInner.cancel();\n            return awaitLateQueue(function() {\n                assert.equal(0, never);\n                assert.equal(2, calls);\n            });\n        });\n    });\n}\n"
  },
  {
    "path": "test/mocha/catch_filter.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\nvar CustomError = function(){};\n\nCustomError.prototype = new Error();\n\nvar predicateFilter = function(e) {\n    return (/invalid/).test(e.message);\n}\n\nfunction BadError(msg) {\n    this.message = msg;\n    return this;\n}\n\nfunction predicatesUndefined(e) {\n    return e === void 0;\n}\n\nfunction predicatesPrimitiveString(e) {\n    return /^asd$/.test(e);\n}\n\nvar token = {};\nvar returnToken = function() {\n    return token;\n};\n\nvar assertToken = function(val) {\n    assert.strictEqual(token, val);\n};\n\ndescribe(\"A promise handler that throws a TypeError must be caught\", function() {\n\n    specify(\"in a middle.caught filter\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n        return a.promise.then(function(){\n            a.b.c.d()\n        }).then(assert.fail).caught(SyntaxError, function(e){\n            assert.fail();\n        }).caught(Promise.TypeError, returnToken)\n        .then(assertToken);\n    });\n\n\n    specify(\"in a generic.caught filter that comes first\", function() {\n        var a = Promise.defer();\n\n        a.fulfill(3);\n        return a.promise.then(function(){\n            a.b.c.d()\n        }).then(assert.fail, returnToken).caught(SyntaxError, function(e){\n            assert.fail();\n        }).caught(Promise.TypeError, function(e){\n            assert.fail();\n        }).then(assertToken);\n\n    });\n\n    specify(\"in an explicitly generic.caught filter that comes first\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n\n        return a.promise.then(function(){\n            a.b.c.d()\n        })\n        .then(assert.fail)\n        .caught(Error, returnToken)\n        .caught(SyntaxError, assert.fail)\n        .caught(Promise.TypeError, assert.fail)\n        .then(assertToken);\n    });\n\n    specify(\"in a specific handler after thrown in generic\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n\n        return a.promise.then(function(){\n            a.b.c.d()\n        }).then(assert.fail, function(e){\n            throw e\n        }).caught(SyntaxError, assert.fail)\n        .then(assert.fail)\n        .caught(Promise.TypeError, returnToken)\n        .then(assertToken);\n\n\n    });\n\n\n    specify(\"in a multi-filter handler\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n\n        return a.promise.then(function(){\n            a.b.c.d()\n        })\n        .then(assert.fail)\n        .caught(SyntaxError, TypeError, returnToken)\n        .then(assertToken);\n    });\n\n\n    specify(\"in a specific handler after non-matching multi.caught handler\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n\n        return a.promise.then(function(){\n            a.b.c.d()\n        })\n        .then(assert.fail)\n        .caught(SyntaxError, CustomError, assert.fail)\n        .caught(Promise.TypeError, returnToken)\n        .then(assertToken)\n    });\n\n});\n\n\ndescribe(\"A promise handler that throws a custom error\", function() {\n\n    specify(\"Is filtered if inheritance was done even remotely properly\", function() {\n        var a = Promise.defer();\n        var b = new CustomError();\n        a.fulfill(3);\n        return a.promise.then(function(){\n            throw b;\n        })\n        .then(assert.fail)\n        .caught(SyntaxError, assert.fail)\n        .caught(Promise.TypeError, assert.fail)\n        .caught(CustomError, function(e){\n            assert.equal(e, b);\n            return token;\n        })\n        .then(assertToken);\n\n\n    });\n\n    specify(\"Is filtered along with built-in errors\", function() {\n        var a = Promise.defer();\n        var b = new CustomError();\n        a.fulfill(3);\n        return a.promise.then(function(){\n            throw b;\n        })\n        .then(assert.fail)\n        .caught(Promise.TypeError, SyntaxError, CustomError, returnToken)\n        .caught(assert.fail)\n        .then(assertToken)\n    });\n\n    specify(\"Throws after matched type handler throws\", function() {\n        var err = new Promise.TypeError();\n        var err2 = new Error();\n        return Promise.reject(err).caught(Promise.TypeError, function() {\n            throw err2;\n        }).then(assert.fail, function(e) {\n            assert.strictEqual(err2, e);\n        });\n    });\n});\n\ndescribe(\"A promise handler that throws a CustomError must be caught\", function() {\n    specify(\"in a middle.caught filter\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n\n        return a.promise.then(function(){\n            throw new CustomError()\n        })\n        .caught(SyntaxError, assert.fail)\n        .caught(CustomError, returnToken)\n        .then(assertToken);\n    });\n\n\n    specify(\"in a generic.caught filter that comes first\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n\n        return a.promise.then(function(){\n            throw new CustomError()\n        }).then(assert.fail, returnToken)\n        .caught(SyntaxError, assert.fail)\n        .caught(CustomError, assert.fail)\n        .then(assertToken)\n    });\n\n    specify(\"in an explicitly generic.caught filter that comes first\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n\n        return a.promise.then(function(){\n            throw new CustomError()\n        })\n        .caught(Error, returnToken)\n        .caught(SyntaxError, assert.fail)\n        .caught(CustomError, assert.fail)\n        .then(assertToken);\n    });\n\n    specify(\"in a specific handler after thrown in generic\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n\n        return a.promise.then(function(){\n            throw new CustomError()\n        }).then(assert.fail, function(e){\n            throw e\n        })\n        .caught(SyntaxError, assert.fail)\n        .caught(CustomError, returnToken)\n        .then(assertToken);\n\n    });\n\n\n    specify(\"in a multi-filter handler\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n\n        return a.promise.then(function(){\n            throw new CustomError()\n        })\n        .caught(SyntaxError, CustomError, returnToken)\n        .then(assertToken)\n\n    });\n\n\n    specify(\"in a specific handler after non-matching multi.caught handler\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n\n        return a.promise.then(function(){\n            throw new CustomError()\n        })\n        .caught(SyntaxError, TypeError, assert.fail)\n        .caught(CustomError, returnToken)\n        .then(assertToken);\n    });\n\n});\n\ndescribe(\"A promise handler that is caught in a filter\", function() {\n\n    specify(\"is continued normally after returning a promise in filter\", function() {\n         var a = Promise.defer();\n         var c = Promise.defer();\n         var b = new CustomError();\n         a.fulfill(3);\n         setTimeout(function(){\n             c.fulfill(3);\n         }, 1);\n         return a.promise.then(function(){\n             throw b;\n         }).caught(SyntaxError, function(e){\n            assert.fail();\n         }).caught(Promise.TypeError, function(e){\n            assert.fail();\n         }).caught(CustomError, function(e){\n            assert.equal(e, b);\n            return c.promise.thenReturn(token);\n         }).then(assertToken, assert.fail, assert.fail);\n    });\n\n    specify(\"is continued normally after returning a promise in original handler\", function() {\n         var a = Promise.defer();\n         var c = Promise.defer();\n         a.fulfill(3);\n         setTimeout(function(){\n             c.fulfill(3);\n         }, 1);\n        return a.promise.then(function(){\n             return c.promise;\n         }).caught(SyntaxError, function(e){\n            assert.fail();\n         }).caught(Promise.TypeError, function(e){\n            assert.fail();\n         }).caught(CustomError, function(e){\n            assert.fail();\n         });\n\n    });\n\n    specify(\"should throw type error for not passing function\", function() {\n        try {\n            var a = Promise.reject(new Error(\"asd\"));\n            a.caught(Promise.TypeError, \"string\");\n            throw new Error(\"fail\");\n        } catch (e) {\n            if (e instanceof Promise.TypeError) {\n                return true;\n            } else {\n                throw new Error(\"fail\");\n            }\n        }\n    });\n});\n\ndescribe(\"A promise handler with a predicate filter\", function() {\n\n    specify(\"will catch a thrown thing matching the filter\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n        return a.promise.then(function(){\n            throw new Error(\"horrible invalid error string\");\n        }).caught(predicateFilter, returnToken)\n        .then(assertToken);\n\n    });\n    specify(\"will NOT catch a thrown thing not matching the filter\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n        return a.promise.then(function(){\n            throw new Error(\"horrible valid error string\");\n        }).caught(predicateFilter, function(e){\n            assert.fail();\n        }).then(assert.fail, function(){})\n    });\n\n    specify(\"will assert.fail when a predicate is a bad error class\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n        return a.promise.then(function(){\n            throw new Error(\"horrible custom error\");\n        }).caught(BadError, function(e){\n            assert.fail();\n        }).then(assert.fail, returnToken)\n        .then(assertToken);\n\n    });\n\n    specify(\"will catch a thrown undefiend\", function(){\n        var a = Promise.defer();\n        a.fulfill(3);\n        return a.promise.then(function(){\n            throw void 0;\n        }).caught(function(e) { return false }, function(e){\n            assert.fail();\n        }).caught(predicatesUndefined, returnToken)\n        .then(assertToken);\n\n    });\n\n    specify(\"will catch a thrown string\", function(){\n        var a = Promise.defer();\n        a.fulfill(3);\n        return a.promise.then(function(){\n            throw \"asd\";\n        }).caught(function(e) { return false }, function(e){\n            assert.fail();\n        }).caught(predicatesPrimitiveString, returnToken)\n        .then(assertToken);\n\n    });\n\n    specify(\"will assert.fail when a predicate throws\", function() {\n        var a = Promise.defer();\n        a.fulfill(3);\n        return a.promise.then(function(){\n            throw new CustomError(\"error happens\");\n        }).then(assert.fail, function(e) { return e.f.g; }, function(e){\n            assert.fail();\n        }).caught(TypeError, returnToken)\n        .then(assertToken);\n    });\n});\n\ndescribe(\"object property predicates\", function() {\n    specify(\"matches 1 property loosely\", function() {\n        var e = new Error();\n        e.code = \"3\";\n        return Promise.resolve()\n            .then(function() {\n                throw e;\n            })\n            .caught({code: 3}, function(err) {\n                assert.equal(e, err);\n            });\n    });\n\n    specify(\"matches 2 properties loosely\", function() {\n        var e = new Error();\n        e.code = \"3\";\n        e.code2 = \"3\";\n        return Promise.resolve()\n            .then(function() {\n                throw e;\n            })\n            .caught({code: 3, code2: 3}, function(err) {\n                assert.equal(e, err);\n            });\n    });\n\n    specify(\"doesn't match inequal properties\", function() {\n        var e = new Error();\n        e.code = \"3\";\n        e.code2 = \"4\";\n        return Promise.resolve()\n            .then(function() {\n                throw e;\n            })\n            .caught({code: 3, code2: 3}, function(err) {\n                assert.fail();\n            })\n            .caught(function(v) {return v === e}, function() {});\n    });\n\n    specify(\"doesn't match primitives even if the property matches\", function() {\n        var e = \"string\";\n        var length = e.length;\n        return Promise.resolve()\n            .then(function() {\n                throw e;\n            })\n            .caught({length: length}, function(err) {\n                assert.fail();\n            })\n            .caught(function(v) {return typeof v === \"string\"}, function(err) {\n                assert.equal(e, err);\n            });\n    });\n});\n\n"
  },
  {
    "path": "test/mocha/collections_thenables.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\nfunction Thenable(value, defer, reject) {\n    this.value = value;\n    this.defer = !!defer;\n    this.reject = !!reject;\n}\n\nThenable.prototype.then = function Then$then(onFulfilled, onRejected) {\n    var fn = this.reject ? onRejected : onFulfilled;\n    var value = this.value;\n\n    if (this.defer) {\n        setTimeout(function(){\n            fn(value);\n        }, 1)\n    }\n    else {\n        fn(value);\n    }\n\n};\n\nfunction testFulfillSync(name, cb, a1, a2, a3) {\n    var thenables = [new Thenable(1), new Thenable(2), new Thenable(3)];\n\n    specify(\"Promise.\" + name + \" thenables that fulfill synchronously\", function(){\n        return cb(Promise[name](thenables, a1, a2, a3));\n    });\n\n}\n\nfunction testFulfillAsync(name, cb, a1, a2, a3) {\n    var thenables = [new Thenable(1, true), new Thenable(2, true), new Thenable(3, true)];\n\n    specify(\"Promise.\" + name + \" thenables that fulfill asynchronously\", function(){\n        return cb(Promise[name](thenables, a1, a2, a3));\n    });\n}\n\nfunction testRejectSync(name, cb, a1, a2, a3) {\n    var thenables = [new Thenable(1, false, true), new Thenable(2, false, true), new Thenable(3, false, true)];\n\n    specify(\"Promise.\" + name + \" thenables that reject synchronously\", function(){\n        return cb(Promise[name](thenables, a1, a2, a3));\n    });\n\n}\n\nfunction testRejectAsync(name, cb, a1, a2, a3) {\n    var thenables = [new Thenable(1, true, true), new Thenable(2, true, true), new Thenable(3, true, true)];\n\n    specify(\"Promise.\" + name + \" thenables that reject asynchronously\", function(){\n        return cb(Promise[name](thenables, a1, a2, a3));\n    });\n}\n\n\ndescribe(\"Using collection methods with thenables\", function() {\n    var name = \"race\";\n    testFulfillSync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v === 1);\n        });\n    });\n    testFulfillAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v === 1);\n        });\n    });\n    testRejectSync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert(v === 1);\n        });\n    });\n    testRejectAsync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert(v === 1);\n        });\n    });\n});\n\ndescribe(\"Using collection methods with thenables\", function() {\n    var name = \"all\";\n    testFulfillSync(name, function(promise) {\n        return promise.then(function(v){\n            assert.deepEqual(v, [1,2,3]);\n        });\n    });\n    testFulfillAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert.deepEqual(v, [1,2,3]);\n        });\n    });\n    testRejectSync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert(v === 1);\n        });\n    });\n    testRejectAsync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert(v === 1);\n        });\n    });\n});\n\ndescribe(\"Using collection methods with thenables\", function() {\n    var name = \"settle\";\n    testFulfillSync(name, function(promise) {\n        return promise.then(function(v) {\n            assert(v[0].value() === 1)\n            assert(v[1].value() === 2)\n            assert(v[2].value() === 3)\n        });\n    });\n    testFulfillAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v[0].value() === 1)\n            assert(v[1].value() === 2)\n            assert(v[2].value() === 3)\n        });\n    });\n    testRejectSync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v[0].error() === 1)\n            assert(v[1].error() === 2)\n            assert(v[2].error() === 3)\n        });\n    });\n    testRejectAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v[0].error() === 1)\n            assert(v[1].error() === 2)\n            assert(v[2].error() === 3)\n        });\n    });\n});\n\ndescribe(\"Using collection methods with thenables\", function() {\n    var name = \"any\";\n    testFulfillSync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v === 1);\n        });\n    });\n    testFulfillAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v === 1);\n        });\n    });\n    testRejectSync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert(v[0] === 1);\n            assert(v[1] === 2);\n            assert(v[2] === 3);\n        });\n    });\n    testRejectAsync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert(v[0] === 1);\n            assert(v[1] === 2);\n            assert(v[2] === 3);\n        });\n    });\n});\n\ndescribe(\"Using collection methods with thenables\", function() {\n    var name = \"some\";\n    testFulfillSync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v[0] === 1);\n        });\n    }, 1);\n    testFulfillAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v[0] === 1);\n        });\n    }, 1);\n    testRejectSync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert(v[0] === 1);\n            assert(v[1] === 2);\n            assert(v[2] === 3);\n        });\n    }, 1);\n    testRejectAsync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert(v[0] === 1);\n            assert(v[1] === 2);\n            assert(v[2] === 3);\n        });\n    }, 1);\n});\n\ndescribe(\"Using collection methods with thenables\", function() {\n    var name = \"join\";\n    testFulfillSync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v[0][0].value === 1);\n            assert(v[0][1].value === 2);\n            assert(v[0][2].value === 3);\n            assert(v[1] === 1);\n            assert(v[2] === 2);\n            assert(v[3] === 3);\n        });\n    }, 1, 2, 3);\n    testFulfillAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v[0][0].value === 1);\n            assert(v[0][1].value === 2);\n            assert(v[0][2].value === 3);\n            assert(v[1] === 1);\n            assert(v[2] === 2);\n            assert(v[3] === 3);\n        });\n    }, 1, 2, 3);\n    testRejectSync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v[0][0].value === 1);\n            assert(v[0][1].value === 2);\n            assert(v[0][2].value === 3);\n            assert(v[1] === 1);\n            assert(v[2] === 2);\n            assert(v[3] === 3);\n        });\n    }, 1, 2, 3);\n    testRejectAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert(v[0][0].value === 1);\n            assert(v[0][1].value === 2);\n            assert(v[0][2].value === 3);\n            assert(v[1] === 1);\n            assert(v[2] === 2);\n            assert(v[3] === 3);\n        });\n    }, 1, 2, 3);\n});\n\nfunction mapper(v) {\n    return {\n        then: function(f) {\n            f(v*2);\n        }\n    };\n}\nfunction reducer(a, b) {\n    return a + b;\n}\nfunction filterer(v) {\n    return {\n        then: function(f) {\n            f(v > 0);\n        }\n    };\n}\n\ndescribe(\"Using collection methods with thenables\", function() {\n    var name = \"map\";\n    testFulfillSync(name, function(promise) {\n        return promise.then(function(v){\n            assert.deepEqual(v, [2,4,6]);\n        });\n    }, mapper);\n    testFulfillAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert.deepEqual(v, [2,4,6]);\n        });\n    }, mapper);\n    testRejectSync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        });\n    }, mapper);\n    testRejectAsync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        });\n    }, mapper);\n});\n\ndescribe(\"Using collection methods with thenables\", function() {\n    var name = \"reduce\";\n    testFulfillSync(name, function(promise) {\n        return promise.then(function(v){\n            assert.deepEqual(v, 6);\n        });\n    }, reducer);\n    testFulfillAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert.deepEqual(v, 6);\n        });\n    }, reducer);\n    testRejectSync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        });\n    }, reducer);\n    testRejectAsync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        });\n    }, reducer);\n});\n\ndescribe(\"Using collection methods with thenables\", function() {\n    var name = \"filter\";\n    testFulfillSync(name, function(promise) {\n        return promise.then(function(v){\n            assert.deepEqual(v, [1,2,3]);\n        });\n    }, filterer);\n    testFulfillAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert.deepEqual(v, [1,2,3]);\n        });\n    }, filterer);\n    testRejectSync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        });\n    }, filterer);\n    testRejectAsync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        });\n    }, filterer);\n});\n\ndescribe(\"Using collection methods with thenables\", function() {\n    var name = \"props\";\n    testFulfillSync(name, function(promise) {\n        return promise.then(function(v){\n            assert.deepEqual(v, {0: 1, 1: 2, 2: 3});\n        });\n    }, filterer);\n    testFulfillAsync(name, function(promise) {\n        return promise.then(function(v){\n            assert.deepEqual(v, {0: 1, 1: 2, 2: 3});\n        });\n    }, filterer);\n    testRejectSync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        });\n    }, filterer);\n    testRejectAsync(name, function(promise) {\n        return promise.then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        });\n    }, filterer);\n});\n"
  },
  {
    "path": "test/mocha/constructor.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\nfunction fulfills(value, test) {\n    specify(\"immediately-fulfilled\", function() {\n        return test(new Promise(function(resolve){\n            resolve(value);\n        }));\n    });\n\n    specify(\"eventually-fulfilled\", function() {\n        return test(new Promise(function(resolve){\n            setTimeout(function(){\n                resolve(value);\n            }, 1);\n        }));\n    });\n};\n\nfunction rejects(reason, test) {\n    specify(\"immediately-rejected\", function() {\n        return test(new Promise(function(resolve, reject){\n            reject(reason);\n        }));\n    });\n\n    specify(\"eventually-rejected\", function() {\n        return test(new Promise(function(resolve, reject){\n            setTimeout(function(){\n                reject(reason);\n            }, 1);\n        }));\n    });\n};\n\nfunction testFulfilled(value, test) {\n    describe(\"immediate value\", function(){\n        fulfills(value, test);\n    });\n\n    describe(\"already fulfilled promise for value\", function(){\n        fulfills(Promise.resolve(value), test);\n    });\n\n    describe(\"immediately fulfilled promise for value\", function(){\n        var a = Promise.defer();\n        fulfills(a.promise, test);\n        a.resolve(value);\n    });\n\n    describe(\"eventually fulfilled promise for value\", function(){\n        var a = Promise.defer();\n        fulfills(a.promise, test);\n        setTimeout(function(){\n            a.resolve(value);\n        }, 1)\n\n    });\n\n    describe(\"synchronous thenable for value\", function () {\n        fulfills({\n            then: function (f) {\n                f(value);\n            }\n        }, test);\n    });\n\n    describe(\"asynchronous thenable for value\", function () {\n        fulfills({\n            then: function (f) {\n                setTimeout(function () {\n                    f(value);\n                }, 1);\n            }\n        }, test);\n    });\n}\n\nfunction testRejected(reason, test) {\n    describe(\"immediate reason\", function(){\n        rejects(reason, test);\n    });\n}\n\n\ndescribe(\"Promise constructor\", function() {\n    it(\"should throw type error when called as function\", function() {\n        try {\n            Promise(function(){});\n        }\n        catch (e) {\n            return;\n        }\n        assert.fail();\n    });\n\n    it(\"should throw type error when passed non-function\", function() {\n        try {\n            new Promise({});\n        }\n        catch (e) {\n            return;\n        }\n        assert.fail();\n    });\n\n\n    var defaultThis = (function(){\n        return this;\n    })();\n\n    it(\"calls the resolver as a function\", function(){\n        new Promise(function() {\n            assert(this === defaultThis);\n        });\n    });\n\n    it(\"passes arguments even if parameters are not defined\", function(){\n        new Promise(function() {\n            assert(arguments.length === 2 || arguments.length === 3);\n        });\n    });\n\n\n    it(\"should reject with any thrown error\", function() {\n        var e = new Error();\n        return new Promise(function(){\n            throw e;\n        }).then(assert.fail, function(err) {\n            assert(err === e)\n        });\n    });\n\n    it(\"should call the resolver function synchronously\", function() {\n        var e = new Error();\n        var a = 0;\n        new Promise(function(){\n            a = 1;\n        });\n        assert(a === 1);\n    });\n\n\n    describe(\"resolves the promise with the given object value\", function() {\n        var value = {};\n        testFulfilled(value, function(promise) {\n            return promise.then(function(v){\n                assert(v === value);\n            });\n        });\n    });\n\n    describe(\"resolves the promise with the given primitive value\", function() {\n        var value = 3;\n        testFulfilled(value, function(promise) {\n            return promise.then(function(v){\n                assert(v === value);\n            });\n        });\n    });\n\n    describe(\"resolves the promise with the given undefined value\", function() {\n        var value = void 0;\n        testFulfilled(value, function(promise) {\n            return promise.then(function(v){\n                assert(v === value);\n            });\n        });\n    });\n\n    describe(\"rejects the promise with the given object reason\", function() {\n        var reason = {};\n        testRejected(reason, function(promise) {\n            return promise.then(assert.fail, function(v){\n                assert(v === reason);\n            });\n        });\n    });\n\n    describe(\"rejects the promise with the given primitive reason\", function() {\n        var reason = 3;\n        testRejected(reason, function(promise) {\n            return promise.then(assert.fail, function(v){\n                assert(v === reason);\n            });\n        });\n    });\n\n    describe(\"rejects the promise with the given undefined reason\", function() {\n        var reason = void 0;\n        testRejected(reason, function(promise) {\n            return promise.then(assert.fail, function(v){\n                assert(v === reason);\n            });\n        });\n    });\n\n});\n"
  },
  {
    "path": "test/mocha/cycles.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\nvar helpers = require(\"./helpers/testThreeCases.js\");\nvar TypeError = Promise.TypeError;\n\n\ndescribe(\"Cyclical promises should throw TypeError when\", function(){\n    describe(\"returning from fulfill\", function() {\n        helpers.testFulfilled(3, function(promise) {\n            var self = promise.then(function() {\n                return self;\n            });\n\n            return self.then(assert.fail).caught(TypeError, testUtils.noop);\n        });\n    });\n\n    describe(\"returning from reject\", function() {\n        helpers.testRejected(3, function(promise) {\n            var self = promise.then(assert.fail, function() {\n                return self;\n            });\n\n            return self.then(assert.fail).caught(TypeError, testUtils.noop);\n        });\n    });\n\n    describe(\"fulfill with itself when using a \", function() {\n        specify(\"deferred\", function() {\n            var d = Promise.defer();\n            d.fulfill(d.promise);\n            return d.promise.then(assert.fail).caught(TypeError, testUtils.noop);\n        });\n\n        specify(\"constructor\", function() {\n            var resolve;\n            var p = new Promise(function(r) {\n                resolve = r;\n            });\n            resolve(p);\n            return p.then(assert.fail).caught(TypeError, testUtils.noop);\n        });\n    });\n\n    describe(\"reject with itself when using a \", function() {\n        specify(\"deferred\", function() {\n            var d = Promise.defer();\n            d.reject(d.promise);\n            return d.promise.then(assert.fail).caught(function(v) {\n                assert.equal(d.promise, v);\n            });\n        });\n\n        specify(\"constructor\", function() {\n            var reject;\n            var p = new Promise(function(f, r) {\n                reject = r;\n            });\n            reject(p);\n            return p.then(assert.fail).caught(function(v) {\n                assert.equal(p, v);\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/direct_resolving.js",
    "content": "\"use strict\";\n\n\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\nvar helpers = require(\"./helpers/testThreeCases.js\");\nvar TypeError = Promise.TypeError;\n\nfunction passthru(fn) {\n    return function() {\n        fn();\n    };\n}\n\nfunction wrap(fn, val) {\n    var args = [].slice.call(arguments, 1);\n    return function() {\n        return fn.apply(this, args);\n    }\n}\n\nfunction returnValue(value) {\n    helpers.testFulfilled(void 0, function(promise) {\n        return promise.thenReturn(value).then(function(v){\n            assert(v === value);\n        });\n    });\n}\n\nfunction throwValue(value) {\n    helpers.testFulfilled(void 0, function(promise) {\n        return promise.thenThrow(value).then(assert.fail, function(v) {\n            assert(v === value);\n        });\n    });\n}\n\nfunction returnThenable(thenable, expected) {\n    helpers.testFulfilled(void 0, function(promise) {\n        return promise.thenReturn(thenable).then(function(v){\n            assert(v === expected);\n        });\n    });\n}\n\nfunction returnThenableReject(thenable, expected) {\n    helpers.testFulfilled(void 0, function(promise) {\n        return promise.thenReturn(thenable).then(assert.fail, function(v){\n            assert(v === expected);\n        });\n    });\n}\n\ndescribe(\"thenReturn\", function () {\n\n    describe(\"primitives\", function() {\n        describe(\"null\", wrap(returnValue, null));\n        describe(\"undefined\", wrap(returnValue, void 0));\n        describe(\"string\", wrap(returnValue, \"asd\"));\n        describe(\"number\", wrap(returnValue, 3));\n        describe(\"boolean\", wrap(returnValue, true));\n    });\n\n    describe(\"objects\", function() {\n        describe(\"plain\", wrap(returnValue, {}));\n        describe(\"function\", wrap(returnValue, function(){}));\n        describe(\"built-in function\", wrap(returnValue, Array));\n        describe(\"built-in object\", wrap(returnValue, Math));\n    });\n\n    describe(\"thenables\", function() {\n        describe(\"which fulfill\", function() {\n            describe(\"immediately\", wrap(returnThenable, {\n                then: function(f) {\n                    f(10);\n                }\n            }, 10));\n            describe(\"eventually\", wrap(returnThenable, {\n                then: function(f) {\n                    setTimeout(function() {\n                        f(10);\n                    }, 1);\n                }\n            }, 10));\n        });\n        describe(\"which reject\", function(){\n            describe(\"immediately\", wrap(returnThenableReject, {\n                then: function(f, r) {\n                    r(10);\n                }\n            }, 10));\n            describe(\"eventually\", wrap(returnThenableReject, {\n                then: function(f, r) {\n                    setTimeout(function() {\n                        r(10);\n                    }, 1);\n                }\n            }, 10));\n        });\n    });\n\n    describe(\"promises\", function() {\n        describe(\"which fulfill\", function() {\n            var d1 = Promise.defer();\n            var d2 = Promise.defer();\n            describe(\"already\", wrap(returnThenable, Promise.resolve(10), 10));\n            describe(\"immediately\", wrap(returnThenable, d1.promise, 10));\n            describe(\"eventually\", wrap(returnThenable, d2.promise, 10));\n            d1.fulfill(10);\n            setTimeout(function(){\n                d2.fulfill(10);\n            }, 1);\n        });\n        describe(\"which reject\", function() {\n            var d1 = Promise.defer();\n            var d2 = Promise.defer();\n            var alreadyRejected = Promise.reject(10);\n            alreadyRejected.then(assert.fail, function(){});\n            describe(\"already\", wrap(returnThenableReject, alreadyRejected, 10));\n            describe(\"immediately\", wrap(returnThenableReject, d1.promise, 10));\n            describe(\"eventually\", wrap(returnThenableReject, d2.promise, 10));\n            d1.reject(10);\n            setTimeout(function(){\n                d2.reject(10);\n            }, 1);\n\n            d1.promise.caught(function(){});\n            d2.promise.caught(function(){});\n        });\n\n    });\n\n    describe(\"doesn't swallow errors\", function() {\n        var e = {};\n        helpers.testRejected(e, function(promise){\n            return promise.thenReturn(3).then(assert.fail, function(err) {\n                assert(err = e);\n            });\n        });\n    });\n});\n\ndescribe(\"thenThrow\", function () {\n\n    describe(\"primitives\", function() {\n        describe(\"null\", wrap(throwValue, null));\n        describe(\"undefined\", wrap(throwValue, void 0));\n        describe(\"string\", wrap(throwValue, \"asd\"));\n        describe(\"number\", wrap(throwValue, 3));\n        describe(\"boolean\", wrap(throwValue, true));\n    });\n\n    describe(\"objects\", function() {\n        describe(\"plain\", wrap(throwValue, {}));\n        describe(\"function\", wrap(throwValue, function(){}));\n        describe(\"built-in function\", wrap(throwValue, Array));\n        describe(\"built-in object\", wrap(throwValue, Math));\n    });\n\n    describe(\"doesn't swallow errors\", function() {\n        var e = {};\n        helpers.testRejected(e, function(promise){\n            return promise.thenThrow(3).then(assert.fail, function(err) {\n                assert(err = e);\n            });\n        });\n    });\n});\n\ndescribe(\"catchReturn\", function () {\n\n    specify(\"catches and returns\", function() {\n        return Promise.reject(3).catchReturn(1).then(function(val) {\n            assert.strictEqual(1, val);\n        });\n    });\n\n    specify(\"doesn't catch succesful promise\", function() {\n        return Promise.resolve(3).catchReturn(1).then(function(val) {\n            assert.strictEqual(3, val);\n        });\n    });\n\n    specify(\"supports 1 error type\", function() {\n        var e = new Error();\n        e.prop = 3;\n        var predicate = function(e) {return e.prop === 3};\n        return Promise.reject(e)\n                .catchReturn(TypeError, 1)\n                .catchReturn(predicate, 2)\n                .then(function(val) {\n            assert.strictEqual(2, val);\n        });\n    });\n});\n\ndescribe(\"catchThrow\", function () {\n\n    specify(\"catches and throws\", function() {\n        return Promise.reject(3).catchThrow(1).then(assert.fail, function(val) {\n            assert.strictEqual(1, val);\n        });\n    });\n\n    specify(\"doesn't catch succesful promise\", function() {\n        return Promise.resolve(3).catchThrow(1).then(function(val) {\n            assert.strictEqual(3, val);\n        });\n    });\n\n    specify(\"supports 1 error type\", function() {\n        var e = new Error();\n        e.prop = 3;\n        var predicate = function(e) {return e.prop === 3};\n        return Promise.reject(e)\n                .catchThrow(TypeError, 1)\n                .catchThrow(predicate, 2)\n                .then(assert.fail, function(val) {\n            assert.strictEqual(2, val);\n        });\n    });\n});\n\n\ndescribe(\"gh-627\", function() {\n    it(\"can return undefined\", function() {\n        return Promise.bind(42)\n            .thenReturn(undefined)\n            .then(function (value) {\n              assert.strictEqual(value, undefined);\n            });\n    });\n    it(\"can throw undefined\", function() {\n        return Promise.bind(42)\n            .thenThrow(undefined)\n            .then(assert.fail, function (reason) {\n              assert.strictEqual(reason, undefined);\n            });\n    });\n\n    it(\"can catch return undefined\", function() {\n        return Promise.bind(42).thenThrow(new Error())\n            .catchReturn()\n            .then(function (value) {\n              assert.strictEqual(value, undefined);\n            });\n    });\n    it(\"can catch throw undefined\", function() {\n        return Promise.bind(42).thenThrow(new Error())\n            .catchThrow()\n            .then(assert.fail, function (reason) {\n              assert.strictEqual(reason, undefined);\n            });\n    });\n});\n"
  },
  {
    "path": "test/mocha/domain.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\nif (testUtils.isRecentNode) {\n    describe(\"domain\", function() {\n        afterEach(function() {\n            Promise.onPossiblyUnhandledRejection(null);\n        });\n\n        specify(\"gh-148\", function() {\n            var called = false;\n            var e = new Error(\"the error\");\n            Promise.resolve(23).then(function(){called = true});\n            return testUtils.awaitDomainException(function(E) {\n                assert.equal(e, E);\n                assert(called);\n            }, function() {\n                Promise.onPossiblyUnhandledRejection(function(error) {\n                    throw error;\n                });\n                var P = new Promise(function(_, reject){reject(e);});\n            });\n        });\n\n        specify(\"gh-521-promisified\", function() {\n            return new Promise(function(resolve, reject) {\n                var domain = require('domain').create();\n                var data = {};\n\n                function callsBack(cb) {\n                    setTimeout(function() {\n                        cb(null, 1);\n                    }, 1);\n                }\n\n                var promisified = Promise.promisify(callsBack);\n                domain.on('error', reject);\n                domain.run(function() {\n                    process.domain.data = data;\n                    resolve(promisified().then(function() {\n                        assert.strictEqual(process.domain.data, data);\n                        assert.strictEqual(process.domain, domain);\n                    }));\n                });\n            });\n        });\n\n        specify(\"gh-521-constructed\", function() {\n            return new Promise(function(resolve, reject) {\n                var domain = require('domain').create();\n                var data = {asd: 3};\n                domain.on('error', reject);\n                domain.run(function() {\n                    var promise = new Promise(function(resolve) {\n                        setTimeout(resolve, 1);\n                    });\n\n                    process.domain.data = data;\n                    resolve(promise.then(function() {\n                        assert.strictEqual(process.domain.data, data);\n                        assert.strictEqual(process.domain, domain);\n                    }));\n                });\n            });\n        });\n    });\n\n\n    describe(\"domain preservation\" , function() {\n        var Domain = require(\"domain\");\n\n        function createGroupDone(limit, next) {\n\n            return function done(err) {\n                if (err) {\n                    return next(err);\n                }\n                if (--limit <= 0) {\n                    next();\n                }\n            };\n        }\n\n        before(function () {\n            var current;\n            while((current = process.domain)) {\n                current.exit();\n            }\n        });\n\n        afterEach(function () {\n            var current;\n            while((current = process.domain)) {\n                current.exit();\n            }\n        });\n\n        it(\"should preserve empty domain and this function\", function(done) {\n\n            var deferred = new Promise.defer();\n            var p = deferred.promise;\n\n            p.then(function shouldBeEmpty() {\n                assert.equal(false, !!process.domain);\n            }).bind({\n                ref: 'foo'\n            }).then(function shouldKeepThisAndEmptyDomain() {\n                assert.equal(false, !!process.domain);\n                assert.equal('foo', this.ref);\n                done();\n            }).caught(done);\n\n            deferred.resolve(\"ok\");\n\n        });\n\n        it(\"should preserve empty domain, nodeify\", function(done) {\n            done = createGroupDone(3, done);\n\n            var deferred = new Promise.defer();\n            var p = deferred.promise;\n\n            p.then(function shouldBeEmpty() {\n                assert.equal(false, !!process.domain);\n                done();\n            }).bind({\n                ref: 'foo'\n            }).then(function shouldKeepThisAndEmptyDomain() {\n                assert.equal(false, !!process.domain);\n                assert.equal('foo', this.ref);\n                done();\n            }).nodeify(function shouldKeepThisAndEmptyDomain() {\n                try {\n                    assert.equal(false, !!process.domain);\n                    assert.equal('foo', this.ref);\n                    done();\n                } catch (err) {\n                    done(err);\n                }\n            }).caught(done);\n\n            deferred.resolve(\"ok\");\n\n        });\n\n        it(\"should preserve corresponding state of domain\", function(done) {\n\n            done = createGroupDone(6, done);\n\n            var deferred = new Promise.defer();\n            var p = deferred.promise;\n\n            p.then(function shouldBeEmpty() {\n                assert.equal(false, !!process.domain);\n                done();\n            }).bind({\n                ref: 'foo'\n            }).then(function shouldKeepThisAndEmptyDomain() {\n                assert.equal(false, !!process.domain);\n                assert.equal('foo', this.ref);\n                done();\n            }).nodeify(function shouldKeepThisAndEmptyDomain() {\n                try {\n                    assert.equal(false, !!process.domain);\n                    assert.equal('foo', this.ref);\n                    done();\n                } catch (err) { done(err); }\n            }).caught(done);\n\n            var domain = Domain.create();\n            domain.run(function () {\n                p.then(function shouldNoBeEmpty() {\n                    assert.equal(domain, process.domain);\n                    done();\n                }).bind({\n                    ref: 'bar'\n                }).then(function shouldKeepThisAndDomain() {\n                    assert.equal(domain, process.domain);\n                    assert.equal('bar', this.ref);\n                    done();\n                }).caught(done).nodeify(function shouldKeepThisAndDomain() {\n                    try {\n                        assert.equal(domain, process.domain);\n                        assert.equal('bar', this.ref);\n                        done();\n                    } catch (err) { done(err); }\n                });\n            });\n\n            deferred.resolve(\"ok\");\n\n        });\n\n        it('should preserve corresponding state of domain, complex', function(done) {\n\n            done = createGroupDone(9, done);\n\n            var deferred = new Promise.defer();\n            var p = deferred.promise;\n            p.then(function shouldBeEmpty() {\n                assert.equal(false, !!process.domain);\n                done();\n            }).bind({\n                ref: 'foo'\n            }).then(function shouldKeepThisAndEmptyDomain() {\n                assert.equal(false, !!process.domain);\n                assert.equal('foo', this.ref);\n                done();\n            }).caught(done).nodeify(function shouldKeepThisAndEmptyDomain() {\n                try {\n                    assert.equal(false, !!process.domain);\n                    assert.equal('foo', this.ref);\n                    done();\n                }\n                catch (err) { done(err); }\n            }, done);\n\n            var domain1 = Domain.create();\n            domain1.run(function () {\n                p.then(function shouldNoBeEmpty() {\n                    assert.equal(domain1, process.domain);\n                    done();\n                }).bind({\n                    ref: 'bar'\n                }).then(function shouldKeepThisAndDomain() {\n                    assert.equal(domain1, process.domain);\n                    assert.equal('bar', this.ref);\n                    done();\n                }).caught(done).nodeify(function shouldKeepThisAndDomain() {\n                    try {\n                        assert.equal(domain1, process.domain);\n                        assert.equal('bar', this.ref);\n                        done();\n                    }\n                    catch (err) { done(err); }\n                }, done);\n            });\n\n            var domain2 = Domain.create();\n            domain2.run(function () {\n                p.then(function shouldNoBeEmpty() {\n                    assert.equal(domain2, process.domain);\n                    done();\n                }).bind({\n                    ref: 'qaz'\n                }).then(function shouldKeepThisAndDomain() {\n                    assert.equal(domain2, process.domain);\n                    assert.equal('qaz', this.ref);\n                    done();\n                }).caught(done).nodeify(function shouldKeepThisAndDomain() {\n                    try {\n                        assert.equal(domain2, process.domain);\n                        assert.equal('qaz', this.ref);\n                        done();\n                    }\n                    catch (err) { done(err); }\n                });\n            });\n\n            deferred.resolve(\"ok\");\n\n        });\n\n        it('should preserve corresponding state of domain in reject', function(done) {\n\n            done = createGroupDone(4, done);\n\n            var deferred = new Promise.defer();\n            var p = deferred.promise;\n\n            p.bind({\n                ref: 'foo'\n            }).caught(function shouldKeepThisAndEmptyDomain() {\n                assert.equal(false, !!process.domain);\n                assert.equal('foo', this.ref);\n                done();\n            }).caught(done).nodeify(function shouldKeepThisAndEmptyDomain() {\n                try {\n                    assert.equal(false, !!process.domain);\n                    assert.equal('foo', this.ref);\n                    done();\n                }\n                catch (err) { done(err); }\n            });\n\n            var domain = Domain.create();\n            domain.run(function () {\n                p.bind({\n                    ref: 'bar'\n                }).caught(function shouldNoBeEmpty() {\n                    assert.equal(true, !!process.domain);\n                    assert.equal('bar', this.ref);\n                    done();\n                }).caught(done).nodeify(function shouldKeepThisAndDomain(err) {\n                    try {\n                        assert.equal(true, !!process.domain);\n                        assert.equal('bar', this.ref);\n                        done();\n                    }\n                    catch (err) { done(err); }\n                }).caught(done);\n            });\n\n            deferred.reject('bad');\n\n        });\n\n        it('should preserve corresponding state of domain in reject, complex', function(done) {\n\n            done = createGroupDone(6, done);\n\n            var deferred = new Promise.defer();\n            var p = deferred.promise;\n            p.bind({\n                ref: 'foo'\n            }).caught(function shouldBeEmpty() {\n                assert.equal(false, !!process.domain);\n                assert.equal('foo', this.ref);\n                done();\n            }).caught(done).nodeify(function shouldKeepThisAndEmptyDomain() {\n                try {\n                    assert.equal(false, !!process.domain);\n                    assert.equal('foo', this.ref);\n                    done();\n                }\n                catch (err) { done(err); }\n            });\n\n            var domain1 = Domain.create();\n            domain1.run(function () {\n                p.bind({\n                    ref: 'bar'\n                }).caught(function shouldNoBeEmpty() {\n                    assert.equal(domain1, process.domain);\n                    assert.equal('bar', this.ref);\n                    done();\n                }).caught(done).nodeify(function shouldKeepThisAndDomain() {\n                    try {\n                        assert.equal(domain1, process.domain);\n                        assert.equal('bar', this.ref);\n                        done();\n                    }\n                    catch (err) { done(err); }\n                });\n            });\n\n            var domain2 = Domain.create();\n            domain2.run(function () {\n                p.bind({\n                    ref: 'qaz'\n                }).caught(function shouldNoBeEmpty() {\n                    assert.equal(domain2, process.domain);\n                    assert.equal('qaz', this.ref);\n                    done();\n                }).caught(done).nodeify(function shouldKeepThisAndDomain() {\n                    try {\n                        assert.equal(domain2, process.domain);\n                        assert.equal('qaz', this.ref);\n                        done();\n                    }\n                    catch (err) { done(err); }\n                });\n            });\n\n            deferred.reject('bad');\n\n        });\n\n        it('should preserve domain when using .join', function() {\n            var domain = Domain.create();\n            var d1 = new Promise(function(resolve, reject) {\n                Domain.create().run(function() {\n                    setTimeout(resolve, 1);\n                });\n            });\n            var d2 = new Promise(function(resolve, reject) {\n                Domain.create().run(function() {\n                    setTimeout(resolve, 1);\n                });\n            });\n\n            return new Promise(function(resolve, reject) {\n                domain.on(\"error\", reject);\n                domain.run(function() {\n                    resolve(Promise.join(d1, d2, function() {\n                        assert.strictEqual(domain, process.domain);\n                    }));\n                });\n            });\n        });\n\n        it('should preserve domain when using .using', function() {\n            var domain = Domain.create();\n            var d1 = new Promise(function(resolve, reject) {\n                Domain.create().run(function() {\n                    setTimeout(resolve, 1);\n                });\n            });\n            var d2 = new Promise(function(resolve, reject) {\n                Domain.create().run(function() {\n                    setTimeout(resolve, 1);\n                });\n            });\n\n            return new Promise(function(resolve, reject) {\n                domain.on(\"error\", reject);\n                domain.run(function() {\n                    resolve(Promise.using(d1, d2, function() {\n                        assert.strictEqual(domain, process.domain);\n                    }));\n                });\n            });\n        });\n\n        it('should preserve domain when using .map', function() {\n            var domain = Domain.create();\n            var d1 = new Promise(function(resolve, reject) {\n                Domain.create().run(function() {\n                    setTimeout(resolve, 1);\n                });\n            });\n\n            return new Promise(function(resolve, reject) {\n                domain.on(\"error\", reject);\n                domain.run(function() {\n                    resolve(Promise.map([d1, null, Promise.resolve(1), Promise.delay(1)], function() {\n                        return process.domain;\n                    }).then(function(domains) {\n                        assert.deepEqual([domain, domain, domain, domain], domains);\n                        assert.equal(process.domain, domain);\n                    }));\n                });\n            });\n        });\n\n        it('should preserve domain when using .filter', function() {\n            var domain = Domain.create();\n            var d1 = new Promise(function(resolve, reject) {\n                Domain.create().run(function() {\n                    setTimeout(resolve, 1);\n                });\n            });\n\n            return new Promise(function(resolve, reject) {\n                domain.on(\"error\", reject);\n                domain.run(function() {\n                    resolve(Promise.filter([d1, null, Promise.resolve(1), Promise.delay(1)], function() {\n                        assert.equal(process.domain, domain);\n                    }));\n                });\n            });\n        });\n\n        it('should preserve domain when using .reduce', function() {\n            var domain = Domain.create();\n            var d1 = new Promise(function(resolve, reject) {\n                Domain.create().run(function() {\n                    setTimeout(resolve, 1);\n                });\n            });\n\n            return new Promise(function(resolve, reject) {\n                domain.on(\"error\", reject);\n                domain.run(function() {\n                    resolve(Promise.reduce([d1, null, Promise.resolve(1), Promise.delay(1)], function() {\n                        assert.equal(process.domain, domain);\n                    }));\n                });\n            });\n        });\n\n        it('should preserve domain when using .each', function() {\n            var domain = Domain.create();\n            var d1 = new Promise(function(resolve, reject) {\n                Domain.create().run(function() {\n                    setTimeout(resolve, 1);\n                });\n            });\n\n            return new Promise(function(resolve, reject) {\n                domain.on(\"error\", reject);\n                domain.run(function() {\n                    resolve(Promise.each([d1, null, Promise.resolve(1), Promise.delay(1)], function() {\n                        assert.equal(process.domain, domain);\n                    }));\n                });\n            });\n        });\n\n        it(\"should not crash with already rejected promise\", function() {\n            return new Promise(function(resolve) {\n                Domain.create().run(function() {\n                    Promise.resolve(1).timeout(200).then(function() {\n                        resolve();\n                    })\n                });\n            });\n        })\n    });\n\n}\n"
  },
  {
    "path": "test/mocha/done.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar isNodeJS = testUtils.isNodeJS;\n\n/*!\n *\nCopyright 2009–2012 Kristopher Michael Kowal. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\ndescribe(\"done\", function () {\n    var errCount = 0;\n    var safeError = new Error(\"safe_error\");\n\n    describe(\"when the promise is fulfilled\", function () {\n        describe(\"and the callback does not throw\", function () {\n            it(\"should call the callback and return nothing\", function () {\n                var called = false;\n                var promise = Promise.resolve();\n\n                var returnValue = promise.done(function () {\n                    called = true;\n                });\n\n                return promise.lastly(function () {\n                    assert.equal(called,true);\n                    assert.equal(returnValue,undefined);\n                });\n            });\n        });\n\n        if (isNodeJS) {\n            describe(\"and the callback throws\", function () {\n                it(\"should rethrow that error in the next turn and return nothing\", function() {\n                    var turn = 0;\n                    process.nextTick(function () {\n                        ++turn;\n                    });\n\n                    var returnValue = Promise.resolve().done(\n                        function () {\n                            throw safeError;\n                        }\n                    );\n\n                    return testUtils.awaitProcessExit(function(e) {\n                        assert.equal(turn,1);\n                        assert.equal(returnValue,undefined);\n                    });\n                });\n            });\n        }\n    });\n\n\n    describe(\"when the promise is rejected\", function () {\n        describe(\"and the errback handles it\", function () {\n            it(\"should call the errback and return nothing\", function () {\n                var called = false;\n\n                var promise = Promise.reject(\"unsafe_error\");\n\n                var returnValue = promise.done(\n                    function () { },\n                    function () {\n                        called = true;\n                    }\n                );\n\n                return promise.caught(function(){}).lastly(function () {\n                    assert.equal(called,true);\n                    assert.equal(returnValue,undefined);\n                });\n            });\n        });\n\n        if (isNodeJS) {\n            describe(\"and the errback throws\", function () {\n                it(\"should rethrow that error in the next turn and return nothing\", function() {\n                    var turn = 0;\n                    process.nextTick(function () {\n                        ++turn;\n                    });\n\n                    var returnValue = Promise.reject(\"unsafe_error\").done(\n                        null,\n                        function () {\n                            throw safeError;\n                        }\n                    );\n                    return testUtils.awaitProcessExit(function(e) {\n                        assert.equal(turn,1);\n                        assert.equal(returnValue,undefined);\n                    });\n                });\n            });\n\n\n            describe(\"and there is no errback\", function () {\n                it(\"should throw the original error in the next turn\", function() {\n                    var turn = 0;\n                    process.nextTick(function () {\n                        ++turn;\n                    });\n\n                    var returnValue = Promise.reject(safeError).done();\n                    return testUtils.awaitProcessExit(function(e) {\n                        assert.equal(turn,1);\n                        assert.equal(returnValue,undefined);\n                    });\n                });\n            });\n        }\n    });\n});\n"
  },
  {
    "path": "test/mocha/each.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\nfunction promised(val) {\n    return new Promise(function(f) {\n        setTimeout(function() {\n            f(val);\n        }, 1);\n    });\n}\n\nfunction thenabled(val, arr) {\n    return {\n        then: function(f){\n            setTimeout(function() {\n                if (arr) arr.push(val);\n                f(val);\n            }, 1);\n        }\n    };\n}\n\ndescribe(\"Promise.each\", function() {\n\n    it(\"should return the array's values mapped\", function() {\n        var a = [promised(1), promised(2), promised(3)];\n        var b = [];\n        return Promise.resolve(a).mapSeries(function(val) {\n            b.push(3-val);\n            return val + 2;\n        }).then(function(ret) {\n            assert.deepEqual(ret, [3,4,5]);\n            assert.deepEqual(b, [2, 1, 0]);\n        });\n    });\n\n\n    it(\"takes value, index and length\", function() {\n        var a = [promised(1), promised(2), promised(3)];\n        var b = [];\n        return Promise.resolve(a).each(function(value, index, length) {\n            b.push(value, index, length);\n        }).then(function(ret) {\n            assert.deepEqual(b, [1, 0, 3, 2, 1, 3, 3, 2, 3]);\n        });\n    });\n\n    it(\"waits for returned promise before proceeding next\", function() {\n        var a = [promised(1), promised(2), promised(3)];\n        var b = [];\n        return Promise.resolve(a).each(function(value) {\n            b.push(value);\n            return Promise.delay(1).then(function(){\n                b.push(value*2);\n            });\n        }).then(function(ret) {\n            assert.deepEqual(b, [1,2,2,4,3,6]);\n        });\n    });\n\n    it(\"waits for returned thenable before proceeding next\", function() {\n        var b = [1, 2, 3];\n        var a = [thenabled(1), thenabled(2), thenabled(3)];\n        return Promise.resolve(a).each(function(val) {\n            b.push(val * 50);\n            return thenabled(val * 500, b);\n        }).then(function(ret) {\n            assert.deepEqual(b, [1, 2, 3, 50, 500, 100, 1000, 150, 1500]);\n        });\n    });\n\n    it(\"doesnt iterate with an empty array\", function() {\n        return Promise.each([], function(val) {\n            throw new Error();\n        }).then(function(ret) {\n            assert.deepEqual(ret, []);\n        });\n    });\n\n    it(\"iterates with an array of single item\", function() {\n        var b = [];\n        return Promise.each([promised(1)], function(val) {\n            b.push(val);\n            return thenabled(val*2, b);\n        }).then(function(ret) {\n            assert.deepEqual(b, [1,2]);\n        });\n    });\n});\n\ndescribe(\"Promise.prototype.each\", function() {\n\n    it(\"should return the array's values\", function() {\n        var a = [promised(1), promised(2), promised(3)];\n        var b = [];\n        return Promise.resolve(a).each(function(val) {\n            b.push(3-val);\n            return val;\n        }).then(function(ret) {\n            assert.deepEqual(ret, [1,2,3]);\n            assert.deepEqual(b, [2, 1, 0]);\n        });\n    });\n\n\n    it(\"takes value, index and length\", function() {\n        var a = [promised(1), promised(2), promised(3)];\n        var b = [];\n        return Promise.resolve(a).each(function(value, index, length) {\n            b.push(value, index, length);\n        }).then(function(ret) {\n            assert.deepEqual(b, [1, 0, 3, 2, 1, 3, 3, 2, 3]);\n        });\n    });\n\n    it(\"waits for returned promise before proceeding next\", function() {\n        var a = [promised(1), promised(2), promised(3)];\n        var b = [];\n        return Promise.resolve(a).each(function(value) {\n            b.push(value);\n            return Promise.delay(1).then(function(){\n                b.push(value*2);\n            });\n        }).then(function(ret) {\n            assert.deepEqual(b, [1,2,2,4,3,6]);\n        });\n    });\n\n    it(\"waits for returned thenable before proceeding next\", function() {\n        var b = [1, 2, 3];\n        var a = [thenabled(1), thenabled(2), thenabled(3)];\n        return Promise.resolve(a).each(function(val) {\n            b.push(val * 50);\n            return thenabled(val * 500, b);\n        }).then(function(ret) {\n            assert.deepEqual(b, [1, 2, 3, 50, 500, 100, 1000, 150, 1500]);\n        });\n    });\n\n    it(\"doesnt iterate with an empty array\", function() {\n        return Promise.resolve([]).each(function(val) {\n            throw new Error();\n        }).then(function(ret) {\n            assert.deepEqual(ret, []);\n        });\n    });\n\n    it(\"iterates with an array of single item\", function() {\n        var b = [];\n        return Promise.resolve([promised(1)]).each(function(val) {\n            b.push(val);\n            return thenabled(val*2, b);\n        }).then(function(ret) {\n            assert.deepEqual(b, [1,2]);\n        });\n    });\n});\n\ndescribe(\"mapSeries and each\", function() {\n    it(\"is mixed\", function() {\n        return Promise.mapSeries([1, 2, 3], function(value) {\n            return value * 2;\n        }).then(function(result) {\n            assert.deepEqual(result, [2, 4, 6]);\n        }).then(function() {\n            return Promise.each([1, 2, 3], function(value) {\n                return value * 2;\n            }).then(function(result) {\n                assert.deepEqual(result, [1, 2, 3]);\n            });\n        }).thenReturn([1, 2, 3]).mapSeries(function(value) {\n            return value * 2;\n        }).then(function(result) {\n            assert.deepEqual(result, [2, 4, 6]);\n        }).thenReturn([1, 2, 3]).each(function(value) {\n            return value * 2;\n        }).then(function(result) {\n            assert.deepEqual(result, [1, 2, 3]);\n        });\n    })\n});\n"
  },
  {
    "path": "test/mocha/error.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\ndescribe(\"Promise.prototype.error\", function(){\n    describe(\"catches stuff originating from explicit rejections\", function() {\n        specify(\"using callback\", function() {\n            var e = new Promise.TypeError(\"sup\");\n            function callsback(a, b, c, fn) {\n                fn(e);\n            }\n            callsback = Promise.promisify(callsback);\n\n            return callsback(1, 2, 3).error(function(err) {\n                assert(err === e);\n            });\n        });\n    });\n\n    describe(\"does not catch stuff originating from thrown errors\", function() {\n        specify(\"using constructor\", function() {\n            var e = new Error(\"sup\");\n            return new Promise(function(resolve, reject) {\n                throw e;\n            }).error(function(err) {\n                assert.fail();\n            }).then(assert.fail, function(err){\n                assert(err === e);\n            });\n        });\n        specify(\"using thenable\", function() {\n            var e = new Error(\"sup\");\n            var thenable = {\n                then: function(resolve, reject){\n                    reject(e);\n                }\n            };\n            return Promise.cast(thenable).error(function(err) {\n                console.error(err);\n                assert.fail();\n            }).then(assert.fail, function(err) {\n                assert(err === e);\n            });\n        });\n        specify(\"using callback\", function() {\n            var e = new Error(\"sup\");\n            function callsback(a, b, c, fn) {\n                throw e;\n            }\n            callsback = Promise.promisify(callsback);\n\n            return callsback(1, 2, 3).error(function(err) {\n                assert.fail();\n            }).then(assert.fail, function(err){\n                assert(err === e);\n            });\n        });\n    });\n})\n\nif (testUtils.ecmaScript5) {\n    describe(\"Weird errors\", function() {\n        specify(\"unwritable stack\", function() {\n            var e = new Error();\n            var stack = e.stack;\n            Object.defineProperty(e, \"stack\", {\n                configurable: true,\n                get: function() {return stack;},\n                set: function() {throw new Error(\"cannot set\");}\n            });\n            return new Promise(function(_, reject) {\n                setTimeout(function() {\n                    reject(e);\n                }, 1);\n            }).caught(function(err) {\n                assert.equal(e, err);\n            });\n        });\n    });\n}\n\ndescribe(\"Error constructors\", function() {\n    describe(\"OperationalError\", function() {\n        it(\"should work without new\", function() {\n            var a = Promise.OperationalError(\"msg\");\n            assert.strictEqual(a.message, \"msg\");\n            assert(a instanceof Error);\n        });\n\n        it(\"should work with new\", function() {\n            var a = new Promise.OperationalError(\"msg\");\n            assert.strictEqual(a.message, \"msg\");\n            assert(a instanceof Error);\n        });\n\n        it(\"should retain custom properties\", function() {\n            var message;\n            var name;\n            function f(cb) {\n                var err = new Error(\"custom message\");\n                message = err.message;\n                name = err.name;\n                err.code = \"ENOENT\";\n                err.path = \"C:\\\\\";\n                cb(err);\n            }\n            return Promise.promisify(f)().error(function(e) {\n                assert.strictEqual(e.message, message);\n                assert.strictEqual(e.name, name);\n                assert(e instanceof Promise.OperationalError);\n                assert.strictEqual(e.code, \"ENOENT\");\n                assert.strictEqual(e.path, \"C:\\\\\");\n            });\n        });\n    });\n\n    describe(\"CancellationError\", function() {\n        it(\"should work without new\", function() {\n            var a = Promise.CancellationError(\"msg\");\n            assert.strictEqual(a.message, \"msg\");\n            assert(a instanceof Error);\n        });\n\n        it(\"should work with new\", function() {\n            var a = new Promise.CancellationError(\"msg\");\n            assert.strictEqual(a.message, \"msg\");\n            assert(a instanceof Error);\n        });\n    });\n\n    describe(\"TimeoutError\", function() {\n        it(\"should work without new\", function() {\n            var a = Promise.TimeoutError(\"msg\");\n            assert.strictEqual(a.message, \"msg\");\n            assert(a instanceof Error);\n        });\n\n        it(\"should work with new\", function() {\n            var a = new Promise.TimeoutError(\"msg\");\n            assert.strictEqual(a.message, \"msg\");\n            assert(a instanceof Error);\n        });\n    });\n\n    describe(\"AggregateError\", function() {\n        it(\"should work without new\", function() {\n            var a = Promise.AggregateError(\"msg\");\n            assert.strictEqual(a.message, \"msg\");\n            assert(a instanceof Error);\n        });\n\n        it(\"should work with new\", function() {\n            var a = new Promise.AggregateError(\"msg\");\n            assert.strictEqual(a.message, \"msg\");\n            assert(a instanceof Error);\n        });\n\n        if (testUtils.isNodeJS) {\n            it(\"should stringify without circular errors\", function() {\n                var a = Promise.AggregateError();\n                a.push(new Error(\"1\"));\n                a.push(new Error(\"2\"));\n                a.push(new Error(\"3\"));\n                a = a.toString();\n                assert(a.indexOf(\"Error: 1\") >= 0);\n                assert(a.indexOf(\"Error: 2\") >= 0);\n                assert(a.indexOf(\"Error: 3\") >= 0);\n            });\n\n            it(\"should stringify with circular errors\", function() {\n                var a = Promise.AggregateError();\n                a.push(new Error(\"1\"));\n                a.push(a);\n                a.push(new Error(\"3\"));\n                a = a.toString();\n                assert(a.indexOf(\"Error: 1\") >= 0);\n                assert(a.indexOf(\"[Circular AggregateError]\") >= 0);\n                assert(a.indexOf(\"Error: 3\") >= 0);\n            });\n        }\n    });\n\n\n});\n"
  },
  {
    "path": "test/mocha/filter.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\n\ndescribe(\"Promise filter\", function() {\n\n    function ThrownError() {}\n\n\n    var arr = [1,2,3];\n\n    function assertArr(arr) {\n        assert(arr.length === 2);\n        assert(arr[0] === 1);\n        assert(arr[1] === 3);\n    }\n\n    function assertErr(e) {\n        assert(e instanceof ThrownError);\n    }\n\n    function assertFail() {\n        assert.fail();\n    }\n\n    describe(\"should accept eventual booleans\", function() {\n        specify(\"immediately fulfilled\", function() {\n            return Promise.filter(arr, function(v) {\n                return new Promise(function(r){\n                    r(v !== 2);\n                });\n            }).then(assertArr);\n        });\n\n        specify(\"already fulfilled\", function() {\n            return Promise.filter(arr, function(v) {\n                return Promise.resolve(v !== 2);\n            }).then(assertArr);\n        });\n\n        specify(\"eventually fulfilled\", function() {\n            return Promise.filter(arr, function(v) {\n                return new Promise(function(r){\n                    setTimeout(function(){\n                        r(v !== 2);\n                    }, 1);\n                });\n            }).then(assertArr);\n        });\n\n        specify(\"immediately rejected\", function() {\n            return Promise.filter(arr, function(v) {\n                return new Promise(function(v, r){\n                    r(new ThrownError());\n                });\n            }).then(assertFail, assertErr);\n        });\n        specify(\"already rejected\", function() {\n            return Promise.filter(arr, function(v) {\n                return Promise.reject(new ThrownError());\n            }).then(assertFail, assertErr);\n        });\n        specify(\"eventually rejected\", function() {\n            return Promise.filter(arr, function(v) {\n                return new Promise(function(v, r){\n                    setTimeout(function(){\n                        r(new ThrownError());\n                    }, 1);\n                });\n            }).then(assertFail, assertErr);\n        });\n\n\n        specify(\"immediately fulfilled thenable\", function() {\n            return Promise.filter(arr, function(v) {\n                return {\n                    then: function(f, r) {\n                        f(v !== 2);\n                    }\n                };\n            }).then(assertArr);\n        });\n        specify(\"eventually fulfilled thenable\", function() {\n            return Promise.filter(arr, function(v) {\n                return {\n                    then: function(f, r) {\n                        setTimeout(function(){\n                            f(v !== 2);\n                        }, 1);\n                    }\n                };\n            }).then(assertArr);\n        });\n\n        specify(\"immediately rejected thenable\", function() {\n            return Promise.filter(arr, function(v) {\n                return {\n                    then: function(f, r) {\n                        r(new ThrownError());\n                    }\n                };\n            }).then(assertFail, assertErr);\n        });\n        specify(\"eventually rejected thenable\", function() {\n            return Promise.filter(arr, function(v) {\n                return {\n                    then: function(f, r) {\n                        setTimeout(function(){\n                            r(new ThrownError());\n                        }, 1);\n                    }\n                };\n            }).then(assertFail, assertErr);\n        });\n\n    });\n});\n"
  },
  {
    "path": "test/mocha/finally.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n/*!\n *\nCopyright 2009–2012 Kristopher Michael Kowal. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\n\ndescribe(\"finally\", function () {\n\n    var exception1 = new Error(\"boo!\");\n    var exception2 = new Promise.TypeError(\"evil!\");\n\n    describe(\"when nothing is passed\", function() {\n        it(\"should do nothing\", function() {\n            return Promise.resolve(\"foo\")\n                .lastly()\n                .lastly()\n                .lastly()\n                .lastly()\n                .then(function(val){\n                    assert(val === \"foo\");\n                })\n        });\n    });\n\n    describe(\"when the promise is fulfilled\", function () {\n\n        it(\"should call the callback\", function() {\n            var called = false;\n\n            return Promise.resolve(\"foo\")\n            .lastly(function () {\n                called = true;\n            })\n            .then(function () {\n                assert.equal(called,true);\n            });\n        });\n\n        it(\"should fulfill with the original value\", function() {\n            return Promise.resolve(\"foo\")\n            .lastly(function () {\n                return \"bar\";\n            })\n            .then(function (result) {\n                assert.equal(result,\"foo\");\n            });\n        });\n\n        describe(\"when the callback returns a promise\", function () {\n\n            describe(\"that is fulfilled\", function () {\n                it(\"should fulfill with the original reason after that promise resolves\", function() {\n                    var promise = Promise.delay(1);\n\n                    return Promise.resolve(\"foo\")\n                    .lastly(function () {\n                        return promise;\n                    })\n                    .then(function (result) {\n                        assert.equal(promise.isPending(),false);\n                        assert.equal(result,\"foo\");\n                    });\n                });\n            });\n\n            describe(\"that is rejected\", function () {\n                it(\"should reject with this new rejection reason\", function() {\n                    return Promise.resolve(\"foo\")\n                    .lastly(function () {\n                        return Promise.reject(exception1);\n                    })\n                    .then(function () {\n                        assert.equal(false,true);\n                    },\n                    function (exception) {\n                        assert.equal(exception,exception1);\n                    });\n                });\n            });\n\n        });\n\n        describe(\"when the callback throws an exception\", function () {\n            it(\"should reject with this new exception\", function() {\n                return Promise.resolve(\"foo\")\n                .lastly(function () {\n                    throw exception1;\n                })\n                .then(function () {\n                    assert.equal(false,true);\n                },\n                function (exception) {\n                    assert.equal(exception,exception1);\n                });\n            });\n        });\n\n    });\n\n    describe(\"when the promise is rejected\", function () {\n\n        it(\"should call the callback\", function() {\n            var called = false;\n\n            return Promise.reject(exception1)\n            .lastly(function () {\n                called = true;\n            })\n            .then(function () {\n                assert.fail();\n            }, function () {\n                assert.equal(called,true);\n            });\n        });\n\n        it(\"should reject with the original reason\", function() {\n            return Promise.reject(exception1)\n            .lastly(function () {\n                return \"bar\";\n            })\n            .then(function () {\n                assert.equal(false,true);\n            },\n            function (exception) {\n                assert.equal(exception,exception1);\n            });\n        });\n\n        describe(\"when the callback returns a promise\", function () {\n\n            describe(\"that is fulfilled\", function () {\n                it(\"should reject with the original reason after that promise resolves\", function() {\n                    var promise = Promise.delay(1);\n\n                    return Promise.reject(exception1)\n                    .lastly(function () {\n                        return promise;\n                    })\n                    .then(function () {\n                        assert.equal(false,true);\n                    },\n                    function (exception) {\n                        assert.equal(exception,exception1);\n                        assert.equal(promise.isPending(),false);\n                    });\n                });\n            });\n\n            describe(\"that is rejected\", function () {\n                it(\"should reject with the new reason\", function() {\n                    return Promise.reject(exception1)\n                    .lastly(function () {\n                        return Promise.reject(exception2);\n                    })\n                    .then(function () {\n                        assert.equal(false,true);\n                    },\n                    function (exception) {\n                        assert.equal(exception,exception2);\n                    });\n                });\n            });\n\n        });\n\n        describe(\"when the callback throws an exception\", function () {\n            it(\"should reject with this new exception\", function() {\n                return Promise.reject(exception1)\n                .lastly(function () {\n                    throw exception2;\n                })\n                .then(function () {\n                    assert.equal(false,true);\n                },\n                function (exception) {\n                    assert.equal(exception,exception2);\n                });\n            });\n        });\n\n    });\n\n    describe(\"when the callback returns a thenable\", function () {\n\n        describe(\"that will fulfill\", function () {\n            it(\"should reject with the original reason after that\", function() {\n                var promise = {\n                    then: function(fn) {\n                        setTimeout(function(){\n                            fn(15);\n                        }, 1);\n                    }\n                };\n\n                return Promise.reject(exception1)\n                .lastly(function () {\n                    return promise;\n                })\n                .then(function () {\n                    assert.equal(false,true);\n                },\n                function (exception) {\n                    assert.equal(exception,exception1);\n                });\n            });\n        });\n\n        describe(\"that is rejected\", function () {\n            it(\"should reject with the new reason\", function() {\n                var promise = {\n                    then: function(f, fn) {\n                        setTimeout(function(){\n                            fn(exception2);\n                        }, 1);\n                    }\n                };\n\n                return Promise.reject(exception1)\n                .lastly(function () {\n                    return promise;\n                })\n                .then(function () {\n                    assert.equal(false,true);\n                },\n                function (exception) {\n                    assert.equal(exception,exception2);\n                });\n            });\n            it(\"should reject with the new primitive reason\", function() {\n                var primitive = 3;\n                var promise = {\n                    then: function(f, fn) {\n                        setTimeout(function(){\n                            fn(primitive);\n                        }, 1);\n                    }\n                };\n\n                return Promise.reject(exception1)\n                .lastly(function () {\n                    return promise;\n                })\n                .then(function () {\n                    assert.equal(false,true);\n                },\n                function (exception) {\n                    assert.strictEqual(exception, primitive);\n                });\n            });\n        });\n\n\n\n    });\n});\n"
  },
  {
    "path": "test/mocha/following.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\ndescribe(\"Using deferreds\", function() {\n    describe(\"a promise A that is following a promise B\", function() {\n        specify(\"Must not react to fulfill/reject/ that don't come from promise B\", function() {\n            var deferred = Promise.defer();\n            var promiseA = deferred.promise;\n            var promiseB = Promise.defer().promise;\n            var called = 0;\n            function incrementCalled() {\n                called++;\n            }\n\n            promiseA.then(\n                incrementCalled,\n                incrementCalled\n            );\n            deferred.fulfill(promiseB);\n\n            deferred.fulfill(1);\n            deferred.reject(1);\n            return Promise.delay(1).then(function() {\n                assert.equal(0, called);\n                assert.equal(promiseA.isPending(), true);\n                assert.equal(promiseB.isPending(), true);\n            });\n        });\n\n        specify(\"Must not start following another promise C\", function() {\n            var deferred = Promise.defer();\n            var promiseA = deferred.promise;\n            var promiseB = Promise.defer().promise;\n            var deferredC = Promise.defer();\n            var promiseC = deferredC.promise;\n            var called = 0;\n            function incrementCalled() {\n                called++;\n            }\n\n\n            promiseA.then(\n                incrementCalled,\n                incrementCalled\n            );\n            deferred.fulfill(promiseB);\n            deferred.fulfill(promiseC);\n\n            deferredC.fulfill(1);\n            deferredC.reject(1);\n\n            return promiseC.then(function() {\n                assert.equal(called, 0);\n                assert.equal(promiseA.isPending(), true);\n                assert.equal(promiseB.isPending(), true);\n                assert.equal(promiseC.isPending(), false);\n            });\n        });\n\n        specify(\"Must react to fulfill/reject that come from promise B\", function() {\n            var deferred = Promise.defer();\n            var promiseA = deferred.promise;\n            var deferredFollowee = Promise.defer();\n            var promiseB = deferredFollowee.promise;\n            var called = 0;\n            function incrementCalled() {\n                called++;\n            }\n            var c = 0;\n\n            var ret = promiseA.then(function(v){\n                c++;\n                assert.equal(c, 1);\n                assert.equal(called, 0);\n            }, incrementCalled);\n\n            deferred.fulfill(promiseB);\n\n\n            deferredFollowee.fulfill(1);\n            deferredFollowee.reject(1);\n            return ret;\n        });\n    });\n});\n\ndescribe(\"Using static immediate methods\", function() {\n    describe(\"a promise A that is following a promise B\", function() {\n        specify(\"Should be instantly fulfilled with Bs fulfillment value if B was fulfilled\", function() {\n            var val = {};\n            var B = Promise.resolve(val);\n            var A = Promise.resolve(B);\n            assert.equal(A.value(), val);\n            assert.equal(A.value(), B.value());\n        });\n\n        specify(\"Should be instantly fulfilled with Bs parent fulfillment value if B was fulfilled with a parent\", function() {\n            var val = {};\n            var parent = Promise.resolve(val);\n            var B = Promise.resolve(parent);\n            var A = Promise.resolve(B);\n            assert.equal(A.value(), val);\n            assert.equal(A.value(), B.value());\n            assert.equal(A.value(), parent.value());\n        });\n    });\n\n    describe(\"Rejecting a promise A with promise B\", function(){\n        specify(\"Should reject promise A with B as reason \", function() {\n            var val = {};\n            var B = Promise.resolve(val);\n            var A = Promise.reject(B);\n            assert.equal(A.reason(), B);\n            A.then(assert.fail, function(){});\n        });\n    });\n});\n\ndescribe(\"Using constructor\", function() {\n    describe(\"a promise A that is following a promise B\", function() {\n        specify(\"Must not react to fulfill/reject that don't come from promise B\", function() {\n            var resolveA;\n            var rejectA;\n            var promiseA = new Promise(function() {\n                resolveA = arguments[0];\n                rejectA = arguments[1];\n            });\n            var promiseB = new Promise(function(){});\n            var called = 0;\n            function incrementCalled() {\n                called++;\n            }\n\n            promiseA.then(\n                incrementCalled,\n                incrementCalled\n            );\n\n            resolveA(promiseB);\n            resolveA(1);\n            rejectA(1);\n            return Promise.delay(1).then(function() {\n                assert.equal(0, called);\n                assert.equal(promiseA.isPending(), true);\n                assert.equal(promiseB.isPending(), true);\n            });\n        });\n\n        specify(\"Must not start following another promise C\", function() {\n            var resolveA;\n            var promiseA = new Promise(function(){\n                resolveA = arguments[0];\n            });\n            var promiseB = new Promise(function(){});\n            var resolveC, rejectC;\n            var promiseC = new Promise(function(){\n                resolveC = arguments[0];\n                rejectC = arguments[1];\n            });\n            var called = 0;\n            function incrementCalled() {\n                called++;\n            }\n\n            promiseA.then(\n                incrementCalled,\n                incrementCalled,\n                incrementCalled\n            );\n            resolveA(promiseB);\n            resolveA(promiseC);\n            resolveC(1);\n            rejectC(1);\n            return promiseC.then(function() {\n                assert.equal(called, 0);\n                assert.equal(promiseA.isPending(), true);\n                assert.equal(promiseB.isPending(), true);\n                assert.equal(promiseC.isPending(), false);\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/generator.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar assertLongTrace = require(\"./helpers/assert_long_trace.js\");\nvar awaitLateQueue = testUtils.awaitLateQueue;\n\nfunction get(arg) {\n    return {\n        then: function(ful, rej) {\n            ful(arg)\n        }\n    }\n}\n\nfunction fail(arg) {\n    return {\n        then: function(ful, rej) {\n            rej(arg)\n        }\n    };\n}\n\nPromise.coroutine.addYieldHandler(function(yieldedValue) {\n    if (Array.isArray(yieldedValue)) return Promise.all(yieldedValue);\n});\n\nvar error = new Error(\"asd\");\n\ndescribe(\"yielding\", function() {\n\n    specify(\"non-promise should throw\", function() {\n        return Promise.coroutine(function*(){\n\n            var a = yield {};\n            assert.fail();\n            return 4;\n\n        })().then(assert.fail).caught(function(e){\n            assert(e instanceof TypeError);\n        });\n    });\n\n    specify(\"an array should implicitly Promise.all them\", function() {\n        var a = Promise.defer();\n        var ap = a.promise;\n        var b = Promise.defer();\n        var bp = b.promise;\n        var c = Promise.defer();\n        var cp = c.promise;\n\n\n        setTimeout(function(){\n            a.fulfill(1);\n            b.fulfill(2);\n            c.fulfill(3);\n        }, 1);\n        return Promise.coroutine(function*(){\n            return yield [ap, bp, cp];\n        })().then(function(r) {\n            //.spread will also implicitly use .all() so that cannot be used here\n            var a = r[0]; var b = r[1]; var c = r[2];\n            assert(a === 1);\n            assert(b === 2);\n            assert(c === 3);\n        });\n    });\n\n    specify(\"non-promise should throw but be catchable\", function() {\n\n        return Promise.coroutine(function*(){\n            try {\n                var a = yield {};\n                assert.fail();\n            }\n            catch (e){\n                assert(e instanceof TypeError);\n                return 4;\n            }\n\n        })().then(function(val){\n            assert.equal(val, 4);\n        });\n    });\n\n    specify(\"yielding a function should not call the function\", function() {\n        let functionWasCalled = false;\n        return Promise.coroutine(function*(){\n            try {\n                yield (function() {functionWasCalled = true;});\n            } \n            catch(e){\n                assert(e instanceof TypeError);\n                assert.equal(functionWasCalled, false);\n                return 4;\n            }\n        })().then(function(val){\n            assert.equal(val, 4);\n        });\n    });\n});\n\ndescribe(\"thenables\", function(){\n\n    specify(\"when they fulfill, the yielded value should be that fulfilled value\", function(){\n\n        return Promise.coroutine(function*(){\n\n            var a = yield get(3);\n            assert.equal(a, 3);\n            return 4;\n\n        })().then(function(arg){\n            assert.equal(arg, 4);\n        });\n\n    });\n\n\n    specify(\"when they reject, and the generator doesn't have try.caught, it should immediately reject the promise\", function(){\n\n        return Promise.coroutine(function*(){\n            var a = yield fail(error);\n            assert.fail();\n\n        })().then(assert.fail).then(assert.fail, function(e){\n            assert.equal(e, error);\n        });\n\n    });\n\n    specify(\"when they reject, and the generator has try.caught, it should continue working normally\", function(){\n\n        return Promise.coroutine(function*(){\n            try {\n                var a = yield fail(error);\n            }\n            catch (e) {\n                return e;\n            }\n            assert.fail();\n\n        })().then(function(v){\n            assert.equal(v, error);\n        });\n\n    });\n\n    specify(\"when they fulfill but then throw, it should become rejection\", function(){\n\n        return Promise.coroutine(function*(){\n            var a = yield get(3);\n            assert.equal(a, 3);\n            throw error;\n        })().then(assert.fail, function(e){\n            assert.equal(e, error);\n        });\n    });\n});\n\ndescribe(\"yield loop\", function(){\n\n    specify(\"should work\", function(){\n        return Promise.coroutine(function* () {\n            var a = [1,2,3,4,5];\n\n            for (var i = 0, len = a.length; i < len; ++i) {\n                a[i] = yield get(a[i] * 2);\n            }\n\n            return a;\n        })().then(function(arr){\n            assert.deepEqual([2,4,6,8,10], arr);\n        });\n    });\n\n    specify(\"inside yield should work\", function(){\n        return Promise.coroutine(function *() {\n            var a = [1,2,3,4,5];\n\n            return yield Promise.all(a.map(function(v){\n                return Promise.coroutine(function *() {\n                    return yield get(v*2);\n                })();\n            }));\n        })().then(function(arr){\n            assert.deepEqual([2,4,6,8,10], arr);\n        });\n    });\n\n    specify(\"with simple map should work\", function(){\n        return Promise.coroutine(function *() {\n            var a = [1,2,3,4,5];\n\n            return yield Promise.map(a, function(v){\n                return Promise.cast(get(v*2));\n            });\n        })().then(function(arr){\n            assert.deepEqual([2,4,6,8,10], arr);\n        });\n    });\n\n});\n\n\ndescribe(\"Promise.coroutine\", function() {\n    describe(\"thenables\", function() {\n        specify(\"when they fulfill, the yielded value should be that fulfilled value\", function(){\n\n            return Promise.coroutine(function*(){\n\n                var a = yield get(3);\n                assert.equal(a, 3);\n                return 4;\n\n            })().then(function(arg){\n                assert.equal(arg, 4);\n            });\n\n        });\n\n\n        specify(\"when they reject, and the generator doesn't have try.caught, it should immediately reject the promise\", function(){\n\n            return Promise.coroutine(function*(){\n                var a = yield fail(error);\n                assert.fail();\n\n            })().then(assert.fail).then(assert.fail, function(e){\n                assert.equal(e, error);\n            });\n\n        });\n\n        specify(\"when they reject, and the generator has try.caught, it should continue working normally\", function(){\n\n            return Promise.coroutine(function*(){\n                try {\n                    var a = yield fail(error);\n                }\n                catch (e) {\n                    return e;\n                }\n                assert.fail();\n\n            })().then(function(v){\n                assert.equal(v, error);\n            });\n\n        });\n\n        specify(\"when they fulfill but then throw, it should become rejection\", function(){\n\n            return Promise.coroutine(function*(){\n                var a = yield get(3);\n                assert.equal(a, 3);\n                throw error;\n            })().then(assert.fail).then(assert.fail, function(e){\n                assert.equal(e, error);\n            });\n        });\n\n        specify(\"when they are already fulfilled, the yielded value should be returned asynchronously\", function(){\n            var value;\n\n            var promise = Promise.coroutine(function*(){\n                yield Promise.resolve();\n                value = 2;\n            })();\n\n            value = 1;\n\n            return promise.then(function(){\n                assert.equal(value, 2);\n            });\n        });\n\n        specify(\"when they are already rejected, the yielded reason should be thrown asynchronously\", function(){\n            var value;\n\n            var promise = Promise.coroutine(function*(){\n                try {\n                    yield Promise.reject();\n                }\n                catch (e) {\n                    value = 2;\n                }\n            })();\n\n            value = 1;\n\n            return promise.then(function(){\n                assert.equal(value, 2);\n            });\n        });\n    });\n\n    describe(\"yield loop\", function(){\n\n        specify(\"should work\", function(){\n            return Promise.coroutine(function* () {\n                var a = [1,2,3,4,5];\n\n                for (var i = 0, len = a.length; i < len; ++i) {\n                    a[i] = yield get(a[i] * 2);\n                }\n\n                return a;\n            })().then(function(arr){\n                assert.deepEqual([2,4,6,8,10], arr);\n            });\n        });\n\n        specify(\"inside yield should work\", function(){\n            return Promise.coroutine(function *() {\n                var a = [1,2,3,4,5];\n\n                return yield Promise.all(a.map(function(v){\n                    return Promise.coroutine(function *() {\n                        return yield get(v*2);\n                    })();\n                }));\n            })().then(function(arr){\n                assert.deepEqual([2,4,6,8,10], arr);\n            });\n        });\n\n        specify(\"with simple map should work\", function(){\n            return Promise.coroutine(function *() {\n                var a = [1,2,3,4,5];\n\n                return yield Promise.map(a, function(v){\n                    return Promise.cast(get(v*2));\n                });\n            })().then(function(arr){\n                assert.deepEqual([2,4,6,8,10], arr);\n            });\n        });\n\n    });\n\n    describe(\"when using coroutine as a method\", function(){\n\n        function MyClass() {\n            this.goblins = 3;\n        }\n\n        MyClass.prototype.spawnGoblins = Promise.coroutine(function* () {\n            this.goblins = yield get(this.goblins+1);\n        });\n\n\n        specify(\"generator function's receiver should be the instance too\", function() {\n            var a = new MyClass();\n            var b = new MyClass();\n\n            return Promise.join(a.spawnGoblins().then(function(){\n                return a.spawnGoblins()\n            }), b.spawnGoblins()).then(function(){\n                assert.equal(a.goblins, 5);\n                assert.equal(b.goblins, 4);\n            });\n\n        });\n    });\n});\n\ndescribe(\"Spawn\", function() {\n    it(\"should work\", function() {\n        return Promise.spawn(function*() {\n            return yield Promise.resolve(1);\n        }).then(function(value) {\n            assert.strictEqual(value, 1);\n        });\n    });\n    it(\"should return rejected promise when passed non function\", function() {\n        return Promise.spawn({}).then(assert.fail, function(err) {\n            assert(err instanceof Promise.TypeError);\n        });\n    });\n});\n\ndescribe(\"custom yield handlers\", function() {\n    specify(\"should work with timers\", function() {\n        var n = 0;\n        Promise.coroutine.addYieldHandler(function(v) {\n            if (typeof v === \"number\") {\n                n = 1;\n                return Promise.resolve(n);\n            }\n        });\n\n\n        return Promise.coroutine(function*() {\n            return yield 50;\n        })().then(function(value) {\n            assert.equal(value, 1);\n            assert.equal(n, 1);\n        });\n    });\n\n    var _ = (function() {\n        var promise = null;\n        Promise.coroutine.addYieldHandler(function(v) {\n            if (v === void 0 && promise != null) {\n                return promise;\n            }\n            promise = null;\n        });\n        return function() {\n          var cb;\n          promise = Promise.fromNode(function(callback) {\n            cb = callback;\n          });\n          return cb;\n        };\n    })();\n\n    specify(\"Should work with callbacks\", function(){\n        var callbackApiFunction = function(a, b, c, cb) {\n            setTimeout(function(){\n                cb(null, [a, b, c]);\n            }, 1);\n        };\n\n        return Promise.coroutine(function*() {\n            return yield callbackApiFunction(1, 2, 3, _());\n        })().then(function(result) {\n            assert(result.length === 3);\n            assert(result[0] === 1);\n            assert(result[1] === 2);\n            assert(result[2] === 3);\n        });\n    });\n\n    specify(\"should work with thunks\", function(){\n        Promise.coroutine.addYieldHandler(function(v) {\n            if (typeof v === \"function\") {\n                var cb;\n                var promise = Promise.fromNode(function(callback) {\n                    cb = callback;\n                });\n                try { v(cb); } catch (e) { cb(e); }\n                return promise;\n            }\n        });\n\n        var thunk = function(a) {\n            return function(callback) {\n                setTimeout(function(){\n                    callback(null, a*a);\n                }, 1);\n            };\n        };\n\n        return Promise.coroutine(function*() {\n            return yield thunk(4);\n        })().then(function(result) {\n            assert(result === 16);\n        });\n    });\n\n    specify(\"individual yield handler\", function() {\n        var dummy = {};\n        var yieldHandler = function(value) {\n            if (value === dummy) return Promise.resolve(3);\n        };\n        var coro = Promise.coroutine(function* () {\n            return yield dummy;\n        }, {yieldHandler: yieldHandler});\n\n        return coro().then(function(result) {\n            assert(result === 3);\n        });\n    });\n\n    specify(\"yield handler that throws\", function() {\n        var dummy = {};\n        var unreached = false;\n        var err = new Error();\n        var yieldHandler = function(value) {\n            if (value === dummy) throw err;\n        };\n\n        var coro = Promise.coroutine(function* () {\n            yield dummy;\n            unreached = true;\n        }, {yieldHandler: yieldHandler});\n\n        return coro().then(assert.fail, function(e) {\n            assert.strictEqual(e, err);\n            assert(!unreached);\n        });\n    });\n\n    specify(\"yield handler is not a function\", function() {\n        try {\n            Promise.coroutine.addYieldHandler({});\n        } catch (e) {\n            assert(e instanceof Promise.TypeError);\n            return;\n        }\n        assert.fail();\n    });\n});\n\nif (Promise.hasLongStackTraces()) {\n    describe(\"Long stack traces with coroutines as context\", function() {\n        it(\"1 level\", function() {\n            return Promise.coroutine(function* () {\n                yield Promise.delay(10);\n                throw new Error();\n            })().then(assert.fail, function(e) {\n                assertLongTrace(e, 1+1, [2]);\n            });\n        });\n        it(\"4 levels\", function() {\n            var secondLevel = Promise.coroutine(function* () {\n                yield thirdLevel();\n            });\n            var thirdLevel = Promise.coroutine(function* () {\n                yield fourthLevel();\n            });\n            var fourthLevel = Promise.coroutine(function* () {\n                throw new Error();\n            });\n\n            return Promise.coroutine(function* () {\n                yield secondLevel();\n            })().then(assert.fail, function(e) {\n                assertLongTrace(e, 4+1, [2, 2, 2, 2]);\n            });\n        });\n    });\n}\n\ndescribe(\"Cancellation with generators\", function() {\n    specify(\"input immediately cancelled\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var unreached = 0;\n\n        var p = new Promise(function(_, __, onCancel) {});\n        p.cancel();\n\n        var asyncFunction = Promise.coroutine(function* () {\n            try {\n                yield p;\n                unreached++;\n            } catch(e) {\n                if (e === Promise.coroutine.returnSentinel) throw e;\n                unreached++;\n            } finally {\n                yield Promise.resolve();\n                finalled++;\n            }\n            unreached++;\n        });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n\n        asyncFunction()\n            .then(reject, function(e) {\n                if(!(e instanceof Promise.CancellationError)) reject(new Error());\n            })\n            .lastly(function() {\n                finalled++;\n                resolve();\n            });\n\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(2, finalled);\n                assert.equal(0, cancelled);\n                assert.equal(0, unreached);\n            });\n        });\n    });\n\n    specify(\"input eventually cancelled\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var unreached = 0;\n\n        var p = new Promise(function(_, __, onCancel) {});\n        var asyncFunction = Promise.coroutine(function* () {\n            try {\n                yield p;\n                unreached++;\n            } catch(e) {\n                if (e === Promise.coroutine.returnSentinel) throw e;\n                unreached++;\n            } finally {\n                yield Promise.resolve();\n                finalled++;\n            }\n            unreached++;\n        });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n\n        asyncFunction()\n            .then(reject, reject)\n            .lastly(function() {\n                finalled++;\n                resolve();\n            });\n\n        Promise.delay(1).then(function() {\n            p.cancel();\n        });\n\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(2, finalled);\n                assert.equal(0, cancelled);\n                assert.equal(0, unreached);\n            });\n        });\n    });\n\n    specify(\"output immediately cancelled\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var unreached = 0;\n\n        var p = new Promise(function(_, __, onCancel) {\n            onCancel(function() {\n                cancelled++;\n            });\n        }).lastly(function() {\n            finalled++;\n        });\n\n        var asyncFunction = Promise.coroutine(function* () {\n            try {\n                yield p;\n                unreached++;\n            } catch(e) {\n                if (e === Promise.coroutine.returnSentinel) throw e;\n                unreached++;\n            } finally {\n                yield Promise.resolve()\n                finalled++;\n            }\n            unreached++;\n        });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n\n        var output = asyncFunction()\n            .then(reject, reject)\n            .lastly(function() {\n                finalled++;\n                resolve();\n            });\n\n        output.cancel();\n\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(3, finalled);\n                assert.equal(1, cancelled);\n                assert.equal(0, unreached);\n            });\n        });\n    });\n\n    specify(\"output eventually cancelled\", function() {\n        var cancelled = 0;\n        var finalled = 0;\n        var unreached = 0;\n\n        var p = new Promise(function(_, __, onCancel) {\n            onCancel(function() {\n                cancelled++;\n            });\n        }).lastly(function() {\n            finalled++;\n        });\n\n        var asyncFunction = Promise.coroutine(function* () {\n            try {\n                yield p;\n                unreached++;\n            } catch(e) {\n                if (e === Promise.coroutine.returnSentinel) throw e;\n                unreached++;\n            } finally {\n                yield Promise.resolve()\n                finalled++;\n            }\n            unreached++;\n        });\n\n        var resolve, reject;\n        var result = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n\n        var output = asyncFunction()\n            .then(reject, reject)\n            .lastly(function() {\n                finalled++;\n                resolve();\n            });\n\n        Promise.delay(1).then(function() {\n            output.cancel();\n        });\n\n        return result.then(function() {\n            return awaitLateQueue(function() {\n                assert.equal(3, finalled);\n                assert.equal(1, cancelled);\n                assert.equal(0, unreached);\n            });\n        });\n    });\n\n\n    specify(\"finally block runs before finally handler\", function(done) {\n        var finallyBlockCalled = false;\n        var asyncFn = Promise.coroutine(function* () {\n            try {\n                yield Promise.delay(100);\n            } finally {\n                yield Promise.delay(100);\n                finallyBlockCalled = true;\n            }\n        });\n        var p = asyncFn();\n        Promise.resolve().then(function() {\n            p.cancel();\n        });\n        p.finally(function() {\n            assert.ok(finallyBlockCalled, \"finally block should have been called before finally handler\");\n            done();\n        }).catch(done);\n    });\n});\n"
  },
  {
    "path": "test/mocha/get.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar join = Promise.join;\n\ndescribe(\"indexed getter\", function() {\n    var p = Promise.resolve([0, 1, 2, 3, 4, 5, 7, 5,10]);\n    specify(\"gets positive index\", function() {\n        var first = p.get(0);\n        var fourth = p.get(3);\n        var last = p.get(8);\n\n        return join(first, fourth, last, function(a, b, c) {\n            assert(a === 0);\n            assert(b === 3);\n            assert(c === 10);\n        });\n    });\n\n    specify(\"gets negative index\", function() {\n        var last = p.get(-1);\n        var first = p.get(-20);\n\n        return join(last, first, function(a, b) {\n            assert.equal(a, 10);\n            assert.equal(b, 0);\n        });\n    });\n});\n\ndescribe(\"identifier getter\", function() {\n    var p = Promise.resolve(new RegExp(\"\", \"\"));\n    specify(\"gets property\", function() {\n        var ci = p.get(\"ignoreCase\");\n        var g = p.get(\"global\");\n        var lastIndex = p.get(\"lastIndex\");\n        var multiline = p.get(\"multiline\");\n\n        return join(ci, g, lastIndex, multiline, function(ci, g, lastIndex, multiline) {\n            assert(ci === false);\n            assert(g === false);\n            assert(lastIndex === 0);\n            assert(multiline === false);\n        });\n    });\n\n    specify(\"gets same property\", function() {\n        var o = {o: 1};\n        var o2 = {o: 2};\n        o = Promise.resolve(o).get(\"o\");\n        o2 = Promise.resolve(o2).get(\"o\");\n        return join(o, o2, function(one, two) {\n            assert.strictEqual(1, one);\n            assert.strictEqual(2, two);\n        });\n    });\n});\n\ndescribe(\"non identifier getters\", function() {\n    var p = Promise.resolve({\"-\": \"val\"});\n    specify(\"get property\", function() {\n        return p.get(\"-\").then(function(val) {\n            assert(val === \"val\");\n        });\n    });\n\n    specify.skip(\"overflow cache\", function() {\n        var a = new Array(1024);\n        var o = {};\n        for (var i = 0; i < a.length; ++i) {\n            a[i] = \"get\" + i;\n            o[\"get\" + i] = i*2;\n        }\n        var b = Promise.map(a, function(item, index) {\n            return Promise.resolve(o).get(a[index]);\n        }).filter(function(value, index) {\n            return value === index * 2;\n        }).then(function(values) {\n            assert.strictEqual(values.length, a.length);\n        });\n        return b;\n    });\n});\n"
  },
  {
    "path": "test/mocha/getNewLibraryCopy.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\ndescribe(\"Promise.getNewLibraryCopy\", function() {\n    it(\"should return an independent copy of Bluebird library\", function() {\n        var Promise2 = Promise.getNewLibraryCopy();\n        Promise2.x = 123;\n\n        assert.equal(typeof Promise2.prototype.then, \"function\");\n        assert.notEqual(Promise2, Promise);\n\n        assert.equal(Promise2.x, 123);\n        assert.notEqual(Promise.x, 123);\n    });\n    it(\"should return copy of Bluebird library with its own getNewLibraryCopy method\", function() {\n        var Promise2 = Promise.getNewLibraryCopy();\n        var Promise3 = Promise2.getNewLibraryCopy();\n        Promise3.x = 123;\n\n        assert.equal(typeof Promise3.prototype.then, \"function\");\n        assert.notEqual(Promise3, Promise);\n        assert.notEqual(Promise3, Promise2);\n\n        assert.equal(Promise3.x, 123);\n        assert.notEqual(Promise.x, 123);\n        assert.notEqual(Promise2.x, 123);\n    });\n});\n"
  },
  {
    "path": "test/mocha/github-2xx-76.js",
    "content": "\"use strict\";\n\n\nPromise.longStackTraces();\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar isNodeJS = testUtils.isNodeJS;\n\n\nif (isNodeJS) {\n    describe(\"github276 - stack trace cleaner\", function(){\n        specify(\"message with newline and a$_b should not be removed\", function(){\n            return Promise.resolve(1).then(function() {\n                throw new Error(\"Blah\\n          a$_b\");\n            }).then(assert.fail, function(e) {\n                var msg = e.stack.split('\\n')[1]\n                assert(msg.indexOf('a$_b') >= 0, 'message should contain a$_b');\n            });\n        });\n    });\n}\n"
  },
  {
    "path": "test/mocha/github-3.6.4.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar Promise = adapter;\n\nfunction defer() {\n    var resolve, reject;\n    var promise = new Promise(function() {\n        resolve = arguments[0];\n        reject = arguments[1];\n    });\n    return {\n        resolve: resolve,\n        reject: reject,\n        promise: promise\n    };\n}\n\n\ndescribe(\"github-364\", function() {\n    specify(\"resolve between thens\", function(done) {\n        var calls = 0;\n        var def = defer();\n\n        def.promise.then(function() {\n            calls++\n        });\n        def.resolve();\n        def.promise.then(function() {\n            calls++\n        }).then(function() {\n            calls++\n        }).then(function() {\n            Promise.delay(11).then(function() {\n                assert.equal(calls, 3);\n                done();\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/github-3.7.3.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar Promise = adapter;\n\ndescribe(\"github-373\", function() {\n    specify(\"unhandled unsuccessful Promise.join should result in correct error being reported\", function() {\n        var err = new Error(\"test\");\n        var rejected = Promise.delay(1).thenThrow(err);\n        Promise.join(rejected, Promise.resolve(1), function(){});\n        return testUtils.onUnhandledSucceed(err);\n    });\n});\n"
  },
  {
    "path": "test/mocha/github-4.1.7.js",
    "content": "var Promise = adapter;\nvar assert = require(\"assert\");\n\ndescribe(\"Github #417\", function() {\n\n    specify(\"minimal repro\", function() {\n        var promise = new Promise(function(resolve) {\n            resolve(Promise.resolve().then(function() {\n                return new Promise(function(resolve) {\n                    setTimeout(resolve, 1);\n                });\n            }));\n        });\n\n        return promise.then(function() {\n            assert(promise.isResolved());\n        });\n    });\n\n    specify(\"original repro\", function() {\n        var called = 0;\n        var bar = Promise.method(function() {\n            return Promise.bind(this)\n                .then(Promise.method(function() {\n                    called++;\n                }));\n        });\n\n        var foo = Promise.method(function() {\n            return Promise.bind(this)\n                .then(Promise.method(function() {\n                    return bar();\n                }))\n                .bind(this)\n                .lastly(Promise.method(function() {\n                    called++;\n                }));\n        });\n\n        return foo().then(function() {\n            called++;\n            assert.equal(3, called);\n        });\n    });\n});\n\n"
  },
  {
    "path": "test/mocha/github36.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\ndescribe(\"github36\", function(){\n    specify(\"should work\", function() {\n        return new Promise(function(resolve, reject) {\n            var called = 0;\n            var donecalled = false;\n            var _d = Promise.defer();\n\n            _d.resolve()\n\n            var f1 = function() {\n                return _d.promise.then(function() {\n                    return true;\n                })\n            }\n\n            var f2 = function() {\n                var d1 = Promise.defer()\n\n                setTimeout(function() {\n                    d1.resolve()\n                }, 1)\n\n                return d1.promise.then(function() {\n                    return _d.promise.then(function() {\n                    })\n                });\n            }\n\n            var f3 = function() {\n                called++;\n                if (called > 15) {\n                    return resolve();\n                }\n                var promise = f1().then(function() {\n                    f2()\n                        .then(function() {\n                            f3()\n                        })\n                })\n\n                promise.lastly(function() {\n                    setTimeout(function() {\n                        f3()\n                    }, 1)\n                })\n\n            }\n\n            f3();\n        });\n    });\n});\n\n"
  },
  {
    "path": "test/mocha/helpers/assert_long_trace.js",
    "content": "var assert = require(\"assert\");\n\nfunction assertLongTrace(error, expectedJumpCount, expectedFramesForJumpsMap) {\n    var envFramePattern = /(?:\\(node.js:|\\(module.js:|\\(timers.js:|\\bcheckTimers\\b|\\bdrainQueue\\b|\\btimerLoop\\b|\\b_onImmediate\\b|\\b_immediateCallback\\b)/;\n    var stack = error.stack.split(\"\\n\");\n    var frameLinePattern = /(^\\s+at|@|\\s+\\(No stack trace\\))/;\n    var previousEventPattern = /^From previous event/;\n    var firstLine;\n    for (var i = 0; i < stack.length; ++i) {\n        if (previousEventPattern.test(stack[i])) {\n            throw new Error(\"From previous event before any frames\");\n        }\n        if (frameLinePattern.test(stack[i])) {\n            firstLine = i - 1;\n            break;\n        }\n    }\n    var prev = stack[firstLine - 1];\n    var jumpCount = 1;\n    var jumpIndex = 0;\n    var currentJumpFramesCount = 0;\n    var envFramesCount = 0;\n    for (var i = firstLine; i < stack.length; ++i) {\n        var line = stack[i];\n        if (previousEventPattern.test(line)) {\n            var jumpContainsOnlyEnvFrames =\n                currentJumpFramesCount === 0 && envFramesCount > 0;\n            if (!jumpContainsOnlyEnvFrames) {\n                if (previousEventPattern.test(prev)) {\n                    throw new Error(\"2 consecutive From previous events\");\n                }\n                if (jumpIndex < expectedFramesForJumpsMap.length) {\n                    var expectedFrames = expectedFramesForJumpsMap[jumpIndex];\n                    var expectedMessage = typeof expectedFrames === \"number\"\n                        ? (expectedFrames + \"\")\n                        : (expectedFrames[0] + \"-\" + expectedFrames[1]);\n                    var message = \"Expected \" + (jumpIndex+1) + \"th jump to contain \" +\n                        expectedMessage + \" frames \" +\n                        \"but it contains \" + currentJumpFramesCount + \" frames\";\n                    if (typeof expectedFrames === \"number\") {\n                        assert(expectedFrames === currentJumpFramesCount, message);\n                    } else {\n                        assert(expectedFrames[0] <= currentJumpFramesCount &&\n                               currentJumpFramesCount <= expectedFrames[1],\n                               message);\n                    }\n                }\n                jumpCount++;\n                jumpIndex++;\n            }\n            currentJumpFramesCount = 0;\n            envFramesCount = 0;\n        } else if (frameLinePattern.test(line)) {\n            if (envFramePattern.test(line)) {\n                envFramesCount++;\n            } else {\n                currentJumpFramesCount++;\n            }\n        }\n        prev = line;\n    }\n    assert.strictEqual(\n        previousEventPattern.test(stack[stack.length - 1]), false,\n        \"The last line cannot be 'From previous event:'\");\n    if (typeof expectedJumpCount === \"number\") {\n        assert.strictEqual(expectedJumpCount, jumpCount, \"Expected \" +\n            expectedJumpCount + \" jumps but saw \" + jumpCount + \" jumps\");\n    } else {\n        assert(expectedJumpCount[0] <= jumpCount &&\n            jumpCount <= expectedJumpCount[1],\n            \"Expected \" +\n            expectedJumpCount[0] + \"-\" + expectedJumpCount[1] +\n            \" jumps but saw \" + jumpCount + \" jumps\"\n        );\n    }\n\n    if (jumpCount > (expectedFramesForJumpsMap.length + 1)) {\n        throw new Error(\"All jumps except the last one require an \"+\n            \"expected frame count. \" +\n            \"Got expected frame counts for only \" +\n            expectedFramesForJumpsMap.length + \" while \" + (jumpCount-1) +\n            \" was expected\");\n    }\n\n}\nmodule.exports = assertLongTrace;\n"
  },
  {
    "path": "test/mocha/helpers/bluebird0_7_0.js",
    "content": "/* jshint -W014, -W116, -W106 */\n/* global process, unreachable */\n/**\n * @preserve Copyright (c) 2013 Petka Antonov\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:</p>\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n(function( global, Function, Array, Error, Object ) {\"use strict\";\n\nvar ASSERT = (function(){/* jshint -W014, -W116 */\n    var AssertionError = (function() {\n        function AssertionError( a ) {\n            this.constructor$( a );\n            this.message = a;\n            this.name = \"AssertionError\";\n        }\n        AssertionError.prototype = new Error();\n        AssertionError.prototype.constructor = AssertionError;\n        AssertionError.prototype.constructor$ = Error;\n        return AssertionError;\n    })();\n\n    return function assert( boolExpr, message ) {\n        if( boolExpr === true ) return;\n\n        var ret = new AssertionError( message );\n        if( Error.captureStackTrace ) {\n            Error.captureStackTrace( ret, assert );\n        }\n        if( console && console.error ) {\n            console.error( ret.stack + \"\" );\n        }\n        throw ret;\n\n    };\n})();\n\nvar errorObj = {e: {}};\nvar rescape = /[\\r\\n\\u2028\\u2029']/g;\n\nvar replacer = function( ch ) {\n        return \"\\\\u\" + ((\"0000\") +\n            (ch.charCodeAt(0).toString(16))).slice(-4);\n};\n\nfunction safeToEmbedString( str ) {\n    return str.replace( rescape, replacer );\n}\n\nfunction tryCatch1( fn, receiver, arg ) {\n    ASSERT(((typeof fn) === \"function\"),\n    \"typeof fn === \\u0022function\\u0022\");\n    try {\n        return fn.call( receiver, arg );\n    }\n    catch( e ) {\n        errorObj.e = e;\n        return errorObj;\n    }\n}\n\nfunction tryCatch2( fn, receiver, arg, arg2 ) {\n    ASSERT(((typeof fn) === \"function\"),\n    \"typeof fn === \\u0022function\\u0022\");\n    try {\n        return fn.call( receiver, arg, arg2 );\n    }\n    catch( e ) {\n        errorObj.e = e;\n        return errorObj;\n    }\n}\n\nfunction tryCatchApply( fn, args ) {\n    ASSERT(((typeof fn) === \"function\"),\n    \"typeof fn === \\u0022function\\u0022\");\n    try {\n        return fn.apply( void 0, args );\n    }\n    catch( e ) {\n        errorObj.e = e;\n        return errorObj;\n    }\n}\n\nvar create = Object.create || function( proto ) {\n    function F(){}\n    F.prototype = proto;\n    return new F();\n};\n\nfunction makeNodePromisified( callback, receiver ) {\n\n    function getCall(count) {\n        var args = new Array(count);\n        for( var i = 0, len = args.length; i < len; ++i ) {\n            args[i] = \"a\" + (i+1);\n        }\n        var comma = count > 0 ? \",\" : \"\";\n        return ( receiver === void 0\n            ? \"callback(\"+args.join(\",\")+ comma +\" fn);\"\n            : \"callback.call(receiver, \"+args.join(\",\") + comma + \" fn);\" ) +\n        \"break;\";\n    }\n\n    return new Function(\"Promise\", \"callback\", \"receiver\",\n        \"return function promisified( a1, a2, a3, a4, a5 ) {\\\"use strict\\\";\" +\n        \"var len = arguments.length;\" +\n        \"var resolver = Promise.pending( promisified );\" +\n        \"\" +\n        \"var fn = function fn( err, value ) {\" +\n        \"if( err ) {\" +\n        \"resolver.reject( err );\" +\n        \"}\" +\n        \"else {\" +\n        \"resolver.fulfill( value );\" +\n        \"}\" +\n        \"};\" +\n        \"switch( len ) {\" +\n        \"case 5:\" + getCall(5) +\n        \"case 4:\" + getCall(4) +\n        \"case 3:\" + getCall(3) +\n        \"case 2:\" + getCall(2) +\n        \"case 1:\" + getCall(1) +\n        \"case 0:\" + getCall(0) +\n        \"default: callback.apply(receiver, arguments); break;\" +\n        \"}\" +\n        \"return resolver.promise;\" +\n        \"\" +\n        \"};\"\n    )(Promise, callback, receiver);\n}\n\n\nvar inherits = function( Child, Parent ) {\n    var hasProp = {}.hasOwnProperty;\n\n    function T() {\n        this.constructor = Child;\n        this.constructor$ = Parent;\n        for (var propertyName in Parent.prototype) {\n            if (hasProp.call( Parent.prototype, propertyName) &&\n                propertyName.charAt(propertyName.length-1) !== \"$\"\n            ) {\n                this[ propertyName + \"$\"] = Parent.prototype[propertyName];\n            }\n        }\n    }\n    T.prototype = Parent.prototype;\n    Child.prototype = new T();\n    return Child.prototype;\n};\n\nfunction subError( constructorName, nameProperty, defaultMessage ) {\n    defaultMessage = safeToEmbedString(\"\" + defaultMessage );\n    nameProperty = safeToEmbedString(\"\" + nameProperty );\n\n    return new Function(\"create\", \"'use strict';\\n\" +\n         constructorName + \".prototype = create(Error.prototype);\" +\n         constructorName + \".prototype.constructor = \"+constructorName+\";\" +\n        \"function \"+constructorName+\"(msg){\" +\n        \"if( Error.captureStackTrace ) {\" +\n        \"Error.captureStackTrace(this, this.constructor);\" +\n        \"}\" +\n        \"Error.call(this, msg);\" +\n        \"this.message = typeof msg === 'string'\" +\n        \"? msg\" +\n        \": '\"+defaultMessage+\"';\" +\n        \"this.name = '\"+nameProperty+\"';\" +\n        \"} return \"+constructorName+\";\")(create);\n}\n\nif( typeof global.TypeError === \"undefined\" ) {\n    global.TypeError = subError( \"TypeError\", \"TypeError\" );\n}\nvar CancellationError = subError( \"CancellationError\",\n    \"Cancel\", \"cancellation error\" );\nvar TimeoutError = subError( \"TimeoutError\", \"Timeout\", \"timeout error\" );\n\n\nvar CapturedTrace = (function() {\n\nvar rignore = new RegExp(\n    \"\\\\b(?:Promise(?:Array)?\\\\$_\\\\w+|tryCatch(?:1|2|Apply)|setTimeout\" +\n    \"|makeNodePromisified|processImmediate|nextTick\" +\n    \"|Async\\\\$\\\\w+)\\\\b\"\n);\n\nvar rtraceline = null;\nvar formatStack = null;\n\nfunction CapturedTrace( ignoreUntil ) {\n    ASSERT(((typeof ignoreUntil) === \"function\"),\n    \"typeof ignoreUntil === \\u0022function\\u0022\");\n    ASSERT(((typeof ignoreUntil.name) === \"string\"),\n    \"typeof ignoreUntil.name === \\u0022string\\u0022\");\n    ASSERT((ignoreUntil.name.length > 0),\n    \"ignoreUntil.name.length > 0\");\n    this.captureStackTrace( ignoreUntil );\n}\nvar method = inherits( CapturedTrace, Error );\n\nmethod.captureStackTrace =\nfunction CapturedTrace$captureStackTrace( ignoreUntil ) {\n    captureStackTrace( this, ignoreUntil );\n};\n\nCapturedTrace.possiblyUnhandledRejection =\nfunction CapturedTrace$PossiblyUnhandledRejection( reason ) {\n    if( typeof console === \"object\" ) {\n        var stack = reason.stack;\n        var message = \"Possibly unhandled \" + formatStack( stack, reason );\n        if( typeof console.error === \"function\" ) {\n            console.error( message );\n        }\n        else if( typeof console.log === \"function\" ) {\n            console.log( message );\n        }\n    }\n};\n\nCapturedTrace.combine = function CapturedTrace$Combine( current, prev ) {\n    var curLast = current.length - 1;\n    for( var i = prev.length - 1; i >= 0; --i ) {\n        var line = prev[i];\n        if( current[ curLast ] === line ) {\n            current.pop();\n            curLast--;\n        }\n        else {\n            break;\n        }\n    }\n    var lines = current.concat( prev );\n\n    var ret = [];\n\n\n    for( var i = 0, len = lines.length; i < len; ++i ) {\n        if( rignore.test( lines[i] ) ||\n            ( i > 0 && !rtraceline.test( lines[i] ) )\n        ) {\n            continue;\n        }\n        ret.push( lines[i] );\n    }\n    return ret;\n};\n\nCapturedTrace.isSupported = function CapturedTrace$IsSupported() {\n    return typeof captureStackTrace === \"function\";\n};\n\nvar captureStackTrace = (function stackDetection() {\n    if( typeof Error.stackTraceLimit === \"number\" &&\n        typeof Error.captureStackTrace === \"function\" ) {\n        rtraceline = /^\\s*at\\s*/;\n        formatStack = function( stack, error ) {\n            return ( typeof stack === \"string\" )\n                ? stack\n                : error.name + \". \" + error.message;\n        };\n        return Error.captureStackTrace;\n    }\n    var err = new Error();\n\n    if( typeof err.stack === \"string\" &&\n        typeof \"\".startsWith === \"function\" &&\n        ( err.stack.startsWith(\"stackDetection@\")) &&\n        stackDetection.name === \"stackDetection\" ) {\n\n        Object.defineProperty( Error, \"stackTraceLimit\", {\n            writable: true,\n            enumerable: false,\n            configurable: false,\n            value: 25\n        });\n        rtraceline = /@/;\n        var rline = /[@\\n]/;\n\n        formatStack = function( stack, error ) {\n            return ( typeof stack === \"string\" )\n                ? ( error.name + \". \" + error.message + \"\\n\" + stack )\n                : ( error.name + \". \" + error.message );\n        };\n\n        return function captureStackTrace(o, fn) {\n            var name = fn.name;\n            var stack = new Error().stack;\n            var split = stack.split( rline );\n            var i, len = split.length;\n            for (i = 0; i < len; i += 2) {\n                if (split[i] === name) {\n                    break;\n                }\n            }\n            ASSERT(((i + 2) < split.length),\n    \"i + 2 < split.length\");\n            split = split.slice(i + 2);\n            len = split.length - 2;\n            var ret = \"\";\n            for (i = 0; i < len; i += 2) {\n                ret += split[i];\n                ret += \"@\";\n                ret += split[i + 1];\n                ret += \"\\n\";\n            }\n            o.stack = ret;\n        };\n    }\n    else {\n        return null;\n    }\n})();\n\nreturn CapturedTrace;})();\n\nfunction GetterCache(){}\nfunction FunctionCache(){}\n\n\nvar getterCache = new GetterCache(),\n    functionCache = new FunctionCache(),\n    rjsident = /^[a-zA-Z$_][a-zA-Z0-9$_]*$/,\n    rkeyword = new RegExp(\n        \"^(?:__proto__|undefined|NaN|Infinity|this|false|true|null|eval|\" +\n        \"arguments|break|case|catch|continue|debugger|default|delete|do|\" +\n        \"else|finally|for|function|if|in|instanceof|new|return|switch|th\" +\n        \"row|try|typeof|var|void|while|with|class|enum|export|extends|im\" +\n        \"port|super|implements|interface|let|package|private|protected|pu\" +\n        \"blic|static|yield)$\"\n    ),\n    hasProp = {}.hasOwnProperty;\n\n\n\nfunction isJsIdentifier( val ) {\n    return rjsident.test(val) &&\n        !rkeyword.test(val);\n}\n\nfunction formatPropertyRead( val ) {\n    if( isJsIdentifier(val) ) {\n        return \".\" + val;\n    }\n    else {\n        return \"['\"+safeToEmbedString(val)+\"']\";\n    }\n}\n\nfunction getGetter( propertyName ) {\n    if( hasProp.call( getterCache, propertyName ) ) {\n        return getterCache[propertyName];\n    }\n    var fn = new Function(\"obj\", \"return obj\"+\n        formatPropertyRead(\"\"+propertyName)\n    +\";\");\n    getterCache[propertyName] = fn;\n    return fn;\n}\n\nfunction getFunction( propertyName ) {\n    if( hasProp.call( functionCache, propertyName ) ) {\n        return functionCache[propertyName];\n    }\n    var fn = new Function(\"obj\", \"return obj\"+\n        formatPropertyRead(\"\"+propertyName)\n    +\"();\");\n    functionCache[propertyName] = fn;\n    return fn;\n}\nvar Async = (function() {\n\nvar deferFn = typeof process !== \"undefined\" ?\n    ( typeof global.setImmediate !== \"undefined\"\n        ? function( fn ){\n            global.setImmediate( fn );\n          }\n        : function( fn ) {\n            process.nextTick( fn );\n        }\n\n    ) :\n    ( typeof setTimeout !== \"undefined\"\n        ? function( fn ) {\n            setTimeout( fn, 4 );\n        }\n        : function( fn ) {\n            fn();\n        }\n) ;\n\nfunction Async() {\n    this._isTickUsed = false;\n    this._length = 0;\n    this._backupBuffer = [];\n    var functionBuffer = this._functionBuffer =\n        new Array( 1000 * 3 );\n    var self = this;\n    this.consumeFunctionBuffer = function Async$consumeFunctionBuffer() {\n        self._consumeFunctionBuffer();\n    };\n\n    for( var i = 0, len = functionBuffer.length; i < len; ++i ) {\n        functionBuffer[i] = void 0;\n    }\n}\nvar method = Async.prototype;\n\nmethod.haveItemsQueued = function Async$haveItemsQueued() {\n    return this._length > 0;\n};\n\nmethod.invokeLater = function Async$invokeLater( fn, receiver, arg ) {\n    ASSERT(((typeof fn) === \"function\"),\n    \"typeof fn === \\u0022function\\u0022\");\n    ASSERT((arguments.length === 3),\n    \"arguments.length === 3\");\n    this._backupBuffer.push( fn, receiver, arg );\n    if( !this._isTickUsed ) {\n        deferFn( this.consumeFunctionBuffer );\n        this._isTickUsed = true;\n    }\n};\n\nmethod.invoke = function Async$invoke( fn, receiver, arg ) {\n    ASSERT(((typeof fn) === \"function\"),\n    \"typeof fn === \\u0022function\\u0022\");\n    ASSERT((arguments.length === 3),\n    \"arguments.length === 3\");\n    var functionBuffer = this._functionBuffer,\n        len = functionBuffer.length,\n        length = this._length;\n\n    if( length === len ) {\n        functionBuffer.push( fn, receiver, arg );\n    }\n    else {\n        ASSERT((length < len),\n    \"length < len\");\n        functionBuffer[ length + 0 ] = fn;\n        functionBuffer[ length + 1 ] = receiver;\n        functionBuffer[ length + 2 ] = arg;\n    }\n    this._length = length + 3;\n\n    if( !this._isTickUsed ) {\n        deferFn( this.consumeFunctionBuffer );\n        this._isTickUsed = true;\n    }\n};\n\nmethod._consumeFunctionBuffer = function Async$_consumeFunctionBuffer() {\n    var functionBuffer = this._functionBuffer;\n    ASSERT(this._isTickUsed,\n    \"this._isTickUsed\");\n    for( var i = 0; i < this._length; i += 3 ) {\n        functionBuffer[ i + 0 ].call(\n            functionBuffer[ i + 1 ],\n            functionBuffer[ i + 2 ] );\n\n        functionBuffer[ i + 0 ] =\n            functionBuffer[ i + 1 ] =\n            functionBuffer[ i + 2 ] =\n            void 0;\n    }\n    this._reset();\n    if( this._backupBuffer.length ) {\n        var buffer = this._backupBuffer;\n        for( var i = 0; i < buffer.length; i+= 3 ) {\n            buffer[ i + 0 ].call(\n                buffer[ i + 1 ] ,\n                buffer[ i + 2 ] );\n        }\n        buffer.length = 0;\n    }\n};\n\nmethod._reset = function Async$_reset() {\n    this._isTickUsed = false;\n    this._length = 0;\n};\n\n\nreturn Async;})();\n\nvar async = new Async();\nvar Thenable = (function() {\n\nfunction Thenable() {\n    this.errorObj = errorObj;\n    this.__id__ = 0;\n    this.treshold = 1000;\n    this.thenableCache = new Array( this.treshold );\n    this.promiseCache = new Array( this.treshold );\n    this._compactQueued = false;\n}\nvar method = Thenable.prototype;\n\nmethod.couldBe = function Thenable$couldBe( ret ) {\n    if( ret === null ||\n        typeof ret === \"undefined\" ||\n        typeof ret === \"string\" ||\n        typeof ret === \"boolean\" ||\n        typeof ret === \"number\" ) {\n        return false;\n    }\n    var id = ret.__id_$thenable__;\n    if( typeof id === \"number\" &&\n        this.thenableCache[id] !== void 0 ) {\n        return true;\n    }\n    return (\"then\" in ret);\n};\n\nmethod.is = function Thenable$is( ret, ref ) {\n    var id = ret.__id_$thenable__;\n    if( typeof id === \"number\" &&\n        this.thenableCache[id] !== void 0 ) {\n        ref.ref = this.thenableCache[id];\n        ref.promise = this.promiseCache[id];\n        return true;\n    }\n    return this._thenableSlowCase( ret, ref );\n};\n\nmethod.addCache = function Thenable$_addCache( thenable, promise ) {\n    var id = this.__id__;\n    this.__id__ = id + 1;\n    var descriptor = this._descriptor( id );\n    Object.defineProperty( thenable, \"__id_$thenable__\", descriptor );\n    this.thenableCache[id] = thenable;\n    this.promiseCache[id] = promise;\n    ASSERT((this.thenableCache[thenable.__id_$thenable__] === thenable),\n    \"this.thenableCache[ thenable.__id_$thenable__ ] === thenable\");\n    if( this.thenableCache.length > this.treshold &&\n        !this._compactQueued) {\n        this._compactQueued = true;\n        async.invokeLater( this._compactCache, this, void 0 );\n    }\n};\n\nmethod.deleteCache = function Thenable$deleteCache( thenable ) {\n    var id = thenable.__id_$thenable__;\n    ASSERT(((typeof id) === \"number\"),\n    \"typeof id === \\u0022number\\u0022\");\n    ASSERT(((id | 0) === id),\n    \"(id | 0) === id\");\n    if( id === -1 ) {\n        return;\n    }\n    ASSERT((id > -1),\n    \"id > -1\");\n    ASSERT((id < this.__id__),\n    \"id < this.__id__\");\n    ASSERT((this.thenableCache[id] === thenable),\n    \"this.thenableCache[id] === thenable\");\n    this.thenableCache[id] = void 0;\n    this.promiseCache[id] = void 0;\n    thenable.__id_$thenable__ = -1;};\n\nvar descriptor = {\n    value: 0,\n    enumerable: false,\n    writable: true,\n    configurable: true\n};\nmethod._descriptor = function Thenable$_descriptor( id ) {\n    descriptor.value = id;\n    return descriptor;\n};\n\nmethod._compactCache = function Thenable$_compactCache() {\n    var arr = this.thenableCache;\n    var promiseArr = this.promiseCache;\n    var skips = 0;\n    var j = 0;\n    for( var i = 0, len = arr.length; i < len; ++i ) {\n        var item = arr[ i ];\n        if( item === void 0 ) {\n            skips++;\n        }\n        else {\n            promiseArr[ j ] = promiseArr[ i ];\n            item.__id_$thenable__ = j;\n            arr[ j++ ] = item;\n        }\n    }\n    var newId = arr.length - skips;\n    if( newId === this.__id__ ) {\n        this.treshold *= 2;\n    }\n    else for( var i = newId, len = arr.length; i < len; ++i ) {\n        promiseArr[ j ] = arr[i] = void 0;\n    }\n\n    this.__id__ = newId;\n    this._compactQueued = false;\n};\n\nmethod._thenableSlowCase = function Thenable$_thenableSlowCase( ret, ref ) {\n    try {\n        var then = ret.then;\n        if( typeof then === \"function\" ) {\n            ref.ref = then;\n            return true;\n        }\n        return false;\n    }\n    catch(e) {\n        this.errorObj.e = e;\n        ref.ref = this.errorObj;\n        return true;\n    }\n};\n\n\n\n\nreturn Thenable;})();\nvar CatchFilter = (function() {\n\nfunction CatchFilter( instances, callback ) {\n    this._instances = instances;\n    this._callback = callback;\n}\nvar method = CatchFilter.prototype;\n\nmethod.doFilter = function( e ) {\n    if( e === null || typeof e !== \"object\" ) {\n        throw e;\n    }\n    var cb = this._callback;\n    for( var i = 0, len = this._instances.length; i < len; ++i ) {\n        var item = this._instances[i];\n        if( e instanceof item ) {\n            var ret = tryCatch1( cb, void 0, e );\n            if( ret === errorObj ) {\n                throw ret.e;\n            }\n            return ret;\n        }\n    }\n    throw e;\n};\n\nreturn CatchFilter;})();\nvar Promise = (function() {\n\nfunction isObject( value ) {\n    if( value === null ) {\n        return false;\n    }\n    return ( typeof value === \"object\" ||\n            typeof value === \"function\" );\n}\n\nfunction isPromise( obj ) {\n    if( typeof obj !== \"object\" ) return false;\n    return obj instanceof Promise;\n}\n\nvar Err = Error;\nfunction isError( obj ) {\n    if( typeof obj !== \"object\" ) return false;\n    return obj instanceof Err;\n}\n\nvar Arr = Array;\nvar isArray = Arr.isArray || function( obj ) {\n    return obj instanceof Arr;\n};\n\n\nvar APPLY = {};\nvar thenable = new Thenable( errorObj );\n\nfunction Promise( resolver ) {\n    if( typeof resolver === \"function\" )\n        this._resolveResolver( resolver );\n\n\n    this._bitField = 67108864;\n    this._fulfill0 = void 0;\n    this._reject0 = void 0;\n    this._progress0 = void 0;\n    this._promise0 = void 0;\n    this._receiver0 = void 0;\n    this._resolvedValue = void 0;\n    this._cancellationParent = void 0;\n    if( longStackTraces ) this._traceParent = this._peekContext();\n}\n\nvar method = Promise.prototype;\n\nvar longStackTraces = true;\nPromise.longStackTraces = function() {\n    if( async.haveItemsQueued() &&\n        longStackTraces === false\n    ) {\n        throw new Error(\"Cannot enable long stack traces \" +\n        \"after promises have been created\");\n    }\n    longStackTraces = true;\n};\n\nmethod._setTrace = function _setTrace( fn ) {\n    ASSERT((this._trace == null),\n    \"this._trace == null\");\n    if( longStackTraces ) {\n        this._trace = new CapturedTrace(\n            typeof fn === \"function\"\n            ? fn\n            : _setTrace\n        );\n    }\n    return this;\n};\n\nmethod.toString = function Promise$toString() {\n    return \"[object Promise]\";\n};\n\n\nmethod.caught = method[\"catch\"] = function Promise$catch( fn ) {\n    var len = arguments.length;\n    if( len > 1 ) {\n        var catchInstances = new Array( len - 1 ),\n            j = 0, i;\n        for( i = 0; i < len - 1; ++i ) {\n            var item = arguments[i];\n            if( typeof item === \"function\" &&\n                ( item.prototype instanceof Error ||\n                item === Error ) ) {\n                catchInstances[j++] = item;\n            }\n        }\n        catchInstances.length = j;\n        fn = arguments[i];\n        var catchFilter = new CatchFilter( catchInstances, fn );\n        return this._then( void 0, catchFilter.doFilter, void 0,\n            catchFilter, void 0, this.caught );\n    }\n    return this._then( void 0, fn, void 0, void 0, void 0, this.caught );\n};\n\nmethod.progressed = function Promise$progressed( fn ) {\n    return this._then( void 0, void 0, fn, void 0, void 0, this.progressed );\n};\n\n\nfunction thrower( r ) {\n    throw r;\n}\nfunction slowFinally( ret, reasonOrValue ) {\n    if( this.isFulfilled() ) {\n        return ret._then(function() {\n            return reasonOrValue;\n        }, thrower, void 0, this, void 0, slowFinally );\n    }\n    else {\n        return ret._then(function() {\n            throw reasonOrValue;\n        }, thrower, void 0, this, void 0, slowFinally );\n    }\n}\nmethod.lastly = method[\"finally\"] = function Promise$finally( fn ) {\n    var r = function( reasonOrValue ) {\n        var ret = fn( reasonOrValue );\n        if( isPromise( ret ) ) {\n            return slowFinally.call( this, ret, reasonOrValue );\n        }\n        if( this.isRejected() ) throw reasonOrValue;\n        return reasonOrValue;\n    };\n    return this._then( r, r, void 0, this, void 0, this.anyway );\n};\n\nmethod.inspect = function Promise$inspect() {\n    return new PromiseInspection( this );\n};\n\nmethod.cancel = function Promise$cancel() {\n    if( !this.isCancellable() ) return this;\n    var cancelTarget = this;\n    while( cancelTarget._cancellationParent !== void 0 ) {\n        cancelTarget = cancelTarget._cancellationParent;\n    }\n    if( cancelTarget === this ) {\n        var err = new CancellationError();\n        this._attachExtraTrace( err );\n        async.invoke( this._reject, this, err );\n    }\n    else {\n        async.invoke( cancelTarget.cancel, cancelTarget, void 0 );\n    }\n    return this;\n};\n\nmethod.uncancellable = function Promise$uncancellable() {\n    var ret = new Promise();\n    ret._setTrace();\n    ret._unsetCancellable();\n    ret._assumeStateOf( this, true );\n    return ret;\n};\n\nmethod.fork = function Promise$fork( didFulfill, didReject, didProgress ) {\n    var ret = this._then( didFulfill, didReject, didProgress,\n        void 0, void 0, this.fork );\n    ret._cancellationParent = void 0;\n    return ret;\n};\n\nmethod.call = function Promise$call( propertyName ) {\n    var len = arguments.length;\n\n    if( len < 2 ) {\n        return this._callFast( propertyName );\n    }\n    else {\n        var args = new Array(len-1);\n        for( var i = 1; i < len; ++i ) {\n            args[ i - 1 ] = arguments[ i ];\n        }\n        return this._callSlow( propertyName, args );\n    }\n\n};\n\nmethod.get = function Promise$get( propertyName ) {\n    return this._then(\n        getGetter( propertyName ),\n        void 0,\n        void 0,\n        void 0,\n        void 0,\n        this.get\n    );\n};\n\nmethod.then = function Promise$then( didFulfill, didReject, didProgress ) {\n    return this._then( didFulfill, didReject, didProgress,\n        void 0, void 0, this.then );\n};\n\nmethod.spread = function Promise$spread( didFulfill, didReject ) {\n    return this._then( didFulfill, didReject, void 0,\n        APPLY, void 0, this.spread );\n};\nmethod.isFulfilled = function Promise$isFulfilled() {\n    return ( this._bitField & 268435456 ) > 0;\n};\n\nmethod.isRejected = function Promise$isRejected() {\n    return ( this._bitField & 134217728 ) > 0;\n};\n\nmethod.isPending = function Promise$isPending() {\n    return !this.isResolved();\n};\n\nmethod.isResolved = function Promise$isResolved() {\n    return ( this._bitField & 402653184 ) > 0;\n};\n\nmethod.isCancellable = function Promise$isCancellable() {\n    return !this.isResolved() &&\n        this._cancellable();\n};\n\nmethod.toJSON = function Promise$toJSON() {\n    var inspection = this.inspect();\n    var ret = {\n        isFulfilled: false,\n        isRejected: false\n    };\n    if( inspection.isFulfilled() ) {\n        ret.fulfillmentValue = inspection.value();\n        ret.isFulfilled = true;\n    }\n    else if( inspection.isRejected() ) {\n        ret.rejectionReason = inspection.error();\n        ret.isRejected = true;\n    }\n    return ret;\n};\n\nmethod.map = function Promise$map( fn ) {\n    return Promise.map( this, fn );\n};\n\nmethod.all = function Promise$all() {\n    return Promise.all( this );\n};\n\nmethod.any = function Promise$any() {\n    return Promise.any( this );\n};\n\nmethod.settle = function Promise$settle() {\n    return Promise.settle( this );\n};\n\nmethod.some = function Promise$some( count ) {\n    return Promise.some( this, count );\n};\n\nmethod.reduce = function Promise$reduce( fn, initialValue ) {\n    return Promise.reduce( this, fn, initialValue );\n};\n\nPromise.is = isPromise;\n\nPromise.settle = function Promise$Settle( promises ) {\n    var ret = Promise._all( promises, SettledPromiseArray );\n    return ret.promise();\n};\n\nPromise.all = function Promise$All( promises ) {\n    var ret = Promise._all( promises, PromiseArray );\n    return ret.promise();\n};\n\nPromise.join = function Promise$Join() {\n    var ret = new Array( arguments.length );\n    for( var i = 0, len = ret.length; i < len; ++i ) {\n        ret[i] = arguments[i];\n    }\n    return Promise._all( ret, PromiseArray ).promise();\n};\n\nPromise.any = function Promise$Any( promises ) {\n    var ret = Promise._all( promises, AnyPromiseArray );\n    return ret.promise();\n};\n\nPromise.some = function Promise$Some( promises, howMany ) {\n    var ret = Promise._all( promises, SomePromiseArray );\n    if( ( howMany | 0 ) !== howMany ) {\n        throw new TypeError(\"howMany must be an integer\");\n    }\n    var len = ret.length();\n    howMany = Math.max(0, Math.min( howMany, len ) );\n    ret._howMany = howMany;\n    return ret.promise();\n};\n\n\nfunction mapper( fulfilleds ) {\n    var fn = this;\n    var shouldDefer = false;\n    for( var i = 0, len = fulfilleds.length; i < len; ++i ) {\n        var fulfill = fn(fulfilleds[i]);\n        if( !shouldDefer && isPromise( fulfill ) ) {\n            if( fulfill.isFulfilled() ) {\n                fulfilleds[i] = fulfill._resolvedValue;\n                continue;\n            }\n            else {\n                shouldDefer = true;\n            }\n        }\n        fulfilleds[i] = fulfill;\n    }\n    return shouldDefer ? Promise.all( fulfilleds ) : fulfilleds;\n}\nPromise.map = function Promise$Map( promises, fn ) {\n    if( typeof fn !== \"function\" )\n        throw new TypeError( \"fn is not a function\" );\n    return Promise.all( promises )._then(\n        mapper,\n        void 0,\n        void 0,\n        fn,\n        void 0,\n        Promise.all\n    );\n};\n\nfunction reducer( fulfilleds, initialValue ) {\n    var fn = this;\n    var len = fulfilleds.length;\n    var accum;\n    var startIndex = 0;\n\n    if( initialValue !== void 0 ) {\n        accum = initialValue;\n        startIndex = 0;\n    }\n    else {\n        accum = len > 0 ? fulfilleds[0] : void 0;\n        startIndex = 1;\n    }\n    for( var i = startIndex; i < len; ++i ) {\n        accum = fn( accum, fulfilleds[i], i, len );\n    }\n    return accum;\n}\n\nfunction slowReduce( promises, fn, initialValue ) {\n    return Promise._all( promises, PromiseArray, slowReduce )\n        .promise()\n        .then( function( fulfilleds ) {\n            return reducer.call( fn, fulfilleds, initialValue );\n        });\n}\n\n\nPromise.reduce = function Promise$Reduce( promises, fn, initialValue ) {\n    if( typeof fn !== \"function\" )\n        throw new TypeError( \"fn is not a function\");\n    if( initialValue !== void 0 ) {\n        return slowReduce( promises, fn, initialValue );\n    }\n    return Promise\n        .all( promises )\n        ._then( reducer, void 0, void 0, fn, void 0, Promise.all );\n};\n\nPromise.fulfilled = function Promise$Fulfilled( value ) {\n    var ret = new Promise();\n    ret._setTrace();\n    if( ret._tryAssumeStateOf( value, false ) ) {\n        return ret;\n    }\n    ret._cleanValues();\n    ret._setFulfilled();\n    ret._resolvedValue = value;\n    return ret;\n};\n\nPromise.rejected = function Promise$Rejected( reason ) {\n    var ret = new Promise();\n    ret._setTrace();\n    ret._cleanValues();\n    ret._setRejected();\n    ret._resolvedValue = reason;\n    return ret;\n};\n\nPromise.pending = function Promise$Pending( caller ) {\n    var promise = new Promise();\n    promise._setTrace( caller );\n    return new PromiseResolver( promise );\n};\n\n\nPromise.cast = function Promise$Cast( obj ) {\n    var ret = cast( obj );\n    if( !( ret instanceof Promise ) ) {\n        return Promise.fulfilled( ret );\n    }\n    return ret;\n};\n\nPromise.onPossiblyUnhandledRejection =\nfunction Promise$OnPossiblyUnhandledRejection( fn ) {\n    if( typeof fn === \"function\" ) {\n        CapturedTrace.possiblyUnhandledRejection = fn;\n    }\n    else {\n        CapturedTrace.possiblyUnhandledRejection = void 0;\n    }\n};\n\nPromise.promisify = function Promise$Promisify( callback, receiver) {\n    return makeNodePromisified( callback, receiver );\n};\n\nmethod._then =\nfunction Promise$_then(\n    didFulfill,\n    didReject,\n    didProgress,\n    receiver,\n    internalData,\n    caller\n) {\n    var haveInternalData = internalData !== void 0;\n    var ret = haveInternalData ? internalData : new Promise();\n\n    if( longStackTraces && !haveInternalData ) {\n        ret._traceParent = this;\n        ret._setTrace( typeof caller === \"function\" ? caller : this._then );\n    }\n\n    var callbackIndex =\n        this._addCallbacks( didFulfill, didReject, didProgress, ret, receiver );\n\n    if( this.isResolved() ) {\n        async.invoke( this._resolveLast, this, callbackIndex );\n    }\n    else if( !haveInternalData && this.isCancellable() ) {\n        ret._cancellationParent = this;\n    }\n\n    if( this._isDelegated() ) {\n        this._unsetDelegated();\n        ASSERT((! this.isResolved()),\n    \"!this.isResolved()\");\n        var x = this._resolvedValue;\n        if( !this._tryThenable( x ) ) {\n            async.invoke( this._fulfill, this, x );\n        }\n    }\n    return ret;\n};\n\nmethod._length = function Promise$_length() {\n    ASSERT(isPromise(this),\n    \"isPromise( this )\");\n    ASSERT((arguments.length === 0),\n    \"arguments.length === 0\");\n    return this._bitField & 16777215;\n};\n\nmethod._isFollowingOrFulfilledOrRejected =\nfunction Promise$_isFollowingOrFulfilledOrRejected() {\n    return ( this._bitField & 939524096 ) > 0;\n};\n\nmethod._setLength = function Promise$_setLength( len ) {\n    this._bitField = ( this._bitField & -16777216 ) |\n        ( len & 16777215 ) ;\n};\n\nmethod._cancellable = function Promise$_cancellable() {\n    return ( this._bitField & 67108864 ) > 0;\n};\n\nmethod._setFulfilled = function Promise$_setFulfilled() {\n    this._bitField = this._bitField | 268435456;\n};\n\nmethod._setRejected = function Promise$_setRejected() {\n    this._bitField = this._bitField | 134217728;\n};\n\nmethod._setFollowing = function Promise$_setFollowing() {\n    this._bitField = this._bitField | 536870912;\n};\n\nmethod._setDelegated = function Promise$_setDelegated() {\n    this._bitField = this._bitField | -1073741824;\n\n};\n\nmethod._isDelegated = function Promise$_isDelegated() {\n    return ( this._bitField & -1073741824 ) === -1073741824;\n};\n\nmethod._unsetDelegated = function Promise$_unsetDelegated() {\n    this._bitField = this._bitField & ( ~-1073741824 );\n};\n\nmethod._setCancellable = function Promise$_setCancellable() {\n    this._bitField = this._bitField | 67108864;\n};\n\nmethod._unsetCancellable = function Promise$_unsetCancellable() {\n    this._bitField = this._bitField & ( ~67108864 );\n};\n\nmethod._receiverAt = function Promise$_receiverAt( index ) {\n    ASSERT(((typeof index) === \"number\"),\n    \"typeof index === \\u0022number\\u0022\");\n    ASSERT((index >= 0),\n    \"index >= 0\");\n    ASSERT((index < this._length()),\n    \"index < this._length()\");\n    ASSERT(((index % 5) === 0),\n    \"index % CALLBACK_SIZE === 0\");\n    if( index === 0 ) return this._receiver0;\n    return this[ index + 4 - 5 ];\n};\n\nmethod._promiseAt = function Promise$_promiseAt( index ) {\n    ASSERT(((typeof index) === \"number\"),\n    \"typeof index === \\u0022number\\u0022\");\n    ASSERT((index >= 0),\n    \"index >= 0\");\n    ASSERT((index < this._length()),\n    \"index < this._length()\");\n    ASSERT(((index % 5) === 0),\n    \"index % CALLBACK_SIZE === 0\");\n    if( index === 0 ) return this._promise0;\n    return this[ index + 3 - 5 ];\n};\n\nmethod._fulfillAt = function Promise$_fulfillAt( index ) {\n    ASSERT(((typeof index) === \"number\"),\n    \"typeof index === \\u0022number\\u0022\");\n    ASSERT((index >= 0),\n    \"index >= 0\");\n    ASSERT((index < this._length()),\n    \"index < this._length()\");\n    ASSERT(((index % 5) === 0),\n    \"index % CALLBACK_SIZE === 0\");\n    if( index === 0 ) return this._fulfill0;\n    return this[ index + 0 - 5 ];\n};\n\nmethod._rejectAt = function Promise$_rejectAt( index ) {\n    ASSERT(((typeof index) === \"number\"),\n    \"typeof index === \\u0022number\\u0022\");\n    ASSERT((index >= 0),\n    \"index >= 0\");\n    ASSERT((index < this._length()),\n    \"index < this._length()\");\n    ASSERT(((index % 5) === 0),\n    \"index % CALLBACK_SIZE === 0\");\n    if( index === 0 ) return this._reject0;\n    return this[ index + 1 - 5 ];\n};\n\nmethod._progressAt = function Promise$_progressAt( index ) {\n    ASSERT(((typeof index) === \"number\"),\n    \"typeof index === \\u0022number\\u0022\");\n    ASSERT((index >= 0),\n    \"index >= 0\");\n    ASSERT((index < this._length()),\n    \"index < this._length()\");\n    ASSERT(((index % 5) === 0),\n    \"index % CALLBACK_SIZE === 0\");\n    if( index === 0 ) return this._progress0;\n    return this[ index + 2 - 5 ];\n};\n\nvar fulfiller = new Function(\"p\",\n    \"'use strict';return function Promise$_fulfiller(a){ p.fulfill( a ); }\" );\nvar rejecter = new Function(\"p\",\n    \"'use strict';return function Promise$_rejecter(a){ p.reject( a ); }\" );\n\nmethod._resolveResolver = function Promise$_resolveResolver( resolver ) {\n    ASSERT(((typeof resolver) === \"function\"),\n    \"typeof resolver === \\u0022function\\u0022\");\n    this._setTrace( this._resolveResolver );\n    var p = new PromiseResolver( this );\n    this._pushContext();\n    var r = tryCatch2( resolver, this, fulfiller( p ), rejecter( p ) );\n    this._popContext();\n    if( r === errorObj ) {\n        p.reject( r.e );\n    }\n};\n\nmethod._addCallbacks = function Promise$_addCallbacks(\n    fulfill,\n    reject,\n    progress,\n    promise,\n    receiver\n) {\n    fulfill = typeof fulfill === \"function\" ? fulfill : void 0;\n    reject = typeof reject === \"function\" ? reject : void 0;\n    progress = typeof progress === \"function\" ? progress : void 0;\n    var index = this._length();\n\n    if( index === 0 ) {\n        this._fulfill0 = fulfill;\n        this._reject0  = reject;\n        this._progress0 = progress;\n        this._promise0 = promise;\n        this._receiver0 = receiver;\n        this._setLength( index + 5 );\n        return index;\n    }\n\n    this[ index - 5 + 0 ] = fulfill;\n    this[ index - 5 + 1 ] = reject;\n    this[ index - 5 + 2 ] = progress;\n    this[ index - 5 + 3 ] = promise;\n    this[ index - 5 + 4 ] = receiver;\n\n    this._setLength( index + 5 );\n    return index;\n};\n\nmethod._callFast = function Promise$_callFast( propertyName ) {\n    return this._then(\n        getFunction( propertyName ),\n        void 0,\n        void 0,\n        void 0,\n        void 0,\n        this.call\n    );\n};\n\nmethod._callSlow = function Promise$_callSlow( propertyName, args ) {\n    ASSERT(isArray(args),\n    \"isArray( args )\");\n    ASSERT((args.length > 0),\n    \"args.length > 0\");\n    return this._then( function( obj ) {\n        return obj[propertyName].apply( obj, args );\n    },\n        void 0,\n        void 0,\n        void 0,\n        void 0,\n        this.call\n    );\n};\n\nmethod._resolveLast = function Promise$_resolveLast( index ) {\n    ASSERT(((typeof index) === \"number\"),\n    \"typeof index === \\u0022number\\u0022\");\n    ASSERT((index >= 0),\n    \"index >= 0\");\n    ASSERT((index < this._length()),\n    \"index < this._length()\");\n    var promise = this._promiseAt( index );\n    var receiver = this._receiverAt( index );\n    var fn;\n\n    if( this.isFulfilled() ) {\n        fn = this._fulfillAt( index );\n    }\n    else if( this.isRejected() ) {\n        fn = this._rejectAt( index );\n    }\n    else unreachable();\n\n    var obj = this._resolvedValue;\n    var ret = obj;\n    if( fn !== void 0 ) {\n        this._resolvePromise( fn, receiver, obj, promise );\n    }\n    else if( this.isFulfilled() ) {\n        promise._fulfill( ret );\n    }\n    else {\n        promise._reject( ret );\n    }\n};\n\nmethod._spreadSlowCase =\nfunction Promise$_spreadSlowCase( targetFn, promise, values ) {\n    promise._assumeStateOf(\n        Promise.all( values )._then( targetFn, void 0, void 0, APPLY, void 0,\n            this._spreadSlowCase ),\n        false\n    );\n};\n\n\nfunction cast( obj ) {\n    if( isObject( obj ) ) {\n        if( obj instanceof Promise ) {\n            return obj;\n        }\n        var ref = { ref: null, promise: null };\n        if( thenable.is( obj, ref ) ) {\n            if( ref.promise != null ) {\n                return ref.promise;\n            }\n            var resolver = Promise.pending();\n            var result = ref.ref;\n            if( result === errorObj ) {\n                resolver.reject( result.e );\n                return resolver.promise;\n            }\n            thenable.addCache( obj, resolver.promise );\n            var called = false;\n            var ret = tryCatch2( result, obj, function t( a ) {\n                if( called ) return;\n                called = true;\n                async.invoke( thenable.deleteCache, thenable, obj );\n                var b = cast( a );\n                if( b === a ) {\n                    resolver.fulfill( a );\n                }\n                else {\n                    b._then(\n                        resolver.fulfill,\n                        resolver.reject,\n                        void 0,\n                        resolver,\n                        void 0,\n                        t\n                    );\n                }\n            }, function t( a ) {\n                if( called ) return;\n                called = true;\n                async.invoke( thenable.deleteCache, thenable, obj );\n                resolver.reject( a );\n            });\n            if( ret === errorObj && !called ) {\n                resolver.reject( ret.e );\n                async.invoke( thenable.deleteCache, thenable, obj );\n            }\n            return resolver.promise;\n        }\n    }\n    return obj;\n}\n\nmethod._resolveThenable = function Promise$_resolveThenable( x, ref ) {\n    if( ref.promise != null ) {\n        this._assumeStateOf( ref.promise, true );\n        return;\n    }\n    if( ref.ref === errorObj ) {\n        this._attachExtraTrace( ref.ref.e );\n        async.invoke( this._reject, this, ref.ref.e );\n    }\n    else {\n        thenable.addCache( x, this );\n        var then = ref.ref;\n        var localX = x;\n        var localP = this;\n        var key = {};\n        var called = false;\n        var t = function t( v ) {\n            if( called && this !== key ) return;\n            called = true;\n            var b = cast( v );\n\n            if( b !== v ||\n                ( b instanceof Promise && b.isPending() ) ) {\n                b._then( t, r, void 0, key, void 0, t);\n                return;\n            }\n\n            var fn = localP._fulfill;\n            if( b instanceof Promise ) {\n                var fn = b.isFulfilled()\n                    ? localP._fulfill : localP._reject;\n                ASSERT(b.isResolved(),\n    \"b.isResolved()\");\n                v = v._resolvedValue;\n                b = cast( v );\n                ASSERT(((b instanceof Promise) || (b === v)),\n    \"b instanceof Promise || b === v\");\n                if( b !== v ||\n                    ( b instanceof Promise && b !== v ) ) {\n                    b._then( t, r, void 0, key, void 0, t);\n                    return;\n                }\n            }\n            async.invoke( fn, localP, v );\n            async.invoke( thenable.deleteCache,\n                    thenable, localX );\n        };\n\n        var r = function r( v ) {\n            if( called && this !== key ) return;\n            called = true;\n\n            var b = cast( v );\n\n            if( b !== v ||\n                ( b instanceof Promise && b.isPending() ) ) {\n                b._then( t, r, void 0, key, void 0, t);\n                return;\n            }\n\n            var fn = localP._reject;\n            if( b instanceof Promise ) {\n                var fn = b.isFulfilled()\n                    ? localP._fulfill : localP._reject;\n                ASSERT(b.isResolved(),\n    \"b.isResolved()\");\n                v = v._resolvedValue;\n                b = cast( v );\n                if( b !== v ||\n                    ( b instanceof Promise && b.isPending() ) ) {\n                    b._then( t, r, void 0, key, void 0, t);\n                    return;\n                }\n            }\n\n            async.invoke( fn, localP, v );\n            async.invoke( thenable.deleteCache,\n                thenable, localX );\n\n        };\n        var threw = tryCatch2( then, x, t, r);\n        if( threw === errorObj &&\n            !called ) {\n            this._attachExtraTrace( threw.e );\n            async.invoke( this._reject, this, threw.e );\n            async.invoke( thenable.deleteCache, thenable, x );\n        }\n    }\n};\n\nmethod._tryThenable = function Promise$_tryThenable( x ) {\n    var ref;\n    if( !thenable.is( x, ref = {ref: null, promise: null} ) ) {\n        return false;\n    }\n    this._resolveThenable( x, ref );\n    return true;\n};\n\nvar ignore = CatchFilter.prototype.doFilter;\nmethod._resolvePromise = function Promise$_resolvePromise(\n    onFulfilledOrRejected, receiver, value, promise\n) {\n    if( isError( value ) ) {\n        value.__handled = true;\n    }\n\n    if( !isPromise( promise ) ) {\n        return onFulfilledOrRejected.call( receiver, value, promise );\n    }\n\n    var x;\n    if( receiver === APPLY ) {\n        if( isArray( value ) ) {\n            for( var i = 0, len = value.length; i < len; ++i ) {\n                if( isPromise( value[i] ) ) {\n                    this._spreadSlowCase(\n                        onFulfilledOrRejected,\n                        promise,\n                        value\n                    );\n                    return;\n                }\n            }\n            promise._pushContext();\n            x = tryCatchApply( onFulfilledOrRejected, value );\n        }\n        else {\n            this._spreadSlowCase( onFulfilledOrRejected, promise, value );\n            return;\n        }\n    }\n    else {\n        promise._pushContext();\n        x = tryCatch1( onFulfilledOrRejected, receiver, value );\n    }\n\n    promise._popContext();\n\n    if( x === errorObj ) {\n        if( onFulfilledOrRejected !== ignore ) {\n            promise._attachExtraTrace( x.e );\n        }\n        async.invoke( promise._reject, promise, x.e );\n    }\n    else if( x === promise ) {\n        async.invoke(\n            promise._reject,\n            promise,\n            new TypeError( \"Circular thenable chain\" )\n        );\n    }\n    else {\n        if( promise._tryAssumeStateOf( x, true ) ) {\n            return;\n        }\n        else if( thenable.couldBe( x ) ) {\n\n            if( promise._length() === 0 ) {\n                promise._resolvedValue = x;\n                promise._setDelegated();\n                return;\n            }\n            else if( promise._tryThenable( x ) ) {\n                return;\n            }\n        }\n        async.invoke( promise._fulfill, promise, x );\n    }\n};\n\nmethod._assumeStateOf =\nfunction Promise$_assumeStateOf( promise, mustAsync ) {\n    ASSERT(isPromise(promise),\n    \"isPromise( promise )\");\n    ASSERT(((typeof mustAsync) === \"boolean\"),\n    \"typeof mustAsync === \\u0022boolean\\u0022\");\n    ASSERT((this._isFollowingOrFulfilledOrRejected() === false),\n    \"this._isFollowingOrFulfilledOrRejected() === false\");\n    this._setFollowing();\n    if( promise.isPending() ) {\n        if( promise._cancellable()  ) {\n            this._cancellationParent = promise;\n        }\n        promise._then(\n            this._resolveFulfill,\n            this._resolveReject,\n            this._resolveProgress,\n            this,\n            void 0,\n            this._tryAssumeStateOf\n        );\n    }\n    else if( promise.isFulfilled() ) {\n        if( mustAsync )\n            async.invoke( this._resolveFulfill, this, promise._resolvedValue );\n        else\n            this._resolveFulfill( promise._resolvedValue );\n    }\n    else {\n        if( mustAsync )\n            async.invoke( this._resolveReject, this, promise._resolvedValue );\n        else\n            this._resolveReject( promise._resolvedValue );\n    }\n\n    if( longStackTraces &&\n        promise._traceParent == null ) {\n        promise._traceParent = this;\n    }\n};\n\nmethod._tryAssumeStateOf =\nfunction Promise$_tryAssumeStateOf( value, mustAsync ) {\n    if( !isPromise( value ) ||\n        this._isFollowingOrFulfilledOrRejected() ) return false;\n\n    this._assumeStateOf( value, mustAsync );\n    return true;\n};\n\n\n\nmethod._attachExtraTrace = function Promise$_attachExtraTrace( error ) {\n    if( longStackTraces &&\n        isError( error ) ) {\n        var promise = this;\n        var stack = error.stack.split(\"\\n\");\n        var headerLineCount = 1;\n\n        while( promise != null &&\n            promise._trace != null ) {\n            stack = CapturedTrace.combine(\n                stack,\n                promise._trace.stack.split( \"\\n\" )\n            );\n            promise = promise._traceParent;\n        }\n\n        var max = Error.stackTraceLimit + headerLineCount;\n        var len = stack.length;\n        if( len  > max ) {\n            stack.length = max;\n        }\n        if( stack.length <= headerLineCount ) {\n            error.stack = \"(No stack trace)\";\n        }\n        else {\n            error.stack = stack.join(\"\\n\");\n        }\n    }\n};\n\nmethod._notifyUnhandledRejection =\nfunction Promise$_notifyUnhandledRejection( reason ) {\n    if( !reason.__handled ) {\n        reason.__handled = true;\n        CapturedTrace.possiblyUnhandledRejection( reason );\n    }\n};\n\nmethod._unhandledRejection = function Promise$_unhandledRejection( reason ) {\n    if( !reason.__handled ) {\n        async.invokeLater( this._notifyUnhandledRejection, this, reason );\n    }\n};\n\nmethod._cleanValues = function Promise$_cleanValues() {\n    this._cancellationParent = void 0;\n};\n\nmethod._fulfill = function Promise$_fulfill( value ) {\n    if( this._isFollowingOrFulfilledOrRejected() ) return;\n    this._resolveFulfill( value );\n\n};\n\nmethod._reject = function Promise$_reject( reason ) {\n    if( this._isFollowingOrFulfilledOrRejected() ) return;\n    this._resolveReject( reason );\n};\n\nmethod._progress = function Promise$_progress( progressValue ) {\n    if( this._isFollowingOrFulfilledOrRejected() ) return;\n    this._resolveProgress( progressValue );\n\n};\n\nmethod._resolveFulfill = function Promise$_resolveFulfill( value ) {\n    ASSERT(this.isPending(),\n    \"this.isPending()\");\n    this._cleanValues();\n    this._setFulfilled();\n    this._resolvedValue = value;\n    var len = this._length();\n    for( var i = 0; i < len; i+= 5 ) {\n        var fn = this._fulfillAt( i );\n        var promise = this._promiseAt( i );\n        var receiver = this._receiverAt( i );\n        if( fn !== void 0 ) {\n            this._resolvePromise(\n                fn,\n                receiver,\n                value,\n                promise\n            );\n\n        }\n        else {\n            async.invoke( promise._fulfill, promise, value );\n        }\n    }\n};\n\nmethod._resolveReject = function Promise$_resolveReject( reason ) {\n    ASSERT(this.isPending(),\n    \"this.isPending()\");\n    this._cleanValues();\n    this._setRejected();\n    this._resolvedValue = reason;\n    var len = this._length();\n    var rejectionWasHandled = false;\n    for( var i = 0; i < len; i+= 5 ) {\n        var fn = this._rejectAt( i );\n        var promise = this._promiseAt( i );\n        if( fn !== void 0 ) {\n            rejectionWasHandled = true;\n            this._resolvePromise(\n                fn,\n                this._receiverAt( i ),\n                reason,\n                promise\n            );\n        }\n        else {\n            if( !rejectionWasHandled )\n                rejectionWasHandled = promise._length() > 0;\n            async.invoke( promise._reject, promise, reason );\n        }\n    }\n    if( !rejectionWasHandled &&\n        isError( reason ) &&\n        CapturedTrace.possiblyUnhandledRejection !== void 0\n\n    ) {\n        if( reason.__handled !== true ) {\n            reason.__handled = false;\n            async.invoke(\n                this._unhandledRejection,\n                this,\n                reason\n            );\n        }\n    }\n\n};\n\nmethod._resolveProgress = function Promise$_resolveProgress( progressValue ) {\n    ASSERT(this.isPending(),\n    \"this.isPending()\");\n    var len = this._length();\n    for( var i = 0; i < len; i += 5 ) {\n        var fn = this._progressAt( i );\n        var promise = this._promiseAt( i );\n        if( !isPromise( promise ) ) {\n            fn.call( this._receiverAt( i ), progressValue, promise );\n            continue;\n        }\n        var ret = progressValue;\n        if( fn !== void 0 ) {\n            this._pushContext();\n            ret = tryCatch1( fn, this._receiverAt( i ), progressValue );\n            this._popContext();\n            if( ret === errorObj ) {\n                if( ret.e != null &&\n                    ret.e.name === \"StopProgressPropagation\" ) {\n                    ret.e.__handled = true;\n                }\n                else {\n                    promise._attachExtraTrace( ret.e );\n                    async.invoke( promise._progress, promise, ret.e );\n                }\n            }\n            else if( isPromise( ret ) ) {\n                ret._then( promise._progress, null, null, promise, void 0,\n                    this._progress );\n            }\n            else {\n                async.invoke( promise._progress, promise, ret );\n            }\n        }\n        else {\n            async.invoke( promise._progress, promise, ret );\n        }\n    }\n};\n\nvar contextStack = [];\nmethod._peekContext = function Promise$_peekContext() {\n    var lastIndex = contextStack.length - 1;\n    if( lastIndex >= 0 ) {\n        return contextStack[ lastIndex ];\n    }\n    return void 0;\n\n};\n\nmethod._pushContext = function Promise$_pushContext() {\n    if( !longStackTraces ) return;\n    contextStack.push( this );\n};\n\nmethod._popContext = function Promise$_popContext() {\n    if( !longStackTraces ) return;\n    contextStack.pop();\n};\n\n\nPromise._all =\nfunction Promise$_All( promises, PromiseArray, caller ) {\n    ASSERT(((typeof PromiseArray) === \"function\"),\n    \"typeof PromiseArray === \\u0022function\\u0022\");\n    if( isPromise( promises ) ||\n        isArray( promises ) ) {\n\n        return new PromiseArray( promises,\n            typeof caller === \"function\"\n            ? caller\n            : Promise$_All\n        );\n    }\n    throw new TypeError(\"expecting an array or a promise\");\n};\n\n\nif( !CapturedTrace.isSupported() ) {\n    Promise.longStackTraces = void 0;\n    CapturedTrace.possiblyUnhandledRejection = void 0;\n    Promise.onPossiblyUnhandledRejection = void 0;\n    longStackTraces = false;\n}\n\nreturn Promise;})();\n\n\n\nvar PromiseArray = (function() {\n\nfunction nullToUndefined( val ) {\n    return val === null\n        ? void 0\n        : val;\n}\n\nvar hasOwn = {}.hasOwnProperty;\nvar empty = [];\n\nfunction isPromise( obj ) {\n    if( typeof obj !== \"object\" ) return false;\n    return obj instanceof Promise;\n}\n\nvar Arr = Array;\nvar isArray = Arr.isArray || function( obj ) {\n    return obj instanceof Arr;\n};\n\nfunction PromiseArray( values, caller ) {\n    this._values = values;\n    this._resolver = Promise.pending( caller );\n    this._length = 0;\n    this._totalResolved = 0;\n    this._init( void 0, empty );\n}\nvar method = PromiseArray.prototype;\n\nmethod.length = function PromiseArray$length() {\n    return this._length;\n};\n\nmethod.promise = function PromiseArray$promise() {\n    return this._resolver.promise;\n};\n\n\nmethod._init = function PromiseArray$_init( _, fulfillValueIfEmpty ) {\n    var values = this._values;\n    if( isPromise( values ) ) {\n        if( values.isPending() ) {\n            values._then(\n                this._init,\n                this._reject,\n                void 0,\n                this,\n                fulfillValueIfEmpty,\n                this.constructor\n            );\n            return;\n        }\n        else if( values.isRejected() ) {\n            this._reject( values._resolvedValue );\n            return;\n        }\n        else {\n            values = values._resolvedValue;\n            if( !isArray( values ) ) {\n                this._fulfill( nullToUndefined( fulfillValueIfEmpty ) );\n                return;\n            }\n            this._values = values;\n        }\n\n    }\n    if( !values.length ) {\n        this._fulfill( nullToUndefined( fulfillValueIfEmpty ) );\n        return;\n    }\n    var len = values.length;\n    var newLen = len;\n    var newValues = new Array( len );\n    for( var i = 0; i < len; ++i ) {\n        var promise = values[i];\n\n        if( promise === void 0 && !hasOwn.call( values, i ) ) {\n            newLen--;\n            continue;\n        }\n\n        promise = Promise.cast( promise );\n\n        promise._then(\n            this._promiseFulfilled,\n            this._promiseRejected,\n            this._promiseProgressed,\n\n            this,            Integer.get( i ),             this.constructor\n\n\n\n        );\n        newValues[i] = promise;\n    }\n    this._values = newValues;\n    this._length = newLen;\n};\n\nmethod._isResolved = function PromiseArray$_isResolved() {\n    return this._values === null;\n};\n\nmethod._fulfill = function PromiseArray$_fulfill( value ) {\n    ASSERT((! this._isResolved()),\n    \"!this._isResolved()\");\n    this._values = null;\n    this._resolver.fulfill( value );\n};\n\nmethod._reject = function PromiseArray$_reject( reason ) {\n    ASSERT((! this._isResolved()),\n    \"!this._isResolved()\");\n    this._values = null;\n    this._resolver.reject( reason );\n};\n\nmethod._promiseProgressed =\nfunction PromiseArray$_promiseProgressed( progressValue, index ) {\n    if( this._isResolved() ) return;\n    ASSERT(isArray(this._values),\n    \"isArray( this._values )\");\n\n    this._resolver.progress({\n        index: index.valueOf(),\n        value: progressValue\n    });\n};\n\nmethod._promiseFulfilled =\nfunction PromiseArray$_promiseFulfilled( value, index ) {\n    if( this._isResolved() ) return;\n    ASSERT(isArray(this._values),\n    \"isArray( this._values )\");\n    ASSERT((index instanceof Integer),\n    \"index instanceof Integer\");\n    this._values[ index.valueOf() ] = value;\n    var totalResolved = ++this._totalResolved;\n    if( totalResolved >= this._length ) {\n        this._fulfill( this._values );\n    }\n};\n\nmethod._promiseRejected =\nfunction PromiseArray$_promiseRejected( reason ) {\n    if( this._isResolved() ) return;\n    ASSERT(isArray(this._values),\n    \"isArray( this._values )\");\n    this._totalResolved++;\n    this._reject( reason );\n};\n\nfunction Integer( value ) {\n    this._value = value;\n}\n\nInteger.prototype.valueOf = function Integer$valueOf() {\n    return this._value;\n};\nInteger.get = function Integer$get( i ) {\n    if( i < 256 ) {\n        return ints[i];\n    }\n    return new Integer(i);\n};\n\nvar ints = [];\nfor( var i = 0; i < 256; ++i ) {\n    ints.push( new Integer(i) );\n}\n\n\n\n\n\nreturn PromiseArray;})();\nvar SettledPromiseArray = (function() {\nfunction SettledPromiseArray( values, caller ) {\n    this.constructor$( values, caller );\n}\nvar method = inherits( SettledPromiseArray, PromiseArray );\n\n\n\nmethod._promiseResolved =\nfunction SettledPromiseArray$_promiseResolved( index, inspection ) {\n    ASSERT(((typeof index) === \"number\"),\n    \"typeof index === \\u0022number\\u0022\");\n    this._values[ index ] = inspection;\n    var totalResolved = ++this._totalResolved;\n    if( totalResolved >= this._length ) {\n        this._fulfill( this._values );\n    }\n};\n\nvar throwawayPromise = new Promise()._setTrace();\nmethod._promiseFulfilled =\nfunction SettledPromiseArray$_promiseFulfilled( value, index ) {\n    if( this._isResolved() ) return;\n    var ret = new PromiseInspection( throwawayPromise );\n    ret._bitField = 268435456;\n    ret._resolvedValue = value;\n    this._promiseResolved( index.valueOf(), ret );\n};\nmethod._promiseRejected =\nfunction SettledPromiseArray$_promiseRejected( reason, index ) {\n    if( this._isResolved() ) return;\n    var ret = new PromiseInspection( throwawayPromise );\n    ret._bitField = 134217728;\n    ret._resolvedValue = reason;\n    this._promiseResolved( index.valueOf(), ret );\n};\n\nreturn SettledPromiseArray;})();\nvar AnyPromiseArray = (function() {\nfunction AnyPromiseArray( values, caller ) {\n    this.constructor$( values, caller );\n}\nvar method = inherits( AnyPromiseArray, PromiseArray );\n\nmethod._init = function AnyPromiseArray$_init() {\n    this._init$( void 0, null );\n};\n\nmethod._promiseFulfilled =\nfunction AnyPromiseArray$_promiseFulfilled( value ) {\n    if( this._isResolved() ) return;\n    ++this._totalResolved;\n    this._fulfill( value );\n\n};\nmethod._promiseRejected =\nfunction AnyPromiseArray$_promiseRejected( reason, index ) {\n    if( this._isResolved() ) return;\n    var totalResolved = ++this._totalResolved;\n    this._values[ index.valueOf() ] = reason;\n    if( totalResolved >= this._length ) {\n        this._reject( this._values );\n    }\n\n};\n\nreturn AnyPromiseArray;})();\nvar SomePromiseArray = (function() {\nfunction SomePromiseArray( values, caller ) {\n    this.constructor$( values, caller );\n}\nvar method = inherits( SomePromiseArray, PromiseArray );\n\n\n\nmethod._init = function SomePromiseArray$_init() {\n    this._init$( void 0, [] );\n    this._howMany = 0;\n    this._rejected = 0;\n    this._rejectionValues = new Array( this.length() );\n    this._resolutionValues = new Array( this.length() );\n    if( this._isResolved() ) return;\n\n    if( this._howMany > this._canPossiblyFulfill()  ) {\n        this._reject( [] );\n    }\n};\n\nmethod._canPossiblyFulfill =\nfunction SomePromiseArray$_canPossiblyFulfill() {\n    return this._totalResolved - this._rejected +\n        ( this.length() - this._totalResolved );\n};\n\nmethod._promiseFulfilled =\nfunction SomePromiseArray$_promiseFulfilled( value ) {\n    if( this._isResolved() ) return;\n\n    var totalResolved = this._totalResolved;\n    this._resolutionValues[ totalResolved ] = value;\n    this._totalResolved = totalResolved + 1;\n    if( totalResolved + 1 === this._howMany ) {\n        this._resolutionValues.length = this._howMany;\n        this._fulfill( this._resolutionValues );\n        this._resolutionValues =\n            this._rejectionValues = null;\n    }\n\n};\nmethod._promiseRejected =\nfunction SomePromiseArray$_promiseRejected( reason ) {\n    if( this._isResolved() ) return;\n\n    this._rejectionValues[ this._rejected ] = reason;\n    this._rejected++;\n    this._totalResolved++;\n\n    if( this._howMany > this._canPossiblyFulfill() ) {\n        this._rejectionValues.length = this._rejected;\n        this._reject( this._rejectionValues );\n        this._resolutionValues =\n            this._rejectionValues = null;\n    }\n};\n\nreturn SomePromiseArray;})();\nvar PromiseInspection = (function() {\n\n\nfunction PromiseInspection( promise ) {\n    this._bitField = promise._bitField;\n    this._resolvedValue = promise.isResolved()\n        ? promise._resolvedValue\n        : void 0;\n}\nvar method = PromiseInspection.prototype;\n\nmethod.isFulfilled = function PromiseInspection$isFulfilled() {\n    return ( this._bitField & 268435456 ) > 0;\n};\n\nmethod.isRejected = function PromiseInspection$isRejected() {\n    return ( this._bitField & 134217728 ) > 0;\n};\n\nmethod.isPending = function PromiseInspection$isPending() {\n    return ( this._bitField & 402653184 ) === 0;\n};\n\nmethod.value = function PromiseInspection$value() {\n    if( !this.isFulfilled() ) {\n        throw new TypeError(\n            \"cannot get fulfillment value of a non-fulfilled promise\");\n    }\n    return this._resolvedValue;\n};\n\nmethod.error = function PromiseInspection$error() {\n    if( !this.isRejected() ) {\n        throw new TypeError(\n            \"cannot get rejection reason of a non-rejected promise\");\n    }\n    return this._resolvedValue;\n};\n\n\n\n\nreturn PromiseInspection;})();\n\nvar PromiseResolver = (function() {\n\nfunction PromiseResolver( promise ) {\n    this.promise = promise;\n}\nvar method = PromiseResolver.prototype;\n\nmethod.toString = function PromiseResolver$toString() {\n    return \"[object PromiseResolver]\";\n};\n\nmethod.fulfill = function PromiseResolver$fulfill( value ) {\n    if( this.promise._tryAssumeStateOf( value, false ) ) {\n        return;\n    }\n    async.invoke( this.promise._fulfill, this.promise, value );\n};\n\nmethod.reject = function PromiseResolver$reject( reason ) {\n    this.promise._attachExtraTrace( reason );\n    async.invoke( this.promise._reject, this.promise, reason );\n};\n\nmethod.progress = function PromiseResolver$progress( value ) {\n    async.invoke( this.promise._progress, this.promise, value );\n};\n\nmethod.cancel = function PromiseResolver$cancel() {\n    async.invoke( this.promise.cancel, this.promise, void 0 );\n};\n\nmethod.timeout = function PromiseResolver$timeout() {\n    this.reject( new TimeoutError( \"timeout\" ) );\n};\n\nmethod.isResolved = function PromiseResolver$isResolved() {\n    return this.promise.isResolved();\n};\n\nmethod.toJSON = function PromiseResolver$toJSON() {\n    return this.promise.toJSON();\n};\n\n\nreturn PromiseResolver;})();\nif( typeof module !== \"undefined\" && module.exports ) {\n    module.exports = Promise;\n}\nelse if( typeof define === \"function\" && define.amd ) {\n    define( \"Promise\", [], function(){return Promise;});\n}\nelse {\n    global.Promise = Promise;\n}\n\n\nreturn Promise;})(\n    new Function(\"return this\")(),\n    Function,\n    Array,\n    Error,\n    Object\n);\n"
  },
  {
    "path": "test/mocha/helpers/error.js",
    "content": "\n"
  },
  {
    "path": "test/mocha/helpers/reasons.js",
    "content": "\"use strict\";\n\n// This module exports some valid rejection reason factories, keyed by human-readable versions of their names.\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\n\nvar dummy = { dummy: \"dummy\" };\n\nexports[\"`undefined`\"] = function () {\n    return undefined;\n};\n\nexports[\"`null`\"] = function () {\n    return null;\n};\n\nexports[\"`false`\"] = function () {\n    return false;\n};\n\nexports[\"`0`\"] = function () {\n    return 0;\n};\n\nexports[\"an error\"] = function () {\n    return new Error();\n};\n\nexports[\"an error without a stack\"] = function () {\n    var error = new Error();\n    delete error.stack;\n\n    return error;\n};\n\nexports[\"a date\"] = function () {\n    return new Date();\n};\n\nexports[\"an object\"] = function () {\n    return {};\n};\n\nexports[\"an always-pending thenable\"] = function () {\n    return { then: function () { } };\n};\n\nexports[\"a fulfilled promise\"] = function () {\n    return fulfilled(dummy);\n};\n\nexports[\"a rejected promise\"] = function () {\n    return rejected(dummy);\n};\n"
  },
  {
    "path": "test/mocha/helpers/testThreeCases.js",
    "content": "\"use strict\";\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\nvar pending = adapter.pending;\n\nfunction success(done) {\n    return function() {\n        done();\n    };\n}\n\nfunction fail(done) {\n    return function(err) {\n        done(err);\n    };\n}\n\nfunction handlePromise(val, done) {\n    if (val && typeof val.then === \"function\") {\n        val.then(success(done), fail(done));\n    }\n}\n\nexports.testFulfilled = function (value, test) {\n    specify(\"already-fulfilled\", function (done) {\n        handlePromise(test(fulfilled(value), done), done);\n    });\n\n    specify(\"immediately-fulfilled\", function (done) {\n        var tuple = pending();\n        handlePromise(test(tuple.promise, done), done);\n        tuple.fulfill(value);\n    });\n\n    specify(\"eventually-fulfilled\", function (done) {\n        var tuple = pending();\n        handlePromise(test(tuple.promise, done), done);\n        setTimeout(function () {\n            tuple.fulfill(value);\n        }, 1);\n    });\n};\n\nexports.testRejected = function (reason, test) {\n    specify(\"already-rejected\", function (done) {\n        handlePromise(test(rejected(reason), done), done);\n    });\n\n    specify(\"immediately-rejected\", function (done) {\n        var tuple = pending();\n        handlePromise(test(tuple.promise, done), done);\n        tuple.reject(reason);\n    });\n\n    specify(\"eventually-rejected\", function (done) {\n        var tuple = pending();\n        handlePromise(test(tuple.promise, done), done);\n        setTimeout(function () {\n            tuple.reject(reason);\n        }, 1);\n    });\n};\n"
  },
  {
    "path": "test/mocha/helpers/thenables.js",
    "content": "\"use strict\";\n\nvar adapter = global.adapter;\nvar fulfilled = adapter.fulfilled;\nvar rejected = adapter.rejected;\nvar pending = adapter.pending;\n\nvar other = { other: \"other\" }; // a value we don't want to be strict equal to\n\nexports.fulfilled = {\n    \"a synchronously-fulfilled custom thenable\": function (value) {\n        return {\n            then: function (onFulfilled) {\n                onFulfilled(value);\n            }\n        };\n    },\n\n    \"an asynchronously-fulfilled custom thenable\": function (value) {\n        return {\n            then: function (onFulfilled) {\n                setTimeout(function () {\n                    onFulfilled(value);\n                }, 1);\n            }\n        };\n    },\n\n    \"a synchronously-fulfilled one-time thenable\": function (value) {\n        var numberOfTimesThenRetrieved = 0;\n        var ret = Object.create(null, {\n            then: {\n                get: function () {\n\n                    if (numberOfTimesThenRetrieved === 0) {\n                        ++numberOfTimesThenRetrieved;\n                        return function (onFulfilled) {\n                            onFulfilled(value);\n                        };\n                    }\n                    return null;\n                }\n            }\n        });\n        return ret;\n    },\n\n    \"a thenable that tries to fulfill twice\": function (value) {\n        return {\n            then: function (onFulfilled) {\n                onFulfilled(value);\n                onFulfilled(other);\n            }\n        };\n    },\n\n    \"a thenable that fulfills but then throws\": function (value) {\n        return {\n            then: function (onFulfilled) {\n                onFulfilled(value);\n                throw other;\n            }\n        };\n    },\n\n    \"an already-fulfilled promise\": function (value) {\n        return fulfilled(value);\n    },\n\n    \"an eventually-fulfilled promise\": function (value) {\n        var tuple = pending();\n        setTimeout(function () {\n            tuple.fulfill(value);\n        }, 1);\n        return tuple.promise;\n    }\n};\n\nexports.rejected = {\n    \"a synchronously-rejected custom thenable\": function (reason) {\n        return {\n            then: function (onFulfilled, onRejected) {\n                onRejected(reason);\n            }\n        };\n    },\n\n    \"an asynchronously-rejected custom thenable\": function (reason) {\n        return {\n            then: function (onFulfilled, onRejected) {\n                setTimeout(function () {\n                    onRejected(reason);\n                }, 1);\n            }\n        };\n    },\n\n    \"a synchronously-rejected one-time thenable\": function (reason) {\n        var numberOfTimesThenRetrieved = 0;\n        return Object.create(null, {\n            then: {\n                get: function () {\n                    if (numberOfTimesThenRetrieved === 0) {\n                        ++numberOfTimesThenRetrieved;\n                        return function (onFulfilled, onRejected) {\n                            onRejected(reason);\n                        };\n                    }\n                    return null;\n                }\n            }\n        });\n    },\n\n    \"a thenable that immediately throws in `then`\": function (reason) {\n        return {\n            then: function () {\n                throw reason;\n            }\n        };\n    },\n\n    \"an object with a throwing `then` accessor\": function (reason) {\n        return Object.create(null, {\n            then: {\n                get: function () {\n                    throw reason;\n                }\n            }\n        });\n    },\n\n    \"an already-rejected promise\": function (reason) {\n        var ret = rejected(reason);\n        ret.caught(function(){});\n        return ret;\n    },\n\n    \"an eventually-rejected promise\": function (reason) {\n        var tuple = pending();\n        setTimeout(function () {\n            tuple.reject(reason);\n        }, 1);\n        return tuple.promise;\n    }\n};\n"
  },
  {
    "path": "test/mocha/helpers/util.js",
    "content": "var assert = require(\"assert\");\nvar token = {};\nmodule.exports = {\n    awaitGlobalException: function(fn) {\n        function replaceListeners(by) {\n            var single = typeof by === \"function\";\n            if (process.title === \"browser\") {\n                var original = window.onerror;\n                window.onerror = single ? function(message, file, line, column, e) {\n                    return by(e);\n                } : by[0];\n                return [original];\n            } else {\n                var original = process.listeners(\"uncaughtException\");\n                process.removeAllListeners(\"uncaughtException\");\n                if (single) by = [by];\n                by.forEach(function(listener) {\n                    process.on(\"uncaughtException\", listener);\n                });\n                return original;\n            }\n        }\n        return new Promise(function(resolve, reject) {\n            var listeners = replaceListeners(function(e) {\n                var err;\n                var ret;\n                try {\n                    ret = fn(e);\n                } catch (e) {\n                    err = e;\n                }\n                if (!err && ret === false) return;\n                replaceListeners(listeners);\n                Promise.delay(1).then(function() {\n                    if (err) reject(err);\n                    resolve();\n                });\n            });\n        });\n    },\n\n    awaitLateQueue: function(fn) {\n        return new Promise(function(res, rej) {\n            Promise._async.invokeLater(function() {\n                try {\n                    var result = fn();\n                    res(result);\n                } catch(e) {\n                    rej(e);\n                }\n            }, null, null);\n        });\n    },\n\n    awaitProcessExit: function(fn) {\n        if (typeof process !== \"undefined\" && typeof process.execPath === \"string\") {\n            var exit;\n            return new Promise(function(resolve, reject) {\n                exit = process.exit;\n                process.exit = function(code) {\n                    try {\n                        assert(code != 0);\n                        fn();\n                        resolve();\n                    } catch (e) {\n                        reject(e);\n                    }\n                };\n            }).lastly(function() {\n                process.exit = exit;\n            });\n        } else {\n            return Promise.delay(1);\n        }\n    },\n\n    addDeferred: function(Promise) {\n        Promise.defer = Promise.pending = function() {\n            var ret = {};\n            ret.promise = new Promise(function(resolve, reject) {\n                ret.resolve = ret.fulfill = resolve;\n                ret.reject = reject;\n            });\n            return ret;\n        };\n        return Promise;\n    },\n\n    returnToken: function() {\n        return token;\n    },\n\n    assertToken: function(val) {\n        assert.strictEqual(token, val);\n    },\n\n    getSpy: function() {\n        var resolve, reject;\n        var promise = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        var ret = function(fn) {\n            ret.callback = fn;\n            return ret.node;\n        };\n        ret.promise = promise;\n        ret.node = function() {\n            try {\n                ret.callback.apply(this, arguments);\n                resolve();\n            } catch (e) {\n                reject(e);\n            }\n        };\n        return ret;\n    },\n\n    awaitDomainException: function(onError, fn) {\n        var domain;\n        var resolve, reject;\n        var promise = new Promise(function() {\n            resolve = arguments[0];\n            reject = arguments[1];\n        });\n        domain = require('domain').create();\n        domain.on(\"error\", function(e) {\n            try {\n                onError(e);\n                resolve();\n            } catch (err) {\n                reject(err);\n            }\n        });\n        domain.run(fn);\n        return promise;\n    },\n\n    onUnhandledFail: function(testFunction) {\n        Promise._unhandledRejectionClear();\n        return new Promise(function(resolve, reject) {\n            var err = new Error(\"Reporting handled rejection as unhandled from: \" +\n                    testFunction);\n            Promise.onPossiblyUnhandledRejection(function() {\n                reject(err);\n            });\n            Promise.delay(150).then(function() {\n                Promise._unhandledRejectionCheck();\n                resolve();\n            });\n        }).lastly(function() {\n            Promise.onPossiblyUnhandledRejection(null);\n        });\n    },\n\n    onUnhandledSucceed: function(testAgainst, count) {\n        return new Promise(function(resolveTest, reject) {\n            var total = typeof count === \"number\" ? count : 1;\n            var cur = 0;\n\n            function resolve(e) {\n                cur++;\n                if (cur >= total) {\n                    resolveTest(e);\n                }\n            }\n\n            Promise.onPossiblyUnhandledRejection(function(e){\n                 if (testAgainst !== undefined) {\n                    try {\n                        if (typeof testAgainst === \"function\") {\n                            assert(testAgainst(e));\n                        }\n                        else {\n                            assert.equal(testAgainst, e);\n                        }\n                        resolve(e);\n                    }\n                    catch (e) {\n                        reject(e);\n                    }\n                 } else {\n                    resolve(e);\n                 }\n            });\n            Promise.delay(50).then(function() {\n                Promise._unhandledRejectionCheck();\n                return Promise.delay(1);\n            }).then(function() {\n                var message = \"Expected onPossiblyUnhandledRejection to be called \" +\n                    total + \" times but it was only called \" + cur + \" times\";\n                reject(new Error(message));\n            });\n        }).lastly(function() {\n            Promise.onPossiblyUnhandledRejection(null);\n        });\n\n    },\n\n    //Used in expressions like: onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    //If strict mode is supported NFEs work, if it is not, NFEs don't work but arguments.callee does\n    isStrictModeSupported: (function() {\n        try {\n            new Function(\"'use strict'; with({});\");\n            return false;\n        }\n        catch (e) {\n            return true;\n        }\n    })(),\n\n    noop: function(v) {\n        return v;\n    },\n\n    isSubset: function(subset, superset) {\n        var i, subsetLen;\n\n        subsetLen = subset.length;\n\n        if (subsetLen > superset.length) {\n            return false;\n        }\n\n        for(i = 0; i<subsetLen; i++) {\n            if(!module.exports.contains(superset, subset[i])) {\n                return false;\n            }\n        }\n\n        return true;\n    },\n\n    contains: function(arr, result) {\n        return arr.indexOf(result) > -1;\n    },\n\n    fakeResolved: function(val) {\n        return {\n            then: function(callback) {\n                return fakeResolved(callback ? callback(val) : val);\n            }\n        };\n    },\n\n    fakeRejected: function(reason) {\n        return {\n            then: function(callback, errback) {\n                return errback ? fakeResolved(errback(reason)) : fakeRejected(reason);\n            }\n        };\n    },\n\n    assertFulfilled: function(p, v) {\n        assert.strictEqual(p.value(), v);\n    },\n\n    assertRejected: function(p, v) {\n        assert.strictEqual(p.error(), v);\n    },\n\n    ecmaScript6Collections: (typeof Set === \"function\" &&\n                            typeof Symbol !== \"undefined\" &&\n                            Symbol.iterator &&\n                            typeof ((new Set())[Symbol.iterator]().next) === \"function\"),\n\n    ecmaScript5: (function() {\"use strict\"\n      return this === undefined;\n    })(),\n    isNodeJS: typeof process !== \"undefined\" && typeof process.execPath === \"string\"\n};\n\nif (module.exports.isNodeJS) {\n    var version = process.versions.node.split(\".\").map(Number);\n    module.exports.isRecentNode = version[0] > 0;\n    module.exports.isOldNode = !module.exports.isRecentNode;\n} else {\n    module.exports.isOldNode = false;\n    module.exports.isRecentNode = false;\n}\n"
  },
  {
    "path": "test/mocha/is.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\ndescribe(\"Promise.is\", function() {\n    it(\"should return true for trusted promise\", function() {\n        assert.strictEqual(Promise.is(new Promise(function(){})), true);\n    });\n    it(\"should return false for untrusted promise\", function() {\n        assert.strictEqual(Promise.is({\n            then: function() {}\n        }), false);\n    });\n});\n"
  },
  {
    "path": "test/mocha/join.js",
    "content": "\"use strict\";\n/*\nBased on When.js tests\n\nOpen Source Initiative OSI - The MIT License\n\nhttp://www.opensource.org/licenses/mit-license.php\n\nCopyright (c) 2011 Brian Cavalier\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\ndescribe(\"Promise.join-test\", function () {\n\n\n\n    specify(\"should resolve empty input\", function() {\n        return Promise.join().then(\n            function(result) {\n                assert.deepEqual(result, []);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should join values\", function() {\n        return Promise.join(1, 2, 3).then(\n            function(results) {\n                assert.deepEqual(results, [1, 2, 3]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should join promises array\", function() {\n        return Promise.join(Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)).then(\n            function(results) {\n                assert.deepEqual(results, [1, 2, 3]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should join mixed array\", function() {\n        return Promise.join(Promise.resolve(1), 2, Promise.resolve(3), 4).then(\n            function(results) {\n                assert.deepEqual(results, [1, 2, 3, 4]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reject if any input promise rejects\", function() {\n        return Promise.join(Promise.resolve(1), Promise.reject(2), Promise.resolve(3)).then(\n            assert.fail,\n            function(err) {\n                assert.deepEqual(err, 2);\n            }\n        );\n    });\n\n    specify(\"should call last argument as a spread function\", function() {\n        return Promise.join(Promise.resolve(1), Promise.resolve(2), Promise.resolve(3), function(a, b, c) {\n            assert(a === 1);\n            assert(b === 2);\n            assert(c === 3);\n        });\n    });\n\n\n    specify(\"gh-227\", function() {\n        function a() {\n            return Promise.join(Promise.resolve(1), function () {\n                throw new Error();\n            });\n        }\n\n        return a().then(assert.fail, function(e) {});\n    });\n\n    specify(\"should not pass the callback as argument, <5 arguments\", function() {\n        return Promise.join(1, 2, 3, function() {\n            assert.strictEqual(arguments.length, 3);\n        });\n    });\n\n    specify(\"should not pass the callback as argument >5 arguments\", function() {\n        return Promise.join(1, 2, 3, 4, 5, 6, 7, function() {\n            assert.strictEqual(arguments.length, 7);\n        });\n    });\n\n    specify(\"should ensure asynchronity\", function() {\n        var sync = false;\n        Promise.join(Promise.resolve(1), Promise.resolve(2), function() {\n            sync = true;\n        });\n        assert.strictEqual(false, sync);\n    })\n});\n"
  },
  {
    "path": "test/mocha/late_buffer_safety.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar isNodeJS = testUtils.isNodeJS;\n\nfunction async(cb){\n    return Promise.resolve().nodeify(cb);\n}\n\nif (isNodeJS) {\n    describe(\"Late buffer\", function() {\n        specify(\"shouldn't stop at first error but continue consumption until everything is consumed\", function(){\n            var length = 10;\n            var l = length;\n            var a = 0;\n            while (l--){\n                async(function(){\n                    throw (a++);\n                });\n            }\n            var errs = [];\n            return testUtils.awaitGlobalException(function(e) {\n                errs.push(e);\n                if (errs.length === length) {\n                    var a = [];\n                    for (var i = 0, len = length; i < len; ++i) {\n                        a[i] = i;\n                    }\n                    assert.deepEqual(a, errs);\n                } else {\n                    return false;\n                }\n            });\n        });\n    });\n}\n"
  },
  {
    "path": "test/mocha/long_stack_traces.js",
    "content": "var assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar assertLongTrace = require(\"./helpers/assert_long_trace.js\");\nvar nodeVersion = typeof process !== \"undefined\" &&\n        typeof process.version === \"string\"\n        ? process.version.replace(/[^0-9.]/g, \"\").split(\".\").map(Number)\n        : [-1, -1, -1];\n\n// Node's V8 captureStackTrace is completely broken - it returns different\n// results on different runs and sometimes causes this test to fail\nif (!Promise.hasLongStackTraces() || testUtils.isOldNode) return;\n\ndescribe(\".then as context\", function() {\n    it(\"1 level\", function() {\n        return Promise.resolve().then(function() {\n            throw new Error();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"4 levels\", function() {\n        return Promise.resolve().then(function() {\n            return Promise.resolve().then(function() {\n                return Promise.resolve().then(function() {\n                    return Promise.resolve().then(function() {\n                        throw new Error();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n    it(\"1 level using promise reject with no stack\", function() {\n        return Promise.resolve().then(function() {\n            var e;\n            try {throw new Error()} catch (err){e = err;}\n            e.stack;\n            delete e.stack;\n            return Promise.reject(e);\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1, 1]);\n        });\n    });\n    it(\"4 levels using promise reject\", function() {\n        return Promise.resolve().then(function() {\n            return Promise.resolve().then(function() {\n                return Promise.resolve().then(function() {\n                    return Promise.resolve().then(function() {\n                        var e;\n                        try {throw new Error()} catch (err){e = err;}\n                        return Promise.reject(e);\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n    it(\"Circular 1 level\", function() {\n        var i = 0;\n        return (function circle() {\n            if (i++ > 5) throw new Error()\n            return Promise.resolve().then(circle);\n        })().then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"Circular 4 levels\", function() {\n        var i = 0;\n        return (function circle() {\n            if (i++ > 5) throw new Error()\n            return Promise.resolve().then(function() {\n                return Promise.resolve().then(function() {\n                    return Promise.resolve().then(function() {\n                        return Promise.resolve().then(circle);\n                    });\n                });\n            });\n        })().then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n\n    it(\"followers unaffected\", function() {\n        return Promise.resolve().then(function() {\n            return new Promise(function(res) {\n                res(Promise.delay(13).then(function() {\n                    return new Promise(function(res) {\n                        res(Promise.delay(13).then(function() {\n                            throw new Error();\n                        }));\n                    });\n                }));\n            }).then(assert.fail, function(e) {\n                assertLongTrace(e, 5 + 1, [1, 1, 1, 1, 1]);\n                throw new Error();\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 2 + 1, [1, 1]);\n        });\n    });\n\n    it(\"3 distinct episodes of circularity with unique frames in between\", function() {\n        var i = 0;\n        var j = 0;\n        var k = 0;\n\n        function circle1() {\n            if (i++ > 5) return u1_1();\n            return Promise.resolve().then(function() {\n                return Promise.resolve().then(function() {\n                    return Promise.resolve().then(function() {\n                        return Promise.resolve().then(circle1);\n                    });\n                });\n            });\n        }\n\n        function circle2() {\n            if (j++ > 5) return u2_1();\n            return Promise.resolve().then(function() {\n                return Promise.resolve().then(function() {\n                    return Promise.resolve().then(function() {\n                        return Promise.resolve().then(circle2);\n                    });\n                });\n            });\n        }\n\n        function circle3() {\n            if (k++ > 5) return u3_1();\n            return Promise.resolve().then(function() {\n                return Promise.resolve().then(function() {\n                    return Promise.resolve().then(function() {\n                        return Promise.resolve().then(circle3);\n                    });\n                });\n            });\n        }\n\n        function u1_1() {\n            return Promise.resolve().then(u1_2);\n        }\n\n        function u1_2() {\n            return Promise.resolve().then(circle2);\n        }\n\n        function u2_1() {\n            return Promise.resolve().then(u2_2);\n        }\n\n        function u2_2() {\n            return Promise.resolve().then(circle3);\n        }\n\n        function u3_1() {\n            return Promise.resolve().then(u3_2);\n        }\n\n        function u3_2() {\n            return Promise.resolve().then(function() {\n                throw new Error(\"The error\");\n            });\n        }\n\n        return circle1().then(assert.fail, function(e) {\n            assertLongTrace(e,\n                1 + 1 + 1 + 1,\n                [\n                    1, 1, 2, 1, 1,\n                    1, 1, 2, 1, 1,\n                    1, 1, 2, 1, 1\n                ]);\n        });\n    });\n});\n\ndescribe(\".spread as context\", function() {\n    it(\"1 level\", function() {\n        return Promise.resolve([]).spread(function() {\n            throw new Error();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"4 levels\", function() {\n        return Promise.resolve([]).spread(function() {\n            return Promise.resolve([]).spread(function() {\n                return Promise.resolve([]).spread(function() {\n                    return Promise.resolve([]).spread(function() {\n                        throw new Error();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n});\n\ndescribe(\"constructor as context\", function() {\n    it(\"0 level\", function() {\n        return new Promise(function() {\n            throw new Error();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1, []);\n        });\n    });\n    it(\"1 level\", function() {\n        return new Promise(function(res) {\n            res(new Promise(function() {\n                throw new Error();\n            }))\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [2]);\n        });\n    });\n    it(\"0 level, no stack property\", function() {\n        return new Promise(function(_ ,rej) {\n            var e = new Error();\n            e.stack;\n            delete e.stack;\n            rej(e);\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1, [1]);\n        });\n    });\n    it(\"1 level, no stack property\", function() {\n        return new Promise(function(res) {\n            res(new Promise(function(_, rej) {\n                var e = new Error();\n                e.stack;\n                delete e.stack;\n                rej(e);\n            }))\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1, 1]);\n        });\n    });\n\n    it(\"4 levels\", function() {\n        return new Promise(function(res) {\n            res(new Promise(function(res) {\n                res(new Promise(function(res) {\n                    res(new Promise(function(res) {\n                        res(new Promise(function(res) {\n                            throw new Error();\n                        }));\n                    }));\n                }));\n            }));\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [2, 1, 1, 1]);\n        });\n    });\n});\n\ndescribe(\".join as context\", function() {\n    it(\"0 level\", function() {\n        var err;\n        try {throw new Error(); } catch(e) {err = e;};\n        return Promise.join(1, 2, Promise.reject(err), function() {\n            throw new Error();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 0 + 1, []);\n        });\n    });\n    it(\"1 level\", function() {\n        return Promise.join(1, 2, 3, function() {\n            throw new Error();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"4 levels\", function() {\n        return Promise.join(1, 2, 3, function() {\n            return Promise.join(1, 2, 3, function() {\n                return Promise.join(1, 2, 3, function() {\n                    return Promise.join(1, 2, 3, function() {\n                        throw new Error();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n});\n\ndescribe(\".map as context\", function() {\n    it(\"1 level\", function() {\n        return Promise.map([1,2,3], function() {\n            throw new Error();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"4 levels\", function() {\n        return Promise.map([1,2,3], function() {\n            return Promise.map([1,2,3], function() {\n                return Promise.map([1,2,3], function() {\n                    return Promise.map([1,2,3], function() {\n                        throw new Error();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n});\n\ndescribe(\".reduce as context\", function() {\n    it(\"1 level\", function() {\n        return Promise.reduce([1,2,3], function() {\n            throw new Error();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"4 levels\", function() {\n        return Promise.reduce([1,2,3], function() {\n            return Promise.reduce([1,2,3], function() {\n                return Promise.reduce([1,2,3], function() {\n                    return Promise.reduce([1,2,3], function() {\n                        throw new Error();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n});\n\ndescribe(\".method as context\", function() {\n    it(\"1 level\", function() {\n        return Promise.method(function() {\n            throw new Error();\n        })().then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"4 levels\", function() {\n        var second = Promise.method(function() {\n            return third();\n        });\n        var third = Promise.method(function() {\n            return fourth();\n        });\n        var fourth = Promise.method(function() {\n            throw new Error();\n        });\n\n        return Promise.method(function() {\n            return second();\n        })().then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [[1,2], 1, 1, 1]);\n        });\n    });\n});\n\ndescribe(\".try as context\", function() {\n    it(\"1 level\", function() {\n        return Promise.attempt(function() {\n            throw new Error();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n\n    it(\"4 levels\", function() {\n        return Promise.attempt(function() {\n            return Promise.attempt(function() {\n                return Promise.attempt(function() {\n                    return Promise.attempt(function() {\n                        throw new Error();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n});\n\ndescribe(\".using as context\", function() {\n    it(\"0 level\", function() {\n        var err;\n        try {throw new Error(); } catch(e) {err = e};\n        return Promise.using(1, 2, Promise.reject(err), function() {\n            throw new Error();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 0 + 1, []);\n        });\n    });\n    it(\"1 level\", function() {\n        return Promise.using(1, 2, 3, function() {\n            throw new Error();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"4 levels\", function() {\n        return Promise.using(1, 2, 3, function() {\n            return Promise.using(1, 2, 3, function() {\n                return Promise.using(1, 2, 3, function() {\n                    return Promise.using(1, 2, 3, function() {\n                        throw new Error();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n});\n\ndescribe(\"Long stack traces from thenable rejections\", function() {\n    var es5 = (function(){\"use strict\"; return this})() === undefined;\n    // Todo, for 100% coverage thenables should be tested with every\n    // feature, not just then\n    var syncRej = function() {\n        return {\n            then: function(_, rej) {\n                rej(new Error());\n            }\n        };\n    };\n    var asyncRej = function() {\n        return {\n            then: function(_, rej) {\n                setTimeout(function() {\n                    rej(new Error());\n                }, 1);\n            }\n        };\n    };\n    var throwRej = function() {\n        return {\n            then: function(_, rej) {\n                throw(new Error());\n            }\n        };\n    };\n    var thenGetRej = function() {\n        var ret = {};\n        Object.defineProperty(ret, \"then\", {\n            get: function() {\n                throw new Error()\n            }\n        });\n        return ret;\n    };\n    it(\"1 level sync reject\", function() {\n        return Promise.resolve().then(function() {\n            return syncRej();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1+1, [1]);\n        });\n    });\n    it(\"4 levels sync reject\", function() {\n        return Promise.resolve().then(function() {\n            return Promise.resolve().then(function() {\n                return Promise.resolve().then(function() {\n                    return Promise.resolve().then(function() {\n                        return syncRej();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n    it(\"1 level async reject\", function() {\n        return Promise.resolve().then(function() {\n            return asyncRej();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"4 levels async reject\", function() {\n        return Promise.resolve().then(function() {\n            return Promise.resolve().then(function() {\n                return Promise.resolve().then(function() {\n                    return Promise.resolve().then(function() {\n                        return asyncRej();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n    it(\"1 level throw\", function() {\n        return Promise.resolve().then(function() {\n            return throwRej();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"4 levels throw\", function() {\n        return Promise.resolve().then(function() {\n            return Promise.resolve().then(function() {\n                return Promise.resolve().then(function() {\n                    return Promise.resolve().then(function() {\n                        return throwRej();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n    it(\"1 level getter throw\", function() {\n        return Promise.resolve().then(function() {\n            return thenGetRej();\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 1 + 1, [1]);\n        });\n    });\n    it(\"4 levels getter throw\", function() {\n        return Promise.resolve().then(function() {\n            return Promise.resolve().then(function() {\n                return Promise.resolve().then(function() {\n                    return Promise.resolve().then(function() {\n                        return thenGetRej();\n                    });\n                });\n            });\n        }).then(assert.fail, function(e) {\n            assertLongTrace(e, 4 + 1, [1, 1, 1, 1]);\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/map.js",
    "content": "\"use strict\";\n/*\nBased on When.js tests\n\nOpen Source Initiative OSI - The MIT License\n\nhttp://www.opensource.org/licenses/mit-license.php\n\nCopyright (c) 2011 Brian Cavalier\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\ndescribe(\"Promise.map-test\", function () {\n\n    function mapper(val) {\n        return val * 2;\n    }\n\n    function deferredMapper(val) {\n        return Promise.delay(1, mapper(val));\n    }\n\n    specify(\"should map input values array\", function() {\n        var input = [1, 2, 3];\n        return Promise.map(input, mapper).then(\n            function(results) {\n                assert.deepEqual(results, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should map input promises array\", function() {\n        var input = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];\n        return Promise.map(input, mapper).then(\n            function(results) {\n                assert.deepEqual(results, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should map mixed input array\", function() {\n        var input = [1, Promise.resolve(2), 3];\n        return Promise.map(input, mapper).then(\n            function(results) {\n                assert.deepEqual(results, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should map input when mapper returns a promise\", function() {\n        var input = [1,2,3];\n        return Promise.map(input, deferredMapper).then(\n            function(results) {\n                assert.deepEqual(results, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should accept a promise for an array\", function() {\n        return Promise.map(Promise.resolve([1, Promise.resolve(2), 3]), mapper).then(\n            function(result) {\n                assert.deepEqual(result, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should throw a TypeError when input promise does not resolve to an array\", function() {\n        return Promise.map(Promise.resolve(123), mapper).caught(TypeError, function(e){\n        });\n    });\n\n    specify(\"should map input promises when mapper returns a promise\", function() {\n        var input = [Promise.resolve(1),Promise.resolve(2),Promise.resolve(3)];\n        return Promise.map(input, mapper).then(\n            function(results) {\n                assert.deepEqual(results, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reject when input contains rejection\", function() {\n        var input = [Promise.resolve(1), Promise.reject(2), Promise.resolve(3)];\n        return Promise.map(input, mapper).then(\n            assert.fail,\n            function(result) {\n                assert(result === 2);\n            }\n        );\n    });\n\n    specify(\"should call mapper asynchronously on values array\", function() {\n        var calls = 0;\n        function mapper(val) {\n            calls++;\n        }\n\n        var input = [1, 2, 3];\n        var p = Promise.map(input, mapper);\n        assert(calls === 0);\n        return p.then(function() {\n            assert(calls === 3);\n        });\n    });\n\n    specify(\"should call mapper asynchronously on promises array\", function() {\n        var calls = 0;\n        function mapper(val) {\n            calls++;\n        }\n\n        var input = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];\n        var p = Promise.map(input, mapper);\n        assert(calls === 0);\n        return p.then(function() {\n            assert(calls === 3);\n        });\n    });\n\n    specify(\"should call mapper asynchronously on mixed array\", function() {\n        var calls = 0;\n        function mapper(val) {\n            calls++;\n        }\n\n        var input = [1, Promise.resolve(2), 3];\n        var p = Promise.map(input, mapper);\n        assert(calls === 0);\n        return p.then(function() {\n            assert(calls === 3);\n        });\n    });\n});\n\ndescribe(\"Promise.map-test with concurrency\", function () {\n\n    var concurrency = {concurrency: 2};\n\n    function mapper(val) {\n        return val * 2;\n    }\n\n    function deferredMapper(val) {\n        return Promise.delay(1, mapper(val));\n    }\n\n    specify(\"should map input values array with concurrency\", function() {\n        var input = [1, 2, 3];\n        return Promise.map(input, mapper, concurrency).then(\n            function(results) {\n                assert.deepEqual(results, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should map input promises array with concurrency\", function() {\n        var input = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];\n        return Promise.map(input, mapper, concurrency).then(\n            function(results) {\n                assert.deepEqual(results, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should map mixed input array with concurrency\", function() {\n        var input = [1, Promise.resolve(2), 3];\n        return Promise.map(input, mapper, concurrency).then(\n            function(results) {\n                assert.deepEqual(results, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should map input when mapper returns a promise with concurrency\", function() {\n        var input = [1,2,3];\n        return Promise.map(input, deferredMapper, concurrency).then(\n            function(results) {\n                assert.deepEqual(results, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should accept a promise for an array with concurrency\", function() {\n        return Promise.map(Promise.resolve([1, Promise.resolve(2), 3]), mapper, concurrency).then(\n            function(result) {\n                assert.deepEqual(result, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should resolve to empty array when input promise does not resolve to an array with concurrency\", function() {\n        return Promise.map(Promise.resolve(123), mapper, concurrency).caught(TypeError, function(e){\n        });\n    });\n\n    specify(\"should map input promises when mapper returns a promise with concurrency\", function() {\n        var input = [Promise.resolve(1),Promise.resolve(2),Promise.resolve(3)];\n        return Promise.map(input, mapper, concurrency).then(\n            function(results) {\n                assert.deepEqual(results, [2,4,6]);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reject when input contains rejection with concurrency\", function() {\n        var input = [Promise.resolve(1), Promise.reject(2), Promise.resolve(3)];\n        return Promise.map(input, mapper, concurrency).then(\n            assert.fail,\n            function(result) {\n                assert(result === 2);\n            }\n        );\n    });\n\n    specify(\"should not have more than {concurrency} promises in flight\", function() {\n        var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n        var b = [];\n        var now = Date.now();\n\n        var immediates = [];\n        function immediate(index) {\n            var resolve;\n            var ret = new Promise(function(){resolve = arguments[0]});\n            immediates.push([ret, resolve, index]);\n            return ret;\n        }\n\n        var lates = [];\n        function late(index) {\n            var resolve;\n            var ret = new Promise(function(){resolve = arguments[0]});\n            lates.push([ret, resolve, index]);\n            return ret;\n        }\n\n\n        function promiseByIndex(index) {\n            return index < 5 ? immediate(index) : late(index);\n        }\n\n        function resolve(item) {\n            item[1](item[2]);\n        }\n\n        var ret1 = Promise.map(array, function(value, index) {\n            return promiseByIndex(index).then(function() {\n                b.push(value);\n            });\n        }, {concurrency: 5});\n\n        var ret2 = Promise.delay(100).then(function() {\n            assert.strictEqual(0, b.length);\n            immediates.forEach(resolve);\n            return immediates.map(function(item){return item[0]});\n        }).delay(100).then(function() {\n            assert.deepEqual(b, [0, 1, 2, 3, 4]);\n            lates.forEach(resolve);\n        }).delay(100).then(function() {\n            assert.deepEqual(b, [0, 1, 2, 3, 4, 10, 9, 8, 7, 6 ]);\n            lates.forEach(resolve);\n        }).thenReturn(ret1).then(function() {\n            assert.deepEqual(b, [0, 1, 2, 3, 4, 10, 9, 8, 7, 6, 5]);\n        });\n        return Promise.all([ret1, ret2]);\n    });\n});\n"
  },
  {
    "path": "test/mocha/method.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\nvar obj = {};\nvar error = new Error();\nvar thrower = Promise.method(function() {\n    throw error;\n});;\n\nvar identity = Promise.method(function(val) {\n    return val;\n});\n\nvar array = Promise.method(function() {\n    return [].slice.call(arguments);\n});\n\nvar receiver = Promise.method(function() {\n    return this;\n});\n\n\n\ndescribe(\"Promise.method\", function(){\n    specify(\"should reject when the function throws\", function() {\n        var async = false;\n        var ret = thrower().then(assert.fail, function(e) {\n            assert(async);\n            assert(e === error);\n        });\n        async = true;\n        return ret;\n    });\n    specify(\"should throw when the function is not a function\", function() {\n        try {\n            Promise.method(null);\n        }\n        catch (e) {\n            assert(e instanceof TypeError);\n            return;\n        }\n        assert.fail();\n    });\n    specify(\"should call the function with the given receiver\", function(){\n        var async = false;\n        var ret = receiver.call(obj).then(function(val) {\n            assert(async);\n            assert(val === obj);\n        }, assert.fail);\n        async = true;\n        return ret;\n    });\n    specify(\"should call the function with the given value\", function(){\n        var async = false;\n        var ret = identity(obj).then(function(val) {\n            assert(async);\n            assert(val === obj);\n        }, assert.fail);\n        async = true;\n        return ret;\n    });\n    specify(\"should apply the function if given value is array\", function(){\n        var async = false;\n        var ret = array(1, 2, 3).then(function(val) {\n            assert(async);\n            assert.deepEqual(val, [1,2,3]);\n        }, assert.fail);\n        async = true;\n        return ret;\n    });\n\n    specify(\"should unwrap returned promise\", function(){\n        var d = Promise.defer();\n\n        var ret = Promise.method(function(){\n            return d.promise;\n        })().then(function(v){\n            assert(v === 3);\n        })\n\n        setTimeout(function(){\n            d.fulfill(3);\n        }, 1);\n        return ret;\n    });\n    specify(\"should unwrap returned thenable\", function(){\n\n        return Promise.method(function(){\n            return {\n                then: function(f, v) {\n                    f(3);\n                }\n            }\n        })().then(function(v){\n            assert(v === 3);\n        });\n    });\n\n    specify(\"should unwrap a following promise\", function() {\n        var resolveF;\n        var f = new Promise(function() {\n            resolveF = arguments[0];\n        });\n        var v = new Promise(function(f) {\n            setTimeout(function() {\n                f(3);\n            }, 1);\n        });\n        resolveF(v);\n        return Promise.method(function(){\n            return f;\n        })().then(function(v){\n            assert(v === 3);\n        });\n    });\n\n    specify(\"zero arguments length should remain zero\", function() {\n        return Promise.method(function(){\n            assert(arguments.length === 0);\n        })();\n    });\n    specify(\"should retain binding from returned promise\", function() {\n        var THIS = {};\n        return Promise.method(function() {\n            return Promise.bind(THIS, 1);\n        })().then(function(value) {\n            assert.strictEqual(THIS, this);\n            assert.strictEqual(1, value);\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/monitoring.js",
    "content": "var assert = require(\"assert\");\nvar util = require(\"../../js/debug/util\");\n\ndescribe(\"monitoring: promise lifecycle events subscriptions\", function() {\n    var numCreated = 0;\n    var numChained = 0;\n    var numFulfilled = 0;\n    var numRejected = 0;\n    var on = null;\n    var off = null;\n\n    before(function(){\n        Promise.config({monitoring: true});\n    });\n\n    after(function(){\n        Promise.config({monitoring: false});\n    });\n\n    beforeEach(function(){\n        numCreated = 0;\n        numChained = 0;\n        numFulfilled = 0;\n        numRejected = 0;\n    });\n\n    function nodeOn(eventName, eventHandler) {\n        process.on.call(process, eventName, eventHandler);\n    }\n    function nodeOff(eventName, eventHandler) {\n        process.removeListener.call(process, eventName, eventHandler);\n    }\n    function browserSimpleOn(eventName, eventHandler) {\n        eventName = \"on\" + eventName.toLowerCase();\n        self[eventName] = eventHandler;\n    }\n    function browserSimpleOff(eventName, eventHandler) {\n        eventName = \"on\" + eventName.toLowerCase();\n        assert(self[eventName] === eventHandler);\n        delete self[eventName];\n    }\n    function browserDomOn (eventName, eventHandler) {\n        self.addEventListener.call(self, eventName.toLowerCase(),\n            eventHandler);\n    }\n    function browserDomOff (eventName, eventHandler) {\n        self.removeEventListener.call(self, eventName.toLowerCase(),\n            eventHandler);\n    }\n\n    function testCreated(onCreated) {\n        on(\"promiseCreated\", onCreated);\n        var promise = new Promise(function(resolve){resolve()});\n        assert(numCreated === 1);\n        promise =  promise.then(function(){});\n        assert(numCreated === 2);\n        off(\"promiseCreated\", onCreated);\n        promise.then(function(){});\n        assert(numCreated === 2);\n    }\n\n    function testChained(onChained) {\n        on(\"promiseChained\", onChained);\n        var promise = new Promise(function(resolve){resolve()});\n        assert(numChained === 0);\n        promise = promise.then(function(){});\n        assert(numChained === 1);\n        off(\"promiseChained\", onChained);\n        promise.then(function(){});\n        assert(numChained === 1);\n    }\n\n    function testRejected(onRejected) {\n        on(\"promiseRejected\", onRejected);\n        assert(numRejected === 0);\n        var promise = new Promise(function(resolve,reject){\n            reject();\n        });\n        assert(numRejected === 1);\n        promise = promise.caught(function(resolve,reject){\n            assert(numRejected === 1);\n            reject();\n        });\n        off(\"promiseRejected\", onRejected);\n        return promise.caught(function(){\n            assert(numRejected === 1);\n        });\n\n    }\n\n    function testFulfilled(onFulfilled) {\n        on(\"promiseFulfilled\", onFulfilled);\n        assert(numFulfilled === 0);\n        var promise = new Promise(function(resolve){resolve()});\n        assert(numFulfilled === 1);\n        promise = promise.then(function(){});\n        assert(numFulfilled === 1);\n        off(\"promiseFulfilled\", onFulfilled);\n        promise.then(function(){});\n        assert(numFulfilled === 1);\n    }\n\n    describe(\"simple events API\", function() {\n\n        before(function() {\n            if (util.isNode) {\n                on = nodeOn;\n                off = nodeOff;\n            } else if (typeof self !== \"undefined\") {\n                on = browserSimpleOn;\n                off = browserSimpleOff;\n            } else {\n                assert(1===0);\n            }\n        });\n\n        it(\"promiseCreated\", function () {\n            return testCreated(function (promise) {\n                assert(Promise.is(promise));\n                numCreated++\n            });\n        });\n        it(\"promiseChained\", function () {\n            return testChained(function (promise, child) {\n                assert(Promise.is(promise));\n                assert(Promise.is(child));\n                numChained++;\n            });\n        });\n        it(\"promiseRejected\", function () {\n            return testRejected(function (promise) {\n                assert(Promise.is(promise));\n                numRejected++\n            });\n        });\n        it(\"promiseFulfilled\", function () {\n            return testFulfilled(function (promise) {\n                assert(Promise.is(promise));\n                numFulfilled++\n            });\n        });\n    });\n\n    if (!util.isNode) {\n        describe(\"events API\", function() {\n\n            before(function() {\n                on = browserDomOn;\n                off = browserDomOff;\n            });\n\n            it(\"promiseCreated\", function () {\n                return testCreated(function (event) {\n                    assert(event.type === \"promisecreated\");\n                    assert(Promise.is(event.detail.promise));\n                    numCreated++;\n                });\n            });\n            it(\"promiseChained\", function () {\n                return testChained(function (event) {\n                    assert(event.type === \"promisechained\");\n                    assert(Promise.is(event.detail.promise));\n                    assert(Promise.is(event.detail.child));\n                    numChained++;\n                });\n            });\n            it(\"promiseRejected\", function () {\n                return testRejected(function (event) {\n                    numRejected++;\n                    assert(event.type === \"promiserejected\");\n                    assert(Promise.is(event.detail.promise));\n                });\n            });\n            it(\"promiseFulfilled\", function () {\n                return testFulfilled(function (event) {\n                    numFulfilled++;\n                    assert(event.type === \"promisefulfilled\");\n                    assert(Promise.is(event.detail.promise));\n                });\n            });\n        });\n    }\n});\n"
  },
  {
    "path": "test/mocha/multiple-copies.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\nif (testUtils.isNodeJS) {\n    describe(\"multiple copies\", function() {\n        specify(\"are being loaded\", function() {\n            var a = require(\"../../js/debug/bluebird.js\");\n            Object.keys(require.cache).forEach(function(key) {\n                if (/debug/.test(key))\n                    delete require.cache[key];\n            });\n            var b = require(\"../../js/debug/bluebird.js\");\n            assert.notEqual(a, b);\n        });\n    });\n}\n"
  },
  {
    "path": "test/mocha/no_conflict.js",
    "content": "var assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\ndescribe(\"Promise.noConflict\", function() {\n    specify(\"should work\", function() {\n        var glob = typeof window !== \"undefined\" ? window : global;\n        var bluebird = Promise.noConflict();\n        assert(bluebird !== Promise);\n        glob.Promise = null;\n        assert.strictEqual(bluebird, bluebird.noConflict());\n        try {\n            delete glob.Promise;\n            assert.strictEqual(bluebird, bluebird.noConflict());\n        } catch (e) {\n            assert.strictEqual(bluebird, bluebird.noConflict());\n        }\n        glob.Promise = bluebird;\n        assert.strictEqual(bluebird, Promise.noConflict());\n        glob.Promise = bluebird;\n    })\n});\n"
  },
  {
    "path": "test/mocha/nodeify.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar awaitGlobalException = testUtils.awaitGlobalException;\nvar sinon = require(\"sinon\");\nvar isNodeJS = testUtils.isNodeJS;\n/*\nCopyright 2009–2012 Kristopher Michael Kowal. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\n\ndescribe(\"nodeify\", function () {\n\n    it(\"calls back with a resolution\", function () {\n        var spy = sinon.spy();\n        Promise.resolve(10).nodeify(spy);\n        setTimeout(function(){\n            sinon.assert.calledOnce(spy);\n            sinon.assert.calledWith(spy, null, 10);\n        }, 1);\n    });\n\n    it(\"calls back with an undefined resolution\", function() {\n        var spy = sinon.spy();\n        Promise.resolve().nodeify(spy);\n        setTimeout(function(){\n            sinon.assert.calledOnce(spy);\n            sinon.assert.calledWithExactly(spy, null);\n        }, 1);\n    });\n\n    it(\"calls back with an error\", function () {\n        var spy = sinon.spy();\n        Promise.reject(10).nodeify(spy);\n        setTimeout(function(){\n            sinon.assert.calledOnce(spy);\n            sinon.assert.calledWith(spy, 10);\n        }, 1);\n    });\n\n    it(\"forwards a promise\", function () {\n        return Promise.resolve(10).nodeify().then(function (ten) {\n            assert(10 === ten);\n        });\n    });\n\n    it(\"returns undefined when a callback is passed\", function () {\n        return 'undefined' === typeof Promise.resolve(10).nodeify(function () {});\n    });\n\n});\nvar getSpy = testUtils.getSpy;\nif (isNodeJS) {\n    describe(\"nodeify\", function () {\n        var h = [];\n        var e = new Error();\n        function thrower() {\n            throw e;\n        }\n\n        it(\"throws normally in the node process if the function throws\", function() {\n            var promise = Promise.resolve(10);\n            var turns = 0;\n            process.nextTick(function(){\n                turns++;\n            });\n            promise.nodeify(thrower);\n            return awaitGlobalException(function(err) {\n                assert(err === e);\n                assert(turns === 1);\n            });\n        });\n\n        it(\"always returns promise for now\", function() {\n            return Promise.resolve(3).nodeify().then(function() {\n                var a = 0;\n                Promise.resolve(3).nodeify(function(){\n                    a++;\n                }).then(function() {\n                    assert(1 == 1);\n                });\n            });\n        });\n\n        it(\"should spread arguments with spread option\", function() {\n            var spy = getSpy();\n            Promise.resolve([1,2,3]).nodeify(spy(function(err, a, b, c) {\n                assert(err === null);\n                assert(a === 1);\n                assert(b === 2);\n                assert(c === 3);\n            }), {spread: true});\n            return spy.promise;\n        });\n\n        describe(\"promise rejected with falsy values\", function() {\n            specify(\"no reason\", function() {\n                var spy = getSpy();\n                Promise.reject().nodeify(spy(function(err) {\n                    assert.strictEqual(arguments.length, 1);\n                    assert.strictEqual(err.cause, undefined);\n                }));\n                return spy.promise;\n            });\n            specify(\"null reason\", function() {\n                var spy = getSpy();\n                Promise.reject(null).nodeify(spy(function(err) {\n                    assert.strictEqual(arguments.length, 1);\n                    assert.strictEqual(err.cause, null);\n                }));\n                return spy.promise;\n            });\n            specify(\"nodefying a follewer promise\", function() {\n                var spy = getSpy();\n                new Promise(function(resolve, reject) {\n                    resolve(new Promise(function(_, reject) {\n                        setTimeout(function() {\n                            reject();\n                        }, 1);\n                    }))\n                }).nodeify(spy(function(err) {\n                    assert.strictEqual(arguments.length, 1);\n                    assert.strictEqual(err.cause, undefined);\n                }));\n                return spy.promise;\n            });\n            specify(\"nodefier promise becomes follower\", function() {\n                var spy = getSpy();\n                Promise.resolve(1).then(function() {\n                    return new Promise(function(_, reject) {\n                        setTimeout(function() {\n                            reject();\n                        }, 1);\n                    });\n                }).nodeify(spy(function(err) {\n                    assert.strictEqual(arguments.length, 1);\n                    assert.strictEqual(err.cause, undefined);\n                }));\n                return spy.promise;\n            });\n        });\n        it(\"should wrap arguments with spread option\", function() {\n            var spy = getSpy();\n            Promise.resolve([1,2,3]).nodeify(spy(function(err, a, b, c) {\n                assert(err === null);\n                assert(a === 1);\n                assert(b === 2);\n                assert(c === 3);\n            }), {spread: true});\n            return spy.promise;\n        });\n\n        it(\"should work then result is not an array\", function() {\n            var spy = getSpy();\n            Promise.resolve(3).nodeify(spy(function(err, a) {\n                assert(err === null);\n                assert(a === 3);\n            }), {spread: true});\n            return spy.promise;\n        });\n\n        it(\"should work if the callback throws when spread\", function() {\n            var err = new Error();\n            Promise.resolve([1,2,3]).nodeify(function(_, a) {\n                throw err;\n            }, {spread: true});\n\n            return awaitGlobalException(function(e) {\n                assert.strictEqual(err, e);\n            });\n        });\n\n        it(\"should work if the callback throws when rejected\", function() {\n            var err = new Error();\n            Promise.reject(new Error()).nodeify(function(_, a) {\n                throw err;\n            });\n\n            return awaitGlobalException(function(e) {\n                assert.strictEqual(err, e);\n            });\n        });\n    });\n}\n"
  },
  {
    "path": "test/mocha/promise_array.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n/*!\n *\nCopyright 2009–2012 Kristopher Michael Kowal. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\ndescribe(\"all\", function () {\n    it(\"fulfills when passed an empty array\", function () {\n        return Promise.all([]);\n    });\n\n    if (testUtils.ecmaScript6Collections) {\n        it(\"supports iterables\", function () {\n            return Promise.all(new Set([1, 2, 3])).then(function(v) {\n                assert.deepEqual([1,2,3].sort(), v.sort());\n            });\n        });\n    }\n\n    it(\"rejects after any constituent promise is rejected\", function () {\n        var toResolve = Promise.defer(); // never resolve\n        var toReject = Promise.defer();\n        var promises = [toResolve.promise, toReject.promise];\n        var promise = Promise.all(promises);\n\n        toReject.reject(new Error(\"Rejected\"));\n\n        promise.then(assert.fail, function(e){\n            //Unhandled rejection\n        });\n\n        return Promise.delay(1)\n            .then(function () {\n                assert.equal(promise.isRejected(), true);\n            })\n            .timeout(1000);\n\n\n    });\n\n    it(\"resolves foreign thenables\", function () {\n        var normal = Promise.resolve(1);\n        var foreign = { then: function (f) { f(2); } };\n\n        return Promise.all([normal, foreign])\n        .then(function (result) {\n            assert.deepEqual(result,[1, 2]);\n        });\n    });\n\n\n    it(\"fulfills when passed an sparse array\", function () {\n        var toResolve = Promise.defer();\n        var promises = [];\n        promises[0] = Promise.resolve(0);\n        promises[2] = toResolve.promise;\n        var promise = Promise.all(promises);\n\n        toResolve.resolve(2);\n\n        return promise.then(function (result) {\n            assert.deepEqual(result, [0, void 0, 2]);\n        });\n    });\n});\n\n/*\nBased on When.js tests\n\nOpen Source Initiative OSI - The MIT License\n\nhttp://www.opensource.org/licenses/mit-license.php\n\nCopyright (c) 2011 Brian Cavalier\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/\ndescribe(\"Promise.all-test\", function () {\n\n    specify(\"should resolve empty input\", function() {\n        return Promise.all([]).then(\n            function(result) {\n                assert.deepEqual(result, []);\n            }, assert.fail\n        );\n    });\n\n    specify(\"should resolve values array\", function() {\n        var input = [1, 2, 3];\n        return Promise.all(input).then(\n            function(results) {\n                assert.deepEqual(results, input);\n            }, assert.fail\n        );\n    });\n\n    specify(\"should resolve promises array\", function() {\n        var input = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];\n        return Promise.all(input).then(\n            function(results) {\n                assert.deepEqual(results, [1, 2, 3]);\n            }, assert.fail\n        );\n    });\n\n    specify(\"should not resolve sparse array input\", function() {\n        var input = [, 1, , 1, 1 ];\n        return Promise.all(input).then(\n            function(results) {\n                assert.deepEqual(results, [void 0, 1, void 0, 1, 1]);\n            }, assert.fail\n        );\n    });\n\n    specify(\"should reject if any input promise rejects\", function() {\n        var input = [Promise.resolve(1), Promise.reject(2), Promise.resolve(3)];\n        return Promise.all(input).then(\n            assert.fail,\n            function(err) {\n                assert.deepEqual(err, 2);\n            }\n        );\n    });\n\n    specify(\"should accept a promise for an array\", function() {\n        var expected, input;\n\n        expected = [1, 2, 3];\n        input = Promise.resolve(expected);\n\n        return Promise.all(input).then(\n            function(results) {\n                assert.deepEqual(results, expected);\n            }, assert.fail\n        );\n    });\n\n    specify(\"should reject when input promise does not resolve to array\", function() {\n        return Promise.all(Promise.resolve(1)).caught(TypeError, function(e){\n        });\n    });\n\n});\n"
  },
  {
    "path": "test/mocha/promisify.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\nvar OperationalError = Promise.OperationalError;\n\nvar erroneusNode = function(a, b, c, cb) {\n    setTimeout(function(){\n        cb(sentinelError);\n    }, 1);\n};\n\nvar sentinel = {};\nvar sentinelError = new OperationalError();\n\nvar successNode = function(a, b, c, cb) {\n    setTimeout(function(){\n        cb(null, a);\n    }, 1);\n};\n\nvar successNodeMultipleValues = function(a, b, c, cb) {\n    setTimeout(function(){\n        cb(null, a, b, c);\n    }, 1);\n};\n\nvar syncErroneusNode = function(a, b, c, cb) {\n    cb(sentinelError);\n};\n\nvar syncSuccessNode = function(a, b, c, cb) {\n    cb(null, a);\n};\n\nvar syncSuccessNodeMultipleValues = function(a, b, c, cb) {\n    cb(null, a, b, c);\n};\n\nvar errToThrow;\nvar thrower = Promise.promisify(function(a, b, c, cb) {\n    errToThrow = new OperationalError();\n    throw errToThrow;\n});\n\nvar tprimitive = \"Where is your stack now?\";\nvar throwsStrings = Promise.promisify(function(cb){\n    throw tprimitive;\n});\n\nvar errbacksStrings = Promise.promisify(function(cb){\n    cb(tprimitive);\n});\n\nvar errbacksStringsAsync = Promise.promisify(function(cb){\n    setTimeout(function(){\n        cb(tprimitive);\n    }, 1);\n});\nvar THIS = {};\n\nvar error = Promise.promisify(erroneusNode);\nvar syncError = Promise.promisify(syncErroneusNode);\nvar success = Promise.promisify(successNode);\nvar syncSuccess = Promise.promisify(syncSuccessNode);\nvar successMultiArgsSingleValue = Promise.promisify(successNode, {multiArgs: true});\nvar successMultiOptDisabledNoReceiver = Promise.promisify(successNodeMultipleValues);\nvar syncSuccessMultiOptDisabledNoReceiver = Promise.promisify(syncSuccessNodeMultipleValues);\nvar successMultiOptEnabledNoReceiver = Promise.promisify(successNodeMultipleValues, {multiArgs: true});\nvar syncSuccessMultiOptEnabledNoReceiver = Promise.promisify(syncSuccessNodeMultipleValues, {multiArgs: true});\nvar successMultiOptEnabledWithReceiver = Promise.promisify(successNodeMultipleValues, {multiArgs: true, context: THIS});\nvar syncSccessMultiOptEnabledWithReceiver = Promise.promisify(syncSuccessNodeMultipleValues, {multiArgs: true, context: THIS});\nvar successMultiOptDisabledWithReceiver = Promise.promisify(successNodeMultipleValues, {context: THIS});\nvar syncSccessMultiOptDisabledWithReceiver = Promise.promisify(syncSuccessNodeMultipleValues, {context: THIS});\nvar successMulti = successMultiOptDisabledNoReceiver;\nvar syncSuccessMulti = syncSuccessMultiOptDisabledNoReceiver;\ndescribe(\"when calling promisified function it should \", function(){\n    specify(\"return a promise that is pending\", function() {\n        var a = error(1,2,3);\n        var b = success(1,2,3);\n        var c = successMulti(1,2,3);\n\n        var calls = 0;\n        assert.equal(a.isPending(), true);\n        assert.equal(b.isPending(), true);\n        assert.equal(c.isPending(), true);\n        return a.caught(testUtils.noop);\n    });\n\n    specify(\"should use this if no receiver was given\", function(){\n        var o = {};\n        var fn = Promise.promisify(function(cb){\n\n            cb(null, this === o);\n        });\n\n        o.fn = fn;\n\n        return o.fn().then(function(val){\n            assert(val);\n        });\n    });\n\n    specify(\"do nothing when called more than 1 times\", function() {\n        var err = new Error();\n        var stack = err.stack;\n\n        var fn = Promise.promisify(function(cb) {\n            cb(null);\n            cb(err);\n        });\n\n        return fn().then(function() {\n            return Promise.delay(1).then(function() {\n                assert.strictEqual(stack, err.stack);\n            })\n        });\n    });\n\n    specify(\"undefined as receiver\", function() {\n        return Promise.promisify(function(cb) {\n            assert.strictEqual(this, (function(){return this;})());\n            cb(null, 1);\n        }, {context: undefined})().then(function(result) {\n            assert.strictEqual(1, result);\n        });\n    });\n\n    specify(\"double promisification returns same function back\", function() {\n        var c = function(){};\n        var a = Promise.promisify(function(){});\n        var b = Promise.promisify(a);\n        assert.notEqual(c, a);\n        assert.strictEqual(a, b);\n    });\n\n    specify(\"call future attached handlers later\", function() {\n        var a = error(1,2,3).then(0, testUtils.noop);\n        var b = success(1,2,3);\n        var c = successMulti(1,2,3);\n        var d = syncError(1,2,3).then(0, testUtils.noop);\n        var e = syncSuccess(1,2,3).then(0, testUtils.noop);\n        var f = syncSuccessMulti(1,2,3).then(0, testUtils.noop);\n        var calls = 0;\n        return Promise.all([a, b, c, d, e, f]);\n    });\n\n    specify(\"Reject with the synchronously caught reason\", function(){\n        thrower(1, 2, 3).then(assert.fail).then(assert.fail, function(e){\n            assert(e === errToThrow);\n        });\n    });\n\n    specify(\"reject with the proper reason\", function() {\n        var a = error(1,2,3);\n        var b = syncError(1,2,3);\n\n        return Promise.all([\n            a.then(assert.fail, function(e){\n                assert.equal(sentinelError, e);\n            }),\n            b.then(assert.fail, function(e){\n                assert.equal(sentinelError, e);\n            })\n        ]);\n    });\n\n    describe(\"multi-args behaviors\", function() {\n        specify(\"successMultiArgsSingleValue\", function() {\n            var a = successMultiArgsSingleValue(1, 2, 3);\n            return a.then(function(value) {\n                assert.deepEqual([1], value);\n            })\n        });\n        specify(\"successMultiOptDisabledNoReceiver\", function() {\n            var a = successMultiOptDisabledNoReceiver(1, 2, 3);\n            return a.then(function(value) {\n                assert.strictEqual(value, 1);\n            })\n        });\n        specify(\"syncSuccessMultiOptDisabledNoReceiver\", function() {\n            var a = syncSuccessMultiOptDisabledNoReceiver(1, 2, 3);\n            return a.then(function(value) {\n                assert.strictEqual(value, 1);\n            })\n        });\n        specify(\"successMultiOptEnabledNoReceiver\", function() {\n            var a = successMultiOptEnabledNoReceiver(1, 2, 3);\n            return a.then(function(value) {\n                assert.deepEqual([1,2,3], value);\n            })\n        });\n        specify(\"syncSuccessMultiOptEnabledNoReceiver\", function() {\n            var a = syncSuccessMultiOptEnabledNoReceiver(1, 2, 3);\n            return a.then(function(value) {\n                assert.deepEqual([1,2,3], value);\n            })\n        });\n        specify(\"successMultiOptEnabledWithReceiver\", function() {\n            var a = successMultiOptEnabledWithReceiver(1, 2, 3);\n            return a.then(function(value) {\n                assert.deepEqual([1,2,3], value);\n            })\n        });\n        specify(\"syncSccessMultiOptEnabledWithReceiver\", function() {\n            var a = syncSccessMultiOptEnabledWithReceiver(1, 2, 3);\n            return a.then(function(value) {\n                assert.deepEqual([1,2,3], value);\n            })\n        });\n        specify(\"successMultiOptDisabledWithReceiver\", function() {\n            var a = successMultiOptDisabledWithReceiver(1, 2, 3);\n            return a.then(function(value) {\n                assert.strictEqual(value, 1);\n            })\n        });\n        specify(\"syncSccessMultiOptDisabledWithReceiver\", function() {\n            var a = syncSccessMultiOptDisabledWithReceiver(1, 2, 3);\n            return a.then(function(value) {\n                assert.strictEqual(value, 1);\n            })\n        });\n    });\n});\n\ndescribe(\"with more than 5 arguments\", function(){\n\n    var o = {\n        value: 15,\n\n        f: function(a,b,c,d,e,f,g, cb) {\n            cb(null, [a,b,c,d,e,f,g, this.value])\n        }\n\n    }\n\n\n    var prom = Promise.promisify(o.f, {context: o});\n\n    specify(\"receiver should still work\", function() {\n        return prom(1,2,3,4,5,6,7).then(function(val){\n            assert.deepEqual(\n                val,\n                [1,2,3,4,5,6,7, 15]\n            );\n        });\n\n    });\n\n});\n\ndescribe(\"promisify on objects\", function(){\n\n    var o = {\n        value: 15,\n\n        f: function(a,b,c,d,e,f,g, cb) {\n            cb(null, [a,b,c,d,e,f,g, this.value])\n        }\n\n    };\n\n    var objf = function(){};\n\n    objf.value = 15;\n    objf.f = function(a,b,c,d,e,f,g, cb) {\n        cb(null, [a,b,c,d,e,f,g, this.value])\n    };\n\n    function Test(data) {\n        this.data = data;\n    }\n\n    Test.prototype.get = function(a, b, c, cb) {\n        cb(null, a, b, c, this.data);\n    };\n\n    Test.prototype.getMany = function(a, b, c, d, e, f, g, cb) {\n        cb(null, a, b, c, d, e, f, g, this.data);\n    };\n\n    Promise.promisifyAll(o);\n    Promise.promisifyAll(objf);\n    Promise.promisifyAll(Test.prototype);\n\n    specify(\"should not repromisify\", function() {\n        var f = o.f;\n        var fAsync = o.fAsync;\n        var getOwnPropertyNames = Object.getOwnPropertyNames(o);\n        var ret = Promise.promisifyAll(o);\n        assert.equal(f, o.f);\n        assert.equal(fAsync, o.fAsync);\n        assert.deepEqual(getOwnPropertyNames, Object.getOwnPropertyNames(o));\n        assert.equal(ret, o);\n    });\n\n    specify(\"should not repromisify function object\", function() {\n        var f = objf.f;\n        var fAsync = objf.fAsync;\n        var getOwnPropertyNames = Object.getOwnPropertyNames(objf);\n        var ret = Promise.promisifyAll(objf);\n        assert.equal(f, objf.f);\n        assert.equal(fAsync, objf.fAsync);\n        assert.deepEqual(getOwnPropertyNames, Object.getOwnPropertyNames(objf));\n        assert.equal(ret, objf);\n    });\n\n    specify(\"should work on function objects too\", function() {\n        objf.fAsync(1, 2, 3, 4, 5, 6, 7).then(function(result){\n            assert.deepEqual(result, [1, 2, 3, 4, 5, 6, 7, 15]);\n        });\n    });\n\n    specify(\"should work on prototypes and not mix-up the instances\", function() {\n        var a = new Test(15);\n        var b = new Test(30);\n        var c = new Test(45);\n        return Promise.all([\n            a.getAsync(1, 2, 3).then(function(result){\n                assert.strictEqual(result, 1);\n            }),\n\n            b.getAsync(4, 5, 6).then(function(result){\n                assert.strictEqual(result, 4);\n            }),\n\n            c.getAsync(7, 8, 9).then(function(result){\n                assert.strictEqual(result, 7);\n            })\n        ]);\n    });\n\n    specify(\"should work on prototypes and not mix-up the instances with more than 5 arguments\", function() {\n        var a = new Test(15);\n        var b = new Test(30);\n        var c = new Test(45);\n\n        return Promise.all([\n            a.getManyAsync(1, 2, 3, 4, 5, 6, 7).then(function(result){\n                assert.strictEqual(result, 1);\n            }),\n\n            b.getManyAsync(4, 5, 6, 7, 8, 9, 10).then(function(result){\n                assert.strictEqual(result, 4);\n            }),\n\n            c.getManyAsync(7, 8, 9, 10, 11, 12, 13).then(function(result){\n                assert.strictEqual(result, 7);\n            })\n        ]);\n    });\n\n    specify(\"Fails to promisify Async suffixed methods\", function() {\n        var o = {\n            x: function(cb){\n                cb(null, 13);\n            },\n            xAsync: function(cb) {\n                cb(null, 13);\n            },\n\n            xAsyncAsync: function(cb) {\n                cb(null, 13)\n            }\n        };\n        try {\n            Promise.promisifyAll(o);\n        }\n        catch (e) {\n            assert(e instanceof Promise.TypeError);\n        }\n    });\n\n    specify(\"Calls overridden methods\", function() {\n        function Model() {\n            this.save = function() {};\n        }\n        Model.prototype.save = function() {\n            throw new Error(\"\");\n        };\n\n        Promise.promisifyAll(Model.prototype);\n        var model = new Model();\n        model.saveAsync();\n    });\n\n    specify(\"gh-232\", function() {\n        function f() {\n            var args = [].slice.call(arguments, 0, -1);\n            assert.deepEqual(args, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);\n            var cb = [].slice.call(arguments, -1)[0];\n            cb(null, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n        }\n        var fAsync = Promise.promisify(f);\n        return fAsync(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).then(function(result) {\n            assert.strictEqual(result, 1);\n        });\n    });\n\n    specify(\"Should lookup method dynamically if 'this' is given\", function() {\n        var obj = {\n            fn: function(cb) {\n                cb(null, 1);\n            }\n        };\n        Promise.promisifyAll(obj);\n        obj.fn = function(cb) {\n            cb(null, 2);\n        };\n        return obj.fnAsync().then(function(val) {\n            assert.strictEqual(2, val);\n        });\n    });\n\n    specify(\"gh335\", function() {\n        function HasArgs() { }\n        HasArgs.prototype.args = function(cb) {\n            return cb(null, \"ok\");\n        };\n\n        Promise.promisifyAll(HasArgs.prototype);\n        var a = new HasArgs();\n        return a.argsAsync().then(function(res) {\n            assert.equal(res, \"ok\");\n        });\n    });\n    specify(\"Should not promisify Object.prototype methods\", function() {\n        var o = {};\n        var keys = Object.keys(o);\n        Promise.promisifyAll(o);\n        assert.deepEqual(keys.sort(), Object.keys(o).sort());\n    });\n\n    specify(\"Should not promisify Object.prototype methods\", function() {\n        var o = {method: function(){}};\n        Promise.promisifyAll(o);\n        assert.deepEqual([\"method\", \"methodAsync\"].sort(), Object.keys(o).sort());\n    });\n\n    if (testUtils.ecmaScript5) {\n        specify(\"Should promisify non-enumerable methods\", function() {\n            var o = {};\n            Object.defineProperty(o, \"method\", {\n                value: function() {},\n                enumerable: false\n            });\n            Promise.promisifyAll(o);\n            assert.deepEqual([\"method\", \"methodAsync\"].sort(),\n                    Object.getOwnPropertyNames(o).sort());\n        });\n    }\n});\n\ndescribe(\"Promisify with custom suffix\", function() {\n    it(\"should define methods with the custom suffix\", function() {\n        function Test() {\n\n        }\n\n        Test.prototype.method = function method() {};\n\n        Promise.promisifyAll(Test.prototype, {suffix: \"$P\"});\n        assert(typeof Test.prototype.method$P == \"function\");\n    });\n\n    it(\"should throw on invalid suffix\", function() {\n        try {\n            Promise.promisifyAll({}, {suffix: \"\"});\n        }\n        catch (e) {\n            return;\n        }\n        assert.fail();\n    });\n})\n\ndescribe(\"Module promisification\", function() {\n    it(\"should promisify module with direct property classes\", function() {\n        function RedisClient() {}\n        RedisClient.prototype.query = function() {};\n        function Multi() {}\n        Multi.prototype.exec = function() {};\n        Multi.staticMethod = function() {}\n\n        var redis = {\n            RedisClient: RedisClient,\n            Multi: Multi,\n            moduleMethod: function() {}\n        };\n        redis.Multi.staticMethod.tooDeep = function() {};\n\n        Promise.promisifyAll(redis);\n\n        assert(typeof redis.moduleMethodAsync === \"function\");\n        assert(typeof redis.Multi.staticMethodAsync === \"function\");\n        assert(typeof redis.Multi.prototype.execAsync === \"function\");\n        assert(typeof redis.RedisClient.prototype.queryAsync === \"function\");\n        assert(typeof redis.Multi.staticMethod.tooDeepAsync === \"undefined\");\n    })\n\n    it(\"should promisify module with inherited property classes\", function() {\n        function Mongoose() {}\n        var Model = Mongoose.prototype.Model = function() {};\n        Model.prototype.find = function() {};\n        var Document = Mongoose.prototype.Document = function() {};\n        Document.prototype.create = function() {};\n        Document.staticMethod = function() {};\n        var mongoose = new Mongoose();\n\n        Promise.promisifyAll(mongoose);\n\n        assert(typeof mongoose.Model.prototype.findAsync === \"function\");\n        assert(typeof mongoose.Document.prototype.createAsync === \"function\");\n        assert(typeof mongoose.Document.staticMethodAsync === \"function\")\n    })\n\n    it(\"should promisify classes that have static methods\", function() {\n        function MongoClient() {this.connect = 3;}\n        MongoClient.connect = function() {};\n        var module = {};\n        module.MongoClient = MongoClient;\n        Promise.promisifyAll(module);\n\n        assert(typeof MongoClient.connectAsync === \"function\");\n    });\n})\n\ndescribe(\"Promisify from prototype to object\", function() {\n    var getterCalled = 0;\n\n    function makeClass() {\n        var Test = (function() {\n\n        function Test() {\n\n        }\n        var method = Test.prototype;\n\n        method.test = function() {\n\n        };\n\n        method[\"---invalid---\"] = function(){};\n\n        if (testUtils.ecmaScript5) {\n            Object.defineProperty(method, \"thrower\", {\n                enumerable: true,\n                configurable: true,\n                get: function() {\n                    throw new Error(\"getter called\");\n                },\n                set: function() {\n                    throw new Error(\"setter called\");\n                }\n            });\n            Object.defineProperty(method, \"counter\", {\n                enumerable: true,\n                configurable: true,\n                get: function() {\n                    getterCalled++;\n                },\n                set: function() {\n                    throw new Error(\"setter called\");\n                }\n            });\n        }\n\n        return Test;})();\n\n        return Test;\n    }\n\n    specify(\"Shouldn't touch the prototype when promisifying instance\", function() {\n        var Test = makeClass();\n\n        var origKeys = Object.getOwnPropertyNames(Test.prototype).sort();\n        var a = new Test();\n        Promise.promisifyAll(a);\n\n        assert(typeof a.testAsync === \"function\");\n        assert(a.hasOwnProperty(\"testAsync\"));\n        assert.deepEqual(Object.getOwnPropertyNames(Test.prototype).sort(), origKeys);\n        assert(getterCalled === 0);\n    });\n\n    specify(\"Shouldn't touch the method\", function() {\n        var Test = makeClass();\n\n        var origKeys = Object.getOwnPropertyNames(Test.prototype.test).sort();\n        var a = new Test();\n        Promise.promisifyAll(a);\n\n\n        assert(typeof a.testAsync === \"function\");\n        assert.deepEqual(Object.getOwnPropertyNames(Test.prototype.test).sort(), origKeys);\n        assert(Promise.promisify(a.test) !== a.testAsync);\n        assert(getterCalled === 0);\n    });\n\n    specify(\"Should promisify own method even if a promisified method of same name already exists somewhere in proto chain\", function(){\n        var Test = makeClass();\n        var instance = new Test();\n        Promise.promisifyAll(instance);\n        var origKeys = Object.getOwnPropertyNames(Test.prototype).sort();\n        var origInstanceKeys = Object.getOwnPropertyNames(instance).sort();\n        instance.test = function() {};\n        Promise.promisifyAll(instance);\n        assert.deepEqual(origKeys, Object.getOwnPropertyNames(Test.prototype).sort());\n        assert.notDeepEqual(origInstanceKeys,  Object.getOwnPropertyNames(instance).sort());\n        assert(getterCalled === 0);\n    });\n\n    specify(\"Shouldn promisify the method closest to the object if method of same name already exists somewhere in proto chain\", function(){\n        //IF the implementation is for-in, this pretty much tests spec compliance\n        var Test = makeClass();\n        var origKeys = Object.getOwnPropertyNames(Test.prototype).sort();\n        var instance = new Test();\n        instance.test = function() {};\n        Promise.promisifyAll(instance);\n\n        assert.deepEqual(Object.getOwnPropertyNames(Test.prototype).sort(), origKeys);\n        assert(instance.test === instance.test);\n        assert(getterCalled === 0);\n    });\n\n});\n\n\nfunction assertLongStackTraces(e) {\n    assert(e.stack.indexOf(\"From previous event:\") > -1);\n}\nif (Promise.hasLongStackTraces()) {\n    describe(\"Primitive errors wrapping\", function() {\n        specify(\"when the node function throws it\", function(){\n            return throwsStrings().then(assert.fail, function(e){\n                assert(e instanceof Error);\n                assert(e.message == tprimitive);\n            });\n        });\n\n        specify(\"when the node function throws it inside then\", function(){\n            return Promise.resolve().then(function() {\n                throwsStrings().then(assert.fail, function(e) {\n                    assert(e instanceof Error);\n                    assert(e.message == tprimitive);\n                    assertLongStackTraces(e);\n                });\n            });\n        });\n\n\n        specify(\"when the node function errbacks it synchronously\", function(){\n            return errbacksStrings().then(assert.fail, function(e){\n                assert(e instanceof Error);\n                assert(e.message == tprimitive);\n            });\n        });\n\n        specify(\"when the node function errbacks it synchronously inside then\", function(){\n            return Promise.resolve().then(function(){\n                errbacksStrings().then(assert.fail, function(e){\n                    assert(e instanceof Error);\n                    assert(e.message == tprimitive);\n                    assertLongStackTraces(e);\n                });\n            });\n        });\n\n        specify(\"when the node function errbacks it asynchronously\", function(){\n            return errbacksStringsAsync().then(assert.fail, function(e){\n                assert(e instanceof Error);\n                assert(e.message == tprimitive);\n                assertLongStackTraces(e);\n            });\n        });\n\n        specify(\"when the node function errbacks it asynchronously inside then\", function(){\n            return Promise.resolve().then(function(){\n                errbacksStringsAsync().then(assert.fail, function(e){\n                    assert(e instanceof Error);\n                    assert(e.message == tprimitive);\n                    assertLongStackTraces(e);\n                });\n            });\n        });\n    });\n}\n\ndescribe(\"Custom promisifier\", function() {\n    var dummy = {};\n    var err = new Error();\n    var chrome = {\n        getTab: function(tabId, callback) {\n            setTimeout(function() {\n                callback(dummy);\n            }, 1);\n        },\n        getTabErroneous: function(tabId, callback, errback) {\n            setTimeout(function() {\n                errback(err);\n            }, 1);\n        }\n    };\n\n    Promise.promisifyAll(chrome, {\n        promisifier: function(originalMethod) {\n            return function() {\n                var self = this;\n                var args = [].slice.call(arguments);\n                return new Promise(function(f, r) {\n                    args.push(f, r);\n                    originalMethod.apply(self, args);\n                });\n            };\n        }\n    });\n\n    specify(\"getTab\", function() {\n        return chrome.getTabAsync(1).then(function(result) {\n            assert.equal(dummy, result);\n        });\n    });\n\n    specify(\"getTabErroneous\", function() {\n        return chrome.getTabErroneousAsync(2).then(assert.fail, function(e) {\n            assert.equal(e, err);\n        });\n    });\n\n    specify(\"Copies custom props promisifyFirst\", function() {\n        var request = function(cb){\n            cb(null, 1);\n        };\n        request.zero = 0;\n        request.get = function(cb) {\n            cb(null, 2 + this.zero);\n        };\n        request.post = function(cb) {\n            cb(null, 3);\n        };\n\n        request = Promise.promisifyAll(Promise.promisify(request));\n        return Promise.all([\n            request(),\n            request.getAsync(),\n            request.postAsync()\n        ]).then(function(a) {\n            assert.deepEqual([1,2,3], a);\n        });\n    });\n\n    specify(\"Copies custom props promisifyAll first\", function() {\n        var request = function(cb){\n            cb(null, 1);\n        };\n        request.zero = 0;\n        request.get = function(cb) {\n            cb(null, 2 + this.zero);\n        };\n        request.post = function(cb) {\n            cb(null, 3);\n        };\n\n        request = Promise.promisify(Promise.promisifyAll(request));\n        return Promise.all([\n            request(),\n            request.getAsync(),\n            request.postAsync()\n        ]).then(function(a) {\n            assert.deepEqual([1,2,3], a);\n        });\n    });\n\n    specify(\"Copies custom props no this\", function() {\n        var request = function(cb){\n            cb(null, 1);\n        };\n        request.zero = 0;\n        request.get = function(cb) {\n            cb(null, 2);\n        };\n        request.post = function(cb) {\n            cb(null, 3);\n        };\n\n        request = Promise.promisify(Promise.promisifyAll(request));\n        var getAsync = request.getAsync;\n        var postAsync = request.postAsync;\n        return Promise.all([\n            request(),\n            getAsync(),\n            postAsync()\n        ]).then(function(a) {\n            assert.deepEqual([1,2,3], a);\n        });\n    });\n\n    specify(\"custom promisifier enhancing default promisification\", function() {\n        var obj = {\n            a: function(cb) {\n                setTimeout(function() {\n                    cb(null, 1);\n                }, 1);\n            },\n\n            b: function(val, cb) {\n                setTimeout(function() {\n                    cb(null, val);\n                }, 1);\n            }\n        };\n        obj = Promise.promisifyAll(obj, {\n            promisifier: function(originalFunction, defaultPromisifier) {\n                var promisified = defaultPromisifier(originalFunction);\n\n                return function() {\n                    var args = [].slice.call(arguments);\n                    var self = this;\n                    return Promise.all(args).then(function(awaitedArgs) {\n                        return promisified.apply(self, awaitedArgs);\n                    });\n                };\n            }\n        });\n\n        return obj.bAsync(obj.aAsync()).then(function(val) {\n            assert.strictEqual(val, 1);\n        });\n\n    });\n\n    specify(\"multiArgs option enabled single value\", function() {\n        var o = {\n            get: function(cb) {\n                cb(null, 1)\n            }\n        };\n        Promise.promisifyAll(o, {multiArgs: true});\n        return o.getAsync().then(function(value) {\n            assert.deepEqual([1], value);\n        });\n    });\n    specify(\"multiArgs option enabled multi value\", function() {\n        var o = {\n            get: function(cb) {\n                cb(null, 1, 2, 3)\n            }\n        };\n        Promise.promisifyAll(o, {multiArgs: true});\n        return o.getAsync().then(function(value) {\n            assert.deepEqual([1,2,3], value);\n        });\n    });\n    specify(\"multiArgs option disabled single value\", function() {\n        var o = {\n            get: function(cb) {\n                cb(null, 1)\n            }\n        };\n        Promise.promisifyAll(o);\n        return o.getAsync().then(function(value) {\n            assert.strictEqual(value, 1);\n        });\n    });\n    specify(\"multiArgs option disabled multi value\", function() {\n        var o = {\n            get: function(cb) {\n                cb(null, 1)\n            }\n        };\n        Promise.promisifyAll(o);\n        return o.getAsync().then(function(value) {\n            assert.strictEqual(value, 1);\n        });\n    });\n});\n\ndescribe(\"OperationalError wrapping\", function() {\n\n    var CustomError = function(){\n    }\n    CustomError.prototype = new Error();\n    CustomError.prototype.constructor = CustomError;\n\n    function isUntypedError(obj) {\n        return obj instanceof Error &&\n            Object.getPrototypeOf(obj) === Error.prototype;\n    }\n\n\n    if (!isUntypedError(new Error())) {\n        console.log(\"error must be untyped\");\n    }\n\n    if (isUntypedError(new CustomError())) {\n        console.log(\"customerror must be typed\");\n    }\n\n    function stringback(cb) {\n        cb(\"Primitive as error\");\n    }\n\n    function errback(cb) {\n        cb(new Error(\"error as error\"));\n    }\n\n    function typeback(cb) {\n        cb(new CustomError());\n    }\n\n    function stringthrow(cb) {\n        throw(\"Primitive as error\");\n    }\n\n    function errthrow(cb) {\n        throw(new Error(\"error as error\"));\n    }\n\n    function typethrow(cb) {\n        throw(new CustomError());\n    }\n\n    stringback = Promise.promisify(stringback);\n    errback = Promise.promisify(errback);\n    typeback = Promise.promisify(typeback);\n    stringthrow = Promise.promisify(stringthrow);\n    errthrow = Promise.promisify(errthrow);\n    typethrow = Promise.promisify(typethrow);\n\n    specify(\"should wrap stringback\", function() {\n        return stringback().error(function(e) {\n            assert(e instanceof OperationalError);\n        });\n    });\n\n    specify(\"should wrap errback\", function() {\n        return errback().error(function(e) {\n            assert(e instanceof OperationalError);\n        });\n    });\n\n    specify(\"should not wrap typeback\", function() {\n        return typeback().caught(CustomError, function(e){\n            });\n    });\n\n    specify(\"should not wrap stringthrow\", function() {\n        return stringthrow().error(assert.fail).then(assert.fail, function(e){\n            assert(e instanceof Error);\n        });\n    });\n\n    specify(\"should not wrap errthrow\", function() {\n        return errthrow().error(assert.fail).then(assert.fail, function(e) {\n            assert(e instanceof Error);\n        });\n    });\n\n    specify(\"should not wrap typethrow\", function() {\n        return typethrow().error(assert.fail)\n            .caught(CustomError, function(e){\n            });\n    });\n});\ndescribe(\"nodeback with multiple arguments\", function() {\n    specify(\"spreaded with immediate values\", function() {\n        var promise = Promise.promisify(function(cb) {\n            cb(null, 1, 2, 3);\n        }, {multiArgs: true})();\n\n        return promise.spread(function(a, b, c) {\n            assert.equal(a, 1);\n            assert.equal(b, 2);\n            assert.equal(c, 3);\n        });\n    });\n\n    specify(\"spreaded with thenable values should be unwrapped\", function() {\n        var a = {then: function(a){a(1)}};\n        var b = a;\n        var c = a;\n        var promise = Promise.promisify(function(cb) {\n            cb(null, a, b, c);\n        }, {multiArgs: true})();\n\n        return promise.spread(function(a_, b_, c_) {\n            assert.equal(a_, 1);\n            assert.equal(b_, 1);\n            assert.equal(c_, 1);\n        });\n    });\n\n    specify(\"spreaded with promise values should be unwrapped\", function() {\n        var a = Promise.resolve(1);\n        var b = Promise.resolve(2);\n        var c = Promise.resolve(3);\n        var promise = Promise.promisify(function(cb) {\n            cb(null, a, b, c);\n        }, {multiArgs: true})();\n\n        return promise.spread(function(a_, b_, c_) {\n            assert.strictEqual(a_, 1);\n            assert.strictEqual(b_, 2);\n            assert.strictEqual(c_, 3);\n        });\n    });\n});\ndescribe(\"filter\", function() {\n    specify(\"gets an argument whether default filter was passed\", function() {\n        Promise.promisifyAll({\n            abc: function() {}\n        }, {\n            filter: function(_, __, ___, passesDefaultFilter) {\n                assert.strictEqual(passesDefaultFilter, true);\n            }\n        })\n    });\n\n    specify(\"doesn't fail when allowing non-identifier methods\", function() {\n        var a = Promise.promisifyAll({\n            \" a s d \": function(cb) {\n                cb(null, 1);\n            }\n        }, {\n            filter: function() {\n                return true;\n            }\n        });\n\n        a[\" a s d Async\"]().then(function(val) {\n            assert.strictEqual(1, val);\n        });\n    });\n});\n\nvar global = new Function(\"return this\")();\nvar canEvaluate = (function() {\n    if (typeof window !== \"undefined\" && window !== null &&\n        typeof window.document !== \"undefined\" &&\n        typeof navigator !== \"undefined\" && navigator !== null &&\n        typeof navigator.appName === \"string\" &&\n        window === global) {\n        return false;\n    }\n    return true;\n})();\nvar canTestArity = (function(a, b, c) {}).length === 3 && canEvaluate;\n\nif (canTestArity) {\n    describe(\"arity\", function() {\n        specify(\"should be original - 1\", function() {\n            var fn = function(a, b, c, callback) {};\n            assert.equal(Promise.promisify(fn).length, 3);\n\n            var o = {\n                fn: function(a, b, c, callback) {\n\n                }\n            };\n            assert.equal(Promise.promisifyAll(o).fnAsync.length, 3);\n        })\n    })\n}\n\ndescribe(\"github 680\", function() {\n    before(function() {\n        Function.prototype.method = function() {};\n    });\n\n    after(function() {\n        delete Function.prototype.method;\n    });\n\n    specify(\"should not try to promisify methods from Function.prototype, native or otherwise\", function() {\n        var a = function() {};\n        a.fn = function() {};\n        Promise.promisifyAll(a);\n        assert.strictEqual(undefined, a.methodAsync);\n        assert.strictEqual(undefined, a.applyAsync);\n        assert(typeof a.fnAsync === \"function\");\n    });\n});\n\ndescribe(\"github 1063\", function() {\n    specify(\"should not cause error when called with no arguments\", function() {\n        return Promise.promisify(function(cb) {\n            cb();\n        }, { multiArgs: true})().then(function(values) {\n            assert(Array.isArray(values));\n            assert.strictEqual(values.length, 0);\n        });\n    })\n});\n\ndescribe(\"github 1023\", function() {\n    specify(\"promisify triggers custom schedulers\", function() {\n        var triggered = false;\n        var defaultScheduler = Promise.setScheduler(function(fn) {\n            triggered = true;\n            setTimeout(fn, 0);\n        });\n        var fnAsync = Promise.promisify(function(cb) {\n            setTimeout(function() {\n                cb(null, true);\n            }, 0);\n        });\n\n        return fnAsync().then(function(result) {\n            assert(result);\n            assert(triggered);\n        }).lastly(function() {\n            Promise.setScheduler(defaultScheduler);\n        });\n    });\n})\n"
  },
  {
    "path": "test/mocha/props.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\ndescribe(\"Promise.props\", function () {\n\n    specify(\"should reject undefined\", function() {\n        return Promise.props().caught(TypeError, function(){\n        })\n    });\n\n    specify(\"should reject primitive\", function() {\n        return Promise.props(\"str\").caught(TypeError, function(){\n        })\n    });\n\n    specify(\"should resolve to new object\", function() {\n        var o = {};\n        return Promise.props(o).then(function(v){\n            assert(v !== o);\n            assert.deepEqual(o, v);\n        });\n    });\n\n    specify(\"should resolve value properties\", function() {\n        var o = {\n            one: 1,\n            two: 2,\n            three: 3\n        };\n        return Promise.props(o).then(function(v){\n            assert.deepEqual({\n                one: 1,\n                two: 2,\n                three: 3\n            }, v);\n        });\n    });\n\n    specify(\"should resolve immediate properties\", function() {\n        var o = {\n            one: Promise.resolve(1),\n            two: Promise.resolve(2),\n            three: Promise.resolve(3)\n        };\n        return Promise.props(o).then(function(v){\n            assert.deepEqual({\n                one: 1,\n                two: 2,\n                three: 3\n            }, v);\n        });\n    });\n\n    specify(\"should resolve eventual properties\", function() {\n        var d1 = Promise.defer(),\n            d2 = Promise.defer(),\n            d3 = Promise.defer();\n        var o = {\n            one: d1.promise,\n            two: d2.promise,\n            three: d3.promise\n        };\n\n        setTimeout(function(){\n            d1.fulfill(1);\n            d2.fulfill(2);\n            d3.fulfill(3);\n        }, 1);\n\n        return Promise.props(o).then(function(v){\n            assert.deepEqual({\n                one: 1,\n                two: 2,\n                three: 3\n            }, v);\n        });\n\n\n    });\n\n    specify(\"should reject if any input promise rejects\", function() {\n        var o = {\n            one: Promise.resolve(1),\n            two: Promise.reject(2),\n            three: Promise.resolve(3)\n        };\n        return Promise.props(o).then(assert.fail, function(v){\n            assert(v === 2);\n        });\n    });\n\n    specify(\"should accept a promise for an object\", function() {\n         var o = {\n            one: Promise.resolve(1),\n            two: Promise.resolve(2),\n            three: Promise.resolve(3)\n        };\n        var d1 = Promise.defer();\n        setTimeout(function(){\n            d1.fulfill(o);\n        }, 1);\n        return Promise.props(d1.promise).then(function(v){\n            assert.deepEqual({\n                one: 1,\n                two: 2,\n                three: 3\n            }, v);\n        });\n\n    });\n\n    specify(\"should reject a promise for a primitive\", function() {\n        var d1 = Promise.defer();\n        setTimeout(function(){\n            d1.fulfill(\"text\");\n        }, 1);\n        return Promise.props(d1.promise).caught(TypeError, function(){\n        });\n\n    });\n\n    specify(\"should accept thenables in properties\", function() {\n        var t1 = {then: function(cb){cb(1);}};\n        var t2 = {then: function(cb){cb(2);}};\n        var t3 = {then: function(cb){cb(3);}};\n        var o = {\n            one: t1,\n            two: t2,\n            three: t3\n        };\n        return Promise.props(o).then(function(v){\n            assert.deepEqual({\n                one: 1,\n                two: 2,\n                three: 3\n            }, v);\n        });\n    });\n\n    specify(\"should accept a thenable for thenables in properties\", function() {\n        var o = {\n          then: function (f) {\n            f({\n              one: {\n                then: function (cb) {\n                  cb(1);\n                }\n              },\n              two: {\n                then: function (cb) {\n                  cb(2);\n                }\n              },\n              three: {\n                then: function (cb) {\n                  cb(3);\n                }\n              }\n            });\n          }\n        };\n        return Promise.props(o).then(function(v){\n            assert.deepEqual({\n                one: 1,\n                two: 2,\n                three: 3\n            }, v);\n        });\n    });\n\n    specify(\"treats arrays for their properties\", function() {\n        var o = [1,2,3];\n\n        return Promise.props(o).then(function(v){\n            assert.deepEqual({\n                0: 1,\n                1: 2,\n                2: 3\n            }, v);\n        });\n    });\n\n\n    if (typeof Map !== \"undefined\") {\n        specify(\"works with es6 maps\", function() {\n            return Promise.props(new Map([\n                [\"a\", Promise.resolve(1)],\n                [\"b\", Promise.resolve(2)],\n                [\"c\", Promise.resolve(3)]\n            ])).then(function(result) {\n                assert.strictEqual(result.get(\"a\"), 1);\n                assert.strictEqual(result.get(\"b\"), 2);\n                assert.strictEqual(result.get(\"c\"), 3);\n            });\n        });\n\n        specify(\"doesn't await promise keys in es6 maps\", function() {\n            var a = new Promise(function() {});\n            var b = new Promise(function() {});\n            var c = new Promise(function() {});\n\n            return Promise.props(new Map([\n                [a, Promise.resolve(1)],\n                [b, Promise.resolve(2)],\n                [c, Promise.resolve(3)]\n            ])).then(function(result) {\n                assert.strictEqual(result.get(a), 1);\n                assert.strictEqual(result.get(b), 2);\n                assert.strictEqual(result.get(c), 3);\n            });\n        });\n\n        specify(\"empty map should resolve to empty map\", function() {\n            return Promise.props(new Map()).then(function(result) {\n                assert(result instanceof Map);\n            });\n        });\n    }\n\n});\n"
  },
  {
    "path": "test/mocha/race.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\n\n\ndescribe(\"Promise.race\", function(){\n    it(\"remains forever pending when passed an empty array\", function() {\n        var p = Promise.race([]);\n        return Promise.delay(1).then(function() {\n            assert(p.isPending());\n        });\n    });\n\n    it(\"remains forever pending when passed an empty sparse array\", function() {\n        var p = Promise.race([,,,,,]);\n        return Promise.delay(1).then(function() {\n            assert(p.isPending());\n        });\n    });\n\n    it(\"fulfills when passed an immediate value\", function() {\n        return Promise.race([1,2,3]).then(function(v){\n            assert.deepEqual(v, 1);\n        });\n    });\n\n    it(\"fulfills when passed an immediately fulfilled value\", function() {\n        var d1 = Promise.defer();\n        d1.fulfill(1);\n        var p1 = d1.promise;\n\n        var d2 = Promise.defer();\n        d2.fulfill(2);\n        var p2 = d2.promise;\n\n        var d3 = Promise.defer();\n        d3.fulfill(3);\n        var p3 = d3.promise;\n\n        return Promise.race([p1, p2, p3]).then(function(v){\n            assert.deepEqual(v, 1);\n        });\n    });\n\n    it(\"fulfills when passed an eventually fulfilled value\", function() {\n        var d1 = Promise.defer();\n        var p1 = d1.promise;\n\n        var d2 = Promise.defer();\n        var p2 = d2.promise;\n\n        var d3 = Promise.defer();\n        var p3 = d3.promise;\n\n        setTimeout(function(){\n            d1.fulfill(1);\n            d2.fulfill(2);\n            d3.fulfill(3);\n        }, 1);\n\n        return Promise.race([p1, p2, p3]).then(function(v){\n            assert.deepEqual(v, 1);\n        });\n    });\n\n    it(\"rejects when passed an immediate value\", function() {\n        return Promise.race([Promise.reject(1), 2, 3]).then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        });\n    });\n\n    it(\"rejects when passed an immediately rejected value\", function() {\n        var d1 = Promise.defer();\n        d1.reject(1);\n        var p1 = d1.promise;\n\n        var d2 = Promise.defer();\n        d2.fulfill(2);\n        var p2 = d2.promise;\n\n        var d3 = Promise.defer();\n        d3.fulfill(3);\n        var p3 = d3.promise;\n\n        return Promise.race([, p1, , p2, , ,  p3]).then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        });\n    });\n\n    it(\"rejects when passed an eventually rejected value\", function() {\n        var d1 = Promise.defer();\n        var p1 = d1.promise;\n\n        var d2 = Promise.defer();\n        var p2 = d2.promise;\n\n        var d3 = Promise.defer();\n        var p3 = d3.promise;\n\n        setTimeout(function(){\n            d1.reject(1);\n            d2.fulfill(2);\n            d3.fulfill(3);\n        }, 1);\n\n        return Promise.race([p1, p2, p3]).then(assert.fail, function(v){\n            assert.deepEqual(v, 1);\n        })\n    });\n\n    it(\"propagates bound value\", function() {\n        var o = {};\n        return Promise.resolve([1]).bind(o).race().then(function(v){\n            assert(v === 1);\n            assert(this === o);\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/reduce.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\nfunction promised(val) {\n    return new Promise(function(f) {\n        setTimeout(function() {\n            f(val);\n        }, 1);\n    });\n}\nfunction promising(val) {\n    return function() {\n        return promised(val);\n    }\n}\nfunction promisingThen(val) {\n    return function() {\n        return promised(val).then(function(resolved) {\n            return resolved;\n        });\n    }\n}\n\nfunction thenabled(val) {\n    return {\n        then: function(f){\n            setTimeout(function() {\n                f(val);\n            }, 1);\n        }\n    };\n}\nfunction thenabling(val) {\n    return function() { return thenabled(val); }\n}\n\nfunction evaluate(val) {\n    if (typeof val === 'function') {\n        val = val();\n    }\n    if (Array.isArray(val)) {\n        val = val.map(function(member) {\n            return evaluate(member);\n        });\n    }\n    return val;\n}\n\n\nvar ACCUM_CRITERIA = [\n    { value: 0,                desc: \"that is resolved\" },\n    { value: promising(0),     desc: \"as a Promise\" },\n    { value: promisingThen(0), desc: \"as a deferred Promise\" },\n    { value: thenabling(0),    desc: \"as a thenable\" },\n];\n\nvar VALUES_CRITERIA = [\n    { value: [],               total: 0, desc: \"and no values\" },\n    { value: [ 1 ],            total: 1, desc: \"and a single resolved value\" },\n    { value: [ 1, 2, 3 ],      total: 6, desc: \"and multiple resolved values\" },\n    { value: [ promising(1) ], total: 1, desc: \"and a single Promise\" },\n    { value: [\n        promising(1),\n        promising(2),\n        promising(3)\n    ], total: 6, desc: \"and multiple Promises\" },\n    { value: [\n        promisingThen(1)\n    ], total: 1, desc: \"and a single deferred Promise\" },\n    { value: [\n        promisingThen(1),\n        promisingThen(2),\n        promisingThen(3)\n    ], total: 6, desc: \"and multiple deferred Promises\" },\n    { value: [\n        thenabling(1)\n    ], total: 1, desc: \"and a single thenable\" },\n    { value: [\n        thenabling(1),\n        thenabling(2),\n        thenabling(3)\n    ], total: 6, desc: \"and multiple thenables\" },\n    { value: [\n        thenabling(1),\n        promisingThen(2),\n        promising(3),\n        4\n    ], total: 10, desc: \"and a blend of values\" },\n];\n\nvar ERROR = new Error(\"BOOM\");\n\n\ndescribe(\"Promise.prototype.reduce\", function() {\n    it(\"works with no values\", function() {\n        return Promise.resolve([]).reduce(function(total, value) {\n            return total + value + 5;\n        }).then(function(total) {\n            assert.strictEqual(total, undefined);\n        });\n    });\n\n    it(\"works with a single value\", function() {\n        return Promise.resolve([ 1 ]).reduce(function(total, value) {\n            return total + value + 5;\n        }).then(function(total) {\n            assert.strictEqual(total, 1);\n        });\n    });\n\n    it(\"works when the iterator returns a value\", function() {\n        return Promise.resolve([ 1, 2, 3 ]).reduce(function(total, value) {\n            return total + value + 5;\n        }).then(function(total) {\n            assert.strictEqual(total, (1 + 2+5 + 3+5));\n        });\n    });\n\n    it(\"works when the iterator returns a Promise\", function() {\n        return Promise.resolve([ 1, 2, 3 ]).reduce(function(total, value) {\n            return promised(5).then(function(bonus) {\n                return total + value + bonus;\n            });\n        }).then(function(total) {\n            assert.strictEqual(total, (1 + 2+5 + 3+5));\n        });\n    });\n\n    it(\"works when the iterator returns a thenable\", function() {\n        return Promise.resolve([ 1, 2, 3 ]).reduce(function(total, value) {\n            return thenabled(total + value + 5);\n        }).then(function(total) {\n            assert.strictEqual(total, (1 + 2+5 + 3+5));\n        });\n    });\n});\n\n\ndescribe(\"Promise.reduce\", function() {\n\n    it(\"should allow returning values\", function() {\n        var a = [promised(1), promised(2), promised(3)];\n\n        return Promise.reduce(a, function(total, a) {\n            return total + a + 5;\n        }, 0).then(function(total){\n            assert.equal(total, 1+5 + 2+5 + 3+5);\n        });\n    });\n\n    it(\"should allow returning promises\", function() {\n        var a = [promised(1), promised(2), promised(3)];\n\n        return Promise.reduce(a, function(total, a) {\n            return promised(5).then(function(b) {\n                return total + a + b;\n            });\n        }, 0).then(function(total){\n            assert.equal(total, 1+5 + 2+5 + 3+5);\n        });\n    });\n\n    it(\"should allow returning thenables\", function() {\n        var b = [1,2,3];\n        var a = [];\n\n        return Promise.reduce(b, function(total, cur) {\n            a.push(cur);\n            return thenabled(3);\n        }, 0).then(function(total) {\n            assert.equal(total, 3);\n            assert.deepEqual(a, b);\n        });\n    });\n\n    it(\"propagates error\", function() {\n        var a = [promised(1), promised(2), promised(3)];\n        var e = new Error(\"asd\");\n        return Promise.reduce(a, function(total, a) {\n            if (a > 2) {\n                throw e;\n            }\n            return total + a + 5;\n        }, 0).then(assert.fail, function(err) {\n            assert.equal(err, e);\n        });\n    });\n\n    describe(\"with no initial accumulator or values\", function() {\n        it(\"works when the iterator returns a value\", function() {\n            return Promise.reduce([], function(total, value) {\n                return total + value + 5;\n            }).then(function(total){\n                assert.strictEqual(total, undefined);\n            });\n        });\n\n        it(\"works when the iterator returns a Promise\", function() {\n            return Promise.reduce([], function(total, value) {\n                return promised(5).then(function(bonus) {\n                    return total + value + bonus;\n                });\n            }).then(function(total){\n                assert.strictEqual(total, undefined);\n            });\n        });\n\n        it(\"works when the iterator returns a thenable\", function() {\n            return Promise.reduce([], function(total, value) {\n                return thenabled(total + value + 5);\n            }).then(function(total){\n                assert.strictEqual(total, undefined);\n            });\n        });\n    });\n\n    describe(\"with an initial accumulator value\", function() {\n        ACCUM_CRITERIA.forEach(function(criteria) {\n            var initial = criteria.value;\n\n            describe(criteria.desc, function() {\n                VALUES_CRITERIA.forEach(function(criteria) {\n                    var values = criteria.value;\n                    var valueTotal = criteria.total;\n\n                    describe(criteria.desc, function() {\n                        it(\"works when the iterator returns a value\", function() {\n                            return Promise.reduce(evaluate(values), function(total, value) {\n                                return total + value + 5;\n                            }, evaluate(initial)).then(function(total){\n                                assert.strictEqual(total, valueTotal + (values.length * 5));\n                            });\n                        });\n\n                        it(\"works when the iterator returns a Promise\", function() {\n                            return Promise.reduce(evaluate(values), function(total, value) {\n                                return promised(5).then(function(bonus) {\n                                    return total + value + bonus;\n                                });\n                            }, evaluate(initial)).then(function(total){\n                                assert.strictEqual(total, valueTotal + (values.length * 5));\n                            });\n                        });\n\n                        it(\"works when the iterator returns a thenable\", function() {\n                            return Promise.reduce(evaluate(values), function(total, value) {\n                                return thenabled(total + value + 5);\n                            }, evaluate(initial)).then(function(total){\n                                assert.strictEqual(total, valueTotal + (values.length * 5));\n                            });\n                        });\n                    });\n                });\n            });\n        });\n\n        it(\"propagates an initial Error\", function() {\n            var initial = Promise.reject(ERROR);\n            var values = [\n                thenabling(1),\n                promisingThen(2)(),\n                promised(3),\n                4\n            ];\n\n            return Promise.reduce(values, function(total, value) {\n                return value;\n            }, initial).then(assert.fail, function(err) {\n                assert.equal(err, ERROR);\n            });\n        });\n\n        it(\"propagates a value's Error\", function() {\n            var initial = 0;\n            var values = [\n                thenabling(1),\n                promisingThen(2)(),\n                Promise.reject(ERROR),\n                promised(3),\n                4\n            ];\n\n            return Promise.reduce(values, function(total, value) {\n                return value;\n            }, initial).then(assert.fail, function(err) {\n                assert.equal(err, ERROR);\n            });\n        });\n\n        it(\"propagates an Error from the iterator\", function() {\n            var initial = 0;\n            var values = [\n                thenabling(1),\n                promisingThen(2)(),\n                promised(3),\n                4\n            ];\n\n            return Promise.reduce(values, function(total, value) {\n                if (value === 2) {\n                    throw ERROR;\n                }\n                return value;\n            }, initial).then(assert.fail, function(err) {\n                assert.equal(err, ERROR);\n            });\n        });\n    });\n\n    describe(\"with a 0th value acting as an accumulator\", function() {\n        it(\"acts this way when an accumulator value is provided yet `undefined`\", function() {\n            return Promise.reduce([ 1, 2, 3 ], function(total, value) {\n                return ((total === void 0) ? 0 : total) + value + 5;\n            }, undefined).then(function(total){\n                assert.strictEqual(total, (1 + 2+5 + 3+5));\n            });\n        });\n\n        it(\"survives an `undefined` 0th value\", function() {\n            return Promise.reduce([ undefined, 1, 2, 3 ], function(total, value) {\n                return ((total === void 0) ? 0 : total) + value + 5;\n            }).then(function(total){\n                assert.strictEqual(total, (1+5 + 2+5 + 3+5));\n            });\n        });\n\n        ACCUM_CRITERIA.forEach(function(criteria) {\n            var zeroth = criteria.value;\n\n            describe(criteria.desc, function() {\n                VALUES_CRITERIA.forEach(function(criteria) {\n                    var values = criteria.value;\n                    var zerothAndValues = [ zeroth ].concat(values);\n                    var valueTotal = criteria.total;\n\n                    describe(criteria.desc, function() {\n                        it(\"works when the iterator returns a value\", function() {\n                            return Promise.reduce(evaluate(zerothAndValues), function(total, value) {\n                                return total + value + 5;\n                            }).then(function(total){\n                                assert.strictEqual(total, valueTotal + (values.length * 5));\n                            });\n                        });\n\n                        it(\"works when the iterator returns a Promise\", function() {\n                            return Promise.reduce(evaluate(zerothAndValues), function(total, value) {\n                                return promised(5).then(function(bonus) {\n                                    return total + value + bonus;\n                                });\n                            }).then(function(total){\n                                assert.strictEqual(total, valueTotal + (values.length * 5));\n                            });\n                        });\n\n                        it(\"works when the iterator returns a thenable\", function() {\n                            return Promise.reduce(evaluate(zerothAndValues), function(total, value) {\n                                return thenabled(total + value + 5);\n                            }).then(function(total){\n                                assert.strictEqual(total, valueTotal + (values.length * 5));\n                            });\n                        });\n                    });\n                });\n            });\n        });\n\n        it(\"propagates an initial Error\", function() {\n            var values = [\n                Promise.reject(ERROR),\n                thenabling(1),\n                promisingThen(2)(),\n                promised(3),\n                4\n            ];\n\n            return Promise.reduce(values, function(total, value) {\n                return value;\n            }).then(assert.fail, function(err) {\n                assert.equal(err, ERROR);\n            });\n        });\n\n        it(\"propagates a value's Error\", function() {\n            var values = [\n                0,\n                thenabling(1),\n                promisingThen(2)(),\n                Promise.reject(ERROR),\n                promised(3),\n                4\n            ];\n\n            return Promise.reduce(values, function(total, value) {\n                return value;\n            }).then(assert.fail, function(err) {\n                assert.equal(err, ERROR);\n            });\n        });\n\n        it(\"propagates an Error from the iterator\", function() {\n            var values = [\n                0,\n                thenabling(1),\n                promisingThen(2)(),\n                promised(3),\n                4\n            ];\n\n            return Promise.reduce(values, function(total, value) {\n                if (value === 2) {\n                    throw ERROR;\n                }\n                return value;\n            }).then(assert.fail, function(err) {\n                assert.equal(err, ERROR);\n            });\n        });\n    });\n});\n\n/*\nBased on When.js tests\n\nOpen Source Initiative OSI - The MIT License\n\nhttp://www.opensource.org/licenses/mit-license.php\n\nCopyright (c) 2011 Brian Cavalier\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar sentinel = {};\nvar other = {};\ndescribe(\"Promise.reduce-test\", function () {\n\n    function plus(sum, val) {\n        return sum + val;\n    }\n\n    function later(val) {\n        return Promise.delay(1, val);\n    }\n\n\n    specify(\"should reduce values without initial value\", function() {\n        return Promise.reduce([1,2,3], plus).then(\n            function(result) {\n                assert.deepEqual(result, 6);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reduce values with initial value\", function() {\n        return Promise.reduce([1,2,3], plus, 1).then(\n            function(result) {\n                assert.deepEqual(result, 7);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reduce values with initial promise\", function() {\n        return Promise.reduce([1,2,3], plus, Promise.resolve(1)).then(\n            function(result) {\n                assert.deepEqual(result, 7);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reduce promised values without initial value\", function() {\n        var input = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];\n        return Promise.reduce(input, plus).then(\n            function(result) {\n                assert.deepEqual(result, 6);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reduce promised values with initial value\", function() {\n        var input = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];\n        return Promise.reduce(input, plus, 1).then(\n            function(result) {\n                assert.deepEqual(result, 7);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reduce promised values with initial promise\", function() {\n        var input = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];\n        return Promise.reduce(input, plus, Promise.resolve(1)).then(\n            function(result) {\n                assert.deepEqual(result, 7);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reduce empty input with initial value\", function() {\n        var input = [];\n        return Promise.reduce(input, plus, 1).then(\n            function(result) {\n                assert.deepEqual(result, 1);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reduce empty input with eventual promise\", function() {\n        return Promise.reduce([], plus, Promise.delay(1, 1)).then(\n            function(result) {\n                assert.deepEqual(result, 1);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reduce empty input with initial promise\", function() {\n        return Promise.reduce([], plus, Promise.resolve(1)).then(\n            function(result) {\n                assert.deepEqual(result, 1);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should reject Promise input contains rejection\", function() {\n        var input = [Promise.resolve(1), Promise.reject(2), Promise.resolve(3)];\n        return Promise.reduce(input, plus, Promise.resolve(1)).then(\n            assert.fail,\n            function(result) {\n                assert.deepEqual(result, 2);\n            }\n        );\n    });\n\n    specify(\"should reduce to undefined with empty array\", function() {\n        return Promise.reduce([], plus).then(function(r){\n            assert(r === void 0);\n        });\n    });\n\n    specify(\"should reduce to initial value with empty array\", function() {\n        return Promise.reduce([], plus, sentinel).then(function(r){\n            assert(r === sentinel);\n        });\n    });\n\n    specify(\"should reduce in input order\", function() {\n        return Promise.reduce([later(1), later(2), later(3)], plus, '').then(\n            function(result) {\n                assert.deepEqual(result, '123');\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should accept a promise for an array\", function() {\n        return Promise.reduce(Promise.resolve([1, 2, 3]), plus, '').then(\n            function(result) {\n                assert.deepEqual(result, '123');\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should resolve to initialValue Promise input promise does not resolve to an array\", function() {\n        return Promise.reduce(Promise.resolve(123), plus, 1).caught(TypeError, function(e){\n        });\n    });\n\n    specify(\"should provide correct basis value\", function() {\n        function insertIntoArray(arr, val, i) {\n            arr[i] = val;\n            return arr;\n        }\n\n        return Promise.reduce([later(1), later(2), later(3)], insertIntoArray, []).then(\n            function(result) {\n                assert.deepEqual(result, [1,2,3]);\n            },\n            assert.fail\n        );\n    });\n\n    describe(\"checks\", function() {\n        function later(val, ms) {\n            return Promise.delay(ms, val);\n        }\n\n        function plus(sum, val) {\n            return sum + val;\n        }\n\n        function plusDelayed(sum, val) {\n            return Promise.delay(0).then(function() {\n                return sum + val;\n            });\n        }\n\n        function check(delay1, delay2, delay3) {\n          return Promise.reduce([\n            later(1, delay1),\n            later(2, delay2),\n            later(3, delay3)\n          ], plus, '').then(function(result) {\n            assert.deepEqual(result, '123');\n          })\n        }\n\n        function checkDelayed(delay1, delay2, delay3) {\n          return Promise.reduce([\n            later(1, delay1),\n            later(2, delay2),\n            later(3, delay3)\n          ], plusDelayed, '').then(function(result) {\n            assert.deepEqual(result, '123');\n          })\n        }\n\n        specify(\"16, 16, 16\", function() {\n            return check(16, 16, 16);\n        });\n\n        specify(\"16, 16, 4\", function() {\n            return check(16, 16, 4);\n        });\n        specify(\"4, 16, 16\", function() {\n            return check(4, 16, 16);\n        });\n        specify(\"16, 4, 16\", function() {\n            return check(16, 4, 16);\n        });\n        specify(\"16, 16, 4\", function() {\n            return check(16, 16, 4);\n        });\n        specify(\"4, 4, 16\", function() {\n            return check(4, 4, 16);\n        });\n        specify(\"16, 4, 4\", function() {\n            return check(16, 4, 4);\n        });\n        specify(\"4, 16, 4\", function() {\n            return check(4, 16, 4);\n        });\n        specify(\"4, 4, 4\", function() {\n            return check(4, 4, 4);\n        });\n\n\n        specify(\"16, 16, 16\", function() {\n            return checkDelayed(16, 16, 16);\n        });\n\n        specify(\"16, 16, 4\", function() {\n            return checkDelayed(16, 16, 4);\n        });\n        specify(\"4, 16, 16\", function() {\n            return checkDelayed(4, 16, 16);\n        });\n        specify(\"16, 4, 16\", function() {\n            return checkDelayed(16, 4, 16);\n        });\n        specify(\"16, 16, 4\", function() {\n            return checkDelayed(16, 16, 4);\n        });\n        specify(\"4, 4, 16\", function() {\n            return checkDelayed(4, 4, 16);\n        });\n        specify(\"16, 4, 4\", function() {\n            return checkDelayed(16, 4, 4);\n        });\n        specify(\"4, 16, 4\", function() {\n            return checkDelayed(4, 16, 4);\n        });\n        specify(\"4, 4, 4\", function() {\n            return checkDelayed(4, 4, 4);\n        });\n\n    })\n});\n"
  },
  {
    "path": "test/mocha/reflect.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar testFulfilled = require(\"./helpers/testThreeCases\").testFulfilled;\nvar testRejected = require(\"./helpers/testThreeCases\").testRejected;\n\ndescribe(\".reflect()\", function() {\n    testFulfilled(1, function(promise) {\n        return promise.reflect().then(function(inspection) {\n            assert(inspection instanceof Promise.PromiseInspection);\n            assert(inspection.isFulfilled());\n            assert(inspection.value() === 1);\n        });\n    });\n    testRejected(2, function(promise) {\n        return promise.reflect().then(function(inspection) {\n            assert(inspection instanceof Promise.PromiseInspection);\n            assert(inspection.isRejected());\n            assert(inspection.reason() === 2);\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/regress.js",
    "content": "var assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\ndescribe(\"regressions\", function() {\n    specify(\"should be able to call .then more than once inside that promise's handler\", function() {\n        var called = 0;\n        var resolve;\n        var promise = new Promise(function() {\n            resolve = arguments[0];\n        });\n        return new Promise(function(resolve) {\n            promise.then(function() {\n                called++;\n                promise.then(function(){\n                    called++;\n                });\n                promise.then(function(){\n                    called++;\n                    assert.equal(4, called);\n                    resolve();\n                });\n            });\n\n            promise.then(function() {\n                called++;\n            });\n\n            setTimeout(resolve, 1);\n        });\n\n    });\n\n    specify(\"should be able to nest arbitrary amount of then handlers on already resolved promises\", function() {\n        var called = 0;\n        var resolve;\n        var promise = Promise.resolve();\n        return new Promise(function(resolve) {\n            promise.then(function() {\n                called++;\n                promise.then(function(){\n                    called++;\n                    promise.then(function(){\n                        called++;\n                    });\n                    promise.then(function(){\n                        called++;\n                    });\n                });\n                promise.then(function(){\n                    promise.then(function(){\n                        called++;\n                    });\n                    promise.then(function(){\n                        called++;\n                        assert.equal(8, called);\n                        resolve();\n                    });\n                    called++;\n                });\n            });\n\n            promise.then(function() {\n                called++;\n            });\n        });\n    });\n\n    specify(\"github-682\", function() {\n        var o = {\n            then: function(f) {\n                setTimeout(function() {\n                    delete o.then;\n                    f(o);\n                }, 1);\n            }\n        };\n\n        return Promise.resolve(o).then(function(value) {\n            assert.equal(o, value);\n        });\n    });\n\n    specify(\"gh-1006\", function() {\n        return Promise.resolve().then(function() {\n            new Promise(function() {}).tap(function() {}).cancel();\n        });\n    });\n\n    if (testUtils.isNodeJS) {\n        describe(\"github-689\", function() {\n            var originalProperty = Object.getOwnPropertyDescriptor(process, \"domain\");\n            var bindCalls = 0;\n\n            beforeEach(function() {\n                bindCalls = 0;\n            });\n\n            before(function() {\n                Object.defineProperty(process, \"domain\", {\n                    writable: true,\n                    enumerable: true,\n                    configurable: true,\n                    value: {\n                        emit: function() {},\n                        bind: function(fn) {\n                            bindCalls++;\n                            // Ensure non-strict mode.\n                            return new Function(\"fn\", \"return function() {return fn.apply(this, arguments);}\")(fn);\n                        },\n                        enter: function() {},\n                        exit: function() {}\n                    }\n                });\n            });\n\n            after(function() {\n                Object.defineProperty(process, \"domain\", originalProperty);\n            });\n\n            specify(\".return\", function() {\n                return Promise.resolve().thenReturn(true).then(function(val) {\n                    assert.strictEqual(val, true);\n                    assert.strictEqual(bindCalls, 4);\n                });\n            });\n\n            specify(\".throw\", function() {\n                return Promise.resolve().thenThrow(true).then(assert.fail, function(err) {\n                    assert.strictEqual(err, true);\n                    assert.strictEqual(bindCalls, 5);\n                });\n            });\n\n            specify(\".finally\", function() {\n                return Promise.resolve(true).lastly(function() {\n                    return Promise.delay(1);\n                }).then(function(val) {\n                    assert.strictEqual(val, true);\n                    assert.strictEqual(bindCalls, 6);\n                });\n            });\n        });\n\n        describe(\"long promise chain stack overflow\", function() {\n            specify(\"mapSeries\", function() {\n                var array = new Array(5000);\n                for (var i = 0; i < array.length; ++i) {\n                    array[i] = null;\n                }\n\n                var theError = new Error();\n\n                var queryAsync = Promise.promisify(function(cb) {\n                    process.nextTick(function() {\n                        cb(theError);\n                    }, 1);\n                });\n\n                return Promise.mapSeries(array, function() {\n                    return queryAsync();\n                }).caught(function(e) {\n                    assert.strictEqual(e.cause, theError);\n                });\n            });\n        });\n    }\n\n\n});\n"
  },
  {
    "path": "test/mocha/rejections.js",
    "content": "var assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\ndescribe(\"Using as a rejection reason\", function() {\n    var nullObject = (function() {\n        var es5 = (function(){\"use strict\";\n            return this;\n        })() === undefined;\n        if (es5) {\n            return function() {\n                return Object.create(null);\n            };\n        } else {\n            return function() {\n                return {};\n            };\n        }\n    })();\n    describe(\"Object.create(null)\", function() {\n        specify(\"directly\", function() {\n            var o = nullObject();\n            return Promise.reject(o).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through constructor by throw\", function() {\n            var o = nullObject();\n            return new Promise(function() {\n                throw o;\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n\n        specify(\"through constructor immediately\", function() {\n            var o = nullObject();\n            return new Promise(function() {\n                arguments[1](o);\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through constructor eventually\", function() {\n            var o = nullObject();\n            return new Promise(function(_, r) {\n                setTimeout(function() {\n                    r(o);\n                }, 1);\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through defer immediately\", function() {\n            var o = nullObject();\n            var d = Promise.defer();\n            var ret = d.promise.then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n            d.reject(o);\n            return ret;\n        });\n\n        specify(\"through defer eventually\", function() {\n            var o = nullObject();\n            var d = Promise.defer();\n            var ret = d.promise.then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n            setTimeout(function() {\n                d.reject(o);\n            }, 1);\n            return ret;\n        });\n\n        specify(\"through thenThrow immediately\", function() {\n            var o = nullObject();\n            return Promise.resolve().thenThrow(o).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through handler throw\", function() {\n            var o = nullObject();\n            return Promise.resolve().then(function() {\n                throw o;\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through handler-returned-promise immediately\", function() {\n            var o = nullObject();\n            return Promise.resolve().then(function() {\n                return Promise.reject(o);\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through handler-returned-promise eventually\", function() {\n            var o = nullObject();\n            return Promise.resolve().then(function() {\n                return new Promise(function(_, r) {\n                    setTimeout(function() {\n                        r(o);\n                    }, 1);\n                });\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through handler-returned-thenable throw\", function() {\n            var o = nullObject();\n            return Promise.resolve().then(function() {\n                return {\n                    then: function(_, r) {\n                        throw o;\n                    }\n                };\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through handler-returned-thenable immediately\", function() {\n            var o = nullObject();\n            return Promise.resolve().then(function() {\n                return {\n                    then: function(_, r) {\n                        r(o);\n                    }\n                };\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through handler-returned-thenable eventually\", function() {\n            var o = nullObject();\n            return Promise.resolve().then(function() {\n                return {\n                    then: function(_, r) {\n                        setTimeout(function() {\n                            r(o);\n                        }, 1);\n                    }\n                };\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        var BluebirdThenable = require(\"../../js/debug/promise.js\")();\n        specify(\"through handler-returned-bluebird-thenable immediately\", function() {\n            var o = nullObject();\n            return Promise.resolve().then(function() {\n                return BluebirdThenable.reject(o);\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through handler-returned-bluebird-thenable eventually\", function() {\n            var o = nullObject();\n            return Promise.resolve().then(function() {\n                return new BluebirdThenable(function(_, r) {\n                    setTimeout(function() {\n                        r(o);\n                    }, 1);\n                });\n            }).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through promisified callback immediately\", function() {\n            var o = nullObject();\n            return Promise.promisify(function(cb) {\n                cb(o);\n            })().then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through immediate PromiseArray promise\", function() {\n            var o = nullObject();\n            return Promise.all([Promise.reject(o)]).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through eventual PromiseArray promise\", function() {\n            var o = nullObject();\n            return Promise.all([new Promise(function(_, r) {\n                setTimeout(function() {\n                    r(o);\n                }, 1);\n            })]).then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n        specify(\"through promisified callback eventually\", function() {\n            var o = nullObject();\n            return Promise.promisify(function(cb) {\n                setTimeout(function() {\n                    cb(o);\n                }, 1);\n            })().then(assert.fail, function(e) {\n                assert.strictEqual(e, o);\n            });\n        });\n\n    });\n});\n"
  },
  {
    "path": "test/mocha/resolution.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\nvar getValues = function() {\n    var d = Promise.defer();\n    var f = Promise.resolve(3);\n    var r = Promise.reject(3);\n\n    setTimeout(function(){\n        d.resolve(3);\n    }, 1);\n\n    return {\n        value: 3,\n        thenableFulfill: {then: function(fn){setTimeout(function(){fn(3)}, 1);}},\n        thenableReject: {then: function(_, fn){setTimeout(function(){fn(3)}, 1);}},\n        promiseFulfilled: f,\n        promiseRejected: r,\n        promiseEventual: d.promise\n    };\n};\n\nfunction expect(count, callback) {\n    var cur = 0;\n    return new Promise(function() {\n\n    });\n}\n\nfunction expect(count, done) {\n    var total = 0;\n    return function() {\n        total++;\n        if (total >= count) {\n        }\n    }\n}\n\ndescribe(\"Promise.resolve\", function() {\n    specify(\"follows thenables and promises\", function() {\n        var values = getValues();\n        var async = false;\n        var ret = Promise.all([\n            Promise.resolve(values.value).then(testUtils.noop),\n            Promise.resolve(values.thenableFulfill).then(testUtils.noop),\n            Promise.resolve(values.thenableReject).then(assert.fail, testUtils.noop),\n            Promise.resolve(values.promiseFulfilled).then(testUtils.noop),\n            Promise.resolve(values.promiseRejected).then(assert.fail, testUtils.noop),\n            Promise.resolve(values.promiseEventual).then(testUtils.noop)\n        ]).then(function(v) {\n            assert.deepEqual(v, [3, 3, 3, 3, 3, 3]);\n            assert(async);\n        });\n        async = true;\n        return ret;\n    });\n});\n\ndescribe(\"Cast thenable\", function() {\n    var b = {\n        then: function(f, fn){\n            fn(b);\n        }\n    };\n\n    specify(\"rejects with itself\", function() {\n        var promise = Promise.cast(b);\n\n        return promise.then(assert.fail, function(v){\n           assert(v === b);\n        });\n    });\n});\n\ndescribe(\"Implicitly cast thenable\", function() {\n    var b = {\n        then: function(f, fn){\n            fn(b);\n        }\n    };\n\n    specify(\"rejects with itself\", function() {\n        return Promise.resolve().then(function(){\n            return b;\n        }).then(assert.fail, function(v){\n            assert(v === b);\n        });\n    });\n});\n\n\n\n\n/*!\n *\nCopyright 2009–2012 Kristopher Michael Kowal. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\ndescribe(\"propagation\", function () {\n\n    it(\"propagate through then with no callback\", function () {\n        return Promise.resolve(10)\n        .then()\n        .then(function (ten) {\n            assert.equal(ten,10);\n        });\n    });\n\n    it(\"propagate through then with modifying callback\", function () {\n        return Promise.resolve(10)\n        .then(function (ten) {\n            return ten + 10;\n        })\n        .then(function (twen) {\n            assert.equal(twen,20);\n        });\n    });\n\n    it(\"errback recovers from exception\", function () {\n        var error = new Error(\"Bah!\");\n        return Promise.reject(error)\n        .then(null, function (_error) {\n            assert.equal(_error,error);\n            return 10;\n        })\n        .then(function (value) {\n            assert.equal(value,10);\n        });\n    });\n\n    it(\"rejection propagates through then with no errback\", function () {\n        var error = new Error(\"Foolish mortals!\");\n        return Promise.reject(error)\n        .then()\n        .then(null, function (_error) {\n            assert.equal(_error,error);\n        });\n    });\n\n    it(\"rejection intercepted and rethrown\", function () {\n        var error = new Error(\"Foolish mortals!\");\n        var nextError = new Error(\"Silly humans!\");\n        return Promise.reject(error)\n        .caught(function () {\n            throw nextError;\n        })\n        .then(null, function (_error) {\n            assert.equal(_error,nextError);\n        });\n    });\n\n    it(\"resolution is forwarded through deferred promise\", function () {\n        var a = Promise.defer();\n        var b = Promise.defer();\n        a.resolve(b.promise);\n        b.resolve(10);\n        return a.promise.then(function (eh) {\n            assert.equal(eh, 10);\n        });\n    });\n});\n\n/*\nBased on When.js tests\n\nOpen Source Initiative OSI - The MIT License\n\nhttp://www.opensource.org/licenses/mit-license.php\n\nCopyright (c) 2011 Brian Cavalier\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar sentinel = {};\nvar other = {};\ndescribe(\"Promise.defer-test\", function () {\n\n\n    specify(\"should fulfill with an immediate value\", function() {\n        var d = Promise.defer();\n        d.resolve(sentinel);\n        return d.promise.then(\n            function(val) {\n                assert.equal(val, sentinel);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should return a promise for the resolution value\", function() {\n        var d = Promise.defer();\n\n        d.resolve(sentinel);\n        return d.promise.then(\n            function(returnedPromiseVal) {\n                assert.deepEqual(returnedPromiseVal, sentinel);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should return a promise for a promised resolution value\", function() {\n        var d = Promise.defer();\n\n        d.resolve(Promise.resolve(sentinel))\n        return d.promise.then(\n            function(returnedPromiseVal) {\n                assert.deepEqual(returnedPromiseVal, sentinel);\n            },\n            assert.fail\n        );\n    });\n\n    specify(\"should return a promise for a promised rejection value\", function() {\n        var d = Promise.defer();\n\n        // Both the returned promise, and the deferred's own promise should\n        // be rejected with the same value\n        d.resolve(Promise.reject(sentinel))\n        return d.promise.then(\n            assert.fail,\n            function(returnedPromiseVal) {\n                assert.deepEqual(returnedPromiseVal, sentinel);\n            }\n        );\n    });\n\n    specify(\"should invoke newly added callback when already resolved\", function() {\n        var d = Promise.defer();\n\n        d.resolve(sentinel);\n\n        return d.promise.then(\n            function(val) {\n                assert.equal(val, sentinel);\n            },\n            assert.fail\n        );\n    });\n\n\n\n    specify(\"should reject with an immediate value\", function() {\n        var d = Promise.defer();\n        d.reject(sentinel);\n        return d.promise.then(\n            assert.fail,\n            function(val) {\n                assert.equal(val, sentinel);\n            }\n        );\n    });\n\n    specify(\"should reject with fulfilled promised\", function() {\n        var d, expected;\n\n        d = Promise.defer();\n        expected = testUtils.fakeResolved(sentinel);\n\n        var ret = d.promise.then(\n            assert.fail,\n            function(val) {\n                assert.equal(val, expected);\n            }\n        );\n\n        d.reject(expected);\n        return ret;\n    });\n\n    specify(\"should reject with rejected promise\", function() {\n        var d, expected;\n\n        d = Promise.defer();\n        expected = testUtils.fakeRejected(sentinel);\n\n        var ret = d.promise.then(\n            assert.fail,\n            function(val) {\n                assert.equal(val, expected);\n            }\n        );\n\n        d.reject(expected);\n        return ret;\n    });\n\n\n    specify(\"should return a promise for the rejection value\", function() {\n        var d = Promise.defer();\n\n        // Both the returned promise, and the deferred's own promise should\n        // be rejected with the same value\n        d.reject(sentinel);\n        return d.promise.then(\n            assert.fail,\n            function(returnedPromiseVal) {\n                assert.deepEqual(returnedPromiseVal, sentinel);\n            }\n        );\n    });\n\n    specify(\"should invoke newly added errback when already rejected\", function() {\n        var d = Promise.defer();\n\n        d.reject(sentinel);\n\n        return d.promise.then(\n            assert.fail,\n            function (val) {\n                assert.deepEqual(val, sentinel);\n            }\n        );\n    });\n});\n\ndescribe(\"Promise.fromNode\", function() {\n    specify(\"rejects thrown errors from resolver\", function() {\n        var err = new Error();\n        return Promise.fromNode(function(callback) {\n            throw err;\n        }).then(assert.fail, function(e) {\n            assert.strictEqual(err, e);\n        });\n    });\n    specify(\"rejects rejections as operational errors\", function() {\n        var err = new Error();\n        return Promise.fromNode(function(callback) {\n            callback(err);\n        }).caught(Promise.OperationalError, function(e) {\n            assert.strictEqual(err, e.cause);\n        });\n    });\n    specify(\"resolves normally\", function() {\n        var result = {};\n        return Promise.fromNode(function(callback) {\n            callback(null, result);\n        }).then(function(res) {\n            assert.strictEqual(result, res);\n        });\n    });\n    specify(\"resolves with bound thunk\", function() {\n        var nodeFn = function(param, cb) {\n            setTimeout(function() {\n                cb(null, param);\n            }, 1);\n        };\n\n        return Promise.fromNode(nodeFn.bind(null, 1)).then(function(res) {\n            assert.strictEqual(1, res);\n        });\n    });\n    specify(\"multiArgs option enabled single value\", function() {\n        var nodeFn = function(cb) {\n            cb(null, 1);\n        };\n        return Promise.fromNode(function(callback) {\n            nodeFn(callback);\n        }, {multiArgs: true}).then(function(value) {\n            assert.deepEqual([1], value);\n        });\n\n    });\n    specify(\"multiArgs option enabled multi value\", function() {\n        var nodeFn = function(cb) {\n            cb(null, 1, 2, 3);\n        };\n        return Promise.fromNode(function(callback) {\n            nodeFn(callback);\n        }, {multiArgs: true}).then(function(value) {\n            assert.deepEqual([1,2,3], value);\n        });\n\n    });\n    specify(\"multiArgs option disabled single value\", function() {\n        var nodeFn = function(cb) {\n            cb(null, 1);\n        };\n        return Promise.fromNode(function(callback) {\n            nodeFn(callback);\n        }).then(function(value) {\n            assert.strictEqual(1, value);\n        });\n\n    });\n    specify(\"multiArgs option disabled multi value\", function() {\n        var nodeFn = function(cb) {\n            cb(null, 1, 2, 3);\n        };\n        return Promise.fromNode(function(callback) {\n            nodeFn(callback);\n        }).then(function(value) {\n            assert.strictEqual(1, value);\n        });\n\n    });\n});\n"
  },
  {
    "path": "test/mocha/schedule.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar schedule = require(\"../../js/debug/schedule\");\nvar isNodeJS = testUtils.isNodeJS;\n\ndescribe(\"schedule\", function () {\n    if (isNodeJS) {\n        describe(\"for Node.js\", function () {\n            it(\"should preserve the active domain\", function() {\n                var domain       = require(\"domain\");\n                var activeDomain = domain.create();\n                return new Promise(function(resolve) {\n                    activeDomain.run(function () {\n                        schedule(function () {\n                            assert(domain.active);\n                            assert.equal(domain.active, activeDomain);\n                            resolve();\n                        });\n                    });\n                });\n\n            });\n        });\n\n        describe(\"Promise.setScheduler\", function() {\n            it(\"should work with synchronous scheduler\", function() {\n                var prev = Promise.setScheduler(function(task) {\n                    task();\n                });\n                var success = false;\n                Promise.resolve().then(function() {\n                    success = true;\n                });\n                assert(success);\n                Promise.setScheduler(prev);\n            });\n            it(\"should throw for non function\", function() {\n                try {\n                    Promise.setScheduler({});\n                } catch (e) {\n                    return Promise.resolve();\n                }\n                assert.fail();\n            });\n        });\n    }\n});\n"
  },
  {
    "path": "test/mocha/settle.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n/*!\n *\nCopyright 2009–2012 Kristopher Michael Kowal. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\n\ndescribe(\"allSettled\", function () {\n    it(\"works on an empty array\", function () {\n        return Promise.settle([])\n        .then(function (snapshots) {\n            assert.deepEqual(snapshots, []);\n        });\n    });\n\n    it(\"deals with a mix of non-promises and promises\", function () {\n        return Promise.settle([1, Promise.resolve(2), Promise.reject(3)])\n        .then(function (snapshots) {\n            assert.equal(snapshots[0].value(), 1);\n            assert.equal(snapshots[1].value(), 2);\n            assert.equal(snapshots[2].error(), 3);\n        });\n    });\n\n    it(\"is settled after every constituent promise is settled\", function () {\n        var toFulfill = Promise.defer();\n        var toReject = Promise.defer();\n        var promises = [toFulfill.promise, toReject.promise];\n        var fulfilled;\n        var rejected;\n\n        Promise.attempt(function () {\n            toReject.reject();\n            rejected = true;\n        })\n        .delay(1)\n        .then(function () {\n            toFulfill.resolve();\n            fulfilled = true;\n        });\n\n        return Promise.settle(promises)\n        .then(function () {\n            assert.equal(fulfilled, true);\n            assert.equal(rejected, true);\n        });\n    });\n\n    it(\"does not modify the input array\", function () {\n        var input = [1, Promise.resolve(2), Promise.reject(3)];\n\n        return Promise.settle(input)\n        .then(function (snapshots) {\n            assert.notEqual(snapshots, input);\n            assert.equal(snapshots[0].value(), 1);\n            assert.equal(snapshots[1].value(), 2);\n            assert.equal(snapshots[2].error(), 3);\n        });\n    });\n\n});\n\n/*\nBased on When.js tests\n\nOpen Source Initiative OSI - The MIT License\n\nhttp://www.opensource.org/licenses/mit-license.php\n\nCopyright (c) 2011 Brian Cavalier\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar sentinel = {};\nvar other = {};\ndescribe(\"Promise.settle-test\", function () {\n\n\n    Promise.promise = function(rs){\n        var a = Promise.defer();\n        rs(a);\n        return a.promise;\n    };\n\n\n    specify(\"should settle empty array\", function() {\n        return Promise.settle([]).then(function(settled) {\n            assert.deepEqual(settled.length, 0);\n        });\n    });\n\n    specify(\"should reject if promise for input array rejects\", function() {\n        return Promise.settle(Promise.reject(sentinel)).then(\n            assert.fail,\n            function(reason) {\n                assert.equal(reason, sentinel);\n            }\n        );\n    });\n\n    specify(\"should settle values\", function() {\n        var array = [0, 1, sentinel];\n        return Promise.settle(array).then(function(settled) {\n            testUtils.assertFulfilled(settled[0], 0);\n            testUtils.assertFulfilled(settled[1], 1);\n            testUtils.assertFulfilled(settled[2], sentinel);\n        });\n    });\n\n    specify(\"should settle promises\", function() {\n        var array = [0, Promise.resolve(sentinel), Promise.reject(sentinel)];\n        return Promise.settle(array).then(function(settled) {\n            testUtils.assertFulfilled(settled[0], 0);\n            testUtils.assertFulfilled(settled[1], sentinel);\n            testUtils.assertRejected(settled[2], sentinel);\n        });\n    });\n\n    specify(\"returned promise should fulfill once all inputs settle\", function() {\n        var array, p1, p2, resolve, reject;\n\n        p1 = Promise.promise(function(r) { resolve = function(a){r.fulfill(a);}; });\n        p2 = Promise.promise(function(r) { reject = function(a){r.reject(a);}; });\n\n        array = [0, p1, p2];\n\n        setTimeout(function() { resolve(sentinel); }, 0);\n        setTimeout(function() { reject(sentinel); }, 0);\n\n        return Promise.settle(array).then(function(settled) {\n            testUtils.assertFulfilled(settled[0], 0);\n            testUtils.assertFulfilled(settled[1], sentinel);\n            testUtils.assertRejected(settled[2], sentinel);\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/some.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\ndescribe(\"Promise.some\", function(){\n    it(\"should reject on negative number\", function(){\n        return Promise.some([1,2,3], -1)\n            .then(assert.fail)\n            .caught(Promise.TypeError, function(){\n            });\n    });\n\n    it(\"should reject on NaN\", function(){\n        return Promise.some([1,2,3], -0/0)\n            .then(assert.fail)\n            .caught(Promise.TypeError, function(){\n            });\n    });\n\n    it(\"should reject on non-array\", function(){\n        return Promise.some({}, 2)\n            .then(assert.fail)\n            .caught(Promise.TypeError, function(){\n            });\n    });\n\n    it(\"should reject with rangeerror when impossible to fulfill\", function(){\n        return Promise.some([1,2,3], 4)\n            .then(assert.fail)\n            .caught(Promise.RangeError, function(e){\n            });\n    });\n\n    it(\"should fulfill with empty array with 0\", function(){\n        return Promise.some([1,2,3], 0).then(function(result){\n            assert.deepEqual(result, []);\n        });\n    });\n});\n\n/*\nBased on When.js tests\n\nOpen Source Initiative OSI - The MIT License\n\nhttp://www.opensource.org/licenses/mit-license.php\n\nCopyright (c) 2011 Brian Cavalier\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/\n\nvar RangeError = Promise.RangeError;\n\ndescribe(\"Promise.some-test\", function () {\n\n    specify(\"should reject empty input\", function() {\n        return Promise.some([], 1).caught(RangeError, function() {\n        });\n    });\n\n    specify(\"should resolve values array\", function() {\n        var input = [1, 2, 3];\n        return Promise.some(input, 2).then(\n            function(results) {\n                assert(testUtils.isSubset(results, input));\n            },\n            assert.fail\n        )\n    });\n\n    specify(\"should resolve promises array\", function() {\n        var input = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];\n        return Promise.some(input, 2).then(\n            function(results) {\n                assert(testUtils.isSubset(results, [1, 2, 3]));\n            },\n            assert.fail\n        )\n    });\n\n    specify(\"should not resolve sparse array input\", function() {\n        var input = [, 1, , 2, 3 ];\n        return Promise.some(input, 2).then(\n            function(results) {\n                assert.deepEqual(results, [void 0, 1]);\n            },\n            function() {\n                console.error(arguments);\n                assert.fail();\n            }\n        )\n    });\n\n    specify(\"should reject with all rejected input values if resolving howMany becomes impossible\", function() {\n        var input = [Promise.resolve(1), Promise.reject(2), Promise.reject(3)];\n        return Promise.some(input, 2).then(\n            assert.fail,\n            function(err) {\n                //Cannot use deep equality in IE8 because non-enumerable properties are not\n                //supported\n                assert(err[0] === 2);\n                assert(err[1] === 3);\n            }\n        )\n    });\n\n    specify(\"should reject with aggregateError\", function() {\n        var input = [Promise.resolve(1), Promise.reject(2), Promise.reject(3)];\n        var AggregateError = Promise.AggregateError;\n        return Promise.some(input, 2)\n            .then(assert.fail)\n            .caught(AggregateError, function(e) {\n                assert(e[0] === 2);\n                assert(e[1] === 3);\n                assert(e.length === 2);\n            });\n    });\n\n    specify(\"aggregate error should be caught in .error\", function() {\n        var input = [Promise.resolve(1), Promise.reject(2), Promise.reject(3)];\n        var AggregateError = Promise.AggregateError;\n        return Promise.some(input, 2)\n            .then(assert.fail)\n            .error(function(e) {\n                assert(e[0] === 2);\n                assert(e[1] === 3);\n                assert(e.length === 2);\n            });\n    });\n\n    specify(\"should accept a promise for an array\", function() {\n        var expected, input;\n\n        expected = [1, 2, 3];\n        input = Promise.resolve(expected);\n\n        return Promise.some(input, 2).then(\n            function(results) {\n                assert.deepEqual(results.length, 2);\n            },\n            assert.fail\n        )\n    });\n\n    specify(\"should reject when input promise does not resolve to array\", function() {\n        return Promise.some(Promise.resolve(1), 1).caught(TypeError, function(e){\n        });\n    });\n\n    specify(\"should reject when given immediately rejected promise\", function() {\n        var err = new Error();\n        return Promise.some(Promise.reject(err), 1).then(assert.fail, function(e) {\n            assert.strictEqual(err, e);\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/spread.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n/*!\n *\nCopyright 2009–2012 Kristopher Michael Kowal. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\n\ndescribe(\"spread\", function () {\n    it(\"spreads values across arguments\", function () {\n        return Promise.resolve([1, 2, 3]).spread(function (a, b) {\n            assert.equal(b,2);\n        });\n    });\n\n    it(\"spreads promises for arrays across arguments\", function () {\n        return Promise.resolve([Promise.resolve(10)])\n        .all()\n        .spread(function (value) {\n            assert.equal(value,10);\n        });\n    });\n\n    it(\"spreads arrays of promises across arguments\", function () {\n        var deferredA = Promise.defer();\n        var deferredB = Promise.defer();\n\n        var promise = Promise.resolve([deferredA.promise, deferredB.promise]).all().spread(\n                               function (a, b) {\n            assert.equal(a,10);\n            assert.equal(b,20);\n        });\n\n        Promise.delay(1).then(function () {\n            deferredA.resolve(10);\n        });\n        Promise.delay(1).then(function () {\n            deferredB.resolve(20);\n        });\n\n        return promise;\n    });\n\n    it(\"spreads arrays of thenables across arguments\", function () {\n        var p1 = {\n            then: function(v) {\n                v(10);\n            }\n        };\n        var p2 = {\n            then: function(v) {\n                v(20);\n            }\n        };\n\n        var promise = Promise.resolve([p1, p2]).all().spread(function (a, b) {\n            assert.equal(a,10);\n            assert.equal(b,20);\n        });\n        return promise;\n    });\n\n    it(\"should wait for promises in the returned array even when not calling .all\", function() {\n        var d1 = Promise.defer();\n        var d2 = Promise.defer();\n        var d3 = Promise.defer();\n        setTimeout(function(){\n            d1.resolve(1);\n            d2.resolve(2);\n            d3.resolve(3);\n        }, 1);\n        return Promise.resolve().then(function(){\n            return [d1.promise, d2.promise, d3.promise];\n        }).all().spread(function(a, b, c){\n            assert(a === 1);\n            assert(b === 2);\n            assert(c === 3);\n        });\n    });\n\n    it(\"should wait for thenables in the returned array even when not calling .all\", function() {\n        var t1 = {\n            then: function(fn) {\n                setTimeout(function(){\n                    fn(1);\n                }, 1);\n            }\n        };\n        var t2 = {\n            then: function(fn) {\n                setTimeout(function(){\n                    fn(2);\n                }, 1);\n            }\n        };\n        var t3 = {\n            then: function(fn) {\n                setTimeout(function(){\n                    fn(3);\n                }, 1);\n            }\n        };\n        return Promise.resolve().then(function(){\n            return [t1, t2, t3];\n        }).all().spread(function(a, b, c){\n            assert(a === 1);\n            assert(b === 2);\n            assert(c === 3);\n        });\n    });\n\n    it(\"should wait for promises in an array that a returned promise resolves to even when not calling .all\", function() {\n        var d1 = Promise.defer();\n        var d2 = Promise.defer();\n        var d3 = Promise.defer();\n        var defer = Promise.defer();\n\n        setTimeout(function(){\n            defer.resolve([d1.promise, d2.promise, d3.promise]);\n            setTimeout(function(){\n                d1.resolve(1);\n                d2.resolve(2);\n                d3.resolve(3);\n            }, 1);\n        }, 1);\n\n        return Promise.resolve().then(function(){\n            return defer.promise;\n        }).all().spread(function(a, b, c){\n            assert(a === 1);\n            assert(b === 2);\n            assert(c === 3);\n        });\n    });\n\n    it(\"should wait for thenables in an array that a returned thenable resolves to even when not calling .all\", function() {\n        var t1 = {\n            then: function(fn) {\n                setTimeout(function(){\n                    fn(1);\n                }, 1);\n            }\n        };\n        var t2 = {\n            then: function(fn) {\n                setTimeout(function(){\n                    fn(2);\n                }, 1);\n            }\n        };\n        var t3 = {\n            then: function(fn) {\n                setTimeout(function(){\n                    fn(3);\n                }, 1);\n            }\n        };\n\n        var thenable = {\n            then: function(fn) {\n                setTimeout(function(){\n                    fn([t1, t2, t3])\n                }, 1);\n            }\n        };\n\n        return Promise.resolve().then(function(){\n            return thenable;\n        }).all().spread(function(a, b, c){\n            assert(a === 1);\n            assert(b === 2);\n            assert(c === 3);\n        });\n    });\n\n    it(\"should reject with error when non array is the ultimate value to be spread\", function(){\n        return Promise.resolve().then(function(){\n            return 3\n        }).spread(function(a, b, c){\n            assert.fail();\n        }).then(assert.fail, function(e){\n        })\n    });\n\n    specify(\"gh-235\", function() {\n        var P = Promise;\n        return P.resolve(1).then(function(x) {\n          return [x, P.resolve(2)]\n        }).spread(function(x, y) {\n          return P.all([P.resolve(3), P.resolve(4)]);\n        }).then(function(a) {\n          assert.deepEqual([3, 4], a);\n        });\n    })\n\n    specify(\"error when passed non-function\", function() {\n        return Promise.resolve(3)\n                .spread()\n                .then(assert.fail)\n                .caught(Promise.TypeError, function() {});\n    });\n\n    specify(\"error when resolution is non-spredable\", function() {\n        return Promise.resolve(3)\n                .spread(function(){})\n                .then(assert.fail)\n                .caught(Promise.TypeError, function() {});\n    });\n});\n\n/*\nBased on When.js tests\n\nOpen Source Initiative OSI - The MIT License\n\nhttp://www.opensource.org/licenses/mit-license.php\n\nCopyright (c) 2011 Brian Cavalier\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/\n\ndescribe(\"Promise.spread-test\", function () {\n    var slice = [].slice;\n\n    specify(\"should return a promise\", function() {\n        assert(typeof (Promise.defer().promise.spread(function(){}).then) === \"function\");\n    });\n\n    specify(\"should apply onFulfilled with array as argument list\", function() {\n        var expected = [1, 2, 3];\n        return Promise.resolve(expected).spread(function() {\n            assert.deepEqual(slice.call(arguments), expected);\n        });\n    });\n\n    specify(\"should resolve array contents\", function() {\n        var expected = [Promise.resolve(1), 2, Promise.resolve(3)];\n        return Promise.resolve(expected).all().spread(function() {\n            assert.deepEqual(slice.call(arguments), [1, 2, 3]);\n        });\n    });\n\n    specify(\"should reject if any item in array rejects\", function() {\n        var expected = [Promise.resolve(1), 2, Promise.reject(3)];\n        return Promise.resolve(expected).all()\n            .spread(assert.fail)\n            .then(assert.fail, function() {});\n    });\n\n    specify(\"should apply onFulfilled with array as argument list\", function() {\n        var expected = [1, 2, 3];\n        return Promise.resolve(Promise.resolve(expected)).spread(function() {\n            assert.deepEqual(slice.call(arguments), expected);\n        });\n    });\n\n    specify(\"should resolve array contents\", function() {\n        var expected = [Promise.resolve(1), 2, Promise.resolve(3)];\n        return Promise.resolve(Promise.resolve(expected)).all().spread(function() {\n            assert.deepEqual(slice.call(arguments), [1, 2, 3]);\n        });\n    });\n\n    specify(\"should reject if input is a rejected promise\", function() {\n        var expected = Promise.reject([1, 2, 3]);\n        return Promise.resolve(expected)\n            .spread(assert.fail)\n            .then(assert.fail, function() {});\n    });\n});\n"
  },
  {
    "path": "test/mocha/synchronous_inspection.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\ndescribe(\"Promise.prototype.toJSON\", function() {\n    it(\"should match pending state\", function() {\n        var a = new Promise(function(){}).toJSON();\n        assert.strictEqual(a.isFulfilled, false);\n        assert.strictEqual(a.isRejected, false);\n        assert.strictEqual(a.rejectionReason, undefined);\n        assert.strictEqual(a.fulfillmentValue, undefined);\n    });\n    it(\"should match rejected state\", function() {\n        var a = Promise.reject(3).toJSON();\n        assert.strictEqual(a.isFulfilled, false);\n        assert.strictEqual(a.isRejected, true);\n        assert.strictEqual(a.rejectionReason, 3);\n        assert.strictEqual(a.fulfillmentValue, undefined);\n    });\n    it(\"should match fulfilled state\", function() {\n        var a = Promise.resolve(3).toJSON();\n        assert.strictEqual(a.isFulfilled, true);\n        assert.strictEqual(a.isRejected, false);\n        assert.strictEqual(a.rejectionReason, undefined);\n        assert.strictEqual(a.fulfillmentValue, 3);\n    });\n});\n/*!\n *\nCopyright 2009–2012 Kristopher Michael Kowal. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\n// In browsers that support strict mode, it'll be `undefined`; otherwise, the global.\nvar calledAsFunctionThis = (function () { return this; }());\ndescribe(\"inspect\", function () {\n\n    it(\"for a fulfilled promise\", function () {\n        var ret = Promise.resolve(10);\n        assert.equal(ret.value(), 10);\n        assert.equal(ret.isFulfilled(), true);\n    });\n\n    it(\"for a rejected promise\", function () {\n        var e = new Error(\"In your face.\");\n        var ret = Promise.reject(e);\n        assert.equal(ret.reason(), e);\n        assert.equal(ret.isRejected(), true);\n        return ret.then(assert.fail, function(){});\n    });\n\n    it(\"for a pending, unresolved promise\", function () {\n        var pending = Promise.defer().promise;\n        assert.equal(pending.isPending(), true);\n    });\n\n    it(\"for a promise resolved to a rejected promise\", function () {\n        var deferred = Promise.defer();\n        var error = new Error(\"Rejected!\");\n        var reject = Promise.reject(error);\n        deferred.resolve(reject);\n\n        assert.equal(deferred.promise.isRejected(), true);\n        assert.equal(deferred.promise.reason(), error);\n        return deferred.promise.then(assert.fail, function(){});\n    });\n\n    it(\"for a promise resolved to a fulfilled promise\", function () {\n        var deferred = Promise.defer();\n        var fulfilled = Promise.resolve(10);\n        deferred.resolve(fulfilled);\n\n        assert.equal(deferred.promise.isFulfilled(), true);\n        assert.equal(deferred.promise.value(), 10);\n    });\n\n    it(\"for a promise resolved to a pending promise\", function () {\n        var a = Promise.defer();\n        var b = Promise.defer();\n        a.resolve(b.promise);\n\n        assert.equal(a.promise.isPending(), true);\n    });\n\n    describe(\".value()\", function() {\n        specify(\"of unfulfilled inspection should throw\", function() {\n            Promise.reject(1).reflect().then(function(inspection) {\n                try {\n                    inspection.value();\n                } catch (e) {\n                    return Promise.resolve();\n                }\n                assert.fail();\n            });\n        });\n        specify(\"of unfulfilled promise should throw\", function() {\n            var r = Promise.reject(1);\n            r.reason();\n            try {\n                r.value();\n            } catch (e) {\n                return Promise.resolve();\n            }\n            assert.fail();\n        });\n    });\n\n    describe(\".reason()\", function() {\n        specify(\"of unrejected inspection should throw\", function() {\n            Promise.resolve(1).reflect().then(function(inspection) {\n                try {\n                    inspection.reason();\n                } catch (e) {\n                    return Promise.resolve();\n                }\n                assert.fail();\n            });\n        });\n\n        specify(\"of unrejected promise should throw\", function() {\n            try {\n                Promise.resolve(1).reason();\n            } catch (e) {\n                return Promise.resolve();\n            }\n            assert.fail();\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/tap.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\n\ndescribe(\"tap\", function () {\n    specify(\"passes through value\", function() {\n        return Promise.resolve(\"test\").tap(function() {\n            return 3;\n        }).then(function(value){\n            assert.equal(value, \"test\");\n        });\n    });\n\n    specify(\"passes through value after returned promise is fulfilled\", function() {\n        var async = false;\n        return Promise.resolve(\"test\").tap(function() {\n            return new Promise(function(r) {\n                setTimeout(function(){\n                    async = true;\n                    r(3);\n                }, 1);\n            });\n        }).then(function(value){\n            assert(async);\n            assert.equal(value, \"test\");\n        });\n    });\n\n    specify(\"is not called on rejected promise\", function() {\n        var called = false;\n        return Promise.reject(\"test\").tap(function() {\n            called = true;\n        }).then(assert.fail, function(value){\n            assert(!called);\n        });\n    });\n\n    specify(\"passes immediate rejection\", function() {\n        var err = new Error();\n        return Promise.resolve(\"test\").tap(function() {\n            throw err;\n        }).tap(assert.fail).then(assert.fail, function(e){\n            assert(err === e);\n        });\n    });\n\n    specify(\"passes eventual rejection\", function() {\n        var err = new Error();\n        return Promise.resolve(\"test\").tap(function() {\n            return new Promise(function(_, rej) {\n                setTimeout(function(){\n                    rej(err);\n                }, 1)\n            });\n        }).tap(assert.fail).then(assert.fail, function(e) {\n            assert(err === e);\n        });\n    });\n\n    specify(\"passes value\", function() {\n        return Promise.resolve(123).tap(function(a) {\n            assert(a === 123);\n        });\n    });\n});\n"
  },
  {
    "path": "test/mocha/tapCatch.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nfunction rejection() {\n    var error = new Error(\"test\");\n    var rejection = Promise.reject(error);\n    rejection.err = error;\n    return rejection;\n}\n\ndescribe(\"tapCatch\", function () {\n\n    specify(\"passes through rejection reason\", function() {\n        return rejection().tapCatch(function() {\n            return 3;\n        }).caught(function(value) {\n            assert.equal(value.message, \"test\");\n        });\n    });\n\n    specify(\"passes through reason after returned promise is fulfilled\", function() {\n        var async = false;\n        return rejection().tapCatch(function() {\n            return new Promise(function(r) {\n                setTimeout(function(){\n                    async = true;\n                    r(3);\n                }, 1);\n            });\n        }).caught(function(value) {\n            assert(async);\n            assert.equal(value.message, \"test\");\n        });\n    });\n\n    specify(\"is not called on fulfilled promise\", function() {\n        var called = false;\n        return Promise.resolve(\"test\").tapCatch(function() {\n            called = true;\n        }).then(function(value){\n            assert(!called);\n        }, assert.fail);\n    });\n\n    specify(\"passes immediate rejection\", function() {\n        var err = new Error();\n        return rejection().tapCatch(function() {\n            throw err;\n        }).tap(assert.fail).then(assert.fail, function(e) {\n            assert(err === e);\n        });\n    });\n\n    specify(\"passes eventual rejection\", function() {\n        var err = new Error();\n        return rejection().tapCatch(function() {\n            return new Promise(function(_, rej) {\n                setTimeout(function(){\n                    rej(err);\n                }, 1)\n            });\n        }).tap(assert.fail).then(assert.fail, function(e) {\n            assert(err === e);\n        });\n    });\n\n    specify(\"passes reason\", function() {\n        return rejection().tapCatch(function(a) {\n            assert(a === rejection);\n        }).then(assert.fail, function() {});\n    });\n\n    specify(\"Works with predicates\", function() {\n        var called = false;\n        return Promise.reject(new TypeError).tapCatch(TypeError, function(a) {\n            called = true;\n            assert(err instanceof TypeError)\n        }).then(assert.fail, function(err) {\n            assert(called === true);\n            assert(err instanceof TypeError);\n        });\n    });\n    specify(\"Does not get called on predicates that don't match\", function() {\n        var called = false;\n        return Promise.reject(new TypeError).tapCatch(ReferenceError, function(a) {\n            called = true;\n        }).then(assert.fail, function(err) {\n            assert(called === false);\n            assert(err instanceof TypeError);\n        });\n    });\n\n    specify(\"Supports multiple predicates\", function() {\n        var calledA = false;\n        var calledB = false;\n        var calledC = false;\n\n        var promiseA = Promise.reject(new ReferenceError).tapCatch(\n            ReferenceError,\n            TypeError,\n            function (e) {\n                assert(e instanceof ReferenceError);\n                calledA = true;\n            }\n        ).catch(function () {});\n\n        var promiseB = Promise.reject(new TypeError).tapCatch(\n            ReferenceError,\n            TypeError,\n            function (e) {\n                assert(e instanceof TypeError);\n                calledB = true;\n            }\n        ).catch(function () {});\n\n        var promiseC = Promise.reject(new SyntaxError).tapCatch(\n            ReferenceError,\n            TypeError,\n            function (e) {\n                calledC = true;\n            }\n        ).catch(function () {});\n\n        return Promise.join(promiseA, promiseB, promiseC, function () {\n            assert(calledA === true);\n            assert(calledB === true);\n            assert(calledC === false);\n        });\n    })\n});\n"
  },
  {
    "path": "test/mocha/timers.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar Q = Promise;\nPromise.config({cancellation: true})\nvar globalObject = typeof window !== \"undefined\" ? window : new Function(\"return this;\")();\n/*\nCopyright 2009–2012 Kristopher Michael Kowal. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n*/\n\ndescribe(\"timeout\", function () {\n    it(\"should do nothing if the promise fulfills quickly\", function() {\n        Promise.delay(1).timeout(200).then(function(){\n        });\n    });\n\n    it(\"should do nothing if the promise rejects quickly\", function() {\n        var goodError = new Error(\"haha!\");\n        return Promise.delay(1)\n        .then(function () {\n            throw goodError;\n        })\n        .timeout(200)\n        .then(undefined, function (error) {\n            assert(error === goodError);\n        });\n    });\n\n    it(\"should reject with a timeout error if the promise is too slow\", function() {\n        return Promise.delay(1)\n        .timeout(10)\n        .caught(Promise.TimeoutError, function(){\n        })\n    });\n\n    it(\"should reject with a custom timeout error if the promise is too slow and msg was provided\", function() {\n        return Promise.delay(1)\n        .timeout(10, \"custom\")\n        .caught(Promise.TimeoutError, function(e){\n            assert(/custom/i.test(e.message));\n        });\n    });\n\n    it(\"should cancel the parent promise once the timeout expires\", function() {\n        var didNotExecute = true;\n        var wasRejectedWithTimeout = false;\n        var p = Promise.delay(22).then(function() {\n            didNotExecute = false;\n        })\n        p.timeout(11).thenReturn(10).caught(Promise.TimeoutError, function(e) {\n            wasRejectedWithTimeout = true;\n        })\n        return Promise.delay(33).then(function() {\n            assert(didNotExecute, \"parent promise was not cancelled\");\n            assert(wasRejectedWithTimeout, \"promise was not rejected with timeout\");\n        })\n    });\n\n    it(\"should not cancel the parent promise if there are multiple consumers\", function() {\n        var derivedNotCancelled = false;\n        var p = Promise.delay(22);\n        var derived = p.then(function() {\n            derivedNotCancelled = true;\n        })\n        p.timeout(11).thenReturn(10)\n        return Promise.delay(33).then(function() {\n            assert(derivedNotCancelled, \"derived promise was cancelled\")\n        })\n    })\n\n    var globalsAreReflectedInGlobalObject = (function(window) {\n        var fn = function(id){return clearTimeout(id);};\n        var old = window.clearTimeout;\n        window.clearTimeout = fn;\n        var ret = clearTimeout === fn;\n        window.clearTimeout = old;\n        return ret;\n    })(globalObject);\n\n    if (globalsAreReflectedInGlobalObject) {\n        describe(\"timer handle clearouts\", function() {\n            var fakeSetTimeout, fakeClearTimeout;\n            var expectedHandleType;\n\n            before(function() {\n                fakeSetTimeout = globalObject.setTimeout;\n                fakeClearTimeout = globalObject.clearTimeout;\n                globalObject.setTimeout = globalObject.oldSetTimeout;\n                globalObject.clearTimeout = globalObject.oldClearTimeout;\n                expectedHandleType = typeof (globalObject.setTimeout(function(){}, 1));\n            });\n\n            after(function() {\n                globalObject.setTimeout = fakeSetTimeout;\n                globalObject.clearTimeout = fakeClearTimeout;\n            });\n\n            it(\"should clear timeouts with proper handle type when fulfilled\", function() {\n                var old = globalObject.clearTimeout;\n                var handleType = \"empty\";\n                globalObject.clearTimeout = function(handle) {\n                    handleType = typeof handle;\n                    globalObject.clearTimeout = old;\n                };\n\n                return Promise.delay(1).timeout(10000).then(function() {\n                    assert.strictEqual(expectedHandleType, handleType);\n                });\n            });\n\n            it(\"should clear timeouts with proper handle type when rejected\", function() {\n                var old = globalObject.clearTimeout;\n                var handleType = \"empty\";\n                globalObject.clearTimeout = function(handle) {\n                    handleType = typeof handle;\n                    globalObject.clearTimeout = old;\n                };\n\n                return new Promise(function(_, reject) {\n                    setTimeout(reject, 10);\n                }).timeout(10000).then(null, function() {\n                    assert.strictEqual(expectedHandleType, handleType);\n                });\n            });\n        })\n\n    }\n});\n\ndescribe(\"delay\", function () {\n    it(\"should not delay rejection\", function() {\n        var promise = Promise.reject(5).delay(1);\n\n        promise.then(assert.fail, function(){});\n\n        return Promise.delay(1).then(function () {\n            assert(!promise.isPending());\n        });\n    });\n\n    it(\"should delay after resolution\", function () {\n        var promise1 = Promise.delay(1, \"what\");\n        var promise2 = promise1.delay(1);\n\n        return promise2.then(function (value) {\n            assert(value === \"what\");\n        });\n    });\n\n    it(\"should resolve follower promise's value\", function() {\n        var resolveF;\n        var f = new Promise(function() {\n            resolveF = arguments[0];\n        });\n        var v = new Promise(function(f) {\n            setTimeout(function() {\n                f(3);\n            }, 1);\n        });\n        resolveF(v);\n        return Promise.delay(1, f).then(function(value) {\n            assert.equal(value, 3);\n        });\n    });\n\n    it(\"should reject with a custom error if an error was provided as a parameter\", function() {\n        var err = Error(\"Testing Errors\")\n        return Promise.delay(1)\n            .timeout(10, err)\n            .caught(function(e){\n                assert(e === err);\n            });\n    });\n\n});\n"
  },
  {
    "path": "test/mocha/try.js",
    "content": "\"use strict\";\n\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\nvar obj = {};\nvar error = new Error();\nvar thrower = function() {\n    throw error;\n};\n\nvar identity = function(val) {\n    return val;\n};\n\nvar array = function() {\n    return [].slice.call(arguments);\n};\n\nvar receiver = function() {\n    return this;\n};\n\nvar tryy = Promise[\"try\"];\n\ndescribe(\"Promise.attempt\", function(){\n    specify(\"should reject when the function throws\", function() {\n        var async = false;\n        var ret = tryy(thrower).then(assert.fail, function(e) {\n            assert(async);\n            assert(e === error);\n        });\n        async = true;\n        return ret;\n    });\n\n    specify(\"should reject when the function is not a function\", function() {\n        var async = false;\n        var ret = tryy(null).then(assert.fail, function(e) {\n            assert(async);\n            assert(e instanceof Promise.TypeError);\n        });\n        async = true;\n        return ret;\n    });\n\n    specify(\"should unwrap returned promise\", function(){\n        var d = Promise.defer();\n\n        var ret = tryy(function(){\n            return d.promise;\n        }).then(function(v){\n            assert(v === 3);\n        })\n\n        setTimeout(function(){\n            d.fulfill(3);\n        }, 1);\n        return ret;\n    });\n    specify(\"should unwrap returned thenable\", function(){\n        return tryy(function(){\n            return {\n                then: function(f, v) {\n                    f(3);\n                }\n            }\n        }).then(function(v){\n            assert(v === 3);\n        });\n\n    });\n});\n"
  },
  {
    "path": "test/mocha/unhandled_rejections.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\nvar noop = testUtils.noop;\nvar isStrictModeSupported = testUtils.isStrictModeSupported;\nvar onUnhandledFail = testUtils.onUnhandledFail;\nvar onUnhandledSucceed = testUtils.onUnhandledSucceed;\n\nfunction yesE() {\n    return new Error();\n}\n\nfunction notE() {\n    var rets = [{}, []];\n    return rets[Math.random()*rets.length|0];\n}\n\nfunction cleanUp() {\n    Promise.onPossiblyUnhandledRejection(null);\n    Promise.onUnhandledRejectionHandled(null);\n}\n\nfunction setupCleanUps() {\n    beforeEach(cleanUp);\n    afterEach(cleanUp);\n}\n\ndescribe(\"Will report rejections that are not handled in time\", function() {\n    setupCleanUps();\n\n    specify(\"Immediately rejected not handled at all\", function testFunction() {\n        var promise = Promise.defer();\n        promise.reject(yesE());\n        return onUnhandledSucceed();\n    });\n\n    specify(\"Eventually rejected not handled at all\", function testFunction() {\n        var promise = Promise.defer();\n        setTimeout(function(){\n            promise.reject(yesE());\n        }, 1);\n        return onUnhandledSucceed();\n    });\n\n    specify(\"Immediately rejected handled too late\", function testFunction() {\n        var promise = Promise.defer();\n        promise.reject(yesE());\n        setTimeout(function() {\n            promise.promise.then(assert.fail, function(){});\n        }, 150);\n        return onUnhandledSucceed();\n    });\n    specify(\"Eventually rejected handled too late\", function testFunction() {\n        var promise = Promise.defer();\n        setTimeout(function(){\n            promise.reject(yesE());\n            setTimeout(function() {\n                promise.promise.then(assert.fail, function(){});\n            }, 150);\n        }, 1);\n\n        return onUnhandledSucceed();\n    });\n});\n\ndescribe(\"Will report rejections that are code errors\", function() {\n    setupCleanUps();\n\n    specify(\"Immediately fulfilled handled with erroneous code\", function testFunction() {\n        var deferred = Promise.defer();\n        var promise = deferred.promise;\n        deferred.fulfill(null);\n        promise.then(function(itsNull){\n            itsNull.will.fail.four.sure();\n        });\n        return onUnhandledSucceed();\n    });\n    specify(\"Eventually fulfilled handled with erroneous code\", function testFunction() {\n        var deferred = Promise.defer();\n        var promise = deferred.promise;\n        setTimeout(function(){\n            deferred.fulfill(null);\n        }, 1);\n        promise.then(function(itsNull){\n            itsNull.will.fail.four.sure();\n        });\n        return onUnhandledSucceed();\n    });\n\n    specify(\"Already fulfilled handled with erroneous code but then recovered and failDeferred again\", function testFunction() {\n        var err = yesE();\n        var promise = Promise.resolve(null);\n        promise.then(function(itsNull){\n            itsNull.will.fail.four.sure();\n        }).then(assert.fail, function(e){\n            assert.ok(e instanceof Promise.TypeError);\n        }).then(function(){\n            //then assert.failing again\n            //this error should be reported\n            throw err;\n        });\n        return onUnhandledSucceed(err);\n    });\n\n    specify(\"Immediately fulfilled handled with erroneous code but then recovered and failDeferred again\", function testFunction() {\n        var err = yesE();\n        var deferred = Promise.defer();\n        var promise = deferred.promise;\n        deferred.fulfill(null);\n        promise.then(function(itsNull){\n            itsNull.will.fail.four.sure();\n        }).then(assert.fail, function(e){\n                assert.ok(e instanceof Promise.TypeError)\n            //Handling the type error here\n        }).then(function(){\n            //then assert.failing again\n            //this error should be reported\n            throw err;\n        });\n        return onUnhandledSucceed(err);\n    });\n\n    specify(\"Eventually fulfilled handled with erroneous code but then recovered and failDeferred again\", function testFunction() {\n        var err = yesE();\n        var deferred = Promise.defer();\n        var promise = deferred.promise;\n\n        promise.then(function(itsNull){\n            itsNull.will.fail.four.sure();\n        }).then(assert.fail, function(e){\n                assert.ok(e instanceof Promise.TypeError)\n            //Handling the type error here\n        }).then(function(){\n            //then assert.failing again\n            //this error should be reported\n            throw err;\n        });\n\n        setTimeout(function(){\n            deferred.fulfill(null);\n        }, 1);\n        return onUnhandledSucceed(err);\n    });\n\n    specify(\"Already fulfilled handled with erroneous code but then recovered in a parallel handler and failDeferred again\", function testFunction() {\n        var err = yesE();\n        var promise = Promise.resolve(null);\n        promise.then(function(itsNull){\n            itsNull.will.fail.four.sure();\n        }).then(assert.fail, function(e){\n            assert.ok(e instanceof Promise.TypeError)\n        });\n\n        promise.then(function(){\n            //then assert.failing again\n            //this error should be reported\n            throw err;\n        });\n        return onUnhandledSucceed(err);\n    });\n});\n\ndescribe(\"Will report rejections that are not instanceof Error\", function() {\n    setupCleanUps();\n\n    specify(\"Immediately rejected with non instanceof Error\", function testFunction() {\n        var failDeferred = Promise.defer();\n        failDeferred.reject(notE());\n        return onUnhandledSucceed();\n    });\n\n    specify(\"Eventually rejected with non instanceof Error\", function testFunction() {\n        var failDeferred = Promise.defer();\n        setTimeout(function(){\n            failDeferred.reject(notE());\n        }, 1);\n        return onUnhandledSucceed();\n    });\n});\n\ndescribe(\"Will handle hostile rejection reasons like frozen objects\", function() {\n    setupCleanUps();\n\n    specify(\"Immediately rejected with non instanceof Error\", function testFunction() {\n        var failDeferred = Promise.defer();\n        failDeferred.reject(Object.freeze({}));\n        return onUnhandledSucceed(function(e) {\n            return true;\n        });\n    });\n\n\n    specify(\"Eventually rejected with non instanceof Error\", function testFunction() {\n        var failDeferred = Promise.defer();\n        var obj = {};\n        setTimeout(function(){\n            failDeferred.reject(Object.freeze(obj));\n        }, 1);\n        return onUnhandledSucceed(function(e) {\n            return e === obj;\n        });\n    });\n});\n\n\ndescribe(\"Will not report rejections that are handled in time\", function() {\n    setupCleanUps();\n\n    specify(\"Already rejected handled\", function testFunction() {\n        var failDeferred = Promise.reject(yesE()).caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"Immediately rejected handled\", function testFunction() {\n        var failDeferred = Promise.defer();\n        failDeferred.promise.caught(noop);\n        failDeferred.reject(yesE());\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n\n    specify(\"Eventually rejected handled\", function testFunction() {\n        var failDeferred = Promise.defer();\n        setTimeout(function() {\n            failDeferred.reject(yesE());\n        }, 1);\n        failDeferred.promise.caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"Already rejected handled in a deep sequence\", function testFunction() {\n        var failDeferred = Promise.reject(yesE());\n\n        failDeferred\n            .then(function(){})\n            .then(function(){}, null, function(){})\n            .then()\n            .then(function(){})\n            .caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"Immediately rejected handled in a deep sequence\", function testFunction() {\n        var failDeferred = Promise.defer();\n\n        failDeferred.promise.then(function(){})\n            .then(function(){}, null, function(){})\n            .then()\n            .then(function(){})\n            .caught(noop);\n\n\n        failDeferred.reject(yesE());\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n\n    specify(\"Eventually handled in a deep sequence\", function testFunction() {\n        var failDeferred = Promise.defer();\n        setTimeout(function() {\n            failDeferred.reject(yesE());\n        }, 1);\n        failDeferred.promise.then(function(){})\n            .then(function(){}, null, function(){})\n            .then()\n            .then(function(){})\n            .caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n\n    specify(\"Already rejected handled in a middle parallel deep sequence\", function testFunction() {\n        var failDeferred = Promise.reject(yesE());\n\n        failDeferred\n            .then(function(){})\n            .then(function(){}, null, function(){})\n            .then()\n            .then(function(){});\n\n\n        failDeferred\n            .then(function(){})\n            .then(function(){}, null, function(){})\n            .then(assert.fail, function(){\n            });\n\n        failDeferred\n            .then(function(){})\n            .then(function(){}, null, function(){})\n            .then()\n            .then(function(){});\n\n        return onUnhandledSucceed(undefined, 2);\n    });\n\n\n    specify(\"Immediately rejected handled in a middle parallel deep  sequence\", function testFunction() {\n        var failDeferred = Promise.defer();\n\n        failDeferred.promise\n            .then(function(){})\n            .then(function(){}, null, function(){})\n            .then()\n            .then(function(){});\n\n        failDeferred.promise\n            .then(function(){})\n            .then(function(){}, null, function(){})\n            .then(assert.fail, function(){\n            });\n\n        failDeferred.promise\n            .then(function(){})\n            .then(function(){}, null, function(){})\n            .then()\n            .then(function(){});\n\n        failDeferred.reject(yesE());\n        return onUnhandledSucceed(undefined, 2);\n    });\n\n\n    specify(\"Eventually handled in a middle parallel deep sequence\", function testFunction() {\n        var failDeferred = Promise.defer();\n\n        failDeferred.promise\n            .then(function(){})\n            .then(function(){}, null, function(){})\n            .then()\n            .then(function(){});\n\n        failDeferred.promise\n            .then(function(){})\n            .then(function(){}, null, function(){})\n            .then(assert.fail, function(){\n            });\n\n        failDeferred.promise\n            .then(function(){})\n            .then(function(){}, null, function(){})\n            .then()\n            .then(function(){});\n\n\n        setTimeout(function(){\n            failDeferred.reject(yesE());\n        }, 1);\n        return onUnhandledSucceed(undefined, 2);\n    });\n});\n\ndescribe(\"immediate assert.failures without .then\", function testFunction() {\n    setupCleanUps();\n    var err = new Error('');\n    specify(\"Promise.reject\", function testFunction() {\n        Promise.reject(err);\n        return onUnhandledSucceed(function(e) {\n            return e === err;\n        });\n    });\n\n    specify(\"new Promise throw\", function testFunction() {\n        new Promise(function() {\n            throw err;\n        });\n        return onUnhandledSucceed(function(e) {\n            return e === err;\n        });\n    });\n\n    specify(\"new Promise reject\", function testFunction() {\n        new Promise(function(_, r) {\n            r(err);\n        });\n        return onUnhandledSucceed(function(e) {\n            return e === err;\n        });\n    });\n\n    specify(\"Promise.method\", function testFunction() {\n        Promise.method(function() {\n            throw err;\n        })();\n        return onUnhandledSucceed(function(e) {\n            return e === err;\n        });\n    });\n\n    specify(\"Promise.all\", function testFunction() {\n        Promise.all([Promise.reject(err)]);\n        return onUnhandledSucceed(function(e) {\n            return e === err;\n        });\n    });\n});\n\n\ndescribe(\"immediate assert.failures with .then\", function testFunction() {\n    setupCleanUps();\n    var err = new Error('');\n    specify(\"Promise.reject\", function testFunction() {\n        Promise.reject(err).caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"new Promise throw\", function testFunction() {\n        new Promise(function() {\n            throw err;\n        }).caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"new Promise reject\", function testFunction() {\n        new Promise(function(_, r) {\n            r(err);\n        }).caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"Promise.method\", function testFunction() {\n        Promise.method(function() {\n            throw err;\n        })().caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"Promise.all\", function testFunction() {\n        Promise.all([Promise.reject(\"err\")])\n            .caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"Promise.all many\", function testFunction() {\n        Promise.all([Promise.reject(\"err\"), Promise.reject(\"err2\")])\n            .caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"Promise.all many, latter async\", function testFunction() {\n        Promise.all([Promise.reject(\"err\"), Promise.delay(1).thenThrow(new Error())])\n            .caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"Promise.all many pending\", function testFunction() {\n        var a = new Promise(function(v, w){\n            setTimeout(function(){w(\"err\");}, 1);\n        });\n        var b = new Promise(function(v, w){\n            setTimeout(function(){w(\"err2\");}, 1);\n        });\n\n        Promise.all([a, b])\n            .caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"Already rejected promise for a collection\", function testFunction(){\n        Promise.settle(Promise.reject(err))\n            .caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n});\n\ndescribe(\"gh-118\", function() {\n    setupCleanUps();\n    specify(\"eventually rejected promise\", function testFunction() {\n        Promise.resolve().then(function() {\n            return new Promise(function(_, reject) {\n                setTimeout(function() {\n                    reject(13);\n                }, 1);\n            });\n        }).caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"already rejected promise\", function testFunction() {\n        Promise.resolve().then(function() {\n            return Promise.reject(13);\n        }).caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n\n    specify(\"immediately rejected promise\", function testFunction() {\n        Promise.resolve().then(function() {\n            return new Promise(function(_, reject) {\n                reject(13);\n            });\n        }).caught(noop);\n        return onUnhandledFail(isStrictModeSupported ? testFunction : arguments.callee);\n    });\n});\n\ndescribe(\"Promise.onUnhandledRejectionHandled\", function() {\n    specify(\"should be called when unhandled promise is later handled\", function() {\n        var unhandledPromises = [];\n        var spy1 = testUtils.getSpy();\n        var spy2 = testUtils.getSpy();\n\n        Promise.onPossiblyUnhandledRejection(spy1(function(reason, promise) {\n            unhandledPromises.push({\n                reason: reason,\n                promise: promise\n            });\n        }));\n\n        Promise.onUnhandledRejectionHandled(spy2(function(promise) {\n            assert.equal(unhandledPromises.length, 1);\n            assert(unhandledPromises[0].promise === promise);\n            assert(promise === a);\n            assert(unhandledPromises[0].reason === reason);\n        }));\n\n        var reason = new Error(\"error\");\n        var a = new Promise(function(){\n            throw reason;\n        });\n\n        setTimeout(function() {\n            Promise._unhandledRejectionCheck();\n            a.then(assert.fail, function(){});\n        }, 1);\n\n        return Promise.all([spy1.promise, spy2.promise]);\n    });\n});\n\ndescribe(\"global events\", function() {\n    var attachGlobalHandler, detachGlobalHandlers;\n    if (typeof process !== \"undefined\" &&\n        typeof process.version === \"string\" &&\n        typeof window === \"undefined\") {\n        attachGlobalHandler = function(name, fn) {\n            process.on(name, fn);\n        };\n        detachGlobalHandlers = function() {\n            process.removeAllListeners(\"unhandledRejection\");\n            process.removeAllListeners(\"rejectionHandled\");\n        };\n    } else {\n        attachGlobalHandler = function(name, fn) {\n            window[(\"on\" + name).toLowerCase()] = fn;\n        };\n        detachGlobalHandlers = function() {\n            window.onunhandledrejection = null;\n            window.onrejectionhandled = null;\n        };\n    }\n    setupCleanUps();\n    beforeEach(detachGlobalHandlers);\n    afterEach(detachGlobalHandlers);\n    specify(\"are fired\", function() {\n        return new Promise(function(resolve, reject) {\n            var err = new Error();\n            var receivedPromise;\n            attachGlobalHandler(\"unhandledRejection\", function(reason, promise) {\n                assert.strictEqual(reason, err);\n                receivedPromise = promise;\n            });\n            attachGlobalHandler(\"rejectionHandled\", function(promise) {\n                assert.strictEqual(receivedPromise, promise);\n                resolve();\n            });\n\n            var promise = new Promise(function() {throw err;});\n            setTimeout(function() {\n                Promise._unhandledRejectionCheck();\n                promise.then(assert.fail, function(){});\n            }, 1);\n        });\n    });\n\n    specify(\"are fired with local events\", function() {\n        return new Promise(function(resolve, reject) {\n            var expectedOrder = [1, 2, 3, 4];\n            var order = [];\n            var err = new Error();\n            var receivedPromises = [];\n\n            Promise.onPossiblyUnhandledRejection(function(reason, promise) {\n                assert.strictEqual(reason, err);\n                receivedPromises.push(promise);\n                order.push(1);\n            });\n\n            Promise.onUnhandledRejectionHandled(function(promise) {\n                assert.strictEqual(receivedPromises[0], promise);\n                order.push(3);\n            });\n\n            attachGlobalHandler(\"unhandledRejection\", function(reason, promise) {\n                assert.strictEqual(reason, err);\n                receivedPromises.push(promise);\n                order.push(2);\n            });\n\n            attachGlobalHandler(\"rejectionHandled\", function(promise) {\n                assert.strictEqual(receivedPromises[1], promise);\n                order.push(4);\n                assert.deepEqual(expectedOrder, order);\n                assert.strictEqual(receivedPromises.length, 2);\n                resolve();\n            });\n\n            var promise = new Promise(function() {throw err;});\n            setTimeout(function() {\n                Promise._unhandledRejectionCheck();\n                promise.then(assert.fail, function(){});\n            }, 1);\n        });\n\n    });\n});\nvar windowDomEventSupported = true;\ntry {\n    var event = document.createEvent(\"CustomEvent\");\n    event.initCustomEvent(\"testingtheevent\", false, true, {});\n    self.dispatchEvent(event);\n} catch (e) {\n    windowDomEventSupported = false;\n}\nif (windowDomEventSupported) {\n    describe(\"dom events\", function() {\n        var events = [];\n\n        beforeEach(detachEvents);\n        afterEach(detachEvents);\n        function detachEvents() {\n            events.forEach(function(e) {\n                self.removeEventListener(e.type, e.fn, false);\n            });\n            events = [];\n        }\n\n        function attachEvent(type, fn) {\n            events.push({type: type, fn: fn});\n            self.addEventListener(type, fn, false);\n        }\n\n        specify(\"are fired\", function() {\n            return new Promise(function(resolve, reject) {\n                var order = [];\n                var err = new Error();\n                var promise = Promise.reject(err);\n                attachEvent(\"unhandledrejection\", function(e) {\n                    e.preventDefault();\n                    assert.strictEqual(e.detail.promise, promise);\n                    assert.strictEqual(e.detail.reason, err);\n                    assert.strictEqual(e.promise, promise);\n                    assert.strictEqual(e.reason, err);\n                    order.push(1);\n                });\n                attachEvent(\"unhandledrejection\", function(e) {\n                    assert.strictEqual(e.detail.promise, promise);\n                    assert.strictEqual(e.detail.reason, err);\n                    assert.strictEqual(e.promise, promise);\n                    assert.strictEqual(e.reason, err);\n                    assert.strictEqual(e.defaultPrevented, true);\n                    order.push(2);\n                });\n                attachEvent(\"rejectionhandled\", function(e) {\n                    e.preventDefault();\n                    assert.strictEqual(e.detail.promise, promise);\n                    assert.strictEqual(e.detail.reason, undefined);\n                    assert.strictEqual(e.promise, promise);\n                    assert.strictEqual(e.reason, undefined);\n                    order.push(3);\n                });\n                attachEvent(\"rejectionhandled\", function(e) {\n                    assert.strictEqual(e.detail.promise, promise);\n                    assert.strictEqual(e.detail.reason, undefined);\n                    assert.strictEqual(e.promise, promise);\n                    assert.strictEqual(e.reason, undefined);\n                    assert.strictEqual(e.defaultPrevented, true);\n                    order.push(4);\n                    resolve();\n                });\n\n                setTimeout(function() {\n                    Promise._unhandledRejectionCheck();\n                    promise.then(assert.fail, function(r) {\n                        order.push(5);\n                        assert.strictEqual(r, err);\n                        assert.deepEqual(order, [1,2,3,4,5]);\n                    });\n                }, 1);\n            });\n\n        })\n    });\n\n    if (typeof Worker !== \"undefined\") {\n        describe(\"dom events in a worker\", function() {\n            var worker;\n            beforeEach(function () {\n                worker = new Worker(\"./worker.js\");\n            });\n\n            afterEach(function () {\n                worker.terminate();\n            });\n\n            specify(\"are fired\", function() {\n                var order = [];\n                return new Promise(function(resolve, reject) {\n                    worker.onmessage = function (message) {\n                        try {\n                            switch(message.data) {\n                            case \"unhandledrejection\":\n                                order.push(1);\n                                break;\n                            case \"rejectionhandled\":\n                                order.push(2);\n                                resolve();\n                                break;\n                            default:\n                                throw new Error(\"unexpected message: \" + message);\n                            }\n                        }\n                        catch (e) {\n                            reject(e);\n                        }\n                    };\n\n                    worker.postMessage(\"reject\");\n                }).then(function () {\n                    assert.deepEqual(order, [1, 2]);\n                });\n            });\n        });\n    }\n\n}\n\ndescribe(\"Unhandled rejection when joining chains with common rejected parent\", function testFunction() {\n    specify(\"GH 645\", function() {\n        var aError = new Error('Something went wrong');\n        var a = Promise.try(function(){\n            throw aError;\n        });\n\n        var b = Promise.try(function(){\n            throw new Error('Something went wrong here as well');\n        });\n\n        var c = Promise\n            .join(a, b)\n            .spread(function( a, b ){\n                return a+b;\n            });\n\n        var test1 = Promise\n            .join(a, c)\n            .spread(function( a, product ){\n                // ...\n            })\n            .caught(Error, function(e) {\n                assert.strictEqual(aError, e);\n            });\n\n         var test2 = onUnhandledFail(testFunction);\n\n         return Promise.all([test1, test2]);\n    });\n});\n\nvar asyncAwaitSupported = (function() {\n    try {\n        new Function(\"async function abc() {}\");\n        return true;\n    } catch (e) {\n        return false;\n    }\n})();\n\nif (asyncAwaitSupported) {\n    describe(\"No unhandled rejection from async await\", function () {\n        setupCleanUps();\n        specify(\"gh-1404\", function testFunction() {\n            var ret = onUnhandledFail(testFunction);\n            Promise.using(Promise.resolve(),\n                (new Function(\"Bluebird\", \"return async function() { await Bluebird.reject(new Error('foo')); }\"))(Promise))\n            .caught(function() {});\n            return ret;\n        });\n    });\n}\n\ndescribe(\"issues\", function () {\n    setupCleanUps();\n\n    specify(\"GH-1501-1\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        Promise.reduce([Promise.resolve(\"foo\"), Promise.reject(new Error(\"reason\"), Promise.resolve(\"bar\"))],\n            function() {},\n            {}).caught(function() {});\n        return ret;\n    });\n\n    specify(\"GH-1501-2\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        Promise.reduce([Promise.delay(1), Promise.reject(new Error(\"reason\"))],\n            function() {},\n            {}).caught(function() {});\n        return ret;\n    });\n\n    specify(\"GH-1501-3\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        Promise.reduce([Promise.reject(new Error(\"reason\"))],\n            function() {},\n            Promise.reject(new Error(\"reason2\"))).caught(function() {});\n        return ret;\n    });\n\n    specify(\"GH-1487-1\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        var p = Promise.reject( new Error('foo') );\n        Promise.map( p, function() {} ).caught( function() {} );\n        return ret;\n    });\n\n    specify(\"GH-1487-2\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        var arr = [ Promise.reject( new Error('foo') ) ];\n        Promise.map( arr, function() {} ).caught( function() {} );\n        return ret;\n    });\n\n    specify(\"GH-1487-3\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        var p = Promise.reject( new Error('foo') );\n        p.map( function() {} ).caught( function() {} );\n        return ret;\n    });\n\n    specify(\"GH-1487-4\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        var arr = [ Promise.reject( new Error('foo') ) ];\n        var p = Promise.resolve( arr );\n        p.map( function() {} ).caught( function() {} );\n        return ret;\n    });\n\n    specify(\"GH-1487-5\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        var p = Promise.reject( new Error('foo') );\n        Promise.filter( p, function() {} ).caught( function() {} );\n        return ret;\n    });\n\n    specify(\"GH-1487-6\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        var arr = [ Promise.reject( new Error('foo') ) ];\n        Promise.filter( arr, function() {} ).caught( function() {} );\n        return ret;\n    });\n\n    specify(\"GH-1487-7\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        var p = Promise.reject( new Error('foo') );\n        p.filter( function() {} ).caught( function() {} );\n        return ret;\n    });\n\n    specify(\"GH-1487-8\", function testFunction() {\n        var ret = onUnhandledFail(testFunction);\n        var arr = [ Promise.reject( new Error('foo') ) ];\n        var p = Promise.resolve( arr );\n        p.filter( function() {} ).caught( function() {} );\n        return ret;\n    });\n})\n"
  },
  {
    "path": "test/mocha/using.js",
    "content": "\"use strict\";\nvar assert = require(\"assert\");\nvar testUtils = require(\"./helpers/util.js\");\n\nvar Promise2 = require(\"../../js/debug/promise.js\")();\n\nvar using = Promise.using;\nvar error = new Error(\"\");\nvar id = 0;\nfunction Resource() {\n    this.isClosed = false;\n    this.closesCalled = 0;\n    this.commited = false;\n    this.rollbacked = false;\n    this.id = id++;\n\n}\n\nResource.prototype.commit = function () {\n    if (this.commited || this.rollbacked) {\n        throw new Error(\"was already commited or rolled back\")\n    }\n    this.commited = true;\n};\n\nResource.prototype.commitAsync = function () {\n    return Promise.delay(1).bind(this).then(this.commit)\n}\n\nResource.prototype.rollback = function () {\n    if (this.commited || this.rollbacked) {\n        throw new Error(\"was already commited or rolled back\")\n    }\n    this.rollbacked = true;\n};\n\nResource.prototype.rollbackAsync = function () {\n    return Promise.delay(1).bind(this).then(this.rollback)\n}\n\nResource.prototype.closeAsync = function() {\n    return Promise.delay(1).bind(this).then(this.close);\n};\n\nResource.prototype.close = function() {\n    this.closesCalled++;\n    if (this.isClosed) {\n        return;\n    }\n    this.isClosed = true;\n};\n\nResource.prototype.closeError = function() {\n    throw error;\n};\n\nResource.prototype.query = function(value) {\n    return Promise.delay(1, value);\n};\n\nfunction _connect() {\n    return new Promise(function(resolve) {\n        setTimeout(function(){\n            resolve(new Resource())\n        }, 1);\n    });\n}\n\nfunction _connect2() {\n    return new Promise2(function(resolve) {\n        setTimeout(function(){\n            resolve(new Resource())\n        }, 1);\n    });\n}\n\nfunction connectCloseAsync(arr, value) {\n    return _connect().disposer(function(resource){\n        return resource.closeAsync().then(function() {\n            arr.push(value);\n        });\n    });\n}\n\nfunction promiseForConnectCloseAsync(arr, value) {\n    return Promise.delay(1).then(function() {\n        return connectCloseAsync(arr, value);\n    });\n}\n\nfunction connect() {\n    return _connect().disposer(Resource.prototype.close);\n}\n\nfunction connect2() {\n    return _connect2().disposer(Resource.prototype.close);\n}\n\n\nfunction connectError() {\n    return new Promise(function(resolve, reject) {\n        setTimeout(function(){\n            reject(error);\n        }, 1);\n    });\n}\n\nfunction transactionDisposer(tx, outcome) {\n    outcome.isFulfilled() ? tx.commit() : tx.rollback();\n}\n\nfunction transactionDisposerAsync(tx, outcome) {\n    return outcome.isFulfilled() ? tx.commitAsync() : tx.rollbackAsync();\n}\n\nfunction transaction() {\n    return _connect().disposer(transactionDisposer);\n}\n\nfunction transactionWithImmediatePromiseAfterConnect() {\n    return _connect().then(function (connection) {\n      return Promise.resolve(connection).then(function(c) { return c; })\n    }).disposer(transactionDisposer);\n}\n\nfunction transactionWithEventualPromiseAfterConnect() {\n    return _connect().then(function (connection) {\n      return Promise.delay(1).thenReturn(connection);\n    }).disposer(transactionDisposer);\n}\n\nfunction transactionAsync() {\n    return _connect().disposer(transactionDisposerAsync);\n}\n\ndescribe(\"Promise.using\", function() {\n    specify(\"simple happy case\", function() {\n        var res;\n\n        return using(connect(), function(connection){\n            res = connection;\n        }).then(function() {\n            assert(res.isClosed);\n            assert.equal(res.closesCalled, 1);\n        });\n    });\n\n    specify(\"simple async happy case\", function() {\n        var res;\n        var async = false;\n\n        return using(connect(), function(connection) {\n            res = connection;\n            return Promise.delay(1).then(function() {\n                async = true;\n            });\n        }).then(function() {\n            assert(async);\n            assert(res.isClosed);\n            assert.equal(res.closesCalled, 1);\n        });\n    });\n\n    specify(\"simple unhappy case\", function() {\n        var a = connect();\n        var promise = a._promise;\n        var b = connectError();\n        return using(b, a, function(a, b) {\n            assert(false);\n        }).then(assert.fail, function() {\n            assert(promise.value().isClosed);\n            assert.equal(promise.value().closesCalled, 1);\n        })\n    });\n\n    specify(\"calls async disposers sequentially\", function() {\n         var a = [];\n         var _res3 = connectCloseAsync(a, 3);\n         var _res2 = connectCloseAsync(a, 2);\n         var _res1 = connectCloseAsync(a, 1);\n         return using(_res1, _res2, _res3, function(res1, res2, res3) {\n            _res1 = res1;\n            _res2 = res2;\n            _res3 = res3;\n         }).then(function() {\n            assert.deepEqual(a, [1,2,3]);\n            assert(_res1.isClosed);\n            assert(_res2.isClosed);\n            assert(_res3.isClosed);\n            assert(_res1.closesCalled == 1);\n            assert(_res2.closesCalled == 1);\n            assert(_res3.closesCalled == 1);\n         });\n    });\n\n    specify(\"calls async disposers sequentially when assert.failing\", function() {\n         var a = [];\n         var _res3 = connectCloseAsync(a, 3);\n         var _res2 = connectCloseAsync(a, 2);\n         var _res1 = connectCloseAsync(a, 1);\n         var p1 = _res1.promise();\n         var p2 = _res2.promise();\n         var p3 = _res3.promise();\n         var e = new Error();\n         var promise = Promise.delay(1).thenThrow(e);\n         return using(_res1, _res2, _res3, promise, function() {\n\n         }).then(assert.fail, function(err) {\n            assert.deepEqual(a, [1,2,3]);\n            assert(p1.value().isClosed);\n            assert(p2.value().isClosed);\n            assert(p3.value().isClosed);\n            assert(p1.value().closesCalled == 1);\n            assert(p2.value().closesCalled == 1);\n            assert(p3.value().closesCalled == 1);\n            assert(e === err)\n         });\n    });\n\n    specify(\"calls promised async disposers sequentially\", function() {\n         var a = [];\n         var _res3 = promiseForConnectCloseAsync(a, 3);\n         var _res2 = promiseForConnectCloseAsync(a, 2);\n         var _res1 = promiseForConnectCloseAsync(a, 1);\n         return using(_res1, _res2, _res3, function(res1, res2, res3) {\n            assert(res1 instanceof Resource)\n            assert(res2 instanceof Resource)\n            assert(res3 instanceof Resource)\n            _res1 = res1;\n            _res2 = res2;\n            _res3 = res3;\n         }).then(function() {\n            assert.deepEqual(a, [1,2,3]);\n            assert(_res1.isClosed);\n            assert(_res2.isClosed);\n            assert(_res3.isClosed);\n            assert(_res1.closesCalled == 1);\n            assert(_res2.closesCalled == 1);\n            assert(_res3.closesCalled == 1);\n         });\n    });\n\n    specify(\"calls promised async disposers sequentially when assert.failing\", function() {\n         var a = [];\n         var _res3 = promiseForConnectCloseAsync(a, 3);\n         var _res2 = promiseForConnectCloseAsync(a, 2);\n         var _res1 = promiseForConnectCloseAsync(a, 1);\n         var e = new Error();\n         var promise = Promise.delay(1).thenThrow(e);\n         return using(_res1, _res2, _res3, promise, function() {\n\n         }).then(assert.fail, function(err) {\n            assert.deepEqual(a, [1,2,3]);\n            assert(_res1.value().promise().value().isClosed);\n            assert(_res2.value().promise().value().isClosed);\n            assert(_res3.value().promise().value().isClosed);\n            assert(_res1.value().promise().value().closesCalled == 1);\n            assert(_res2.value().promise().value().closesCalled == 1);\n            assert(_res3.value().promise().value().closesCalled == 1);\n            assert(e === err)\n         });\n    });\n\n    specify(\"mixed promise, promise-for-disposer and disposer\", function() {\n         var a = [];\n         var _res3 = promiseForConnectCloseAsync(a, 3);\n         var _res2 = connectCloseAsync(a, 2);\n         var _res1 = Promise.delay(1, 10);\n         return using(_res1, _res2, _res3, function(res1, res2, res3) {\n            assert(res1 === 10);\n            assert(res2 instanceof Resource);\n            assert(res3 instanceof Resource);\n            _res1 = res1;\n            _res2 = res2;\n            _res3 = res3;\n         }).then(function() {\n            assert.deepEqual(a, [2,3]);\n            assert(_res2.isClosed);\n            assert(_res3.isClosed);\n            assert(_res2.closesCalled == 1);\n            assert(_res3.closesCalled == 1);\n         });\n    });\n\n    specify(\"successful transaction\", function() {\n        var _tx;\n        return using(transaction(), function(tx) {\n            _tx = tx;\n            return tx.query(1).then(function() {\n                return tx.query(2);\n            })\n        }).then(function(){\n            assert(_tx.commited);\n            assert(!_tx.rollbacked);\n        });\n    });\n\n    specify(\"successful async transaction\", function() {\n        var _tx;\n        return using(transactionAsync(), function(tx) {\n            _tx = tx;\n            return tx.query(1).then(function() {\n                return tx.query(3);\n            })\n        }).then(function(){\n            assert(_tx.commited);\n            assert(!_tx.rollbacked);\n        })\n    })\n\n    specify(\"successful transaction with an immediate promise before disposer creation\", function() {\n        var _tx;\n        return using(transactionWithImmediatePromiseAfterConnect(), function(tx) {\n            _tx = tx;\n            return tx.query(1);\n        }).then(function(){\n            assert(_tx.commited);\n            assert(!_tx.rollbacked);\n        });\n    });\n\n    specify(\"successful transaction with an eventual promise before disposer creation\", function() {\n        var _tx;\n        return using(transactionWithEventualPromiseAfterConnect(), function(tx) {\n            _tx = tx;\n            return tx.query(1);\n        }).then(function(){\n            assert(_tx.commited);\n            assert(!_tx.rollbacked);\n        });\n    });\n\n    specify(\"assert.fail transaction\", function() {\n        var _tx;\n        return using(transaction(), function(tx) {\n            _tx = tx;\n            return tx.query(1).then(function() {\n                throw new Error();\n            })\n        }).then(assert.fail, function(){\n            assert(!_tx.commited);\n            assert(_tx.rollbacked);\n        });\n    });\n\n    specify(\"assert.fail async transaction\", function() {\n        var _tx;\n        return using(transactionAsync(), function(tx) {\n            _tx = tx;\n            return tx.query(1).then(function() {\n                throw new Error();\n            })\n        }).then(assert.fail, function(){\n            assert(!_tx.commited);\n            assert(_tx.rollbacked);\n        });\n    });\n\n    specify(\"with using coming from another Promise instance\", function() {\n        var res;\n        return Promise2.using(connect(), function(connection){\n            res = connection;\n        }).then(function() {\n            assert(res.isClosed);\n            assert.equal(res.closesCalled, 1);\n        });\n    });\n\n    specify(\"with using coming from another Promise instance other way around\", function() {\n        var res;\n        return Promise.using(connect2(), function(connection){\n            res = connection;\n        }).then(function() {\n            assert(res.isClosed);\n            assert.equal(res.closesCalled, 1);\n        });\n    });\n\n    if (testUtils.isNodeJS) {\n        specify(\"disposer throwing should throw in node process\", function() {\n            var err = new Error();\n            var disposer = Promise.resolve().disposer(function() {\n                throw err;\n            });\n            using(disposer, function(){});\n            return testUtils.awaitGlobalException(function(e) {\n                assert.strictEqual(e, err);\n            });\n        });\n    }\n\n    specify(\"Return rejected promise with less than 2 arguments\", function() {\n        return Promise.using(1).caught(Promise.TypeError, function(e) {});\n    });\n\n    specify(\"Throw if disposer is not passed a function\", function() {\n        try {\n            Promise.resolve().disposer({});\n        } catch (e) {\n            return Promise.resolve();\n        }\n        assert.fail();\n    });\n\n    specify(\"Mixed rejected disposers are not called\", function() {\n        var err = new Error(\"rejected should not be called\");\n        var a = Promise.delay(1).thenThrow(err).disposer(function() {\n            done(err);\n        });\n        var b = Promise.delay(1).thenReturn(connect());\n        return Promise.using(a, b, function() {\n            done(new Error(\"should not be here\"));\n        }).then(assert.fail, function(e) {\n            assert.strictEqual(b.value()._promise.value().isClosed, true);\n            assert.strictEqual(b.value()._promise.value().closesCalled, 1);\n        });\n    });\n\n    specify(\"Return rejected promise when last argument is not function\", function() {\n        return Promise.using({}, {}, {}, {}).caught(Promise.TypeError, function(e) {});\n    });\n\n\n    specify(\"Supports an array of 2 items\", function() {\n        return Promise.using([Promise.resolve(1), Promise.resolve(2)], function(results) {\n            assert.deepEqual(results, [1,2]);\n        });\n    });\n\n    specify(\"Supports an empty array\", function() {\n        return Promise.using([], function(results) {\n            assert.deepEqual(results, []);\n        });\n    })\n\n    specify(\"null disposer is called\", function() {\n        var calls = 0;\n        var getNull = function() {\n            return Promise.resolve(null).disposer(function() {\n                calls++;\n            });\n        };\n\n        return Promise.using(getNull(), function() {\n            calls++;\n        }).then(function() {\n            assert.equal(2, calls);\n        })\n    })\n})\n"
  },
  {
    "path": "tests",
    "content": "#!/usr/bin/env bash\nnode tools/test.js \"$@\"\n"
  },
  {
    "path": "tools/README.md",
    "content": "## Tools\n\nTools that can be run from command line:\n\n### test.js\n\nFor running tests. See [Testing](../#testing).\n\n### build.js\n\nFor building the library. See [Custom builds](../#custom-builds).\n\n### jshintrc_generator.js\n\nGenerates a .jshintrc file in the project root.\n\nExample:\n\n    node tools/jshintrc_generator\n"
  },
  {
    "path": "tools/ast_passes.js",
    "content": "//All kinds of conversion passes over the source code\nvar jsp = require(\"acorn\");\nvar walk = require(\"acorn-walk\");\nvar rnonIdentMember = /[.\\-_$a-zA-Z0-9]/g;\nvar global = new Function(\"return this\")();\n\nfunction equals( a, b ) {\n    if( a.type === b.type ) {\n        if( a.type === \"MemberExpression\" ) {\n            return equals( a.object, b.object ) &&\n                equals( a.property, b.property );\n        }\n        else if( a.type === \"Identifier\" ) {\n            return a.name === b.name;\n        }\n        else if( a.type === \"ThisExpression\" ) {\n            return true;\n        }\n        else {\n            console.log(\"equals\", a, b);\n            unhandled();\n        }\n    }\n    return false;\n}\n\nfunction getReceiver( expr ) {\n    if( expr.type === \"MemberExpression\" ) {\n        return expr.object;\n    }\n    return null;\n}\n\nfunction nodeToString( expr ) {\n    if( expr == null || typeof expr !== \"object\" ) {\n        if( expr === void 0 ) {\n            return \"void 0\";\n        }\n        else if( typeof expr === \"string\" ) {\n            return '\"' + safeToEmbedString(expr) + '\"';\n        }\n        return (\"\" + expr);\n    }\n    if( expr.type === \"Identifier\" ) {\n        return expr.name;\n    }\n    else if( expr.type === \"MemberExpression\" ) {\n        if( expr.computed )\n            return nodeToString( expr.object ) + \"[\" + nodeToString( expr.property ) + \"]\";\n        else\n            return nodeToString( expr.object ) + \".\" + nodeToString( expr.property );\n    }\n    else if( expr.type === \"UnaryExpression\" ) {\n        if( expr.operator === \"~\" ||\n            expr.operator === \"-\" ||\n            expr.operator === \"+\" ) {\n            return expr.operator + nodeToString( expr.argument );\n        }\n        return \"(\" + expr.operator + \" \" + nodeToString( expr.argument ) + \")\";\n    }\n    else if( expr.type === \"Literal\" ) {\n        return expr.raw;\n    }\n    else if( expr.type === \"BinaryExpression\" || expr.type === \"LogicalExpression\" ) {\n        return \"(\"+nodeToString(expr.left) + \" \" +\n            expr.operator + \" \" +\n            nodeToString(expr.right) + \")\";\n    }\n    else if( expr.type === \"ThisExpression\" ) {\n        return \"this\";\n    }\n    else if( expr.type === \"ObjectExpression\") {\n        var props = expr.properties;\n        var ret = [];\n        for( var i = 0, len = props.length; i < len; ++i ) {\n            var prop = props[i];\n            ret.push( nodeToString(prop.key) + \": \" + nodeToString(prop.value));\n        }\n        return \"({\"+ret.join(\",\\n\")+\"})\";\n    }\n    else if( expr.type === \"NewExpression\" ) {\n        return \"new \" + nodeToString(expr.callee) + \"(\" + nodeToString(expr.arguments) +\")\";\n    }\n    //assuming it is arguments\n    else if( Array.isArray( expr ) ) {\n        var tmp = [];\n        for( var i = 0, len = expr.length; i < len; ++i ) {\n            tmp.push( nodeToString(expr[i]) );\n        }\n        return tmp.join(\", \");\n    }\n    else if( expr.type === \"FunctionExpression\" ) {\n        var params = [];\n        for( var i = 0, len = expr.params.length; i < len; ++i ) {\n            params.push( nodeToString(expr.params[i]) );\n        }\n    }\n    else if( expr.type === \"BlockStatement\" ) {\n        var tmp  = [];\n        for( var i = 0, len = expr.body.length; i < len; ++i ) {\n            tmp.push( nodeToString(expr.body[i]) );\n        }\n        return tmp.join(\";\\n\");\n    }\n    else if( expr.type === \"CallExpression\" ) {\n        var args = [];\n        for( var i = 0, len = expr.arguments.length; i < len; ++i ) {\n            args.push( nodeToString(expr.arguments[i]) );\n        }\n        return nodeToString( expr.callee ) + \"(\"+args.join(\",\")+\")\";\n    }\n    else {\n        console.log( \"nodeToString\", expr );\n        unhandled()\n    }\n}\n\nfunction DynamicCall( receiver, fnDereference, arg, start, end ) {\n    this.receiver = receiver;\n    this.fnDereference = fnDereference;\n    this.arg = arg;\n    this.start = start;\n    this.end = end;\n}\n\nDynamicCall.prototype.toString = function() {\n    return nodeToString(this.fnDereference) + \".call(\" +\n        nodeToString(this.receiver) + \", \" +\n        nodeToString(this.arg) +\n    \")\";\n};\n\nfunction DirectCall( receiver, fnName, arg, start, end ) {\n    this.receiver = receiver;\n    this.fnName = fnName;\n    this.arg = arg;\n    this.start = start;\n    this.end = end;\n}\nDirectCall.prototype.toString = function() {\n    return nodeToString(this.receiver) + \".\" + nodeToString(this.fnName) +\n        \"(\" + nodeToString(this.arg) + \")\"\n};\n\n\nfunction ConstantReplacement( value, start, end ) {\n    this.value = value;\n    this.start = start;\n    this.end = end;\n}\n\nConstantReplacement.prototype.toString = function() {\n    return nodeToString(this.value);\n};\n\nfunction Empty(start, end) {\n    this.start = start;\n    this.end = end;\n}\nEmpty.prototype.toString = function() {\n    return \"\";\n};\n\nfunction Assertion( expr, exprStr, start, end ) {\n    this.expr = expr;\n    this.exprStr = exprStr;\n    this.start = start;\n    this.end = end;\n}\nAssertion.prototype.toString = function() {\n    return 'ASSERT('+nodeToString(this.expr)+',\\n    '+this.exprStr+')';\n};\n\nfunction BitFieldRead(mask, start, end, fieldExpr) {\n    if (mask === 0) throw new Error(\"mask cannot be zero\");\n    this.mask = mask;\n    this.start = start;\n    this.end = end;\n    this.fieldExpr = fieldExpr;\n}\n\nBitFieldRead.prototype.getShiftCount = function() {\n    var b = 1;\n    var shiftCount = 0;\n    while ((this.mask & b) === 0) {\n        b <<= 1;\n        shiftCount++;\n    }\n    return shiftCount;\n};\n\nBitFieldRead.prototype.toString = function() {\n    var fieldExpr = this.fieldExpr ? nodeToString(this.fieldExpr) : \"bitField\";\n    var mask = this.mask;\n    var shiftCount = this.getShiftCount();\n    return shiftCount === 0\n        ? \"(\" + fieldExpr + \" & \" + mask + \")\"\n        : \"((\" + fieldExpr + \" & \" + mask + \") >>> \" + shiftCount + \")\";\n};\n\nfunction BitFieldCheck(value, inverted, start, end, fieldExpr) {\n    this.value = value;\n    this.inverted = inverted;\n    this.start = start;\n    this.end = end;\n    this.fieldExpr = fieldExpr;\n}\n\nBitFieldCheck.prototype.toString = function() {\n    var fieldExpr = this.fieldExpr ? nodeToString(this.fieldExpr) : \"bitField\";\n    var equality = this.inverted ? \"===\" : \"!==\";\n    return \"((\" + fieldExpr + \" & \" + this.value + \") \" + equality + \" 0)\";\n};\n\nfunction InlineSlice(varExpr, collectionExpression, startExpression, endExpression, start, end, isBrowser,\n                    pad) {\n    this.varExpr = varExpr;\n    this.collectionExpression = collectionExpression;\n    this.startExpression = startExpression;\n    this.endExpression = endExpression;\n    this.start = start;\n    this.end = end;\n    this.isBrowser = isBrowser;\n    this.pad = typeof pad === \"number\" ? pad : 0;\n}\n\nInlineSlice.prototype.hasSimpleStartExpression =\nfunction InlineSlice$hasSimpleStartExpression() {\n    return this.startExpression.type === \"Identifier\" ||\n        this.startExpression.type === \"Literal\";\n};\n\nInlineSlice.prototype.hasSimpleEndExpression =\nfunction InlineSlice$hasSimpleEndExpression() {\n    return this.endExpression.type === \"Identifier\" ||\n        this.endExpression.type === \"Literal\";\n};\n\nInlineSlice.prototype.hasSimpleCollection = function InlineSlice$hasSimpleCollection() {\n    return this.collectionExpression.type === \"Identifier\";\n};\n\nInlineSlice.prototype.toString = function InlineSlice$toString() {\n    var pad = this.pad;\n\n    var init = this.hasSimpleCollection()\n        ? \"\"\n        : \"var $_collection = \" + nodeToString(this.collectionExpression) + \";\";\n\n    var collectionExpression = this.hasSimpleCollection()\n        ? nodeToString(this.collectionExpression)\n        : \"$_collection\";\n\n    init += \"var $_len = \" + collectionExpression + \".length\";\n\n    if (pad !== 0) {\n        init += \" + \" + Math.abs(pad) + \";\";\n    } else {\n        init += \";\";\n    }\n\n    var varExpr = nodeToString(this.varExpr);\n\n    //No offset arguments at all\n    if( this.startExpression === firstElement ) {\n        if (this.isBrowser) {\n            if (pad > 0) {\n                return \"var \" + varExpr + \" = (new Array(\"+pad+\")).concat([].slice.call(\"+collectionExpression+\"));\";\n            } else if (pad < 0) {\n                return \"var \" + varExpr + \" = ([].slice.call(\"+collectionExpression+\")).concat(new Array(\"+Math.abs(pad)+\"));\";\n            } else {\n                return \"var \" + varExpr + \" = [].slice.call(\"+collectionExpression+\");\";\n            }\n        } else {\n            var startVal = pad > 0 ? String(pad) : \"0\";\n            var collectionExpressionVal = pad > 0 ? \" - \" + pad : \"\";\n            var lenVal = pad < 0 ? \"- \" + Math.abs(pad) : \"\";\n\n            return init + \"var \" + varExpr + \" = new Array($_len); \" +\n            \"for(var $_i = \" + startVal + \"; $_i < $_len \" + lenVal + \"; ++$_i) {\" +\n                    varExpr + \"[$_i] = \" + collectionExpression + \"[$_i \" + collectionExpressionVal + \"];\" +\n            \"}\";\n        }\n\n    }\n    else {\n        if( !this.hasSimpleStartExpression() ) {\n            init += \"var $_start = \" + nodeToString(this.startExpression) + \";\";\n        }\n        var startExpression = this.hasSimpleStartExpression()\n            ? nodeToString(this.startExpression)\n            : \"$_start\";\n\n            //Start offset argument given\n        if( this.endExpression === lastElement ) {\n            if (this.isBrowser) {\n                return \"var \" + varExpr + \" = [].slice.call(\"+collectionExpression+\", \"+startExpression+\");\";\n            } else {\n                return init + \"var \" + varExpr + \" = new Array(Math.max($_len - \" +\n                 startExpression + \", 0)); \" +\n                \"for(var $_i = \" + startExpression + \"; $_i < $_len; ++$_i) {\" +\n                        varExpr + \"[$_i - \"+startExpression+\"] = \" + collectionExpression + \"[$_i];\" +\n                \"}\";\n            }\n        }\n            //Start and end offset argument given\n        else {\n\n            if( !this.hasSimpleEndExpression() ) {\n                init += \"var $_end = \" + nodeToString(this.endExpression) + \";\";\n            }\n            var endExpression = this.hasSimpleEndExpression()\n                ? nodeToString(this.endExpression)\n                : \"$_end\";\n\n            if (this.isBrowser) {\n                return \"var \" + varExpr + \" = [].slice.call(\"+collectionExpression+\", \"+startExpression+\", \"+endExpression+\");\";\n            } else {\n                return init + \"var \" + varExpr + \" = new Array(Math.max(\" + endExpression + \" - \" +\n                 startExpression + \", 0)); \" +\n                \"for(var $_i = \" + startExpression + \"; $_i < \" + endExpression + \"; ++$_i) {\" +\n                        varExpr + \"[$_i - \"+startExpression+\"] = \" + collectionExpression + \"[$_i];\" +\n                \"}\";\n            }\n\n        }\n\n    }\n};\n\nvar opts = {\n    ecmaVersion: 5,\n    strictSemicolons: false,\n    allowTrailingCommas: true,\n    forbidReserved: false,\n    locations: false,\n    onComment: null,\n    ranges: false,\n    program: null,\n    sourceFile: null\n};\n\nvar rlineterm = /[\\r\\n\\u2028\\u2029]/;\nvar rhorizontalws = /[ \\t]/;\n\nvar convertSrc = function( src, results ) {\n    if( results.length ) {\n        results.sort(function(a, b){\n            var ret = a.start - b.start;\n            if( ret === 0 ) {\n                ret = a.end - b.end;\n            }\n            return ret;\n        });\n        for( var i = 1; i < results.length; ++i ) {\n            var item = results[i];\n            if( item.start === results[i-1].start &&\n                item.end === results[i-1].end ) {\n                results.splice(i++, 1);\n            }\n        }\n        var ret = \"\";\n        var start = 0;\n        for( var i = 0, len = results.length; i < len; ++i ) {\n            var item = results[i];\n            ret += src.substring( start, item.start );\n            ret += item.toString();\n            start = item.end;\n        }\n        ret += src.substring( start );\n        return ret;\n    }\n    return src;\n};\n\nvar rescape = /[\\r\\n\\u2028\\u2029\"]/g;\n\nvar replacer = function( ch ) {\n        return \"\\\\u\" + ((\"0000\") +\n            (ch.charCodeAt(0).toString(16))).slice(-4);\n};\n\nfunction safeToEmbedString( str ) {\n    return str.replace( rescape, replacer );\n}\n\nfunction parse( src, opts, fileName) {\n    if( !fileName ) {\n        fileName = opts;\n        opts = void 0;\n    }\n    try {\n        return jsp.parse(src, opts);\n    }\n    catch(e) {\n        e.message = e.message + \" \" + fileName;\n        e.scriptSrc = src;\n        throw e;\n    }\n}\n\nvar inlinedFunctions = Object.create(null);\n\nvar lastElement = jsp.parse(\"___input.length\").body[0].expression;\nvar firstElement = jsp.parse(\"0\").body[0].expression;\n\ninlinedFunctions.INLINE_SLICE = function( node, isBrowser ) {\n    var statement = node;\n    node = node.expression;\n    var args = node.arguments;\n\n    if( !(2 <= args.length && args.length <= 4 ) ) {\n        throw new Error(\"INLINE_SLICE must have exactly 2, 3 or 4 arguments\");\n    }\n\n    var varExpression = args[0];\n    var collectionExpression = args[1];\n    var startExpression = args.length < 3\n        ? firstElement\n        : args[2];\n    var endExpression = args.length < 4\n        ? lastElement\n        : args[3];\n    return new InlineSlice(varExpression, collectionExpression,\n        startExpression, endExpression, statement.start, statement.end, isBrowser);\n};\n\ninlinedFunctions.INLINE_SLICE_LEFT_PADDED = function( node, isBrowser ) {\n    var statement = node;\n    node = node.expression;\n    var args = node.arguments;\n\n    if(args.length !== 3) {\n        throw new Error(\"INLINE_SLICE_LEFT_PADDED must have exactly 3 arguments\");\n    }\n\n    var padCount = Number(nodeToString(args[0]));\n    var varExpression = args[1];\n    var collectionExpression = args[2];\n    var startExpression = firstElement;\n    var endExpression = lastElement;\n    return new InlineSlice(varExpression, collectionExpression,\n        startExpression, endExpression, statement.start, statement.end, isBrowser, padCount);\n};\n\ninlinedFunctions.BIT_FIELD_READ = function(node) {\n    var statement = node;\n    var args = node.expression.arguments;\n    if (args.length !== 1 && args.length !== 2) {\n        throw new Error(\"BIT_FIELD must have 1 or 2 arguments\");\n    }\n    var arg = args[0];\n    if (arg.type !== \"Identifier\") {\n        throw new Error(\"BIT_FIELD argument must be an identifier\");\n    }\n    var name = arg.name;\n    var constant = constants[name];\n    if (constant === undefined) {\n        throw new Error(name + \" is not a constant\");\n    }\n    var value = constant.value;\n    return new BitFieldRead(value, statement.start, statement.end, args[1]);\n};\ninlinedFunctions.BIT_FIELD_CHECK = function(node) {\n    var statement = node;\n    var args = node.expression.arguments;\n    if (args.length !== 1 && args.length !== 2) {\n        throw new Error(\"BIT_FIELD must have 1 or 2 arguments\");\n    }\n    var arg = args[0];\n    if (arg.type !== \"Identifier\") {\n        throw new Error(\"BIT_FIELD argument must be an identifier\");\n    }\n    var name = arg.name;\n    var constant = constants[name];\n    if (constant === undefined) {\n        throw new Error(name + \" is not a constant\");\n    }\n    var value = constant.value;\n    var inverted = false;\n    if (name.slice(-4) === \"_NEG\") {\n        inverted = true;\n    }\n    return new BitFieldCheck(value, inverted, statement.start, statement.end, args[1]);\n};\ninlinedFunctions.USE = function(node) {\n    return new Empty(node.start, node.end);\n};\n\nvar constants = {};\nvar ignore = [];\nError.stackTraceLimit = 10000;\nvar astPasses = module.exports = {\n\n    inlineExpansion: function( src, fileName, isBrowser ) {\n        var ast = parse(src, fileName);\n        var results = [];\n        var expr = [];\n        function doInline(node) {\n            if( node.expression.type !== 'CallExpression' ) {\n                return;\n            }\n\n            var name = node.expression.callee.name;\n\n            if(typeof inlinedFunctions[ name ] === \"function\" &&\n                expr.indexOf(node.expression) === -1) {\n                expr.push(node.expression);\n                try {\n                    results.push( inlinedFunctions[ name ]( node, isBrowser ) );\n                }\n                catch(e) {\n                    e.fileName = fileName;\n                    throw e;\n                }\n\n            }\n        }\n        walk.simple(ast, {\n            ExpressionStatement: doInline,\n            CallExpression: function(node) {\n                node.expression = node;\n                doInline(node);\n            }\n        });\n        var ret = convertSrc( src, results );\n        return ret;\n    },\n\n    //Parse constants in from constants.js\n    readConstants: function( src, fileName ) {\n        var ast = parse(src, fileName);\n        walk.simple(ast, {\n            ExpressionStatement: function( node ) {\n                if( node.expression.type !== 'CallExpression' ) {\n                    return;\n                }\n\n                var start = node.start;\n                var end = node.end;\n                node = node.expression;\n                var callee = node.callee;\n                if( callee.name === \"CONSTANT\" &&\n                    callee.type === \"Identifier\" ) {\n\n                    if( node.arguments.length !== 2 ) {\n                        throw new Error( \"Exactly 2 arguments must be passed to CONSTANT\\n\" +\n                            src.substring(start, end)\n                        );\n                    }\n\n                    if( node.arguments[0].type !== \"Identifier\" ) {\n                        throw new Error( \"Can only define identifier as a constant\\n\" +\n                            src.substring(start, end)\n                        );\n                    }\n\n                    var args = node.arguments;\n\n                    var name = args[0];\n                    var nameStr = name.name;\n                    var expr = args[1];\n\n                    var e = eval;\n                    constants[nameStr] = {\n                        identifier: name,\n                        value: e(nodeToString(expr))\n                    };\n                    walk.simple( expr, {\n                        Identifier: function( node ) {\n                            ignore.push(node);\n                        }\n                    });\n                    global[nameStr] = constants[nameStr].value;\n                }\n            }\n        });\n    },\n\n    //Expand constants in normal source files\n    expandConstants: function( src, fileName ) {\n        var results = [];\n        var identifiers = [];\n        var ast = parse(src, fileName);\n        walk.simple(ast, {\n            Identifier: function( node ) {\n                identifiers.push( node );\n            }\n        });\n\n        for( var i = 0, len = identifiers.length; i < len; ++i ) {\n            var id = identifiers[i];\n            if( ignore.indexOf(id) > -1 ) {\n                continue;\n            }\n            var constant = constants[id.name];\n            if( constant === void 0 ) {\n                continue;\n            }\n            if( constant.identifier === id ) {\n                continue;\n            }\n\n            results.push( new ConstantReplacement( constant.value, id.start, id.end ) );\n\n        }\n        return convertSrc( src, results );\n    },\n\n    removeComments: function( src, fileName ) {\n        var results = [];\n        var rnoremove = /^[*\\s\\/]*(?:@preserve|jshint|global)/;\n        opts.onComment = function( block, text, start, end ) {\n            if( rnoremove.test(text) ) {\n                return;\n            }\n            var e = end + 1;\n            var s = start - 1;\n            while(rhorizontalws.test(src.charAt(s--)));\n            while(rlineterm.test(src.charAt(e++)));\n            results.push( new Empty( s + 2, e - 1 ) );\n        };\n        var ast = parse(src, opts, fileName);\n        return convertSrc( src, results );\n    },\n\n    expandAsserts: function( src, fileName ) {\n        var ast = parse( src, fileName );\n        var results = [];\n        walk.simple(ast, {\n            CallExpression: function( node ) {\n\n                var start = node.start;\n                var end = node.end;\n                var callee = node.callee;\n\n                if( callee.type === \"Identifier\" &&\n                    callee.name === \"ASSERT\" ) {\n                    if( node.arguments.length !== 1 ) {\n                        results.push({\n                            start: start,\n                            end: end,\n                            toString: function() {\n                                return src.substring(start, end);\n                            }\n                        });\n                        return;\n                    }\n\n                    var expr = node.arguments[0];\n                    var str = src.substring(expr.start, expr.end);\n                    str = '\"' + safeToEmbedString(str) + '\"'\n                    var assertion = new Assertion( expr, str, start, end );\n\n                    results.push( assertion );\n                }\n            }\n        });\n        return convertSrc( src, results );\n    },\n\n    removeAsserts: function( src, fileName ) {\n        var ast = parse( src, fileName );\n        var results = [];\n        walk.simple(ast, {\n            ExpressionStatement: function( node ) {\n                if( node.expression.type !== 'CallExpression' ) {\n                    return;\n                }\n                var start = node.start;\n                var end = node.end;\n                node = node.expression;\n                var callee = node.callee;\n\n                if( callee.type === \"Identifier\" &&\n                    callee.name === \"ASSERT\" ) {\n                    var e = end + 1;\n                    var s = start - 1;\n\n                    while(rhorizontalws.test(src.charAt(s--)));\n                    while(rlineterm.test(src.charAt(e++)));\n                    results.push( new Empty( s + 2, e - 1) );\n                }\n            },\n            VariableDeclaration: function(node) {\n                var start = node.start;\n                var end = node.end;\n                if (node.kind === 'var' && node.declarations.length === 1) {\n                    var decl = node.declarations[0];\n                    if (decl.id.type === \"Identifier\" &&\n                        decl.id.name === \"ASSERT\") {\n                        var e = end + 1;\n                        var s = start - 1;\n                        while(rhorizontalws.test(src.charAt(s--)));\n                        while(rlineterm.test(src.charAt(e++)));\n                        results.push( new Empty( s + 2, e - 1) );\n                    }\n                }\n            }\n        });\n        return convertSrc( src, results );\n    },\n\n    asyncConvert: function( src, objName, fnProp, fileName ) {\n        var ast = parse( src, fileName );\n\n        var results = [];\n        walk.simple(ast, {\n            CallExpression: function( node ) {\n                var start = node.start;\n                var end = node.end;\n                if( node.callee.type === \"MemberExpression\" &&\n                    node.callee.object.name === objName &&\n                    node.callee.property.name === fnProp &&\n                    node.arguments.length === 3\n                ) {\n\n                    var args = node.arguments;\n                    var fnDereference = args[0];\n                    var dynamicReceiver = args[1];\n                    var arg = args[2];\n\n                    var receiver = getReceiver(fnDereference);\n\n                    if( receiver == null || !equals(receiver, dynamicReceiver) ) {\n                        //Have to use fnDereference.call(dynamicReceiver, arg);\n                        results.push(\n                            new DynamicCall( dynamicReceiver, fnDereference, arg, start, end )\n                        );\n                    }\n                    else {\n                        var fnName = fnDereference.property;\n                        results.push(\n                            new DirectCall( receiver, fnName, arg, start, end )\n                        );\n                        //Can use receiver.fnName( arg );\n\n                    }\n\n\n                }\n            }\n        });\n        return convertSrc( src, results );\n    }\n};\n"
  },
  {
    "path": "tools/browser_test_generator.js",
    "content": "var Promise = require(\"bluebird\");\nvar path = require(\"path\");\nvar readFile = Promise.promisify(require(\"fs\").readFile);\nvar writeFile = Promise.promisify(require(\"fs\").writeFile);\nvar stringToStream = require(\"./utils.js\").stringToStream;\nvar baseDir = path.join(__dirname, \"..\", \"test\", \"browser\");\n\n// Sinon pulls the entire NPM as dependencies (including crypto code) for\n// some reason so\n// the browserify bundle ends up taking megabyte and having high risk of\n// IE-incompatible code\nfunction dependsOnSinon(test) {\n    return /3\\.2\\.5\\.|done|nodeify|2\\.2\\.6/.test(test.name);\n};\n\nmodule.exports = function(tests, options) {\n    var testRequires = tests.filter(function(test) {\n        return !dependsOnSinon(test) && test.name.indexOf(\"generator\") === -1;\n    }).map(function(test) {\n        var code = \"require('../mocha/\" + test.name + \"');\";\n        if (test.name.indexOf(\"2.3.3\") >= 0) {\n            code = \"if (haveGetters) \" + code;\n        }\n        return code;\n    }).join(\"\\n\");\n\n    var promiseExport = options.cover\n        ? readFile(path.join(baseDir, \"promise_instrumented.js\"), \"utf8\")\n        : readFile(path.join(baseDir, \"promise_debug.js\"), \"utf8\");\n\n    var main = readFile(path.join(baseDir, \"main.js\"), \"utf8\")\n\n    return Promise.join(promiseExport, main, function(promiseExport, main) {\n        var browserify = require(\"browserify\");\n        var contents = promiseExport + \"\\n\" + main + \"\\n\" + testRequires;\n        var complete = browserify({\n            basedir: baseDir,\n            entries: stringToStream(contents)\n        });\n        var worker = browserify({\n            basedir: baseDir,\n            entries: stringToStream(promiseExport),\n        });\n        return Promise.join(\n            Promise.promisify(complete.bundle, complete)().then(function(src) {\n                return writeFile(path.join(baseDir, \"bundle.js\"), src);\n            }), Promise.promisify(worker.bundle, worker)().then(function (src) {\n                return writeFile(path.join(baseDir, \"worker_bundle.js\"), src);\n            }));\n    }).then(function() {\n        if (options.executeBrowserTests) {\n            return require(\"./browser_test_runner.js\")(options);\n        }\n    }).catch(function(e) {\n        console.error(e.stack || e.message);\n        process.exit(2);\n    });\n};\n"
  },
  {
    "path": "tools/browser_test_runner.js",
    "content": "var path = require(\"path\");\nvar build = require(\"./build.js\");\nvar Promise = require(\"bluebird\");\nvar cp = Promise.promisifyAll(require(\"child_process\"));\nvar fs = Promise.promisifyAll(require(\"fs\"));\nvar baseDir = path.join(__dirname, \"..\", \"test\", \"browser\");\nvar browsers = [\n    [\"Windows XP\", \"internet explorer\", \"7\"],\n    [\"Windows XP\", \"internet explorer\", \"8\"],\n    [\"Windows 7\", \"internet explorer\", \"9\"],\n    [\"Windows 7\", \"internet explorer\", \"10\"],\n    [\"Windows 8.1\", \"internet explorer\", \"11\"],\n    [\"Windows 7\", \"firefox\", \"3.5\"],\n    [\"Windows 7\", \"firefox\", \"4\"],\n    [\"Windows 7\", \"firefox\", \"25\"],\n    [\"Windows 7\", \"firefox\", \"33\"],\n    [\"Windows 7\", \"chrome\", \"beta\"],\n    [\"Windows 7\", \"safari\", \"5\"],\n    [\"OS X 10.9\", \"iphone\", \"8.1\"],\n    [\"OS X 10.8\", \"safari\", \"6\"],\n    [\"OS X 10.9\", \"safari\", \"7\"]\n];\n\nvar saucelabsOptions = {\n    urls: [\"http://127.0.0.1:9999/index.html\"],\n    tunnelTimeout: 30,\n    build: process.env.TRAVIS_JOB_ID,\n    maxPollRetries: 3,\n    throttled: 3,\n    browsers: browsers,\n    testname: \"mocha tests\",\n    tags: [\"master\"]\n};\n\nmodule.exports = function(options) {\n    var Promise = require(\"bluebird\");\n    var ret = Promise.resolve();\n    function createServer() {\n        var http = require(\"http\");\n        var serve = require(\"serve-static\")(baseDir, {'index': ['index.html']});\n        var bodyParser = require(\"body-parser\").urlencoded({\n            limit: \"100mb\",\n            extended: false\n        });\n        var server = http.createServer(function(req, res) {\n            serve(req, res, function() {\n                if (options.cover &&\n                    req.url.indexOf(\"coverdata\") >= 0 &&\n                    req.method.toLowerCase() === \"post\") {\n                    bodyParser(req, res, function() {\n                        try {\n                            var json = JSON.parse(req.body.json);\n                        } catch (e) {\n                            res.writeHead(404, {'Content-Type': 'text/plain'});\n                            res.end('404\\n');\n                            return;\n                        }\n                        var browser = (req.body.browser + \"\").replace(/[^a-zA-Z0-9]/g, \"\");\n                        var fileName = path.join(build.dirs.coverage, \"coverage-\" + browser + \".json\");\n                        fs.writeFileAsync(fileName, JSON.stringify(json), \"utf8\").then(function() {\n                            res.writeHead(200, {'Content-Type': 'text/plain'});\n                            res.end('Success\\n');\n                        });\n                    });\n                } else {\n                    res.writeHead(404, {'Content-Type': 'text/plain'});\n                    res.end('404\\n');\n                }\n            });\n        });\n        return Promise.promisify(server.listen, server)(options.port)\n    }\n\n    if (options.saucelabs) {\n        var saucelabsRunner = require(\"./saucelabs_runner.js\");\n        ret = createServer().then(function() {\n            return saucelabsRunner(saucelabsOptions);\n        }).then(function() {\n            process.exit(0);\n        });\n    } else if (options.nw) {\n        ret = cp.execAsync((options.nwPath || \"nw\") + \" .\", {\n            maxBuffer: 2 * 1024 * 1024,\n            cwd: path.join(process.cwd(), \"test/browser\")\n        });\n    } else {\n        var open = require(\"open\");\n        ret = createServer().then(function() {\n            var url = \"http://localhost:\" + options.port;\n            console.log(\"Test can be run at \" + url);\n            if (options.openBrowser && !options.cover) {\n                return Promise.promisify(open)(url);\n            }\n        });\n    }\n    return ret;\n};\n"
  },
  {
    "path": "tools/build.js",
    "content": "var Promise = require(\"bluebird\");\nvar path = require(\"path\");\nvar jobRunner = require(\"./job-runner/job-runner.js\");\nPromise.longStackTraces();\nvar utils = require(\"./utils.js\");\nvar glob = Promise.promisify(require(\"glob\"));\nvar fs = Promise.promisifyAll(require(\"fs\"));\nvar mkdirp = Promise.promisify(require(\"mkdirp\"));\nvar rimraf = Promise.promisify(require(\"rimraf\"));\n\njobRunner.init(path.join(__dirname, \"..\"), function() {\n    var fs = Promise.promisifyAll(require(\"fs\"));\n    var utils = require(\"./tools/utils.js\");\n    var path = require(\"path\");\n    var astPasses = require(\"./tools/ast_passes.js\");\n    var Mocha = require(\"mocha\");\n    astPasses.readConstants(\n        fs.readFileSync(\"./src/constants.js\", \"utf8\"),\n        \"constants.js\"\n    );\n    function applyOptionalRequires(code, depsRequireCode) {\n        return code.replace( /};([^}]*)$/, depsRequireCode + \"\\n};$1\");\n    }\n});\n\nvar optionalModuleRequireMap = {\n    \"race.js\": true,\n    \"call_get.js\": true,\n    \"generators.js\": true,\n    \"map.js\": true,\n    \"nodeify.js\": true,\n    \"promisify.js\": true,\n    \"props.js\": true,\n    \"reduce.js\": true,\n    \"settle.js\": true,\n    \"some.js\": true,\n    \"using.js\": true,\n    \"timers.js\": true,\n    \"filter.js\": [\"map.js\"],\n    \"any.js\": [\"some.js\"],\n    \"each.js\": [\"reduce.js\"]\n};\n\nvar lastLineCode = \"                                                         \\n\\\n    util.toFastProperties(Promise);                                          \\n\\\n    util.toFastProperties(Promise.prototype);                                \\n\\\n    function fillTypes(value) {                                              \\n\\\n        var p = new Promise(INTERNAL);                                       \\n\\\n        p._fulfillmentHandler0 = value;                                      \\n\\\n        p._rejectionHandler0 = value;                                        \\n\\\n        p._promise0 = value;                                                 \\n\\\n        p._receiver0 = value;                                                \\n\\\n    }                                                                        \\n\\\n    // Complete slack tracking, opt out of field-type tracking and           \\n\\\n    // stabilize map                                                         \\n\\\n    fillTypes({a: 1});                                                       \\n\\\n    fillTypes({b: 2});                                                       \\n\\\n    fillTypes({c: 3});                                                       \\n\\\n    fillTypes(1);                                                            \\n\\\n    fillTypes(function(){});                                                 \\n\\\n    fillTypes(undefined);                                                    \\n\\\n    fillTypes(false);                                                        \\n\\\n    fillTypes(new Promise(INTERNAL));                                        \\n\\\n    debug.setBounds(Async.firstLineError, util.lastLineError);               \\n\\\n    return Promise;                                                          \\n\\\n\";\n\nfunction getOptionalRequireCode(srcs) {\n    return srcs.sort(function(a, b) {\n        var aHasDeps = Array.isArray(optionalModuleRequireMap[a.sourceFileName]);\n        var bHasDeps = Array.isArray(optionalModuleRequireMap[b.sourceFileName]);\n        return aHasDeps - bHasDeps;\n    }).reduce(function(ret, cur, i) {\n        if(optionalModuleRequireMap[cur.sourceFileName]) {\n            ret += \"require('./\"+cur.sourceFileName+\"')(\"+ cur.deps.join(\", \") +\");\\n\";\n        }\n        return ret;\n    }, \"\") +  lastLineCode;\n}\n\nfunction getBrowserBuildHeader(sources, npmPackage) {\n    var header = \"/**\\n * bluebird build version \" + npmPackage.version + \"\\n\";\n    var enabledFeatures = [\"core\"];\n    var disabledFeatures = [];\n    featureLoop: for (var key in optionalModuleRequireMap) {\n        for (var i = 0, len = sources.length; i < len; ++i) {\n            var source = sources[i];\n            if(source.sourceFileName === key) {\n                enabledFeatures.push(key.replace( \".js\", \"\"));\n                continue featureLoop;\n            }\n        }\n        disabledFeatures.push(key.replace(\".js\", \"\"));\n    }\n\n    header += (\" * Features enabled: \" + enabledFeatures.join(\", \") + \"\\n\");\n\n    if (disabledFeatures.length) {\n        header += \" * Features disabled: \" + disabledFeatures.join(\", \") + \"\\n\";\n    }\n    header += \"*/\\n\";\n    return header;\n}\n\nfunction getSourcePaths(features) {\n    return glob(\"./src/*.js\").map(function(v) {\n        return path.basename(v);\n    }).then(function(results) {\n        if (features) features = features.toLowerCase().split(/\\s+/g);\n        return results.filter(function(fileName) {\n            if (features && optionalModuleRequireMap[fileName] !== undefined) {\n                for (var i = 0; i < features.length; ++i) {\n                    if (fileName.indexOf(features[i]) >= 0) {\n                        return true;\n                    }\n                }\n                return false;\n            }\n            return fileName !== \"constants.js\";\n        });\n    });\n}\n\nfunction ensureDirectory(dir, isUsed, clean) {\n    return (clean ? rimraf(dir) : Promise.resolve()).then(function() {\n        if (!isUsed) return dir;\n        return mkdirp(dir).thenReturn(dir);\n    });\n}\n\nfunction buildRelease(sources, depsRequireCode, dir) {\n    return dir.then(function(dir) {\n        return Promise.map(sources, function(source) {\n            return jobRunner.run(function() {\n                var code = source.source;\n                var sourceFileName = source.sourceFileName;\n                code = astPasses.removeAsserts(code, sourceFileName);\n                code = astPasses.inlineExpansion(code, sourceFileName);\n                code = astPasses.expandConstants(code, sourceFileName);\n                code = code.replace( /__DEBUG__/g, \"false\" );\n                code = code.replace( /__BROWSER__/g, \"false\" );\n                if (sourceFileName === \"promise.js\") {\n                    code = applyOptionalRequires(code, depsRequireCode);\n                }\n                return fs.writeFileAsync(path.join(root, sourceFileName), code);\n            }, {\n                context: {\n                    depsRequireCode: depsRequireCode,\n                    source: source,\n                    root: dir\n                }\n            });\n        });\n    });\n}\n\nfunction buildDebug(sources, depsRequireCode, dir) {\n    return dir.then(function(dir) {\n        return Promise.map(sources, function(source) {\n            return jobRunner.run(function() {\n                var code = source.source;\n                var sourceFileName = source.sourceFileName;\n                code = astPasses.expandAsserts(code, sourceFileName);\n                code = astPasses.inlineExpansion(code, sourceFileName);\n                code = astPasses.expandConstants(code, sourceFileName);\n                code = code.replace( /__DEBUG__/g, \"true\" );\n                code = code.replace( /__BROWSER__/g, \"false\" );\n                if (sourceFileName === \"promise.js\") {\n                    code = applyOptionalRequires(code, depsRequireCode);\n                }\n                return fs.writeFileAsync(path.join(root, sourceFileName), code);\n            }, {\n                context: {\n                    depsRequireCode: depsRequireCode,\n                    source: source,\n                    root: dir\n                }\n            });\n        });\n    });\n}\n\nfunction buildBrowser(sources, dir, tmpDir, depsRequireCode, minify, npmPackage, license) {\n    return Promise.join(dir, tmpDir, npmPackage, license, function(dir, tmpDir, npmPackage, license) {\n        return Promise.map(sources, function(source) {\n            return jobRunner.run(function() {\n                var code = source.source;\n                var sourceFileName = source.sourceFileName;\n                code = astPasses.removeAsserts(code, sourceFileName);\n                code = astPasses.inlineExpansion(code, sourceFileName, true);\n                code = astPasses.expandConstants(code, sourceFileName);\n                code = code.replace( /__BROWSER__/g, \"true\" );\n                if (sourceFileName === \"promise.js\") {\n                    code = applyOptionalRequires(code, depsRequireCode);\n                }\n                return fs.writeFileAsync(path.join(root, sourceFileName), code);\n            }, {\n                context: {\n                    depsRequireCode: depsRequireCode,\n                    source: source,\n                    root: tmpDir\n                }\n            });\n        }).then(function() {\n            var header = getBrowserBuildHeader(sources, npmPackage);\n            return jobRunner.run(function() {\n                var UglifyJS = require(\"uglify-js\");\n                var browserify = require(\"browserify\");\n                var dest = path.join(root, \"bluebird.js\");\n                var minDest = path.join(root, \"bluebird.min.js\");\n                var b = browserify({\n                    entries: entries,\n                    detectGlobals: false,\n                    standalone: \"Promise\"\n                }).exclude('async_hooks').exclude(\"timers\");\n                return Promise.promisify(b.bundle, b)().then(function(src) {\n                    var alias = \"\\\n                    ;if (typeof window !== 'undefined' && window !== null) {       \\\n                        window.P = window.Promise;                                 \\\n                    } else if (typeof self !== 'undefined' && self !== null) {     \\\n                        self.P = self.Promise;                                     \\\n                    }\";\n                    src = src + alias;\n                    src = src.replace(/\\brequire\\b/g, \"_dereq_\");\n                    var minWrite, write;\n                    if (minify) {\n                        var minSrc = src.replace( /__DEBUG__/g, \"false\" );\n                        minSrc = UglifyJS.minify(minSrc, {\n                            comments: false,\n                            compress: true,\n                            fromString: true\n                        }).code;\n                        minSrc  = license + header + minSrc;\n                        minWrite = fs.writeFileAsync(minDest, minSrc);\n                    }\n                    src = src.replace( /__DEBUG__/g, \"true\" );\n                    src = license + header + src;\n                    write = fs.writeFileAsync(dest, src);\n\n                    return Promise.all([write, minWrite]);\n                })\n            }, {\n                context: {\n                    header: header,\n                    root: dir,\n                    entries: path.join(tmpDir, \"bluebird.js\"),\n                    license: license,\n                    minify: minify\n                }\n            })\n        });\n    });\n}\n\nvar root = process.cwd();\n// Since rm -rf is called, better be sure...\nif (path.basename(root).toLowerCase().indexOf(\"bluebird\") !== 0) {\n    throw new Error(\"cwd must be set to bluebird project root. cwd is currently\\n\\n\" +\n        \"         \" + process.cwd() + \"\\n\");\n}\nvar dirs = {\n    release: path.join(root, \"js\", \"release\"),\n    debug: path.join(root, \"js\", \"debug\"),\n    browser: path.join(root, \"js\", \"browser\"),\n    browserTmp: path.join(root, \"js\", \"tmp\"),\n    instrumented: path.join(root, \"js\", \"instrumented\"),\n    coverage: path.join(root, \"coverage\")\n};\n\nfunction build(options) {\n    options = Object(options);\n    var clean = (typeof options.clean !== \"boolean\" ? true : options.clean);\n    var npmPackage = fs.readFileAsync(\"./package.json\").then(JSON.parse);\n    var version = npmPackage.get(\"version\");\n    var sourceFileNames = getSourcePaths(options.features);\n    var license = utils.getLicense();\n    var releaseDir = ensureDirectory(dirs.release, options.release, clean);\n    var debugDir = ensureDirectory(dirs.debug, options.debug, clean);\n    var browserDir = ensureDirectory(dirs.browser, options.browser, clean);\n    var browserTmpDir = ensureDirectory(dirs.browserTmp, options.browser, clean);\n    return Promise.join(license, version, function(license, version) {\n        return sourceFileNames.map(function(sourceFileName) {\n            return jobRunner.run(function() {\n                var sourcePath = path.join(\"./src\", sourceFileName);\n                var source = fs.readFileAsync(sourcePath, \"utf8\");\n                return source.then(function(source) {\n                    utils.checkAscii(sourceFileName, source);\n                    var deps = null;\n                    if (optionalModuleRequireMap[sourceFileName] !== undefined) {\n                        deps = utils.parseDeps(source);\n                    }\n                    source = astPasses.removeComments(source, sourceFileName);\n                    source = source.replace(/__VERSION__/g, version);\n                    return {\n                        sourceFileName: sourceFileName,\n                        source: source,\n                        deps: deps\n                    };\n                });\n            }, {\n                context: {\n                    sourceFileName: sourceFileName,\n                    optionalModuleRequireMap: optionalModuleRequireMap,\n                    license: license,\n                    version: version\n                }\n            });\n        });\n    }).then(function(results) {\n        var depsRequireCode = getOptionalRequireCode(results);\n        var release, debug, browser;\n        if (options.release)\n            release = buildRelease(results, depsRequireCode, releaseDir);\n        if (options.debug)\n            debug = buildDebug(results, depsRequireCode, debugDir);\n        if (options.browser)\n            browser = buildBrowser(results, browserDir, browserTmpDir, depsRequireCode, options.minify, npmPackage, license);\n\n        return Promise.all([release, debug, browser]);\n    });\n}\n\nmodule.exports = build;\nmodule.exports.ensureDirectory = ensureDirectory;\nmodule.exports.dirs = dirs;\n\n\nif (require.main === module) {\n    var argv = require(\"optimist\").argv;\n    var browser = (typeof argv.browser !== \"boolean\" ? false : argv.browser) || !!argv.features;\n    var clean = (typeof argv.clean !== \"boolean\" ? true : argv.clean);\n    module.exports({\n        minify: browser && (typeof argv.minify !== \"boolean\" ? true : argv.minify),\n        browser: browser,\n        debug: !!argv.debug,\n        release: !!argv.release,\n        features: argv.features || null,\n        clean: clean\n    });\n}\n"
  },
  {
    "path": "tools/job-runner/job-runner.js",
    "content": "var Promise = require(\"bluebird\");\nvar spawn = require(\"child_process\").spawn;\nvar assert = require(\"assert\");\nvar argv = require(\"optimist\").argv;\nvar ARGS = [].concat(\n    process.execArgv,\n    __filename,\n    process.argv.slice(2)\n);\nfunction sanitizeCpCount(input) {\n    return Math.min(Math.max(1, (+input | 0)), 16);\n}\n\nif (typeof argv[\"child-processes\"] === \"number\") {\n    var CHILD_PROCESSES = sanitizeCpCount(argv[\"child-processes\"]);\n} else if (process.env.CHILD_PROCESSES) {\n    var CHILD_PROCESSES = sanitizeCpCount(process.env.CHILD_PROCESSES);\n} else {\n    var CHILD_PROCESSES = 4;\n}\n\n\nvar debugging = false;\n\nfunction debug() {\n    if (debugging) {\n        var msg = [].slice.call(arguments).join(\" \");\n        console.log(msg);\n    }\n}\n\nfunction ResultWithOutput(result, stdout, stderr) {\n    this.result = result;\n    this.stdout = stdout;\n    this.stderr = stderr;\n}\n\nvar jobRunner = (function() {\n    var taskId = 0;\n    var workerCount;\n    var workers = [];\n    var tasks = [];\n    var killed = true;\n\n    function leastTotalRunningTime(a, b) {\n        return a.totalRunningTime() - b.totalRunningTime();\n    }\n\n    function each(fn) {\n        if (typeof fn === \"string\") {\n            var args = [].slice.call(arguments, 1);\n            return workers.forEach(function(worker) {\n                worker[fn].apply(worker, args);\n            });\n        }\n        return workers.forEach(fn);\n    }\n\n    function retLogger(result) {\n        if (result instanceof ResultWithOutput) {\n            process.stdout.write(result.stdout);\n            process.stderr.write(result.stderr);\n        }\n        return result;\n    }\n\n    function throwLogger(result) {\n        if (result && (result.stderr || result.stdout)) {\n            process.stdout.write(result.stdout);\n            process.stderr.write(result.stderr);\n        }\n        throw result;\n    }\n\n    function reinit() {\n        each(\"init\");\n    }\n\n    function checkShutDown(secondCheck) {\n        if (tasks.length > 0) return;\n        var anyWorkerHasTasks = workers.some(function(w) {\n            return w.hasTasks();\n        });\n        if (anyWorkerHasTasks) return;\n        if (secondCheck) return ret.exit();\n        setTimeout(function() {\n            checkShutDown(true);\n        }, 10);\n    }\n\n    function schedule(task, queued) {\n        var worker = workers.filter(function(worker) {\n            return task.isolated ?\n                !worker.hasTasks() : !worker._runningIsolatedTask;\n        }).sort(leastTotalRunningTime)[0];\n\n        if (!worker) {\n            if (!queued) tasks.push(task);\n            return false;\n        } else {\n            assert(task.isolated ? !worker.hasTasks() : true);\n            debug(\"found free worker\", worker._id, \"for task\", task.id);\n            worker.performTask(task);\n            return true;\n        }\n    }\n\n    var ret = {\n        init: function(requirePath, initTaskFn) {\n            if (workers.length) return;\n            if (typeof requirePath !== \"string\") throw new TypeError();\n            var count = CHILD_PROCESSES;\n            workerCount = count;\n            var id = 0;\n            for (var i = 0; i < count; ++i) {\n                workers.push(new Worker(id++, requirePath, initTaskFn));\n            }\n            process.on(\"exit\", ret.exit);\n        },\n\n        exit: function() {\n            if (killed) return;\n            killed = true;\n            each(\"kill\");\n        },\n\n        run: function(task, opts) {\n            if (!workerCount) throw new Error(\"task runner has not been initialized\");\n            if (typeof task !== \"function\") throw new TypeError(\"fn not function\");\n            if (killed) {\n                killed = false;\n                reinit();\n            }\n            opts = opts || {};\n            var context = opts.context || {};\n            var log = opts.log === false ? false : true;\n            var estimate = typeof opts.estimate === \"number\" ? opts.estimate : null;\n            var progress = typeof opts.progress === \"function\" ? opts.progress : null;\n            var isolated = !!opts.isolated;\n            var resolve, reject;\n            var promise = new Promise(function() {\n                resolve = arguments[0];\n                reject = arguments[1];\n            });\n            task = {\n                isolated: isolated,\n                task: {\n                    code: task + \"\",\n                    context: context\n                },\n                resolve: resolve,\n                reject: reject,\n                estimate: estimate,\n                id: taskId++,\n                log: log,\n                progress: progress\n            };\n            schedule(task, false);\n            if (log) promise = promise.then(retLogger, throwLogger);\n            return promise;\n        },\n\n        setVerbose: function(v) {\n            debugging = !!v;\n        },\n\n        _workerIdleNotification: function() {\n            var _t = tasks;\n            if (_t.length === 0) {\n                return checkShutDown();\n            }\n            while(_t.length > 0) {\n                var task = _t.shift();\n                if (!schedule(task, true)) {\n                    _t.unshift(task);\n                    return;\n                }\n            }\n        }\n    };\n    return ret;\n})();\n\nfunction Worker(id, requirePath, initTaskFn) {\n    this._initTaskFn = initTaskFn;\n    this._requirePath = requirePath;\n    this._id = id;\n    this._runningTaskCount = 0;\n    this._runningIsolatedTask = false;\n    this._performingIsolatedTask = false;\n    this._queuedIsolatedTask = null;\n    this._bufferingStdio = false;\n    this._runningTime = 0;\n    this._c = null;\n    this._stdout = \"\";\n    this._stderr = \"\";\n    this._tasks = {};\n    this._onStdOut = bind(this._onStdOut, this);\n    this._onStdErr = bind(this._onStdErr, this);\n    this._onError = bind(this._onError, this);\n    this._onMessage = bind(this._onMessage, this);\n}\n\nWorker.prototype.totalRunningTime = function() {\n    var ret = this._runningTime;\n    var ids = Object.keys(this._tasks);\n    var now = Date.now();\n    for (var i = 0; i < ids.length; ++i) {\n        var task = this._tasks[ids[i]];\n        ret += task.estimate === null ? (now - task.started + 1): task.estimate;\n    }\n    return ret;\n};\n\nWorker.prototype._onStdOut = function(data) {\n    data = data.toString();\n    if (this._bufferingStdio) {\n        this._stdout += data;\n    } else {\n        process.stdout.write(data);\n    }\n};\n\nWorker.prototype._onStdErr = function(data) {\n    data = data.toString();\n\n    if (this._bufferingStdio) {\n        this._stderr += data;\n    } else {\n        process.stderr.write(data);\n    }\n};\n\nWorker.prototype._onError = function(e) {\n    process.stderr.write(e && e.stack && e.stack + \"\" || (e + \"\"));\n};\n\nWorker.prototype._onMessage = function(payload) {\n    var self = this;\n    setImmediate(function() {\n        self[payload.type].call(self, payload);\n    });\n};\n\nWorker.prototype.removeListeners = function() {\n    var c = this._c;\n    c.stdout.removeListener(\"data\", this._onStdOut);\n    c.stderr.removeListener(\"data\", this._onStdErr);\n    c.removeListener(\"message\", this._onMessage);\n    c.removeListener(\"error\", this._onError);\n};\n\nWorker.prototype.debug = function(msg, task) {\n    debug(\"worker\", this._id, msg, (task.isolated ?\n        \"isolated\" : \"\"), \"task\", task.id);\n};\n\nWorker.prototype.hasTasks = function() {\n    return this.runningTaskCount() > 0 ||\n        this._queuedIsolatedTask ||\n        this._runningIsolatedTask;\n};\n\nWorker.prototype.runningTaskCount = function() {\n    return this._runningTaskCount;\n};\n\nWorker.prototype.performTask = function(task) {\n    if (task !== this._queuedIsolatedTask) {\n        assert(!this._runningIsolatedTask);\n        if (task.isolated) {\n            this._runningIsolatedTask = true;\n            if (this.runningTaskCount() > 0) {\n                this.debug(\"queued\", task);\n                this._queuedIsolatedTask = task;\n                return;\n            } else {\n                assert(this._queuedIsolatedTask === null);\n                this._performingIsolatedTask = true;\n            }\n        }\n    } else {\n        assert(this.runningTaskCount() === 0);\n        assert(this._runningIsolatedTask);\n        this._queuedIsolatedTask = null;\n        this._performingIsolatedTask = true;\n    }\n    this._runningTaskCount++;\n    assert(this._performingIsolatedTask ? this._runningTaskCount === 1 : true);\n    this._tasks[task.id] = task;\n    task.started = Date.now();\n    this.debug(\"starts to perform\", task);\n    this._c.send({\n        type: \"newTask\",\n        id: task.id,\n        task: task.task,\n        isolated: task.isolated,\n        log: task.log,\n        progress: !!task.progress\n    });\n\n};\n\nfunction getFunctionSource(fn) {\n   return (fn + \"\")\n        .replace(/^\\s*function\\s*\\(\\s*\\)\\s*{/, \"\")\n        .replace(/}\\s*$/, \"\");\n}\n\nWorker.prototype.init = function() {\n    assert(Array.isArray(ARGS));\n    assert(!this._c);\n    var env = {};\n    Object.getOwnPropertyNames(process.env).forEach(function(key) {\n        env[key] = process.env[key];\n    });\n    env.requirePath = this._requirePath;\n    if (typeof this._initTaskFn === \"function\") {\n        env.initialCode = getFunctionSource(this._initTaskFn);\n    }\n\n    var c = spawn(process.execPath, ARGS, {\n        env: env,\n        stdio: [\"pipe\", \"pipe\", \"pipe\", \"ipc\"],\n        cwd: this._requirePath\n    });\n    assert(typeof c.send === \"function\");\n    this._c = c;\n    c.stdout.on(\"data\", this._onStdOut);\n    c.stderr.on(\"data\", this._onStdErr);\n    c.on(\"error\", this._onError);\n    c.on(\"message\", this._onMessage);\n};\n\nWorker.prototype.taskComplete = function(payload) {\n    var task = this._tasks[payload.id];\n    this.debug(\"completed\", task);\n    delete this._tasks[payload.id];\n    this._runningTaskCount--;\n    var resolve, result;\n    if (payload.isError) {\n        resolve = task.reject;\n        var err = payload.error;\n        if (err.__isErrorInstance__) {\n            result = new Error();\n            Object.keys(err).forEach(function(key) {\n                if (key === \"__isErrorInstance__\") return;;\n                result[key] = err[key];\n            });\n            result.name = err.name;\n            result.stack = err.stack;\n            result.message = err.message;\n        } else {\n            result = err;\n        }\n    } else {\n        resolve = task.resolve;\n        result = payload.result;\n    }\n    if (this._runningIsolatedTask) {\n        if (this._queuedIsolatedTask) {\n            if (this.runningTaskCount() === 0) {\n                this.performTask(this._queuedIsolatedTask);\n            }\n        } else {\n            if (payload.error) {\n                result.stdout = this._stdout;\n                result.stderr = this._stderr;\n            } else {\n                result = new ResultWithOutput(result, this._stdout, this._stderr);\n            }\n            this._stderr = this._stdout = \"\";\n            this._performingIsolatedTask = false;\n            this._runningIsolatedTask = false;\n            this._bufferingStdio = false;\n            this.kill();\n            this.init();\n        }\n    }\n    resolve(result);\n    if (!this._runningIsolatedTask) {\n        jobRunner._workerIdleNotification();\n    }\n};\n\nWorker.prototype.kill = function() {\n    if (this._c) {\n        this.removeListeners();\n        this._c.kill(\"SIGKILL\");\n        this._c = null;\n    }\n};\n\nWorker.prototype.progress = function(payload) {\n    var id = payload.id;\n    var task = this._tasks[id];\n    if (task && typeof task.progress === \"function\") {\n        task.progress.call(undefined, payload.value);\n    }\n};\n\nWorker.prototype.outputFlushed = function() {\n    this._bufferingStdio = true;\n    this._c.send({type: \"outputFlushedAck\"});\n};\n\n\n\nfunction bind(fn, ctx) {return function() {return fn.apply(ctx, arguments); };}\n\n\nfunction getTaskFunction(context, code) {\n    with (context) {\n        return eval( \"(\" + code + \")\");\n    }\n}\n\nif (require.main === module) {\n    var __requirePath = process.env.requirePath;\n    var __oldreq = require;\n    var __path = require(\"path\");\n    require = function(p) {\n        if (p.charAt(0) === \".\") {\n            p = __path.join(__requirePath, p);\n        }\n        return __oldreq(p);\n    };\n    if (process.env.initialCode) {\n        eval(process.env.initialCode);\n    }\n    (function() {\n        function waitForOutput() {\n            return new Promise(function(resolve, reject) {\n                var flushCount = 0;\n                function onFlushed() {\n                    flushCount++;\n                    if (flushCount === 2) {\n                        resolve();\n                    }\n                }\n                function checkStream(stream) {\n                    if (stream.bufferSize === 0) {\n                        onFlushed();\n                    } else {\n                        stream.write(\"\", \"utf-8\", onFlushed);\n                    }\n                }\n                checkStream(process.stdout);\n                checkStream(process.stderr);\n            });\n        }\n\n        function waitForPreviousOutput(id) {\n            return waitForOutput().then(function() {\n                var ret = waitForFlushAck(id);\n                process.send({type: \"outputFlushed\", id: id});\n                return ret;\n            });\n        }\n\n        var ackWaitResolve = null;\n        function waitForFlushAck(id) {\n            assert(ackWaitResolve === null);\n            return new Promise(function(resolve) {\n                ackWaitResolve = resolve;\n            });\n        }\n        var noop  = function() {};\n        var noopWrite = function(_, a, b) {\n            if (typeof a === \"function\") return a();\n            if (typeof b === \"function\") return b();\n        };\n\n        function toSerializableError(err) {\n            if (err instanceof Error) {\n                var ret = Object.create(null);\n                Object.keys(err).forEach(function(key){\n                    ret[key] = err[key];\n                });\n                ret.name = err.name;\n                ret.stack = err.stack;\n                ret.message = err.message;\n                ret.__isErrorInstance__ = true;\n                return ret;\n            } else {\n                return err;\n            }\n        }\n\n        var actions = {\n            newTask: function(payload) {\n                var task = payload.task;\n                var code = task.code;\n                var context = task.context;\n                var id = payload.id;\n                var promise = payload.isolated\n                                    ? waitForPreviousOutput(id) : Promise.resolve();\n\n\n                return promise\n                    .then(function() {\n                        if (payload.log === false && payload.isolated) {\n                            process.stdout.write = noopWrite;\n                        }\n                        var fn = getTaskFunction(context, code);\n                        if (typeof fn !== \"function\")\n                            throw new Error(\"fn must be function\");\n                        return fn(payload.progress ? function(value) {\n                            process.send({type: \"progress\", id: id, value: value});\n                        } : noop);\n                    })\n                    .finally(function() {\n                        if (payload.isolated) {\n                            return waitForOutput();\n                        }\n                    })\n                    .then(function(result) {\n                        process.send({\n                            type: \"taskComplete\",\n                            id: payload.id,\n                            result: result\n                        });\n                    })\n                    .catch(function(error) {\n                        process.send({\n                            type: \"taskComplete\",\n                            id: payload.id,\n                            error: toSerializableError(error),\n                            isError: true\n                        });\n                    });\n            },\n\n            outputFlushedAck: function() {\n                var resolve = ackWaitResolve;\n                ackWaitResolve = null;\n                resolve();\n            },\n\n            addGlobals: function(payload) {\n                new Function(payload.code)();\n            }\n        };\n\n        process.on(\"message\", function(payload) {\n            setImmediate(function() {\n                actions[payload.type].call(actions, payload);\n            });\n        });\n    })();\n} else {\n    module.exports = jobRunner;\n    Object.defineProperty(module.exports, \"CHILD_PROCESSES\", {\n        value: CHILD_PROCESSES,\n        writable: false\n    });\n}\n"
  },
  {
    "path": "tools/jshint.js",
    "content": "var utils = require(\"./utils.js\");\nvar path = require(\"path\");\n\nmodule.exports = function() {\n    var wd = path.join(__dirname, \"..\");\n    return utils.run(\"node_modules/jshint/bin/jshint\", [\n        \"--verbose\",\n        \"--reporter\",\n        \"node_modules/jshint-stylish/stylish.js\",\n        \"src/\"\n    ], wd);\n};\nfunction log(value) {\n    process.stdout.write(value.stdout);\n    process.stderr.write(value.stderr);\n}\nif (require.main === module) {\n    module.exports().then(log, log);\n}\n\n"
  },
  {
    "path": "tools/jshintrc_generator.js",
    "content": "var assert = require(\"assert\");\nassert.equal(require.main, module);\n// Since many globals are dynamic, this file is needed to generate jshintrc dynamically\nvar Promise = require(\"bluebird\");\nvar path = require(\"path\");\nPromise.longStackTraces();\nvar fs = Promise.promisifyAll(require(\"fs\"));\n\nvar constantsFile = path.join(__dirname, \"..\", \"src\", \"constants.js\");\nvar globals = fs.readFileAsync(constantsFile, \"utf8\").then(function(contents) {\n    var rconstantname = /CONSTANT\\(\\s*([^,]+)/g;\n    var m;\n    var globals = {\n        Symbol: false,\n        Map: false,\n        JSON: false,\n        Error: true,\n        args: true,\n        chrome: true,\n        INLINE_SLICE: false,\n        INLINE_SLICE_LEFT_PADDED: false,\n        BIT_FIELD_CHECK: false,\n        BIT_FIELD_READ: false,\n        USE: false,\n        global: true,\n        setImmediate: true,\n        Promise: true,\n        WebKitMutationObserver: true,\n        TypeError: true,\n        RangeError: true,\n        __DEBUG__: false,\n        __BROWSER__: false,\n        process: true,\n        self: true,\n        \"console\": false,\n        \"require\": false,\n        \"module\": false,\n        \"define\": false\n    };\n    while((m = rconstantname.exec(contents))) {\n        globals[m[1]] = false;\n    }\n    return globals;\n});\n\nvar jshintrcFile = path.join(__dirname, \"..\", \".jshintrc\");\nvar jshintrc = fs.readFileAsync(jshintrcFile, \"utf8\").then(JSON.parse);\n\nPromise.join(jshintrc, globals, function(jshintrc, globals) {\n    jshintrc.globals = globals;\n    var json = JSON.stringify(jshintrc, null, \"    \");\n    return fs.writeFileAsync(jshintrcFile, json);\n});\n"
  },
  {
    "path": "tools/mocha_runner.js",
    "content": "module.exports = function mochaRun(progress) {\n    var currentTime = 0;\n    var timers = {};\n    var currentId = 0;\n\n    function checkTimers() {\n        var keys = Object.keys(timers);\n        for (var i = 0; i < keys.length; ++i) {\n            var key = keys[i];\n            var timer = timers[key];\n            if (!timer) continue;\n            if (currentTime >= (timer.started + timer.time)) {\n                if (timer.interval) {\n                    timer.started = currentTime;\n                } else {\n                    delete timers[key];\n                }\n                var fn = timer.fn;\n                if (timer.domain) timer.domain.enter();\n                fn();\n                if (timer.domain) timer.domain.exit();\n            }\n        }\n    }\n\n    function setInterval(fn, time) {\n        var id = currentId++;\n        time = (+time || 0) | 0;\n        if (time < 0) time = 0;\n        timers[id] = {\n            fn: fn,\n            time: time,\n            started: currentTime,\n            interval: true,\n            domain: process.domain\n        };\n        return id;\n    }\n\n    function setTimeout(fn, time) {\n        var id = currentId++;\n        time = (+time || 0) | 0;\n        if (time < 11) time = 11;\n        timers[id] = {\n            fn: fn,\n            time: time,\n            started: currentTime,\n            interval: false,\n            domain: process.domain\n        };\n        return id;\n    }\n\n    function clearTimeout(id) {\n        delete timers[id];\n    }\n\n    var clearInterval = clearTimeout;\n    if (fakeTimers) {\n        (function timerLoop() {\n            currentTime += 10;\n            try {\n                checkTimers();\n            } finally {\n                setImmediate(timerLoop);\n            }\n        })();\n\n        global.oldSetTimeout = global.setTimeout;\n        global.oldClearTimeout = global.clearTimeout;\n        global.setTimeout = setTimeout;\n        global.clearTimeout = clearTimeout;\n        global.setInterval = setInterval;\n        global.clearInterval = clearInterval;\n    }\n    var failures = [];\n    delete Error.__BluebirdErrorTypes__;\n    global.adapter = cover\n        ? require(\"./js/instrumented/bluebird.js\")\n        : require(\"./js/debug/bluebird.js\");\n    global.Promise = adapter;\n    Promise = adapter;\n    adapter.defer = adapter.pending = function() {\n        var ret = {};\n        ret.promise = new Promise(function(resolve, reject) {\n            ret.resolve = ret.fulfill = resolve;\n            ret.reject = reject;\n        });\n        return ret;\n    };\n    Promise.config({cancellation: true});\n    Promise.config({longStackTraces: false});\n    Promise.config({longStackTraces: true});\n    return Promise.each(testGroup, function(test, index, length) {\n        var mocha = new Mocha({\n            reporter: \"spec\",\n            timeout: \"300s\",\n            enableTimeouts: true,\n            slow: Infinity,\n            bail: true\n        });\n        mocha.addFile(test.path);\n        return new Promise(function(resolve, reject) {\n            mocha.run(function(failures) {\n                if (failures === 0) {\n                    test.failed = false;\n                    progress(test);\n                }\n                resolve();\n            }).on(\"fail\", function(_, err) {\n                test.failed = true;\n                progress(test);\n                failures.push({\n                    name: test.name,\n                    error: err\n                });\n            });\n        });\n    }).then(function() {\n        function failAdvice(failedTestFileName) {\n            return \"For additional details you can run it individually \" +\n                \" with the command `node tools/test --run=\" + failedTestFileName + \"`\";\n        }\n        if (failures.length > 0) {\n            var error;\n            if (singleTest) {\n                error = failures[0].error;\n            }\n            else {\n                var message = \"\\u001b[31mSome tests failed: \\u001b[m\\n\"\n                failures.forEach(function(failResult) {\n                    message += \"    \" + failResult.name + \" \" + failAdvice(failResult.name) + \"\\n\";\n                });\n                error = new Error(message);\n                error.noStackPrint = true;\n            }\n            throw error;\n        }\n        if (cover) {\n            return __coverage__;\n        }\n    });\n};\n"
  },
  {
    "path": "tools/saucelabs_runner.js",
    "content": "/*\n\nRipped from grunt-saucelabs node module and made independent on grunt\n\nMIT license:\n\nCopyright (c) 2012 Parashuram\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n*/\n\nmodule.exports = function(options) {\n  var Promise = require(\"bluebird\");\n  var SauceTunnel = require('grunt-saucelabs/node_modules/sauce-tunnel/index.js');\n  var TestRunner = require('grunt-saucelabs/src/TestRunner.js');\n\n  function reportProgress(notification) {\n    switch (notification.type) {\n    case 'tunnelOpen':\n      console.log('=> Starting Tunnel to Sauce Labs');\n      break;\n    case 'tunnelOpened':\n      console.log('Connected to Saucelabs');\n      break;\n    case 'tunnelClose':\n      console.log('=> Stopping Tunnel to Sauce Labs');\n      break;\n    case 'tunnelEvent':\n      console.log(notification.text);\n      break;\n    case 'jobStarted':\n      console.log('\\n', notification.startedJobs, '/', notification.numberOfJobs, 'tests started');\n      break;\n    case 'jobCompleted':\n      console.log('\\nTested %s', notification.url);\n      console.log('Platform: %s', notification.platform);\n\n      if (notification.tunnelId && unsupportedPort(notification.url)) {\n        console.log('Warning: This url might use a port that is not proxied by Sauce Connect.');\n      }\n\n      console.log('Passed: %s', notification.passed);\n      console.log('Url %s', notification.jobUrl);\n      break;\n    case 'testCompleted':\n      console.log('All tests completed with status %s', notification.passed);\n      break;\n    case 'retrying':\n      console.log('Timed out, retrying');\n      break;\n    default:\n      console.error('Unexpected notification type');\n    }\n  }\n\n  function createTunnel(arg) {\n    var tunnel;\n\n    reportProgress({\n      type: 'tunnelOpen'\n    });\n\n    tunnel = new SauceTunnel(arg.username, arg.key, arg.identifier, true, ['-P', '0'].concat(arg.tunnelArgs));\n\n    ['write', 'writeln', 'error', 'ok', 'debug'].forEach(function (method) {\n      tunnel.on('log:' + method, function (text) {\n        reportProgress({\n          type: 'tunnelEvent',\n          verbose: false,\n          method: method,\n          text: text\n        });\n      });\n      tunnel.on('verbose:' + method, function (text) {\n        reportProgress({\n          type: 'tunnelEvent',\n          verbose: true,\n          method: method,\n          text: text\n        });\n      });\n    });\n\n    return tunnel;\n  }\n\n  function runTask(arg, framework) {\n    var tunnel;\n\n    return Promise\n      .try(function () {\n        var deferred;\n\n        if (arg.tunneled) {\n          deferred = Promise.defer();\n\n          tunnel = createTunnel(arg);\n          tunnel.start(function (succeeded) {\n            if (!succeeded) {\n              deferred.reject('Could not create tunnel to Sauce Labs');\n            } else {\n              reportProgress({\n                type: 'tunnelOpened'\n              });\n\n              deferred.resolve();\n            }\n          });\n          return deferred.promise;\n        }\n      })\n      .then(function () {\n        var testRunner = new TestRunner(arg, framework, reportProgress);\n        return testRunner.runTests();\n      })\n      .finally(function () {\n        var deferred;\n\n        if (tunnel) {\n          deferred = Promise.defer();\n\n          reportProgress({\n            type: 'tunnelClose'\n          });\n\n          tunnel.stop(function () {\n            deferred.resolve();\n          });\n\n          return deferred.promise;\n        }\n      });\n  }\n\n  function unsupportedPort(url) {\n    // Not all ports are proxied by Sauce Connect. List of supported ports is\n    // available at https://saucelabs.com/docs/connect#localhost\n    var portRegExp = /:(\\d+)\\//;\n    var matches = portRegExp.exec(url);\n    var port = matches ? parseInt(matches[1], 10) : null;\n    var supportedPorts = [\n        80, 443, 888, 2000, 2001, 2020, 2109, 2222, 2310, 3000, 3001, 3030,\n        3210, 3333, 4000, 4001, 4040, 4321, 4502, 4503, 4567, 5000, 5001, 5050, 5555, 5432, 6000,\n        6001, 6060, 6666, 6543, 7000, 7070, 7774, 7777, 8000, 8001, 8003, 8031, 8080, 8081, 8765,\n        8888, 9000, 9001, 9080, 9090, 9876, 9877, 9999, 49221, 55001\n      ];\n\n    if (port) {\n      return supportedPorts.indexOf(port) === -1;\n    }\n\n    return false;\n  }\n\n  var defaults = {\n    username: process.env.SAUCE_USERNAME,\n    key: process.env.SAUCE_ACCESS_KEY,\n    tunneled: true,\n    identifier: Math.floor((new Date()).getTime() / 1000 - 1230768000).toString(),\n    pollInterval: 1000 * 2,\n    maxPollRetries: 0,\n    testname: '',\n    browsers: [{}],\n    tunnelArgs: [],\n    sauceConfig: {},\n    maxRetries: 0\n  };\n\n  var opts = {};\n  options = options || {};\n  Object.keys(defaults).forEach(function(key) {\n    opts[key] = defaults[key];\n  });\n  Object.keys(options).forEach(function(key) {\n    opts[key] = options[key];\n  });\n\n  return runTask(opts, \"mocha\");\n};\n"
  },
  {
    "path": "tools/test.js",
    "content": "process.env.BLUEBIRD_WARNINGS = 0;\nvar assert = require(\"assert\");\nassert.equal(require.main, module);\nvar Promise = require(\"bluebird\");\nvar build = require(\"./build.js\");\nvar utils = require(\"./utils.js\");\nvar tableLogger = utils.tableLogger;\nvar argv = require(\"optimist\").argv;\nvar glob = Promise.promisify(require(\"glob\"));\nvar path = require(\"path\");\nvar mkdirp = Promise.promisify(require(\"mkdirp\"));\nvar rimraf = Promise.promisify(require(\"rimraf\"));\nvar jobRunner = require(\"./job-runner/job-runner.js\");\nvar mochaRunner = require(\"./mocha_runner.js\");\nvar fs = Promise.promisifyAll(require(\"fs\"));\nvar testUtils = require(\"../test/mocha/helpers/util\");\njobRunner.setVerbose(0);\n// Random slowness after tests complete\nfunction getTests(options) {\n    var g;\n\n    if (options.testName === \"all\" || options.testName.indexOf(\"no\") === 0) {\n        g = \"./test/mocha/*.js\";\n    } else if (options.testName === \"aplus\") {\n        g = \"./test/mocha/[0-9].[0-9].[0-9].js\";\n    } else if (options.testName.indexOf(\"*\") >= 0) {\n        g = \"./test/mocha/\" + options.testName;\n    } else {\n        var testName = options.testName.replace(/^(\\d)(\\d)(\\d)$/, \"$1.$2.$3\");\n        g = \"./test/mocha/\" + testName + \".js\";\n    }\n\n    var excludes = [];\n    if (options.testName.indexOf(\"no\") === 0) {\n        excludes = options.testName.slice(2).split(\",\");\n    }\n\n    return glob(g).then(function(matches) {\n        return matches.filter(function(match) {\n            if (match.indexOf(\"generator\") >= 0) {\n                return options.generators;\n            }\n\n            for (var i = 0; i < excludes.length; ++i) {\n                if (match.indexOf(excludes[i]) >= 0) {\n                    return false;\n                }\n            }\n\n            return true;\n        })\n    }).tap(function(m) {\n        if (m.length === 0) {\n            throw new Error(\"No test file matches: '\" + options.testName + \"'\");\n        }\n    }).map(function(filePath, i) {\n        var name = path.basename(filePath);\n        return {\n            name: name,\n            path: filePath,\n            index: i,\n            nameMatcher: \"\\\\b\" +\n                name.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\") +\n                \"\\\\b\"\n        };\n    });\n}\n\nfunction getColorForCoverage(coveragePct) {\n    var colorThresholds = {\n        95: \"brightgreen\",\n        85: \"green\",\n        80: \"yellowgreen\",\n        70: \"yellow\",\n        60: \"red\"\n    };\n    var values = Object.keys(colorThresholds).map(Number).sort(function(a, b) {\n        return b - a;\n    });\n    for (var i = 0; i < values.length; ++i) {\n        if (coveragePct >= values[i]) return colorThresholds[values[i].toString()];\n    }\n    return colorThresholds[values[values.length - 1].toString()];\n}\n\nfunction getCoverage() {\n    return utils.run(\"npm\", [\"run\", \"istanbul\", \"--\", \"report\", \"text-summary\"]).then(function(result) {\n        var stdout = result.stdout;\n        var pctPattern = /(\\d+\\.\\d+)%/g;\n        var matches = stdout.match(pctPattern);\n        var sum = matches.map(function(pct) {\n            return parseFloat(pct.replace(/[^0-9.]/g, \"\"))\n        }).reduce(function(a, b) {\n            return a + b;\n        }, 0);\n        var average = Math.round(sum / matches.length);\n        return average;\n    });\n}\n\nfunction generateCoverageBadge(coverage) {\n    var text = \"coverage-\" + coverage + \"%\";\n    var color = getColorForCoverage(coverage);\n    var imgSrc = \"http://img.shields.io/badge/\" + text + \"-\" + color + \".svg?style=flat\";\n    var link = \"http://petkaantonov.github.io/bluebird/coverage/debug/index.html\";\n    var markdown = \"[![\"+text+\"](\"+imgSrc+\")](\"+link+\")\";\n    return markdown;\n}\n\nfunction writeCoverageFile(coverage, groupNumber) {\n    var dir = build.dirs.coverage;\n    var fileName = path.join(dir, \"coverage-group\" + groupNumber + \".json\");\n    var json = JSON.stringify(coverage);\n    return fs.writeFileAsync(fileName, json, \"utf8\").thenReturn(fileName);\n}\n\nfunction needsFreshProcess(testName) {\n    return /regress|using|domain|multiple-copies|unhandled_rejections|nodeify|getNewLibraryCopy|long_stack_traces/.test(testName) ||\n            testUtils.isOldNode && /api_exceptions|promisify/.test(testName);\n}\n\nfunction runTestGroup(testGroup, options, progress) {\n    return jobRunner.run(mochaRunner, {\n        isolated: !options.singleTest,\n        log: options.singleTest,\n        progress: progress,\n        context: {\n            testGroup: testGroup,\n            singleTest: options.singleTest,\n            fakeTimers: options.fakeTimers,\n            cover: options.cover\n        }\n    });\n}\n\nfunction combineTests(tests) {\n    var arrays = new Array(jobRunner.CHILD_PROCESSES);\n    for (var i = 0; i < arrays.length; ++i) {\n        arrays[i] = [];\n    }\n\n    var initialLength = arrays.length;\n    for (var i = 0; i < tests.length; ++i) {\n        var test = tests[i];\n        if (needsFreshProcess(test.name)) {\n            arrays.push([test]);\n        } else {\n            arrays[i % initialLength].push(tests[i]);\n        }\n\n    }\n    return arrays;\n}\n\nvar testName = \"all\";\nif (\"run\" in argv) {\n    testName = (argv.run + \"\");\n    if (testName.indexOf(\"*\") === -1) {\n        testName = testName.toLowerCase()\n            .replace( /\\.js$/, \"\" )\n            .replace( /[^,a-zA-Z0-9_\\-.]/g, \"\" );\n    }\n}\n\nvar options = {\n    generators: (function() {\n        try {\n            new Function(\"(function*(){})\");\n            return true;\n        } catch (e) {\n            return false;\n        }\n    })() || !!argv.nw,\n    cover: !!argv[\"cover\"],\n    testName: testName,\n    singleTest: false,\n    saucelabs: !!argv.saucelabs,\n    testBrowser: !!argv.saucelabs || !!argv.browser || !!argv.nw,\n    executeBrowserTests: !!argv.saucelabs || !!argv.nw || (typeof argv[\"execute-browser-tests\"] === \"boolean\" ?\n        argv[\"execute-browser-tests\"] : !!argv.browser),\n    openBrowser: typeof argv[\"open-browser\"] === \"boolean\" ? argv[\"open-browser\"] : true,\n    port: argv.port || 9999,\n    fakeTimers: typeof argv[\"fake-timers\"] === \"boolean\"\n        ? argv[\"fake-timers\"] : true,\n    jsHint: typeof argv[\"js-hint\"] === \"boolean\" ? argv[\"js-hint\"] : true,\n    nw: !!argv.nw,\n    nwPath: argv[\"nw-path\"]\n};\n\n\n\nif (options.cover && typeof argv[\"cover\"] === \"string\") {\n    options.coverFormat = argv[\"cover\"];\n} else {\n    options.coverFormat = \"html\";\n}\n\nvar jsHint = options.jsHint ? require(\"./jshint.js\")() : Promise.resolve();\nvar tests = getTests(options);\nvar buildOpts = {\n    debug: true\n};\nif (options.testBrowser) {\n    buildOpts.browser = true;\n    buildOpts.minify = true;\n}\nvar buildResult = build(buildOpts);\nif (options.cover) {\n    var exclusions = [\"assert.js\", \"captured_trace.js\"];\n    var coverageInstrumentedRoot = build.ensureDirectory(build.dirs.instrumented,options.cover, true);\n    var coverageReportsRoot = mkdirp(build.dirs.coverage, true).then(function() {\n        return fs.readdirAsync(build.dirs.coverage);\n    }).map(function(fileName) {\n        var filePath = path.join(build.dirs.coverage, fileName);\n        if (path.extname(fileName).indexOf(\"json\") === -1) {\n            return rimraf(filePath);\n        }\n    });\n    buildResult = Promise.join(coverageInstrumentedRoot, buildResult, coverageReportsRoot, function() {\n        return utils.run(\"npm\", [\"-v\"]).then(function(result) {\n            var version = result.stdout.split(\".\").map(Number);\n            if (version[0] < 2) {\n                throw new Error(\"Npm version 2.x.x required, current version is \" + result.stdout);\n            }\n        });\n    }).tap(function() {\n        var copyExclusions = Promise.map(exclusions, function(exclusion) {\n            var fromPath = path.join(build.dirs.debug, exclusion);\n            var toPath = path.join(build.dirs.instrumented, exclusion);\n            return fs.readFileAsync(fromPath, \"utf8\").then(function(contents) {\n                return fs.writeFileAsync(toPath, contents, \"utf8\");\n            });\n        });\n        var args = [\n            \"run\",\n            \"istanbul\",\n            \"--\",\n            \"instrument\",\n            \"--output\",\n            build.dirs.instrumented,\n            \"--no-compact\",\n            \"--preserve-comments\",\n            \"--embed-source\"\n        ];\n        exclusions.forEach(function(x) {\n            args.push(\"-x\", x);\n        });\n        args.push(build.dirs.debug);\n        var istanbul = utils.run(\"npm\", args, null, true);\n        return Promise.all([istanbul, copyExclusions]);\n    });\n}\n\nvar testResults = Promise.join(tests, buildResult, function(tests) {\n    var singleTest = tests.length === 1;\n    options.singleTest = singleTest;\n    process.stdout.write(\"\\u001b[m\");\n    if (options.testBrowser) {\n        return require(\"./browser_test_generator.js\")(tests, options);\n    } else if (singleTest) {\n        return runTestGroup(tests, options);\n    } else {\n        utils.cursorTo(0, 0);\n        utils.clearScreenDown();\n        tableLogger.addTests(tests);\n        return Promise.map(combineTests(tests), function(testGroup, index) {\n            return runTestGroup(testGroup, options, function(test) {\n                if (test.failed) {\n                    tableLogger.testFail(test);\n                } else {\n                    tableLogger.testSuccess(test);\n                }\n            }).then(function(maybeCoverage) {\n                if (options.cover) {\n                    return writeCoverageFile(maybeCoverage.result, index + 1);\n                }\n            })\n        }).then(function() {\n            var p = Promise.resolve();\n            if (options.cover) {\n                var coverage = getCoverage();\n                if (process.execPath.indexOf(\"iojs\") >= 0 && testName === \"all\") {\n                    p = p.return(coverage).then(generateCoverageBadge).then(console.log);\n                }\n                p = p.then(function() {\n                    return utils.run(\"npm\", [\"run\", \"istanbul\", \"--\", \"report\", options.coverFormat], null, true);\n                }).return(coverage).then(function(coverage) {\n                    console.log(\"Total coverage \" + coverage + \"%\");\n                });\n            }\n            console.log(\"All tests passed\");\n            return p;\n        });\n    }\n});\n\nPromise.all([testResults, jsHint]).spread(function(_, jsHintResponse) {\n    if (jsHintResponse) {\n        console.log(\"JSHint:\");\n        console.log(jsHintResponse.stdout);\n        console.log(jsHintResponse.stderr);\n    }\n}).catch(function(e) {\n    if (e && e.stdout || e.stderr) {\n        console.log(e.stdout);\n        console.error(e.stderr);\n    }\n\n    if (!e || !e.stack) {\n        console.error(e + \"\");\n    } else {\n        console.error(e.noStackPrint ? e.message : e.stack);\n    }\n    process.exit(2);\n});\n"
  },
  {
    "path": "tools/utils.js",
    "content": "var Promise = require(\"bluebird\");\nvar assert = require(\"assert\");\nvar path = require(\"path\");\nvar spawn = require(\"cross-spawn\");\nPromise.longStackTraces();\nvar fs = Promise.promisifyAll(require(\"fs\"));\nvar notAscii = /[^\\u000D\\u0019-\\u007E]/;\nvar Table = require('cli-table');\n\nfunction noStackError(message) {\n    var e = new Error(message);\n    e.noStackPrint = true;\n    return e;\n}\n\nfunction checkAscii(fileName, contents) {\n    if (notAscii.test(contents)) {\n        contents.split(\"\\n\").forEach(function(line, i) {\n            if (notAscii.test(line)) {\n                var lineNo = i + 1;\n                var col = line.indexOf(RegExp.lastMatch) + 1;\n                var code = \"U+\" + ((\"0000\" + line.charCodeAt(col-1)\n                                                    .toString(16)).slice(-4));\n                code = RegExp.lastMatch + \" (\" + code.toUpperCase() + \")\";\n                var fullPath = path.join(process.cwd(), \"src\", fileName);\n                throw noStackError(\"The file \" + fullPath + \"\\ncontains an illegal character: \" +\n                    code + \" on line \" + lineNo + \" at column \" + col);\n            }\n        });\n    }\n}\n\nvar license;\nfunction getLicense() {\n    if (license) return license;\n    var licenseFile = path.join(__dirname, \"..\", \"LICENSE\");\n    return license = fs.readFileAsync(licenseFile, \"utf8\").then(function(text) {\n        return \"/* @preserve\\n\" + text.split(\"\\n\").map(function(line) {\n            return \" * \" + line;\n        }).join(\"\\n\") + \"\\n */\\n\";\n    });\n}\n\nfunction cursorTo(x, y) {\n    if (process.stdout.cursorTo)\n        process.stdout.cursorTo(x, y);\n}\n\nfunction clearScreenDown() {\n    if (process.stdout.clearScreenDown)\n        process.stdout.clearScreenDown();\n}\n\nfunction run(cmd, args, dir, log) {\n    return new Promise(function(resolve, reject) {\n        function makeResult(errorMessage) {\n            var ret = errorMessage ? new Error(errorMessage) : {};\n            ret.stdout = out.trim();\n            ret.stderr = err.trim();\n            return ret;\n        }\n\n        var out = \"\";\n        var err = \"\";\n        var c = spawn(cmd, args, {stdin: [\"ignore\", \"ignore\", \"ignore\"], cwd: dir || process.cwd()});\n\n        c.stdout.on(\"data\", function(data) {\n            if (log) process.stdout.write(data.toString());\n            out += data;\n        });\n        c.stderr.on(\"data\", function(data) {\n            if (log) process.stderr.write(data.toString());\n            err += data;\n        });\n\n        c.on(\"error\", function(err) {\n            reject(makeResult(err.message));\n        });\n        c.on(\"close\", function(code) {\n            if (code == 0) resolve(makeResult())\n            else reject(makeResult(path.basename(cmd) + \" exited with code: \" + code + \"\\n\" + err.trim()));\n        })\n    });\n}\n\nfunction parseDeps(src) {\n    var rdeps  = /function\\s*\\(\\s*([^)]+)\\)/;\n    var match = rdeps.exec(src);\n    assert.equal(match.length, 2);\n    var deps = match[1].split(/\\s*,\\s*/g).map(function(val) {\n        return val.trim();\n    });\n    return deps;\n}\n\nvar tableLogger = (function() {\n    var metaKeyCodeReAnywhere = /(?:\\x1b)([a-zA-Z0-9])/;\n    var functionKeyCodeReAnywhere = new RegExp('(?:\\x1b+)(O|N|\\\\[|\\\\[\\\\[)(?:' + [\n      '(\\\\d+)(?:;(\\\\d+))?([~^$])',\n      '(?:M([@ #!a`])(.)(.))', // mouse\n      '(?:1;)?(\\\\d+)?([a-zA-Z])'\n    ].join('|') + ')');\n\n    function stripVTControlCharacters(str) {\n      str = str.replace(new RegExp(functionKeyCodeReAnywhere.source, 'g'), '');\n      return str.replace(new RegExp(metaKeyCodeReAnywhere.source, 'g'), '');\n    }\n\n    var ROWS = 35;\n    var log = new Array(ROWS);\n    for (var i = 0; i < ROWS; ++i) log[i] = [];\n    var tableOpts = {\n        chars: {\n            'mid': '',\n            'left-mid': '',\n            'mid-mid': '',\n            'right-mid': ''\n        },\n        style: {\n            'padding-left': 0,\n            'padding-right': 0,\n            compact: true\n        }\n    };\n    var table;\n    var split;\n\n    function showTable() {\n        assert(!table);\n        table = new Table(tableOpts);\n        table.push.apply(table, log);\n        table = table.toString();\n        split = table.split(\"\\n\").map(function(line) {\n            return stripVTControlCharacters(line);\n        });\n        cursorTo(0, 0);\n        process.stdout.write(table);\n        cursorTo(0, split.length + 1);\n    }\n\n    function addTests(tests) {\n        var cols = 0;\n        tests.forEach(function(test) {\n            var index = test.index;\n            var row = index % ROWS;\n            var column = (index / ROWS) | 0;\n            cols = Math.max(column, cols);\n            log[row][column] = \"\\u001b[m\" + test.name + \" \\u001b[31m\\u00D7   \";\n        });\n        cols = cols + 1;\n        for (var i = 0; i < log.length; ++i) {\n            var row = log[i];\n            for (var j = 0; j < cols; ++j) {\n                if (!row[j]) {\n                    row[j] = \"  \";\n                }\n            }\n        }\n        showTable();\n    }\n\n    function getPosition(test) {\n        for (var y = 0; y < split.length; ++y) {\n            var s = split[y];\n            var x = s.search(new RegExp(test.nameMatcher));\n            if (x >= 0) {\n                return {\n                    x: x + test.name.length,\n                    y: y\n                };\n            }\n        }\n        assert(false);\n    }\n\n    function update(test, message) {\n        var pos = getPosition(test);\n        cursorTo(pos.x + 1, pos.y);\n        process.stdout.write(message);\n        cursorTo(0, split.length + 2);\n    }\n\n    function testFail(test) {\n        update(test, \"\\u001b[31m\\u00D7 FAILURE\\u001b[39m\");\n    }\n\n\n    function testSuccess(test) {\n        update(test, \"\\u001b[32m\\u221A\\u001b[39m\")\n    }\n\n    return {\n        addTests: addTests,\n        testFail: testFail,\n        testSuccess: testSuccess\n    }\n})();\n\nfunction stringToStream(str) {\n    var Readable = require('stream').Readable;\n    var readable = new Readable()\n    readable.push(str + \"\");\n    readable.push(null);\n    return readable;\n}\n\nmodule.exports = {\n    checkAscii: checkAscii,\n    getLicense: getLicense,\n    run: run,\n    parseDeps: parseDeps,\n    tableLogger: tableLogger,\n    stringToStream: stringToStream,\n    cursorTo: cursorTo,\n    clearScreenDown: clearScreenDown\n};\n"
  }
]