--- /dev/null
+// vow.js
+// Douglas Crockford
+// 2013-09-20
+
+// Public Domain
+
+/*global setImmediate */
+
+
+var VOW = (function () {
+ 'use strict';
+
+// The VOW object contains a .make function that is used to make vows.
+// It may also contain other useful functions.
+// In some mythologies, 'VOW' is called 'deferrer'.
+
+ function enlighten(queue, fate) {
+
+// enlighten is a helper function of herald and .when. It schedules the
+// processing of all of the resolution functions in either the keepers queue
+// or the breakers queue in later turns with the promise's fate.
+
+ queue.forEach(function (func) {
+ setImmediate(func, fate);
+ });
+ }
+
+ return {
+ make: function make() {
+
+// The make function makes new vows. A vow contains a promise object and the
+// two resolution functions (break and keep) that determine the fate of the
+// promise.
+
+ var breakers = [], // .when's broken queue
+ fate, // The promise's ultimate value
+ keepers = [], // .when's kept queue
+ status = 'pending'; // 'broken', 'kept', or 'pending'
+
+ function enqueue(
+ resolution, // 'keep' or 'break'
+ func, // A function that was registered with .when
+ vow // A vow that provides the resolution functions
+ ) {
+
+// enqueue is a helper function used by .when. It will append a function to
+// either the keepers queue or the breakers queue.
+
+ var queue = resolution === 'keep' ? keepers : breakers;
+ queue[queue.length] = typeof func !== 'function'
+
+// If func is not a function, push the resolver so that the value passes to
+// the next cascaded .when.
+
+ ? vow[resolution]
+
+// If the func is a function, push a function that calls func with a value.
+// The result can be a promise, or not a promise, or an exception.
+
+ : function (value) {
+ try {
+ var result = func(value);
+
+// If the result is a promise, then register our resolver with that promise.
+
+ if (result && result.is_promise === true) {
+ result.when(vow.keep, vow.break);
+
+// But if it is not a promise, then use the result to resolve our promise.
+
+ } else {
+ vow.keep(result);
+ }
+
+// But if func throws an exception, then break our promise.
+
+ } catch (e) {
+ vow.break(e);
+ }
+ };
+ }
+
+ function herald(state, value, queue) {
+
+// The herald function is a helper function of break and keep.
+// It seals the promise's fate, updates its status, enlightens
+// one of the queues, and empties both queues.
+
+ if (status !== 'pending') {
+ throw "overpromise";
+ }
+ fate = value;
+ status = state;
+ enlighten(queue, fate);
+ keepers.length = 0;
+ breakers.length = 0;
+ }
+
+// Construct and return the vow object.
+
+ return {
+ 'break': function (value) {
+
+// The break method breaks the promise.
+
+ herald('broken', value, breakers);
+ },
+ keep: function keep(value) {
+
+// The keep method keeps the promise.
+
+ herald('kept', value, keepers);
+ },
+ promise: {
+
+// The promise is an object with a .when method.
+
+ is_promise: true,
+
+// The .when method is the promise monad's bind. The .when method can take two
+// optional functions. One of those functions may be called, depending on the
+// promise's resolution. Both could be called if the the kept function throws.
+
+ when: function (kept, broken) {
+
+// Make a new vow. Return the new promise.
+
+ var vow = make();
+ switch (status) {
+
+// If this promise is still pending, then enqueue both kept and broken.
+
+ case 'pending':
+ enqueue('keep', kept, vow);
+ enqueue('break', broken, vow);
+ break;
+
+// If the promise has already been kept, then enqueue only the kept function,
+// and enlighten it.
+
+ case 'kept':
+ enqueue('keep', kept, vow);
+ enlighten(keepers, fate);
+ break;
+
+// If the promise has already been broken, then enqueue only the broken
+// function, and enlighten it.
+
+ case 'broken':
+ enqueue('break', broken, vow);
+ enlighten(breakers, fate);
+ break;
+ }
+ return vow.promise;
+ }
+ }
+ };
+ },
+ every: function every(array) {
+
+// The every function takes an array of promises and returns a promise that
+// will deliver an array of results only if every promise is kept.
+
+ var remaining = array.length, results = [], vow = VOW.make();
+
+ if (!remaining) {
+ vow.break(array);
+ } else {
+ array.forEach(function (promise, i) {
+ promise.when(function (value) {
+ results[i] = value;
+ remaining -= 1;
+ if (remaining === 0) {
+ vow.keep(results);
+ }
+ }, function (reason) {
+ remaining = NaN;
+ vow.break(reason);
+ });
+ });
+ }
+ return vow.promise;
+ },
+ first: function first(array) {
+
+// The first function takes an array of promises and returns a promise to
+// deliver the first observed kept promise, or a broken promise if all of
+// the promises are broken.
+
+ var found = false, remaining = array.length, vow = VOW.make();
+
+ function check() {
+ remaining -= 1;
+ if (remaining === 0 && !found) {
+ vow.break();
+ }
+ }
+
+ if (remaining === 0) {
+ vow.break(array);
+ } else {
+ array.forEach(function (promise) {
+ promise.when(function (value) {
+ if (!found) {
+ found = true;
+ vow.keep(value);
+ }
+ check();
+ }, check);
+ });
+ }
+ return vow.promise;
+ },
+ any: function any(array) {
+
+// The any function takes an array of promises and returns a promise that
+// will deliver a possibly sparse array of results of any kept promises.
+// The result will contain an undefined element for each broken promise.
+
+ var remaining = array.length, results = [], vow = VOW.make();
+
+ function check() {
+ remaining -= 1;
+ if (remaining === 0) {
+ vow.keep(results);
+ }
+ }
+
+ if (!remaining) {
+ vow.keep(results);
+ } else {
+ array.forEach(function (promise, i) {
+ promise.when(function (value) {
+ results[i] = value;
+ check();
+ }, check);
+ });
+ }
+ return vow.promise;
+ },
+ kept: function (value) {
+
+// Returns a new kept promise.
+
+ var vow = VOW.make();
+ vow.keep(value);
+ return vow.promise;
+ },
+ broken: function (reason) {
+
+// Returns a new broken promise.
+
+ var vow = VOW.make();
+ vow.break(reason);
+ return vow.promise;
+ }
+ };
+}());
+
+
+// If your system does not have setImmediate, then simulate it with setTimeout.
+
+if (typeof setImmediate !== 'function') {
+ setImmediate = function setImmediate(func, param) {
+ 'use strict';
+ return setTimeout(function () {
+ func(param);
+ }, 0);
+ };
+}
--- /dev/null
+[[0,92,8470],[1,103,8174],[2,311,656],[3,583,648],[2,685,5093],[3,1155,2682],[4,1964,2667],[5,2566,2645],[3,2696,3201],[3,3290,3423],[3,3447,3579],[3,3961,5050],[2,5110,5975],[3,5469,5917],[4,5526,5770],[4,5772,5897],[2,5992,6931],[3,6282,6446],[3,6568,6873],[4,6622,6846],[2,6946,7814],[3,7277,7437],[3,7555,7756],[4,7612,7729],[2,7830,7986],[2,8004,8165],[1,8323,8467],[2,8408,8456],[0,96,99],[0,8273,8285],[0,8308,8320],[1,320,329],[2,330,335],[2,337,341],[2,569,574],[3,593,597],[0,613,625],[3,626,630],[2,632,636],[2,694,698],[2,886,894],[2,950,954],[2,1022,1029],[2,1084,1090],[2,1164,1171],[2,2705,2711],[3,1189,1199],[3,1238,1242],[3,1311,1314],[3,1536,1541],[2,1568,1575],[2,1578,1586],[3,1544,1554],[3,1604,1609],[3,1610,1615],[3,1633,1637],[3,1781,1784],[3,1785,1795],[4,1974,1979],[4,2045,2051],[3,2054,2058],[4,2059,2064],[4,2178,2184],[4,2188,2194],[4,2250,2256],[3,2262,2265],[3,2272,2275],[4,2439,2445],[3,2430,2433],[5,2573,2574],[5,2616,2617],[3,2606,2609],[3,2712,2717],[3,2719,2724],[3,2726,2731],[2,2930,2936],[2,3029,3033],[3,3036,3041],[2,3059,3065],[3,3068,3073],[1,3091,3100],[3,3101,3106],[2,3108,3112],[2,3131,3138],[2,3167,3175],[3,3300,3305],[2,3371,3377],[3,3388,3393],[2,3395,3403],[3,3456,3460],[3,3461,3466],[2,3530,3536],[3,3545,3550],[2,3552,3559],[3,3971,3975],[3,3977,3983],[3,4060,4063],[2,4066,4070],[2,4106,4112],[2,4258,4265],[3,4275,4279],[3,4283,4286],[2,4317,4324],[3,4334,4340],[3,4342,4345],[2,4549,4556],[3,4565,4569],[3,4571,4574],[1,4605,4614],[2,4615,4622],[2,4624,4628],[2,4838,4845],[3,4855,4861],[3,4863,4866],[1,4897,4906],[2,4907,4915],[2,4917,4921],[3,5016,5019],[2,5119,5124],[2,5125,5130],[2,5295,5304],[2,5321,5328],[2,5335,5338],[2,5307,5312],[0,5341,5344],[2,5371,5380],[2,5410,5415],[2,5400,5403],[2,5455,5460],[2,5953,5956],[3,5479,5486],[3,5488,5489],[3,5513,5520],[4,5536,5541],[4,5582,5587],[2,5569,5576],[3,5577,5578],[2,5613,5622],[2,5657,5666],[2,5713,5720],[2,5704,5707],[4,5782,5788],[2,5816,5825],[0,5828,5831],[4,5867,5873],[2,5857,5860],[2,6001,6006],[2,6007,6012],[2,6210,6215],[2,6225,6234],[2,6251,6254],[2,6291,6296],[2,6237,6242],[0,6257,6260],[2,6464,6473],[2,6509,6514],[2,6499,6502],[2,6554,6559],[2,6909,6912],[2,6317,6326],[2,6353,6362],[2,6373,6378],[2,6402,6405],[3,6578,6585],[2,6848,6853],[3,6609,6616],[4,6632,6637],[2,6670,6675],[2,6707,6712],[4,6758,6763],[2,6749,6752],[2,6816,6821],[2,6955,6958],[2,6959,6964],[2,7206,7215],[2,7232,7239],[2,7246,7249],[2,7286,7291],[2,7218,7223],[0,7252,7255],[2,7456,7465],[2,7494,7501],[2,7485,7488],[2,7541,7546],[2,7792,7795],[2,7312,7321],[2,7348,7357],[2,7396,7403],[2,7387,7390],[3,7565,7572],[3,7574,7575],[2,7731,7736],[3,7599,7606],[4,7622,7627],[4,7668,7673],[2,7655,7662],[3,7663,7664],[2,7699,7704],[2,7840,7845],[2,7898,7901],[0,7904,7907],[2,7937,7942],[2,7928,7931],[2,7964,7967],[2,8014,8020],[2,8075,8078],[0,8081,8084],[2,8115,8121],[2,8105,8108],[2,8143,8146],[1,8332,8344],[1,8345,8349],[1,8351,8356],[0,8397,8407],[1,8434,8438],[1,8439,8444],[-1,1,10],[-1,11,31],[-1,32,45],[-1,47,63],[-1,65,89],[-1,136,206],[-1,207,253],[-1,254,305],[-1,346,417],[-1,418,494],[-1,495,559],[-1,704,780],[-1,781,856],[-1,857,868],[-1,910,933],[-1,974,1005],[-1,1046,1067],[-1,1108,1141],[-1,1201,1221],[-1,1250,1294],[-1,1323,1370],[-1,1388,1463],[-1,1464,1514],[-1,1654,1729],[-1,1730,1757],[-1,1798,1873],[-1,1874,1940],[-1,2068,2144],[-1,2285,2359],[-1,2479,2538],[-1,2736,2798],[-1,2799,2861],[-1,2862,2908],[-1,3203,3242],[-1,3310,3349],[-1,3471,3508],[-1,3609,3657],[-1,3698,3776],[-1,3777,3854],[-1,3855,3933],[-1,3988,4030],[-1,4117,4188],[-1,4384,4461],[-1,4462,4482],[-1,4667,4738],[-1,4739,4769],[-1,5135,5210],[-1,5211,5277],[-1,6017,6090],[-1,6091,6164],[-1,6165,6192],[-1,6969,7042],[-1,7043,7115],[-1,7116,7188],[-1,7850,7880],[-1,8025,8057],[-1,8181,8260]]