| 'use strict'; | 
|   | 
| var PENDING = 'pending'; | 
| var SETTLED = 'settled'; | 
| var FULFILLED = 'fulfilled'; | 
| var REJECTED = 'rejected'; | 
| var NOOP = function () {}; | 
| var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function'; | 
|   | 
| var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; | 
| var asyncQueue = []; | 
| var asyncTimer; | 
|   | 
| function asyncFlush() { | 
|     // run promise callbacks | 
|     for (var i = 0; i < asyncQueue.length; i++) { | 
|         asyncQueue[i][0](asyncQueue[i][1]); | 
|     } | 
|   | 
|     // reset async asyncQueue | 
|     asyncQueue = []; | 
|     asyncTimer = false; | 
| } | 
|   | 
| function asyncCall(callback, arg) { | 
|     asyncQueue.push([callback, arg]); | 
|   | 
|     if (!asyncTimer) { | 
|         asyncTimer = true; | 
|         asyncSetTimer(asyncFlush, 0); | 
|     } | 
| } | 
|   | 
| function invokeResolver(resolver, promise) { | 
|     function resolvePromise(value) { | 
|         resolve(promise, value); | 
|     } | 
|   | 
|     function rejectPromise(reason) { | 
|         reject(promise, reason); | 
|     } | 
|   | 
|     try { | 
|         resolver(resolvePromise, rejectPromise); | 
|     } catch (e) { | 
|         rejectPromise(e); | 
|     } | 
| } | 
|   | 
| function invokeCallback(subscriber) { | 
|     var owner = subscriber.owner; | 
|     var settled = owner._state; | 
|     var value = owner._data; | 
|     var callback = subscriber[settled]; | 
|     var promise = subscriber.then; | 
|   | 
|     if (typeof callback === 'function') { | 
|         settled = FULFILLED; | 
|         try { | 
|             value = callback(value); | 
|         } catch (e) { | 
|             reject(promise, e); | 
|         } | 
|     } | 
|   | 
|     if (!handleThenable(promise, value)) { | 
|         if (settled === FULFILLED) { | 
|             resolve(promise, value); | 
|         } | 
|   | 
|         if (settled === REJECTED) { | 
|             reject(promise, value); | 
|         } | 
|     } | 
| } | 
|   | 
| function handleThenable(promise, value) { | 
|     var resolved; | 
|   | 
|     try { | 
|         if (promise === value) { | 
|             throw new TypeError('A promises callback cannot return that same promise.'); | 
|         } | 
|   | 
|         if (value && (typeof value === 'function' || typeof value === 'object')) { | 
|             // then should be retrieved only once | 
|             var then = value.then; | 
|   | 
|             if (typeof then === 'function') { | 
|                 then.call(value, function (val) { | 
|                     if (!resolved) { | 
|                         resolved = true; | 
|   | 
|                         if (value === val) { | 
|                             fulfill(promise, val); | 
|                         } else { | 
|                             resolve(promise, val); | 
|                         } | 
|                     } | 
|                 }, function (reason) { | 
|                     if (!resolved) { | 
|                         resolved = true; | 
|   | 
|                         reject(promise, reason); | 
|                     } | 
|                 }); | 
|   | 
|                 return true; | 
|             } | 
|         } | 
|     } catch (e) { | 
|         if (!resolved) { | 
|             reject(promise, e); | 
|         } | 
|   | 
|         return true; | 
|     } | 
|   | 
|     return false; | 
| } | 
|   | 
| function resolve(promise, value) { | 
|     if (promise === value || !handleThenable(promise, value)) { | 
|         fulfill(promise, value); | 
|     } | 
| } | 
|   | 
| function fulfill(promise, value) { | 
|     if (promise._state === PENDING) { | 
|         promise._state = SETTLED; | 
|         promise._data = value; | 
|   | 
|         asyncCall(publishFulfillment, promise); | 
|     } | 
| } | 
|   | 
| function reject(promise, reason) { | 
|     if (promise._state === PENDING) { | 
|         promise._state = SETTLED; | 
|         promise._data = reason; | 
|   | 
|         asyncCall(publishRejection, promise); | 
|     } | 
| } | 
|   | 
| function publish(promise) { | 
|     promise._then = promise._then.forEach(invokeCallback); | 
| } | 
|   | 
| function publishFulfillment(promise) { | 
|     promise._state = FULFILLED; | 
|     publish(promise); | 
| } | 
|   | 
| function publishRejection(promise) { | 
|     promise._state = REJECTED; | 
|     publish(promise); | 
|     if (!promise._handled && isNode) { | 
|         global.process.emit('unhandledRejection', promise._data, promise); | 
|     } | 
| } | 
|   | 
| function notifyRejectionHandled(promise) { | 
|     global.process.emit('rejectionHandled', promise); | 
| } | 
|   | 
| /** | 
|  * @class | 
|  */ | 
| function Promise(resolver) { | 
|     if (typeof resolver !== 'function') { | 
|         throw new TypeError('Promise resolver ' + resolver + ' is not a function'); | 
|     } | 
|   | 
|     if (this instanceof Promise === false) { | 
|         throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); | 
|     } | 
|   | 
|     this._then = []; | 
|   | 
|     invokeResolver(resolver, this); | 
| } | 
|   | 
| Promise.prototype = { | 
|     constructor: Promise, | 
|   | 
|     _state: PENDING, | 
|     _then: null, | 
|     _data: undefined, | 
|     _handled: false, | 
|   | 
|     then: function (onFulfillment, onRejection) { | 
|         var subscriber = { | 
|             owner: this, | 
|             then: new this.constructor(NOOP), | 
|             fulfilled: onFulfillment, | 
|             rejected: onRejection | 
|         }; | 
|   | 
|         if ((onRejection || onFulfillment) && !this._handled) { | 
|             this._handled = true; | 
|             if (this._state === REJECTED && isNode) { | 
|                 asyncCall(notifyRejectionHandled, this); | 
|             } | 
|         } | 
|   | 
|         if (this._state === FULFILLED || this._state === REJECTED) { | 
|             // already resolved, call callback async | 
|             asyncCall(invokeCallback, subscriber); | 
|         } else { | 
|             // subscribe | 
|             this._then.push(subscriber); | 
|         } | 
|   | 
|         return subscriber.then; | 
|     }, | 
|   | 
|     catch: function (onRejection) { | 
|         return this.then(null, onRejection); | 
|     } | 
| }; | 
|   | 
| Promise.all = function (promises) { | 
|     if (!Array.isArray(promises)) { | 
|         throw new TypeError('You must pass an array to Promise.all().'); | 
|     } | 
|   | 
|     return new Promise(function (resolve, reject) { | 
|         var results = []; | 
|         var remaining = 0; | 
|   | 
|         function resolver(index) { | 
|             remaining++; | 
|             return function (value) { | 
|                 results[index] = value; | 
|                 if (!--remaining) { | 
|                     resolve(results); | 
|                 } | 
|             }; | 
|         } | 
|   | 
|         for (var i = 0, promise; i < promises.length; i++) { | 
|             promise = promises[i]; | 
|   | 
|             if (promise && typeof promise.then === 'function') { | 
|                 promise.then(resolver(i), reject); | 
|             } else { | 
|                 results[i] = promise; | 
|             } | 
|         } | 
|   | 
|         if (!remaining) { | 
|             resolve(results); | 
|         } | 
|     }); | 
| }; | 
|   | 
| Promise.race = function (promises) { | 
|     if (!Array.isArray(promises)) { | 
|         throw new TypeError('You must pass an array to Promise.race().'); | 
|     } | 
|   | 
|     return new Promise(function (resolve, reject) { | 
|         for (var i = 0, promise; i < promises.length; i++) { | 
|             promise = promises[i]; | 
|   | 
|             if (promise && typeof promise.then === 'function') { | 
|                 promise.then(resolve, reject); | 
|             } else { | 
|                 resolve(promise); | 
|             } | 
|         } | 
|     }); | 
| }; | 
|   | 
| Promise.resolve = function (value) { | 
|     if (value && typeof value === 'object' && value.constructor === Promise) { | 
|         return value; | 
|     } | 
|   | 
|     return new Promise(function (resolve) { | 
|         resolve(value); | 
|     }); | 
| }; | 
|   | 
| Promise.reject = function (reason) { | 
|     return new Promise(function (resolve, reject) { | 
|         reject(reason); | 
|     }); | 
| }; | 
|   | 
| module.exports = Promise; |