|  | @@ -6,371 +6,365 @@ $core.addPackage("Kernel-Promises");
 | 
	
		
			
				|  |  |  $core.packages["Kernel-Promises"].innerEval = function (expr) { return eval(expr); };
 | 
	
		
			
				|  |  |  $core.packages["Kernel-Promises"].transport = {"type":"amd","amdNamespace":"amber_core"};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -$core.addClass("Thenable", $globals.Object, [], "Kernel-Promises");
 | 
	
		
			
				|  |  | -//>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -$globals.Thenable.comment="I am the abstract base class for Promises.\x0a\x0aMy subclasses should wrap existing JS implementations.\x0a\x0aI contain methods that wrap Promises/A+ `.then` behaviour.";
 | 
	
		
			
				|  |  | -//>>excludeEnd("ide");
 | 
	
		
			
				|  |  | +$core.addClass("Promise", $globals.Object, [], "Kernel-Promises");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "catch:",
 | 
	
		
			
				|  |  | -protocol: "promises",
 | 
	
		
			
				|  |  | -fn: function (aBlock){
 | 
	
		
			
				|  |  | +selector: "all:",
 | 
	
		
			
				|  |  | +protocol: "composites",
 | 
	
		
			
				|  |  | +fn: function (aCollection){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return self.then(null, function (err) {return $core.seamless(function () {
 | 
	
		
			
				|  |  | -    return aBlock._value_(err);
 | 
	
		
			
				|  |  | -})});
 | 
	
		
			
				|  |  | +return Promise.all($recv(aCollection)._asArray());
 | 
	
		
			
				|  |  |  return self;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"catch:",{aBlock:aBlock},$globals.Thenable)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"all:",{aCollection:aCollection},$globals.Promise.klass)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aBlock"],
 | 
	
		
			
				|  |  | -source: "catch: aBlock\x0a<inlineJS: 'return self.then(null, function (err) {return $core.seamless(function () {\x0a    return aBlock._value_(err);\x0a})})'>",
 | 
	
		
			
				|  |  | +args: ["aCollection"],
 | 
	
		
			
				|  |  | +source: "all: aCollection\x0a\x22Returns a Promise resolved with results of sub-promises.\x22\x0a<inlineJS: 'return Promise.all($recv(aCollection)._asArray())'>",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  |  messageSends: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Thenable);
 | 
	
		
			
				|  |  | +$globals.Promise.klass);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "on:do:",
 | 
	
		
			
				|  |  | -protocol: "promises",
 | 
	
		
			
				|  |  | -fn: function (aClass,aBlock){
 | 
	
		
			
				|  |  | +selector: "any:",
 | 
	
		
			
				|  |  | +protocol: "composites",
 | 
	
		
			
				|  |  | +fn: function (aCollection){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return self.then(null, function (err) {return $core.seamless(function () {
 | 
	
		
			
				|  |  | -    if (err._isKindOf_(aClass)) return aBlock._value_(err);
 | 
	
		
			
				|  |  | -    else throw err;
 | 
	
		
			
				|  |  | -})});
 | 
	
		
			
				|  |  | +return Promise.race($recv(aCollection)._asArray());
 | 
	
		
			
				|  |  |  return self;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"on:do:",{aClass:aClass,aBlock:aBlock},$globals.Thenable)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"any:",{aCollection:aCollection},$globals.Promise.klass)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aClass", "aBlock"],
 | 
	
		
			
				|  |  | -source: "on: aClass do: aBlock\x0a<inlineJS: 'return self.then(null, function (err) {return $core.seamless(function () {\x0a    if (err._isKindOf_(aClass)) return aBlock._value_(err);\x0a    else throw err;\x0a})})'>",
 | 
	
		
			
				|  |  | +args: ["aCollection"],
 | 
	
		
			
				|  |  | +source: "any: aCollection\x0a\x22Returns a Promise resolved with first result of sub-promises.\x22\x0a<inlineJS: 'return Promise.race($recv(aCollection)._asArray())'>",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  |  messageSends: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Thenable);
 | 
	
		
			
				|  |  | +$globals.Promise.klass);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "on:do:catch:",
 | 
	
		
			
				|  |  | -protocol: "promises",
 | 
	
		
			
				|  |  | -fn: function (aClass,aBlock,anotherBlock){
 | 
	
		
			
				|  |  | +selector: "forBlock:",
 | 
	
		
			
				|  |  | +protocol: "instance creation",
 | 
	
		
			
				|  |  | +fn: function (aBlock){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return self.then(null, function (err) {return $core.seamless(function () {
 | 
	
		
			
				|  |  | -    try { if (err._isKindOf_(aClass)) return aBlock._value_(err); } catch (e) { err = e; }
 | 
	
		
			
				|  |  | -    return anotherBlock._value_(err);
 | 
	
		
			
				|  |  | -})});
 | 
	
		
			
				|  |  | -return self;
 | 
	
		
			
				|  |  | +return $recv(self._new())._then_(aBlock);
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"on:do:catch:",{aClass:aClass,aBlock:aBlock,anotherBlock:anotherBlock},$globals.Thenable)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"forBlock:",{aBlock:aBlock},$globals.Promise.klass)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aClass", "aBlock", "anotherBlock"],
 | 
	
		
			
				|  |  | -source: "on: aClass do: aBlock catch: anotherBlock\x0a<inlineJS: 'return self.then(null, function (err) {return $core.seamless(function () {\x0a    try { if (err._isKindOf_(aClass)) return aBlock._value_(err); } catch (e) { err = e; }\x0a    return anotherBlock._value_(err);\x0a})})'>",
 | 
	
		
			
				|  |  | +args: ["aBlock"],
 | 
	
		
			
				|  |  | +source: "forBlock: aBlock\x0a\x22Returns a Promise that is resolved with the value of aBlock,\x0aand rejected if error happens while evaluating aBlock.\x22\x0a\x09^ self new then: aBlock",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  | -messageSends: []
 | 
	
		
			
				|  |  | +messageSends: ["then:", "new"]
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Thenable);
 | 
	
		
			
				|  |  | +$globals.Promise.klass);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "then:",
 | 
	
		
			
				|  |  | -protocol: "promises",
 | 
	
		
			
				|  |  | -fn: function (aBlockOrArray){
 | 
	
		
			
				|  |  | +selector: "new",
 | 
	
		
			
				|  |  | +protocol: "instance creation",
 | 
	
		
			
				|  |  | +fn: function (){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -var array = Array.isArray(aBlockOrArray) ? aBlockOrArray : [aBlockOrArray];
 | 
	
		
			
				|  |  | -return array.reduce(function (soFar, aBlock) {
 | 
	
		
			
				|  |  | -    return soFar.then(typeof aBlock === "function" && aBlock.length > 1 ?
 | 
	
		
			
				|  |  | -        function (result) {return $core.seamless(function () {
 | 
	
		
			
				|  |  | -            if (Array.isArray(result)) {
 | 
	
		
			
				|  |  | -                return aBlock._valueWithPossibleArguments_([result].concat(result.slice(0, aBlock.length-1)));
 | 
	
		
			
				|  |  | -            } else {
 | 
	
		
			
				|  |  | -                return aBlock._value_(result);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        })} :
 | 
	
		
			
				|  |  | -        function (result) {return $core.seamless(function () {
 | 
	
		
			
				|  |  | -            return aBlock._value_(result);
 | 
	
		
			
				|  |  | -        })}
 | 
	
		
			
				|  |  | -    );
 | 
	
		
			
				|  |  | -}, self);
 | 
	
		
			
				|  |  | +return Promise.resolve();
 | 
	
		
			
				|  |  |  return self;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"then:",{aBlockOrArray:aBlockOrArray},$globals.Thenable)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"new",{},$globals.Promise.klass)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aBlockOrArray"],
 | 
	
		
			
				|  |  | -source: "then: aBlockOrArray\x0a\x22Accepts a block or array of blocks.\x0aEach of blocks in the array or the singleton one is\x0aused in .then call to a promise, to accept a result\x0aand transform it to the result for the next one.\x0aIn case a block has more than one argument\x0aand result is an array, first n-1 elements of the array\x0aare put into additional arguments beyond the first.\x0aThe first argument always contains the result as-is.\x22\x0a<inlineJS: '\x0avar array = Array.isArray(aBlockOrArray) ? aBlockOrArray : [aBlockOrArray];\x0areturn array.reduce(function (soFar, aBlock) {\x0a    return soFar.then(typeof aBlock === \x22function\x22 && aBlock.length > 1 ?\x0a        function (result) {return $core.seamless(function () {\x0a            if (Array.isArray(result)) {\x0a                return aBlock._valueWithPossibleArguments_([result].concat(result.slice(0, aBlock.length-1)));\x0a            } else {\x0a                return aBlock._value_(result);\x0a            }\x0a        })} :\x0a        function (result) {return $core.seamless(function () {\x0a            return aBlock._value_(result);\x0a        })}\x0a    );\x0a}, self)'>",
 | 
	
		
			
				|  |  | +args: [],
 | 
	
		
			
				|  |  | +source: "new\x0a\x22Returns a dumb Promise resolved with nil.\x22\x0a<inlineJS: 'return Promise.resolve()'>",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  |  messageSends: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Thenable);
 | 
	
		
			
				|  |  | +$globals.Promise.klass);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "then:catch:",
 | 
	
		
			
				|  |  | -protocol: "promises",
 | 
	
		
			
				|  |  | -fn: function (aBlockOrArray,anotherBlock){
 | 
	
		
			
				|  |  | +selector: "new:",
 | 
	
		
			
				|  |  | +protocol: "instance creation",
 | 
	
		
			
				|  |  | +fn: function (aBlock){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return $recv(self._then_(aBlockOrArray))._catch_(anotherBlock);
 | 
	
		
			
				|  |  | +return new Promise(function (resolve, reject) {
 | 
	
		
			
				|  |  | +    var model = {value: resolve, signal: reject}; // TODO make faster
 | 
	
		
			
				|  |  | +    aBlock._value_(model);
 | 
	
		
			
				|  |  | +});
 | 
	
		
			
				|  |  | +return self;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"then:catch:",{aBlockOrArray:aBlockOrArray,anotherBlock:anotherBlock},$globals.Thenable)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"new:",{aBlock:aBlock},$globals.Promise.klass)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aBlockOrArray", "anotherBlock"],
 | 
	
		
			
				|  |  | -source: "then: aBlockOrArray catch: anotherBlock\x0a\x09^ (self then: aBlockOrArray) catch: anotherBlock",
 | 
	
		
			
				|  |  | +args: ["aBlock"],
 | 
	
		
			
				|  |  | +source: "new: aBlock\x0a\x22Returns a Promise that is eventually resolved or rejected.\x0aPass a block that is called with one argument, model.\x0aYou should call model value: ... to resolve the promise\x0aand model signal: ... to reject the promise.\x0aIf error happens during run of the block,\x0apromise is rejected with that error as well.\x22\x0a<inlineJS: 'return new Promise(function (resolve, reject) {\x0a    var model = {value: resolve, signal: reject}; // TODO make faster\x0a    aBlock._value_(model);\x0a})'>",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  | -messageSends: ["catch:", "then:"]
 | 
	
		
			
				|  |  | +messageSends: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Thenable);
 | 
	
		
			
				|  |  | +$globals.Promise.klass);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "then:on:do:",
 | 
	
		
			
				|  |  | -protocol: "promises",
 | 
	
		
			
				|  |  | -fn: function (aBlockOrArray,aClass,aBlock){
 | 
	
		
			
				|  |  | +selector: "signal:",
 | 
	
		
			
				|  |  | +protocol: "instance creation",
 | 
	
		
			
				|  |  | +fn: function (anObject){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return $recv(self._then_(aBlockOrArray))._on_do_(aClass,aBlock);
 | 
	
		
			
				|  |  | +return $recv(anObject)._in_(function (x) {return Promise.reject(x)});
 | 
	
		
			
				|  |  | +return self;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"then:on:do:",{aBlockOrArray:aBlockOrArray,aClass:aClass,aBlock:aBlock},$globals.Thenable)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"signal:",{anObject:anObject},$globals.Promise.klass)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aBlockOrArray", "aClass", "aBlock"],
 | 
	
		
			
				|  |  | -source: "then: aBlockOrArray on: aClass do: aBlock\x0a\x09^ (self then: aBlockOrArray) on: aClass do: aBlock",
 | 
	
		
			
				|  |  | +args: ["anObject"],
 | 
	
		
			
				|  |  | +source: "signal: anObject\x0a\x22Returns a Promise rejected with anObject.\x22\x0a<inlineJS: 'return $recv(anObject)._in_(function (x) {return Promise.reject(x)})'>",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  | -messageSends: ["on:do:", "then:"]
 | 
	
		
			
				|  |  | +messageSends: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Thenable);
 | 
	
		
			
				|  |  | +$globals.Promise.klass);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "then:on:do:catch:",
 | 
	
		
			
				|  |  | -protocol: "promises",
 | 
	
		
			
				|  |  | -fn: function (aBlockOrArray,aClass,aBlock,anotherBlock){
 | 
	
		
			
				|  |  | +selector: "value:",
 | 
	
		
			
				|  |  | +protocol: "instance creation",
 | 
	
		
			
				|  |  | +fn: function (anObject){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return $recv($recv(self._then_(aBlockOrArray))._on_do_(aClass,aBlock))._catch_(anotherBlock);
 | 
	
		
			
				|  |  | +return $recv(anObject)._in_(function (x) {return Promise.resolve(x)});
 | 
	
		
			
				|  |  | +return self;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"then:on:do:catch:",{aBlockOrArray:aBlockOrArray,aClass:aClass,aBlock:aBlock,anotherBlock:anotherBlock},$globals.Thenable)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"value:",{anObject:anObject},$globals.Promise.klass)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aBlockOrArray", "aClass", "aBlock", "anotherBlock"],
 | 
	
		
			
				|  |  | -source: "then: aBlockOrArray on: aClass do: aBlock catch: anotherBlock\x0a\x09^ ((self then: aBlockOrArray) on: aClass do: aBlock) catch: anotherBlock",
 | 
	
		
			
				|  |  | +args: ["anObject"],
 | 
	
		
			
				|  |  | +source: "value: anObject\x0a\x22Returns a Promise resolved with anObject.\x22\x0a<inlineJS: 'return $recv(anObject)._in_(function (x) {return Promise.resolve(x)})'>",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  | -messageSends: ["catch:", "on:do:", "then:"]
 | 
	
		
			
				|  |  | +messageSends: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Thenable);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +$globals.Promise.klass);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -$core.addClass("Promise", $globals.Thenable, [], "Kernel-Promises");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +$core.addTrait("TThenable", "Kernel-Promises");
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "all:",
 | 
	
		
			
				|  |  | -protocol: "composites",
 | 
	
		
			
				|  |  | -fn: function (aCollection){
 | 
	
		
			
				|  |  | +selector: "catch:",
 | 
	
		
			
				|  |  | +protocol: "promises",
 | 
	
		
			
				|  |  | +fn: function (aBlock){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return Promise.all($recv(aCollection)._asArray());
 | 
	
		
			
				|  |  | +return self.then(null, function (err) {return $core.seamless(function () {
 | 
	
		
			
				|  |  | +    return aBlock._value_(err);
 | 
	
		
			
				|  |  | +})});
 | 
	
		
			
				|  |  |  return self;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"all:",{aCollection:aCollection},$globals.Promise.klass)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"catch:",{aBlock:aBlock},$globals.TThenable)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aCollection"],
 | 
	
		
			
				|  |  | -source: "all: aCollection\x0a\x22Returns a Promise resolved with results of sub-promises.\x22\x0a<inlineJS: 'return Promise.all($recv(aCollection)._asArray())'>",
 | 
	
		
			
				|  |  | +args: ["aBlock"],
 | 
	
		
			
				|  |  | +source: "catch: aBlock\x0a<inlineJS: 'return self.then(null, function (err) {return $core.seamless(function () {\x0a    return aBlock._value_(err);\x0a})})'>",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  |  messageSends: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Promise.klass);
 | 
	
		
			
				|  |  | +$globals.TThenable);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "any:",
 | 
	
		
			
				|  |  | -protocol: "composites",
 | 
	
		
			
				|  |  | -fn: function (aCollection){
 | 
	
		
			
				|  |  | +selector: "on:do:",
 | 
	
		
			
				|  |  | +protocol: "promises",
 | 
	
		
			
				|  |  | +fn: function (aClass,aBlock){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return Promise.race($recv(aCollection)._asArray());
 | 
	
		
			
				|  |  | +return self.then(null, function (err) {return $core.seamless(function () {
 | 
	
		
			
				|  |  | +    if (err._isKindOf_(aClass)) return aBlock._value_(err);
 | 
	
		
			
				|  |  | +    else throw err;
 | 
	
		
			
				|  |  | +})});
 | 
	
		
			
				|  |  |  return self;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"any:",{aCollection:aCollection},$globals.Promise.klass)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"on:do:",{aClass:aClass,aBlock:aBlock},$globals.TThenable)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aCollection"],
 | 
	
		
			
				|  |  | -source: "any: aCollection\x0a\x22Returns a Promise resolved with first result of sub-promises.\x22\x0a<inlineJS: 'return Promise.race($recv(aCollection)._asArray())'>",
 | 
	
		
			
				|  |  | +args: ["aClass", "aBlock"],
 | 
	
		
			
				|  |  | +source: "on: aClass do: aBlock\x0a<inlineJS: 'return self.then(null, function (err) {return $core.seamless(function () {\x0a    if (err._isKindOf_(aClass)) return aBlock._value_(err);\x0a    else throw err;\x0a})})'>",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  |  messageSends: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Promise.klass);
 | 
	
		
			
				|  |  | +$globals.TThenable);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "forBlock:",
 | 
	
		
			
				|  |  | -protocol: "instance creation",
 | 
	
		
			
				|  |  | -fn: function (aBlock){
 | 
	
		
			
				|  |  | +selector: "on:do:catch:",
 | 
	
		
			
				|  |  | +protocol: "promises",
 | 
	
		
			
				|  |  | +fn: function (aClass,aBlock,anotherBlock){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return $recv(self._new())._then_(aBlock);
 | 
	
		
			
				|  |  | +return $recv(self._on_do_(aClass,aBlock))._catch_(anotherBlock);
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"forBlock:",{aBlock:aBlock},$globals.Promise.klass)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"on:do:catch:",{aClass:aClass,aBlock:aBlock,anotherBlock:anotherBlock},$globals.TThenable)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aBlock"],
 | 
	
		
			
				|  |  | -source: "forBlock: aBlock\x0a\x22Returns a Promise that is resolved with the value of aBlock,\x0aand rejected if error happens while evaluating aBlock.\x22\x0a\x09^ self new then: aBlock",
 | 
	
		
			
				|  |  | +args: ["aClass", "aBlock", "anotherBlock"],
 | 
	
		
			
				|  |  | +source: "on: aClass do: aBlock catch: anotherBlock\x0a\x09^ (self on: aClass do: aBlock) catch: anotherBlock",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  | -messageSends: ["then:", "new"]
 | 
	
		
			
				|  |  | +messageSends: ["catch:", "on:do:"]
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Promise.klass);
 | 
	
		
			
				|  |  | +$globals.TThenable);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "new",
 | 
	
		
			
				|  |  | -protocol: "instance creation",
 | 
	
		
			
				|  |  | -fn: function (){
 | 
	
		
			
				|  |  | +selector: "then:",
 | 
	
		
			
				|  |  | +protocol: "promises",
 | 
	
		
			
				|  |  | +fn: function (aBlockOrArray){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return Promise.resolve();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +var array = Array.isArray(aBlockOrArray) ? aBlockOrArray : [aBlockOrArray];
 | 
	
		
			
				|  |  | +return array.reduce(function (soFar, aBlock) {
 | 
	
		
			
				|  |  | +    return soFar.then(typeof aBlock === "function" && aBlock.length > 1 ?
 | 
	
		
			
				|  |  | +        function (result) {return $core.seamless(function () {
 | 
	
		
			
				|  |  | +            if (Array.isArray(result)) {
 | 
	
		
			
				|  |  | +                return aBlock._valueWithPossibleArguments_([result].concat(result.slice(0, aBlock.length-1)));
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                return aBlock._value_(result);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        })} :
 | 
	
		
			
				|  |  | +        function (result) {return $core.seamless(function () {
 | 
	
		
			
				|  |  | +            return aBlock._value_(result);
 | 
	
		
			
				|  |  | +        })}
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +}, self);
 | 
	
		
			
				|  |  |  return self;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"new",{},$globals.Promise.klass)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"then:",{aBlockOrArray:aBlockOrArray},$globals.TThenable)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: [],
 | 
	
		
			
				|  |  | -source: "new\x0a\x22Returns a dumb Promise resolved with nil.\x22\x0a<inlineJS: 'return Promise.resolve()'>",
 | 
	
		
			
				|  |  | +args: ["aBlockOrArray"],
 | 
	
		
			
				|  |  | +source: "then: aBlockOrArray\x0a\x22Accepts a block or array of blocks.\x0aEach of blocks in the array or the singleton one is\x0aused in .then call to a promise, to accept a result\x0aand transform it to the result for the next one.\x0aIn case a block has more than one argument\x0aand result is an array, first n-1 elements of the array\x0aare put into additional arguments beyond the first.\x0aThe first argument always contains the result as-is.\x22\x0a<inlineJS: '\x0avar array = Array.isArray(aBlockOrArray) ? aBlockOrArray : [aBlockOrArray];\x0areturn array.reduce(function (soFar, aBlock) {\x0a    return soFar.then(typeof aBlock === \x22function\x22 && aBlock.length > 1 ?\x0a        function (result) {return $core.seamless(function () {\x0a            if (Array.isArray(result)) {\x0a                return aBlock._valueWithPossibleArguments_([result].concat(result.slice(0, aBlock.length-1)));\x0a            } else {\x0a                return aBlock._value_(result);\x0a            }\x0a        })} :\x0a        function (result) {return $core.seamless(function () {\x0a            return aBlock._value_(result);\x0a        })}\x0a    );\x0a}, self)'>",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  |  messageSends: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Promise.klass);
 | 
	
		
			
				|  |  | +$globals.TThenable);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "new:",
 | 
	
		
			
				|  |  | -protocol: "instance creation",
 | 
	
		
			
				|  |  | -fn: function (aBlock){
 | 
	
		
			
				|  |  | +selector: "then:catch:",
 | 
	
		
			
				|  |  | +protocol: "promises",
 | 
	
		
			
				|  |  | +fn: function (aBlockOrArray,anotherBlock){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return new Promise(function (resolve, reject) {
 | 
	
		
			
				|  |  | -    var model = {value: resolve, signal: reject}; // TODO make faster
 | 
	
		
			
				|  |  | -    aBlock._value_(model);
 | 
	
		
			
				|  |  | -});
 | 
	
		
			
				|  |  | -return self;
 | 
	
		
			
				|  |  | +return $recv(self._then_(aBlockOrArray))._catch_(anotherBlock);
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"new:",{aBlock:aBlock},$globals.Promise.klass)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"then:catch:",{aBlockOrArray:aBlockOrArray,anotherBlock:anotherBlock},$globals.TThenable)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["aBlock"],
 | 
	
		
			
				|  |  | -source: "new: aBlock\x0a\x22Returns a Promise that is eventually resolved or rejected.\x0aPass a block that is called with one argument, model.\x0aYou should call model value: ... to resolve the promise\x0aand model signal: ... to reject the promise.\x0aIf error happens during run of the block,\x0apromise is rejected with that error as well.\x22\x0a<inlineJS: 'return new Promise(function (resolve, reject) {\x0a    var model = {value: resolve, signal: reject}; // TODO make faster\x0a    aBlock._value_(model);\x0a})'>",
 | 
	
		
			
				|  |  | +args: ["aBlockOrArray", "anotherBlock"],
 | 
	
		
			
				|  |  | +source: "then: aBlockOrArray catch: anotherBlock\x0a\x09^ (self then: aBlockOrArray) catch: anotherBlock",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  | -messageSends: []
 | 
	
		
			
				|  |  | +messageSends: ["catch:", "then:"]
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Promise.klass);
 | 
	
		
			
				|  |  | +$globals.TThenable);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "signal:",
 | 
	
		
			
				|  |  | -protocol: "instance creation",
 | 
	
		
			
				|  |  | -fn: function (anObject){
 | 
	
		
			
				|  |  | +selector: "then:on:do:",
 | 
	
		
			
				|  |  | +protocol: "promises",
 | 
	
		
			
				|  |  | +fn: function (aBlockOrArray,aClass,aBlock){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return $recv(anObject)._in_(function (x) {return Promise.reject(x)});
 | 
	
		
			
				|  |  | -return self;
 | 
	
		
			
				|  |  | +return $recv(self._then_(aBlockOrArray))._on_do_(aClass,aBlock);
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"signal:",{anObject:anObject},$globals.Promise.klass)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"then:on:do:",{aBlockOrArray:aBlockOrArray,aClass:aClass,aBlock:aBlock},$globals.TThenable)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["anObject"],
 | 
	
		
			
				|  |  | -source: "signal: anObject\x0a\x22Returns a Promise rejected with anObject.\x22\x0a<inlineJS: 'return $recv(anObject)._in_(function (x) {return Promise.reject(x)})'>",
 | 
	
		
			
				|  |  | +args: ["aBlockOrArray", "aClass", "aBlock"],
 | 
	
		
			
				|  |  | +source: "then: aBlockOrArray on: aClass do: aBlock\x0a\x09^ (self then: aBlockOrArray) on: aClass do: aBlock",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  | -messageSends: []
 | 
	
		
			
				|  |  | +messageSends: ["on:do:", "then:"]
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Promise.klass);
 | 
	
		
			
				|  |  | +$globals.TThenable);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 | 
	
		
			
				|  |  | -selector: "value:",
 | 
	
		
			
				|  |  | -protocol: "instance creation",
 | 
	
		
			
				|  |  | -fn: function (anObject){
 | 
	
		
			
				|  |  | +selector: "then:on:do:catch:",
 | 
	
		
			
				|  |  | +protocol: "promises",
 | 
	
		
			
				|  |  | +fn: function (aBlockOrArray,aClass,aBlock,anotherBlock){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  |  return $core.withContext(function($ctx1) {
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  | -return $recv(anObject)._in_(function (x) {return Promise.resolve(x)});
 | 
	
		
			
				|  |  | -return self;
 | 
	
		
			
				|  |  | +return $recv($recv(self._then_(aBlockOrArray))._on_do_(aClass,aBlock))._catch_(anotherBlock);
 | 
	
		
			
				|  |  |  //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 | 
	
		
			
				|  |  | -}, function($ctx1) {$ctx1.fill(self,"value:",{anObject:anObject},$globals.Promise.klass)});
 | 
	
		
			
				|  |  | +}, function($ctx1) {$ctx1.fill(self,"then:on:do:catch:",{aBlockOrArray:aBlockOrArray,aClass:aClass,aBlock:aBlock,anotherBlock:anotherBlock},$globals.TThenable)});
 | 
	
		
			
				|  |  |  //>>excludeEnd("ctx");
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  //>>excludeStart("ide", pragmas.excludeIdeData);
 | 
	
		
			
				|  |  | -args: ["anObject"],
 | 
	
		
			
				|  |  | -source: "value: anObject\x0a\x22Returns a Promise resolved with anObject.\x22\x0a<inlineJS: 'return $recv(anObject)._in_(function (x) {return Promise.resolve(x)})'>",
 | 
	
		
			
				|  |  | +args: ["aBlockOrArray", "aClass", "aBlock", "anotherBlock"],
 | 
	
		
			
				|  |  | +source: "then: aBlockOrArray on: aClass do: aBlock catch: anotherBlock\x0a\x09^ ((self then: aBlockOrArray) on: aClass do: aBlock) catch: anotherBlock",
 | 
	
		
			
				|  |  |  referencedClasses: [],
 | 
	
		
			
				|  |  |  //>>excludeEnd("ide");
 | 
	
		
			
				|  |  | -messageSends: []
 | 
	
		
			
				|  |  | +messageSends: ["catch:", "on:do:", "then:"]
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -$globals.Promise.klass);
 | 
	
		
			
				|  |  | +$globals.TThenable);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +$core.setTraitComposition([{trait: $globals.TThenable}], $globals.Promise);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  $core.addMethod(
 | 
	
		
			
				|  |  |  $core.method({
 |