Forráskód Böngészése

Merge remote-tracking branch 'upstream/master'

Laurent Laffont 12 éve
szülő
commit
bc26b1b97a
17 módosított fájl, 4878 hozzáadás és 1879 törlés
  1. 76 0
      js/Compiler.deploy.js
  2. 101 1
      js/Compiler.js
  3. 269 359
      js/IDE.deploy.js
  4. 620 6
      js/IDE.js
  5. 122 39
      js/Kernel.deploy.js
  6. 158 58
      js/Kernel.js
  7. 0 469
      js/SUnit.deploy.js
  8. 0 629
      js/SUnit.js
  9. 826 0
      js/TrySmalltalk.deploy.js
  10. 1114 0
      js/TrySmalltalk.js
  11. 191 17
      js/parser.js
  12. 10 1
      js/parser.pegjs
  13. 44 0
      st/Compiler.st
  14. 281 2
      st/IDE.st
  15. 141 18
      st/Kernel.st
  16. 0 280
      st/SUnit.st
  17. 925 0
      st/TrySmalltalk.st

+ 76 - 0
js/Compiler.deploy.js

@@ -1095,6 +1095,28 @@ return self;}
 }),
 smalltalk.NodeVisitor);
 
+smalltalk.addMethod(
+'_visitDynamicArrayNode_',
+smalltalk.method({
+selector: 'visitDynamicArrayNode:',
+fn: function (aNode){
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+'_visitDynamicDictionaryNode_',
+smalltalk.method({
+selector: 'visitDynamicDictionaryNode:',
+fn: function (aNode){
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;}
+}),
+smalltalk.NodeVisitor);
+
 
 
 smalltalk.addClass('Compiler', smalltalk.NodeVisitor, ['stream', 'nestedBlocks', 'earlyReturn', 'currentClass', 'currentSelector', 'unknownVariables', 'tempVariables', 'messageSends', 'referencedClasses', 'classReferenced', 'source'], 'Compiler');
@@ -1685,6 +1707,32 @@ return self;}
 }),
 smalltalk.Compiler);
 
+smalltalk.addMethod(
+'_visitDynamicArrayNode_',
+smalltalk.method({
+selector: 'visitDynamicArrayNode:',
+fn: function (aNode){
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("%5B")]);
+smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_do_separatedBy_", [(function(each){return smalltalk.send(self, "_visit_", [each]);}), (function(){return smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("%2C")]);})]);
+smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("%5D")]);
+return self;}
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+'_visitDynamicDictionaryNode_',
+smalltalk.method({
+selector: 'visitDynamicDictionaryNode:',
+fn: function (aNode){
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("smalltalk.Dictionary._fromPairs_%28%5B")]);
+smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_do_separatedBy_", [(function(each){return smalltalk.send(self, "_visit_", [each]);}), (function(){return smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("%2C")]);})]);
+smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("%5D%29")]);
+return self;}
+}),
+smalltalk.Compiler);
+
 
 smalltalk.Compiler.klass.iVarNames = ['performOptimizations'];
 smalltalk.addMethod(
@@ -1737,3 +1785,31 @@ smalltalk.Compiler.klass);
 smalltalk.addClass('DoIt', smalltalk.Object, [], 'Compiler');
 
 
+smalltalk.addClass('DynamicArrayNode', smalltalk.Node, [], 'Compiler');
+smalltalk.addMethod(
+'_accept_',
+smalltalk.method({
+selector: 'accept:',
+fn: function (aVisitor){
+var self=this;
+smalltalk.send(aVisitor, "_visitDynamicArrayNode_", [self]);
+return self;}
+}),
+smalltalk.DynamicArrayNode);
+
+
+
+smalltalk.addClass('DynamicDictionaryNode', smalltalk.Node, [], 'Compiler');
+smalltalk.addMethod(
+'_accept_',
+smalltalk.method({
+selector: 'accept:',
+fn: function (aVisitor){
+var self=this;
+smalltalk.send(aVisitor, "_visitDynamicDictionaryNode_", [self]);
+return self;}
+}),
+smalltalk.DynamicDictionaryNode);
+
+
+

+ 101 - 1
js/Compiler.js

@@ -1459,6 +1459,36 @@ referencedClasses: []
 }),
 smalltalk.NodeVisitor);
 
+smalltalk.addMethod(
+'_visitDynamicArrayNode_',
+smalltalk.method({
+selector: 'visitDynamicArrayNode:',
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+source: unescape('visitDynamicArrayNode%3A%20aNode%0A%09self%20visitNode%3A%20aNode'),
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
+smalltalk.addMethod(
+'_visitDynamicDictionaryNode_',
+smalltalk.method({
+selector: 'visitDynamicDictionaryNode:',
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+smalltalk.send(self, "_visitNode_", [aNode]);
+return self;},
+source: unescape('visitDynamicDictionaryNode%3A%20aNode%0A%09self%20visitNode%3A%20aNode'),
+messageSends: ["visitNode:"],
+referencedClasses: []
+}),
+smalltalk.NodeVisitor);
+
 
 
 smalltalk.addClass('Compiler', smalltalk.NodeVisitor, ['stream', 'nestedBlocks', 'earlyReturn', 'currentClass', 'currentSelector', 'unknownVariables', 'tempVariables', 'messageSends', 'referencedClasses', 'classReferenced', 'source'], 'Compiler');
@@ -1493,7 +1523,7 @@ return smalltalk.send((smalltalk.SmalltalkParser || SmalltalkParser), "_new", []
 return self;},
 source: unescape('parser%0A%09%5ESmalltalkParser%20new'),
 messageSends: ["new"],
-referencedClasses: [smalltalk.SmalltalkParser]
+referencedClasses: [smalltalk.nil]
 }),
 smalltalk.Compiler);
 
@@ -2221,6 +2251,40 @@ referencedClasses: []
 }),
 smalltalk.Compiler);
 
+smalltalk.addMethod(
+'_visitDynamicArrayNode_',
+smalltalk.method({
+selector: 'visitDynamicArrayNode:',
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("%5B")]);
+smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_do_separatedBy_", [(function(each){return smalltalk.send(self, "_visit_", [each]);}), (function(){return smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("%2C")]);})]);
+smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("%5D")]);
+return self;},
+source: unescape('visitDynamicArrayNode%3A%20aNode%0A%09stream%20nextPutAll%3A%20%27%5B%27.%0A%09aNode%20nodes%20%0A%09%09do%3A%20%5B%3Aeach%20%7C%20self%20visit%3A%20each%5D%0A%09%09separatedBy%3A%20%5Bstream%20nextPutAll%3A%20%27%2C%27%5D.%0A%09stream%20nextPutAll%3A%20%27%5D%27'),
+messageSends: ["nextPutAll:", "do:separatedBy:", "nodes", "visit:"],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
+smalltalk.addMethod(
+'_visitDynamicDictionaryNode_',
+smalltalk.method({
+selector: 'visitDynamicDictionaryNode:',
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("smalltalk.Dictionary._fromPairs_%28%5B")]);
+smalltalk.send(smalltalk.send(aNode, "_nodes", []), "_do_separatedBy_", [(function(each){return smalltalk.send(self, "_visit_", [each]);}), (function(){return smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("%2C")]);})]);
+smalltalk.send(self['@stream'], "_nextPutAll_", [unescape("%5D%29")]);
+return self;},
+source: unescape('visitDynamicDictionaryNode%3A%20aNode%0A%09stream%20nextPutAll%3A%20%27smalltalk.Dictionary._fromPairs_%28%5B%27.%0A%09%09aNode%20nodes%20%0A%09%09%09do%3A%20%5B%3Aeach%20%7C%20self%20visit%3A%20each%5D%0A%09%09%09separatedBy%3A%20%5Bstream%20nextPutAll%3A%20%27%2C%27%5D.%0A%09%09stream%20nextPutAll%3A%20%27%5D%29%27'),
+messageSends: ["nextPutAll:", "do:separatedBy:", "nodes", "visit:"],
+referencedClasses: []
+}),
+smalltalk.Compiler);
+
 
 smalltalk.Compiler.klass.iVarNames = ['performOptimizations'];
 smalltalk.addMethod(
@@ -2289,3 +2353,39 @@ smalltalk.Compiler.klass);
 smalltalk.addClass('DoIt', smalltalk.Object, [], 'Compiler');
 
 
+smalltalk.addClass('DynamicArrayNode', smalltalk.Node, [], 'Compiler');
+smalltalk.addMethod(
+'_accept_',
+smalltalk.method({
+selector: 'accept:',
+category: 'visiting',
+fn: function (aVisitor){
+var self=this;
+smalltalk.send(aVisitor, "_visitDynamicArrayNode_", [self]);
+return self;},
+source: unescape('accept%3A%20aVisitor%0A%09aVisitor%20visitDynamicArrayNode%3A%20self'),
+messageSends: ["visitDynamicArrayNode:"],
+referencedClasses: []
+}),
+smalltalk.DynamicArrayNode);
+
+
+
+smalltalk.addClass('DynamicDictionaryNode', smalltalk.Node, [], 'Compiler');
+smalltalk.addMethod(
+'_accept_',
+smalltalk.method({
+selector: 'accept:',
+category: 'visiting',
+fn: function (aVisitor){
+var self=this;
+smalltalk.send(aVisitor, "_visitDynamicDictionaryNode_", [self]);
+return self;},
+source: unescape('accept%3A%20aVisitor%0A%09aVisitor%20visitDynamicDictionaryNode%3A%20self'),
+messageSends: ["visitDynamicDictionaryNode:"],
+referencedClasses: []
+}),
+smalltalk.DynamicDictionaryNode);
+
+
+

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 269 - 359
js/IDE.deploy.js


+ 620 - 6
js/IDE.js

@@ -233,11 +233,11 @@ var self=this;
 smalltalk.send(self, "_initialize", [], smalltalk.Widget);
 self['@opened']=true;
 (function($rec){smalltalk.send($rec, "_append_", [self]);smalltalk.send($rec, "_append_", [(function(html){return smalltalk.send(smalltalk.send(html, "_div", []), "_id_", ["jtalk"]);})]);return smalltalk.send($rec, "_addClass_", ["jtalkBody"]);})(smalltalk.send("body", "_asJQuery", []));
-(function($rec){smalltalk.send($rec, "_addTab_", [smalltalk.send((smalltalk.Transcript || Transcript), "_current", [])]);return smalltalk.send($rec, "_addTab_", [smalltalk.send((smalltalk.Workspace || Workspace), "_new", [])]);})(self);
+(function($rec){smalltalk.send($rec, "_addTab_", [smalltalk.send((smalltalk.Transcript || Transcript), "_current", [])]);smalltalk.send($rec, "_addTab_", [smalltalk.send((smalltalk.Workspace || Workspace), "_new", [])]);return smalltalk.send($rec, "_addTab_", [smalltalk.send((smalltalk.TestRunner || TestRunner), "_new", [])]);})(self);
 smalltalk.send(self, "_selectTab_", [smalltalk.send(smalltalk.send(self, "_tabs", []), "_last", [])]);
 (function($rec){smalltalk.send($rec, "_onResize_", [(function(){return (function($rec){smalltalk.send($rec, "_updateBodyMargin", []);return smalltalk.send($rec, "_updatePosition", []);})(self);})]);return smalltalk.send($rec, "_onWindowResize_", [(function(){return smalltalk.send(self, "_updatePosition", []);})]);})(self);
 return self;},
-source: unescape('initialize%0A%20%20%20%20super%20initialize.%0A%20%20%20%20opened%20%3A%3D%20true.%0A%20%20%20%20%27body%27%20asJQuery%20%0A%09append%3A%20self%3B%0A%09append%3A%20%5B%3Ahtml%20%7C%20html%20div%20id%3A%20%27jtalk%27%5D%3B%0A%09addClass%3A%20%27jtalkBody%27.%0A%20%20%20%20self%20%0A%09addTab%3A%20Transcript%20current%3B%0A%09addTab%3A%20Workspace%20new.%0A%20%20%20%20self%20selectTab%3A%20self%20tabs%20last.%0A%20%20%20%20self%20%0A%09onResize%3A%20%5Bself%20updateBodyMargin%3B%20updatePosition%5D%3B%0A%09onWindowResize%3A%20%5Bself%20updatePosition%5D'),
+source: unescape('initialize%0A%20%20%20%20super%20initialize.%0A%20%20%20%20opened%20%3A%3D%20true.%0A%20%20%20%20%27body%27%20asJQuery%20%0A%09append%3A%20self%3B%0A%09append%3A%20%5B%3Ahtml%20%7C%20html%20div%20id%3A%20%27jtalk%27%5D%3B%0A%09addClass%3A%20%27jtalkBody%27.%0A%20%20%20%20self%20%0A%09addTab%3A%20Transcript%20current%3B%0A%09addTab%3A%20Workspace%20new%3B%0A%09addTab%3A%20TestRunner%20new.%0A%20%20%20%20self%20selectTab%3A%20self%20tabs%20last.%0A%20%20%20%20self%20%0A%09onResize%3A%20%5Bself%20updateBodyMargin%3B%20updatePosition%5D%3B%0A%09onWindowResize%3A%20%5Bself%20updatePosition%5D'),
 messageSends: ["initialize", "append:", "id:", "div", "addClass:", "asJQuery", "addTab:", "current", "new", "selectTab:", "last", "tabs", "onResize:", "updateBodyMargin", "updatePosition", "onWindowResize:"],
 referencedClasses: []
 }),
@@ -739,11 +739,11 @@ selector: 'open',
 category: 'instance creation',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(self, "_current", []), "_open", []);
+(function($rec){smalltalk.send($rec, "_open", []);return smalltalk.send($rec, "_selectTab_", [smalltalk.send(self, "_current", [])]);})(smalltalk.send((smalltalk.TabManager || TabManager), "_current", []));
 return self;},
-source: unescape('open%0A%20%20%20%20self%20current%20open'),
-messageSends: ["open", "current"],
-referencedClasses: []
+source: unescape('open%0A%20%20%20%20TabManager%20current%20%0A%09open%3B%0A%09selectTab%3A%20self%20current'),
+messageSends: ["open", "selectTab:", "current"],
+referencedClasses: [smalltalk.TabManager]
 }),
 smalltalk.Transcript.klass);
 
@@ -3317,6 +3317,620 @@ referencedClasses: []
 smalltalk.DebugErrorHandler.klass);
 
 
+smalltalk.addClass('ProgressBar', smalltalk.TabWidget, ['percent', 'progressDiv', 'div'], 'IDE');
+smalltalk.addMethod(
+'_percent',
+smalltalk.method({
+selector: 'percent',
+category: 'accessing',
+fn: function (){
+var self=this;
+return (($receiver = self['@percent']) == nil || $receiver == undefined) ? (function(){return (0);})() : $receiver;
+return self;},
+source: unescape('percent%0A%09%5Epercent%20ifNil%3A%20%5B0%5D'),
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.ProgressBar);
+
+smalltalk.addMethod(
+'_percent_',
+smalltalk.method({
+selector: 'percent:',
+category: 'accessing',
+fn: function (aNumber){
+var self=this;
+self['@percent']=aNumber;
+return self;},
+source: unescape('percent%3A%20aNumber%0A%09percent%20%3A%3D%20aNumber'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ProgressBar);
+
+smalltalk.addMethod(
+'_renderOn_',
+smalltalk.method({
+selector: 'renderOn:',
+category: 'rendering',
+fn: function (html){
+var self=this;
+self['@div']=(function($rec){smalltalk.send($rec, "_class_", ["progress_bar"]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(html, "_div", []));
+smalltalk.send(self, "_renderProgressBar", []);
+return self;},
+source: unescape('renderOn%3A%20html%20%0A%09div%20%3A%3D%20html%20div%20%0A%09%09class%3A%20%27progress_bar%27%3B%0A%09%09yourself.%0A%09self%20renderProgressBar'),
+messageSends: ["class:", "yourself", "div", "renderProgressBar"],
+referencedClasses: []
+}),
+smalltalk.ProgressBar);
+
+smalltalk.addMethod(
+'_renderProgressBar',
+smalltalk.method({
+selector: 'renderProgressBar',
+category: 'rendering',
+fn: function (){
+var self=this;
+smalltalk.send(self['@div'], "_contents_", [(function(html){return (function($rec){smalltalk.send($rec, "_class_", ["progress"]);return smalltalk.send($rec, "_style_", [smalltalk.send(smalltalk.send("width:", "__comma", [smalltalk.send(smalltalk.send(self, "_percent", []), "_asString", [])]), "__comma", [unescape("%25")])]);})(smalltalk.send(html, "_div", []));})]);
+return self;},
+source: unescape('renderProgressBar%0A%09div%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%09html%20div%20%0A%09%09%09class%3A%20%27progress%27%3B%0A%09%09%09style%3A%20%27width%3A%27%2C%20self%20percent%20asString%2C%20%27%25%27%5D'),
+messageSends: ["contents:", "class:", "style:", unescape("%2C"), "asString", "percent", "div"],
+referencedClasses: []
+}),
+smalltalk.ProgressBar);
+
+smalltalk.addMethod(
+'_updatePercent_',
+smalltalk.method({
+selector: 'updatePercent:',
+category: 'updating',
+fn: function (aNumber){
+var self=this;
+smalltalk.send(self, "_percent_", [aNumber]);
+smalltalk.send(self, "_renderProgressBar", []);
+return self;},
+source: unescape('updatePercent%3A%20aNumber%0A%09self%20percent%3A%20aNumber.%0A%09self%20renderProgressBar'),
+messageSends: ["percent:", "renderProgressBar"],
+referencedClasses: []
+}),
+smalltalk.ProgressBar);
+
+
+
+smalltalk.addClass('TestRunner', smalltalk.TabWidget, ['selectedCategories', 'categoriesList', 'selectedClasses', 'classesList', 'selectedMethods', 'progressBar', 'methodsList', 'result', 'statusDiv'], 'IDE');
+smalltalk.addMethod(
+'_label',
+smalltalk.method({
+selector: 'label',
+category: 'accessing',
+fn: function (){
+var self=this;
+return unescape("%5BTest%20runner%5D");
+return self;},
+source: unescape('label%0A%20%20%20%20%5E%27%5BTest%20runner%5D%27'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_categories',
+smalltalk.method({
+selector: 'categories',
+category: 'accessing',
+fn: function (){
+var self=this;
+var categories=nil;
+categories=smalltalk.send((smalltalk.Array || Array), "_new", []);
+smalltalk.send(smalltalk.send(self, "_allClasses", []), "_do_", [(function(each){return (($receiver = smalltalk.send(categories, "_includes_", [smalltalk.send(each, "_category", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(categories, "_add_", [smalltalk.send(each, "_category", [])]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(categories, "_add_", [smalltalk.send(each, "_category", [])]);})]);})]);
+return smalltalk.send(categories, "_sort", []);
+return self;},
+source: unescape('categories%0A%20%20%20%20%7C%20categories%20%7C%0A%20%20%20%20categories%20%3A%3D%20Array%20new.%0A%20%20%20%20self%20allClasses%20do%3A%20%5B%3Aeach%20%7C%0A%09%28categories%20includes%3A%20each%20category%29%20ifFalse%3A%20%5B%0A%09%20%20%20%20categories%20add%3A%20each%20category%5D%5D.%0A%20%20%20%20%5Ecategories%20sort'),
+messageSends: ["new", "do:", "allClasses", "ifFalse:", "includes:", "category", "add:", "sort"],
+referencedClasses: [smalltalk.Array]
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_classes',
+smalltalk.method({
+selector: 'classes',
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_allClasses", []), "_select_", [(function(each){return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_includes_", [smalltalk.send(each, "_category", [])]);})]), "_sort_", [(function(a, b){return (($receiver = smalltalk.send(a, "_name", [])).klass === smalltalk.Number) ? $receiver >smalltalk.send(b, "_name", []) : smalltalk.send($receiver, "__gt", [smalltalk.send(b, "_name", [])]);})]);
+return self;},
+source: unescape('classes%0A%20%20%20%20%5E%28self%20allClasses%20%0A%09select%3A%20%5B%3Aeach%20%7C%20self%20selectedCategories%20includes%3A%20each%20category%5D%29%0A%09sort%3A%20%5B%3Aa%20%3Ab%20%7C%20a%20name%20%3E%20b%20name%5D'),
+messageSends: ["sort:", "select:", "allClasses", "includes:", "selectedCategories", "category", unescape("%3E"), "name"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_selectedCategories',
+smalltalk.method({
+selector: 'selectedCategories',
+category: 'accessing',
+fn: function (){
+var self=this;
+return (($receiver = self['@selectedCategories']) == nil || $receiver == undefined) ? (function(){return self['@selectedCategories']=smalltalk.send((smalltalk.Array || Array), "_new", []);})() : $receiver;
+return self;},
+source: unescape('selectedCategories%0A%09%5EselectedCategories%20ifNil%3A%20%5BselectedCategories%20%3A%3D%20Array%20new%5D'),
+messageSends: ["ifNil:", "new"],
+referencedClasses: [smalltalk.Array]
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_allClasses',
+smalltalk.method({
+selector: 'allClasses',
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.TestCase || TestCase), "_allSubclasses", []);
+return self;},
+source: unescape('allClasses%0A%09%5ETestCase%20allSubclasses'),
+messageSends: ["allSubclasses"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_selectedClasses',
+smalltalk.method({
+selector: 'selectedClasses',
+category: 'accessing',
+fn: function (){
+var self=this;
+return (($receiver = self['@selectedClasses']) == nil || $receiver == undefined) ? (function(){return self['@selectedClasses']=smalltalk.send((smalltalk.Array || Array), "_new", []);})() : $receiver;
+return self;},
+source: unescape('selectedClasses%0A%09%5EselectedClasses%20%20ifNil%3A%20%5BselectedClasses%20%3A%3D%20Array%20new%5D'),
+messageSends: ["ifNil:", "new"],
+referencedClasses: [smalltalk.Array]
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_progressBar',
+smalltalk.method({
+selector: 'progressBar',
+category: 'accessing',
+fn: function (){
+var self=this;
+return (($receiver = self['@progressBar']) == nil || $receiver == undefined) ? (function(){return self['@progressBar']=smalltalk.send((smalltalk.ProgressBar || ProgressBar), "_new", []);})() : $receiver;
+return self;},
+source: unescape('progressBar%0A%09%5EprogressBar%20ifNil%3A%20%5BprogressBar%20%3A%3D%20ProgressBar%20new%5D'),
+messageSends: ["ifNil:", "new"],
+referencedClasses: [smalltalk.ProgressBar]
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_selectedMethods',
+smalltalk.method({
+selector: 'selectedMethods',
+category: 'accessing',
+fn: function (){
+var self=this;
+return (($receiver = self['@selectedMethods']) == nil || $receiver == undefined) ? (function(){return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_collect_", [(function(each){return smalltalk.send(smalltalk.send(smalltalk.send(each, "_methodDictionary", []), "_keys", []), "_select_", [(function(key){return smalltalk.send(key, "_beginsWith_", ["test"]);})]);})]);})() : $receiver;
+return self;},
+source: unescape('selectedMethods%0A%09%5EselectedMethods%20ifNil%3A%20%5Bself%20selectedClasses%20collect%3A%20%5B%3Aeach%20%7C%0A%09%09each%20methodDictionary%20keys%20select%3A%20%5B%3Akey%20%7C%20%20key%20beginsWith%3A%20%27test%27%20%5D%5D%5D'),
+messageSends: ["ifNil:", "collect:", "selectedClasses", "select:", "keys", "methodDictionary", "beginsWith:"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_statusInfo',
+smalltalk.method({
+selector: 'statusInfo',
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_printTotal", []), "__comma", [smalltalk.send(self, "_printPasses", [])]), "__comma", [smalltalk.send(self, "_printErrors", [])]), "__comma", [smalltalk.send(self, "_printFailures", [])]);
+return self;},
+source: unescape('statusInfo%0A%09%5Eself%20printTotal%2C%20self%20printPasses%2C%20self%20printErrors%2C%20self%20printFailures'),
+messageSends: [unescape("%2C"), "printTotal", "printPasses", "printErrors", "printFailures"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_result',
+smalltalk.method({
+selector: 'result',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self['@result'];
+return self;},
+source: unescape('result%0A%09%5Eresult'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_failedMethods',
+smalltalk.method({
+selector: 'failedMethods',
+category: 'accessing',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_collect_", [(function(each){return (function($rec){smalltalk.send($rec, "_class_", ["failures"]);return smalltalk.send($rec, "_with_", [each]);})(smalltalk.send((typeof html == 'undefined' ? nil : html), "_li", []));})]);
+return self;},
+source: unescape('failedMethods%0A%09self%20result%20failures%20collect%3A%20%5B%3Aeach%20%7C%0A%09%09html%20li%20%0A%09%09%09class%3A%20%27failures%27%3B%0A%09%09%09with%3A%20each%5D'),
+messageSends: ["collect:", "failures", "result", "class:", "with:", "li"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_selectAllCategories',
+smalltalk.method({
+selector: 'selectAllCategories',
+category: 'actions',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_categories", []), "_do_", [(function(each){return (($receiver = smalltalk.send(self['@selectedCategories'], "_includes_", [each])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_add_", [each]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_add_", [each]);})]);})]);
+(function($rec){smalltalk.send($rec, "_updateCategoriesList", []);return smalltalk.send($rec, "_updateClassesList", []);})(self);
+return self;},
+source: unescape('selectAllCategories%0A%09self%20categories%20do%3A%20%5B%3Aeach%20%7C%20%0A%09%09%28selectedCategories%20includes%3A%20each%29%20ifFalse%3A%20%5B%0A%09%09%09self%20selectedCategories%20add%3A%20each%5D%5D.%0A%09self%20%0A%09%20%20%20%20updateCategoriesList%3B%0A%09%20%20%20%20updateClassesList'),
+messageSends: ["do:", "categories", "ifFalse:", "includes:", "add:", "selectedCategories", "updateCategoriesList", "updateClassesList"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_toggleCategory_',
+smalltalk.method({
+selector: 'toggleCategory:',
+category: 'actions',
+fn: function (aCategory){
+var self=this;
+(($receiver = smalltalk.send(self, "_isSelectedCategory_", [aCategory])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self['@selectedCategories'], "_add_", [aCategory]);})() : (function(){return smalltalk.send(self['@selectedCategories'], "_remove_", [aCategory]);})()) : smalltalk.send($receiver, "_ifFalse_ifTrue_", [(function(){return smalltalk.send(self['@selectedCategories'], "_add_", [aCategory]);}), (function(){return smalltalk.send(self['@selectedCategories'], "_remove_", [aCategory]);})]);
+(function($rec){smalltalk.send($rec, "_updateCategoriesList", []);return smalltalk.send($rec, "_updateClassesList", []);})(self);
+return self;},
+source: unescape('toggleCategory%3A%20aCategory%0A%09%28self%20isSelectedCategory%3A%20aCategory%29%20%0A%09%09ifFalse%3A%20%5BselectedCategories%20add%3A%20aCategory%5D%0A%09%09ifTrue%3A%20%5BselectedCategories%20remove%3A%20aCategory%5D.%0A%09self%20%0A%09%20%20%20%20updateCategoriesList%3B%0A%09%20%20%20%20updateClassesList'),
+messageSends: ["ifFalse:ifTrue:", "isSelectedCategory:", "add:", "remove:", "updateCategoriesList", "updateClassesList"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_toggleClass_',
+smalltalk.method({
+selector: 'toggleClass:',
+category: 'actions',
+fn: function (aClass){
+var self=this;
+(($receiver = smalltalk.send(self, "_isSelectedClass_", [aClass])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self['@selectedClasses'], "_add_", [aClass]);})() : (function(){return smalltalk.send(self['@selectedClasses'], "_remove_", [aClass]);})()) : smalltalk.send($receiver, "_ifFalse_ifTrue_", [(function(){return smalltalk.send(self['@selectedClasses'], "_add_", [aClass]);}), (function(){return smalltalk.send(self['@selectedClasses'], "_remove_", [aClass]);})]);
+smalltalk.send(self, "_updateClassesList", []);
+return self;},
+source: unescape('toggleClass%3A%20aClass%0A%09%28self%20isSelectedClass%3A%20aClass%29%20%0A%09%09ifFalse%3A%20%5BselectedClasses%20add%3A%20aClass%5D%0A%09%09ifTrue%3A%20%5BselectedClasses%20remove%3A%20aClass%5D.%0A%09self%20%0A%09%20%20%20%20updateClassesList'),
+messageSends: ["ifFalse:ifTrue:", "isSelectedClass:", "add:", "remove:", "updateClassesList"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_selectAllClasses',
+smalltalk.method({
+selector: 'selectAllClasses',
+category: 'actions',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_classes", []), "_do_", [(function(each){return (($receiver = smalltalk.send(self['@selectedClasses'], "_includes_", [each])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_add_", [each]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_add_", [each]);})]);})]);
+(function($rec){smalltalk.send($rec, "_updateCategoriesList", []);return smalltalk.send($rec, "_updateClassesList", []);})(self);
+return self;},
+source: unescape('selectAllClasses%0A%09self%20classes%20do%3A%20%5B%3Aeach%20%7C%20%0A%09%09%28selectedClasses%20includes%3A%20each%29%20ifFalse%3A%20%5B%0A%09%09%09self%20selectedClasses%20add%3A%20each%5D%5D.%0A%09self%20%0A%09%20%20%20%20updateCategoriesList%3B%0A%09%20%20%20%20updateClassesList'),
+messageSends: ["do:", "classes", "ifFalse:", "includes:", "add:", "selectedClasses", "updateCategoriesList", "updateClassesList"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_run_',
+smalltalk.method({
+selector: 'run:',
+category: 'actions',
+fn: function (aCollection){
+var self=this;
+self['@result']=smalltalk.send((smalltalk.TestResult || TestResult), "_new", []);
+(function($rec){smalltalk.send($rec, "_updateStatusDiv", []);return smalltalk.send($rec, "_updateMethodsList", []);})(self);
+smalltalk.send(smalltalk.send(self, "_progressBar", []), "_updatePercent_", [(0)]);
+smalltalk.send(self['@result'], "_total_", [smalltalk.send(aCollection, "_inject_into_", [(0), (function(acc, each){return (($receiver = acc).klass === smalltalk.Number) ? $receiver +smalltalk.send(smalltalk.send(each, "_methods", []), "_size", []) : smalltalk.send($receiver, "__plus", [smalltalk.send(smalltalk.send(each, "_methods", []), "_size", [])]);})])]);
+smalltalk.send(aCollection, "_do_", [(function(each){return smalltalk.send((function(){smalltalk.send(each, "_runCaseFor_", [self['@result']]);smalltalk.send(smalltalk.send(self, "_progressBar", []), "_updatePercent_", [(($receiver = (($receiver = smalltalk.send(self['@result'], "_runs", [])).klass === smalltalk.Number) ? $receiver /smalltalk.send(self['@result'], "_total", []) : smalltalk.send($receiver, "__slash", [smalltalk.send(self['@result'], "_total", [])])).klass === smalltalk.Number) ? $receiver *(100) : smalltalk.send($receiver, "__star", [(100)])]);smalltalk.send(self, "_updateStatusDiv", []);return smalltalk.send(self, "_updateMethodsList", []);}), "_valueWithTimeout_", [(100)]);})]);
+return self;},
+source: unescape('run%3A%20aCollection%0A%09result%20%3A%3D%20TestResult%20new.%0A%09self%20%0A%09%09updateStatusDiv%3B%0A%09%09updateMethodsList.%0A%09self%20progressBar%20updatePercent%3A%200.%0A%09result%20total%3A%20%28aCollection%20inject%3A%200%20into%3A%20%5B%3Aacc%20%3Aeach%20%7C%20acc%20+%20each%20methods%20size%5D%29.%0A%09aCollection%20do%3A%20%5B%3Aeach%20%7C%20%0A%09%09%5Beach%20runCaseFor%3A%20result.%0A%09%09self%20progressBar%20updatePercent%3A%20result%20runs%20/%20result%20total%20*%20100.%0A%09%09self%20updateStatusDiv.%0A%09%09self%20updateMethodsList%5D%20valueWithTimeout%3A%20100%5D.'),
+messageSends: ["new", "updateStatusDiv", "updateMethodsList", "updatePercent:", "progressBar", "total:", "inject:into:", unescape("+"), "size", "methods", "do:", "valueWithTimeout:", "runCaseFor:", unescape("*"), unescape("/"), "runs", "total"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_initialize',
+smalltalk.method({
+selector: 'initialize',
+category: 'initialization',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_initialize", [], smalltalk.TabWidget);
+self['@result']=smalltalk.send((smalltalk.TestResult || TestResult), "_new", []);
+return self;},
+source: unescape('initialize%0A%09super%20initialize.%0A%09result%20%3A%3D%20TestResult%20new'),
+messageSends: ["initialize", "new"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_printErrors',
+smalltalk.method({
+selector: 'printErrors',
+category: 'printing',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_size", []), "_asString", []), "__comma", [unescape("%20errors%2C%20")]);
+return self;},
+source: unescape('printErrors%0A%09%5Eself%20result%20errors%20size%20asString%20%2C%20%27%20errors%2C%20%27'),
+messageSends: [unescape("%2C"), "asString", "size", "errors", "result"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_printFailures',
+smalltalk.method({
+selector: 'printFailures',
+category: 'printing',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", []), "_asString", []), "__comma", [" failures"]);
+return self;},
+source: unescape('printFailures%0A%09%5Eself%20result%20failures%20size%20asString%2C%20%27%20failures%27'),
+messageSends: [unescape("%2C"), "asString", "size", "failures", "result"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_printPasses',
+smalltalk.method({
+selector: 'printPasses',
+category: 'printing',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send((($receiver = smalltalk.send(smalltalk.send(self, "_result", []), "_total", [])).klass === smalltalk.Number) ? $receiver -(($receiver = smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_size", [])).klass === smalltalk.Number) ? $receiver +smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", []) : smalltalk.send($receiver, "__plus", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", [])]) : smalltalk.send($receiver, "__minus", [(($receiver = smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_size", [])).klass === smalltalk.Number) ? $receiver +smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", []) : smalltalk.send($receiver, "__plus", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", [])])]), "_asString", []), "__comma", [unescape("%20passes%2C%20")]);
+return self;},
+source: unescape('printPasses%0A%09%5E%28%28%28self%20result%20total%29%20-%20%28self%20result%20errors%20size%20+%20%28self%20result%20failures%20size%29%29%29%20asString%29%20%2C%20%27%20passes%2C%20%27'),
+messageSends: [unescape("%2C"), "asString", unescape("-"), "total", "result", unescape("+"), "size", "errors", "failures"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_printTotal',
+smalltalk.method({
+selector: 'printTotal',
+category: 'printing',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_total", []), "_asString", []), "__comma", [unescape("%20runs%2C%20")]);
+return self;},
+source: unescape('printTotal%0A%09%5Eself%20result%20total%20asString%2C%20%27%20runs%2C%20%27'),
+messageSends: [unescape("%2C"), "asString", "total", "result"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_renderBoxOn_',
+smalltalk.method({
+selector: 'renderBoxOn:',
+category: 'rendering',
+fn: function (html){
+var self=this;
+(function($rec){smalltalk.send($rec, "_renderCategoriesOn_", [html]);smalltalk.send($rec, "_renderClassesOn_", [html]);return smalltalk.send($rec, "_renderResultsOn_", [html]);})(self);
+return self;},
+source: unescape('renderBoxOn%3A%20html%0A%20%20%20%20self%20%0A%09renderCategoriesOn%3A%20html%3B%0A%09renderClassesOn%3A%20html%3B%0A%09renderResultsOn%3A%20html'),
+messageSends: ["renderCategoriesOn:", "renderClassesOn:", "renderResultsOn:"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_renderButtonsOn_',
+smalltalk.method({
+selector: 'renderButtonsOn:',
+category: 'rendering',
+fn: function (html){
+var self=this;
+(function($rec){smalltalk.send($rec, "_with_", ["Run selected"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_run_", [smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_collect_", [(function(each){return smalltalk.send(each, "_new", []);})])]);})]);})(smalltalk.send(html, "_button", []));
+return self;},
+source: unescape('renderButtonsOn%3A%20html%0A%20%20%20%20html%20button%0A%09with%3A%20%27Run%20selected%27%3B%0A%09onClick%3A%20%5Bself%20run%3A%20%28self%20selectedClasses%20collect%3A%20%5B%3Aeach%20%7C%20each%20new%5D%29%5D'),
+messageSends: ["with:", "onClick:", "run:", "collect:", "selectedClasses", "new", "button"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_renderCategoriesOn_',
+smalltalk.method({
+selector: 'renderCategoriesOn:',
+category: 'rendering',
+fn: function (html){
+var self=this;
+self['@categoriesList']=smalltalk.send(smalltalk.send(html, "_ul", []), "_class_", ["jt_column sunit categories"]);
+smalltalk.send(self, "_updateCategoriesList", []);
+return self;},
+source: unescape('renderCategoriesOn%3A%20html%0A%20%20%20%20%09categoriesList%20%3A%3D%20html%20ul%20class%3A%20%27jt_column%20sunit%20categories%27.%0A%09self%20updateCategoriesList'),
+messageSends: ["class:", "ul", "updateCategoriesList"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_renderClassesOn_',
+smalltalk.method({
+selector: 'renderClassesOn:',
+category: 'rendering',
+fn: function (html){
+var self=this;
+self['@classesList']=smalltalk.send(smalltalk.send(html, "_ul", []), "_class_", ["jt_column sunit classes"]);
+smalltalk.send(self, "_updateClassesList", []);
+return self;},
+source: unescape('renderClassesOn%3A%20html%0A%20%20%20%20%09classesList%20%3A%3D%20html%20ul%20class%3A%20%27jt_column%20sunit%20classes%27.%0A%09self%20updateClassesList'),
+messageSends: ["class:", "ul", "updateClassesList"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_renderResultsOn_',
+smalltalk.method({
+selector: 'renderResultsOn:',
+category: 'rendering',
+fn: function (html){
+var self=this;
+self['@statusDiv']=smalltalk.send(html, "_div", []);
+smalltalk.send(html, "_with_", [smalltalk.send(self, "_progressBar", [])]);
+self['@methodsList']=smalltalk.send(smalltalk.send(html, "_ul", []), "_class_", ["jt_column sunit methods"]);
+smalltalk.send(self, "_updateMethodsList", []);
+smalltalk.send(self, "_updateStatusDiv", []);
+return self;},
+source: unescape('renderResultsOn%3A%20html%0A%20%20%20%20%09statusDiv%20%3A%3D%20html%20div.%0A%09html%20with%3A%20self%20progressBar.%0A%20%20%20%09methodsList%20%3A%3D%20html%20ul%20class%3A%20%27jt_column%20sunit%20methods%27.%0A%09self%20updateMethodsList.%0A%09self%20updateStatusDiv'),
+messageSends: ["div", "with:", "progressBar", "class:", "ul", "updateMethodsList", "updateStatusDiv"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_renderFailuresOn_',
+smalltalk.method({
+selector: 'renderFailuresOn:',
+category: 'rendering',
+fn: function (html){
+var self=this;
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_do_", [(function(each){return (function($rec){smalltalk.send($rec, "_class_", ["failures"]);return smalltalk.send($rec, "_with_", [each]);})(smalltalk.send(html, "_li", []));})]);
+return self;},
+source: unescape('renderFailuresOn%3A%20html%0A%09self%20result%20failures%20do%3A%20%5B%3Aeach%20%7C%0A%09%09html%20li%20%0A%09%09%09class%3A%20%27failures%27%3B%0A%09%09%09with%3A%20each%5D'),
+messageSends: ["do:", "failures", "result", "class:", "with:", "li"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_renderErrorsOn_',
+smalltalk.method({
+selector: 'renderErrorsOn:',
+category: 'rendering',
+fn: function (html){
+var self=this;
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_do_", [(function(each){return (function($rec){smalltalk.send($rec, "_class_", ["errors"]);return smalltalk.send($rec, "_with_", [each]);})(smalltalk.send(html, "_li", []));})]);
+return self;},
+source: unescape('renderErrorsOn%3A%20html%0A%09self%20result%20errors%20do%3A%20%5B%3Aeach%20%7C%0A%09%09html%20li%20%0A%09%09%09class%3A%20%27errors%27%3B%0A%09%09%09with%3A%20each%5D'),
+messageSends: ["do:", "errors", "result", "class:", "with:", "li"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_isSelectedClass_',
+smalltalk.method({
+selector: 'isSelectedClass:',
+category: 'testing',
+fn: function (aClass){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_includes_", [aClass]);
+return self;},
+source: unescape('isSelectedClass%3A%20aClass%0A%09%5E%28self%20selectedClasses%20includes%3A%20aClass%29'),
+messageSends: ["includes:", "selectedClasses"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_isSelectedCategory_',
+smalltalk.method({
+selector: 'isSelectedCategory:',
+category: 'testing',
+fn: function (aCategory){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_includes_", [aCategory]);
+return self;},
+source: unescape('isSelectedCategory%3A%20aCategory%0A%09%5E%28self%20selectedCategories%20includes%3A%20aCategory%29'),
+messageSends: ["includes:", "selectedCategories"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_updateCategoriesList',
+smalltalk.method({
+selector: 'updateCategoriesList',
+category: 'updating',
+fn: function (){
+var self=this;
+smalltalk.send(self['@categoriesList'], "_contents_", [(function(html){(function($rec){smalltalk.send($rec, "_class_", ["all"]);smalltalk.send($rec, "_with_", ["All"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectAllCategories", []);})]);})(smalltalk.send(html, "_li", []));return smalltalk.send(smalltalk.send(self, "_categories", []), "_do_", [(function(each){var li=nil;
+li=smalltalk.send(html, "_li", []);(($receiver = smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_includes_", [each])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(li, "_class_", ["selected"]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(li, "_class_", ["selected"]);})]);return (function($rec){smalltalk.send($rec, "_with_", [each]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_toggleCategory_", [each]);})]);})(li);})]);})]);
+return self;},
+source: unescape('updateCategoriesList%0A%20%20%20%20categoriesList%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%20%20%20%20html%20li%20%0A%09%09class%3A%20%27all%27%3B%0A%09%09with%3A%20%27All%27%3B%0A%09%09onClick%3A%20%5Bself%20selectAllCategories%5D.%0A%09self%20categories%20do%3A%20%5B%3Aeach%20%7C%7C%20li%20%7C%0A%09%20%20%20%20li%20%3A%3D%20html%20li.%0A%09%20%20%20%20%28self%20selectedCategories%20includes%3A%20each%29%20ifTrue%3A%20%5B%0A%09%09li%20class%3A%20%27selected%27%5D.%0A%09%20%20%20%20li%0A%09%09with%3A%20each%3B%0A%09%09onClick%3A%20%5Bself%20toggleCategory%3A%20each%5D%5D%5D'),
+messageSends: ["contents:", "class:", "with:", "onClick:", "selectAllCategories", "li", "do:", "categories", "ifTrue:", "includes:", "selectedCategories", "toggleCategory:"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_updateClassesList',
+smalltalk.method({
+selector: 'updateClassesList',
+category: 'updating',
+fn: function (){
+var self=this;
+smalltalk.send(self['@classesList'], "_contents_", [(function(html){(($receiver = smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_isEmpty", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function($rec){smalltalk.send($rec, "_class_", ["all"]);smalltalk.send($rec, "_with_", ["All"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectAllClasses", []);})]);})(smalltalk.send(html, "_li", []));})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function($rec){smalltalk.send($rec, "_class_", ["all"]);smalltalk.send($rec, "_with_", ["All"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectAllClasses", []);})]);})(smalltalk.send(html, "_li", []));})]);return smalltalk.send(smalltalk.send(self, "_classes", []), "_do_", [(function(each){var li=nil;
+li=smalltalk.send(html, "_li", []);(($receiver = smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_includes_", [each])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(li, "_class_", ["selected"]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(li, "_class_", ["selected"]);})]);return (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send(each, "_name", [])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_toggleClass_", [each]);})]);})(li);})]);})]);
+return self;},
+source: unescape('updateClassesList%0A%20%20%20%20classesList%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%28self%20selectedCategories%20isEmpty%29%20ifFalse%3A%20%5B%0A%09%09html%20li%0A%09%09%09class%3A%20%27all%27%3B%0A%09%09%09with%3A%20%27All%27%3B%0A%09%09%09onClick%3A%20%5Bself%20selectAllClasses%5D%5D.%0A%09self%20classes%20do%3A%20%5B%3Aeach%20%7C%7C%20li%20%7C%0A%09%09li%20%3A%3D%20html%20li.%0A%09%09%28self%20selectedClasses%20includes%3A%20each%29%20ifTrue%3A%20%5B%0A%09%09%09li%20class%3A%20%27selected%27%5D.%0A%09%09li%0A%09%09%09with%3A%20each%20name%3B%0A%09%09%09onClick%3A%20%5Bself%20toggleClass%3A%20each%5D%5D%5D'),
+messageSends: ["contents:", "ifFalse:", "isEmpty", "selectedCategories", "class:", "with:", "onClick:", "selectAllClasses", "li", "do:", "classes", "ifTrue:", "includes:", "selectedClasses", "name", "toggleClass:"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_updateMethodsList',
+smalltalk.method({
+selector: 'updateMethodsList',
+category: 'updating',
+fn: function (){
+var self=this;
+smalltalk.send(self['@methodsList'], "_contents_", [(function(html){smalltalk.send(self, "_renderFailuresOn_", [html]);return smalltalk.send(self, "_renderErrorsOn_", [html]);})]);
+return self;},
+source: unescape('updateMethodsList%0A%09methodsList%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%09self%20renderFailuresOn%3A%20html.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self%20renderErrorsOn%3A%20html%5D'),
+messageSends: ["contents:", "renderFailuresOn:", "renderErrorsOn:"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+smalltalk.addMethod(
+'_updateStatusDiv',
+smalltalk.method({
+selector: 'updateStatusDiv',
+category: 'updating',
+fn: function (){
+var self=this;
+smalltalk.send(self['@statusDiv'], "_class_", [smalltalk.send("sunit status ", "__comma", [smalltalk.send(self['@result'], "_status", [])])]);
+smalltalk.send(self['@statusDiv'], "_contents_", [(function(html){return smalltalk.send(smalltalk.send(html, "_span", []), "_with_", [smalltalk.send(self, "_statusInfo", [])]);})]);
+return self;},
+source: unescape('updateStatusDiv%0A%09statusDiv%20class%3A%20%27sunit%20status%20%27%2C%20result%20status.%0A%09statusDiv%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%09html%20span%20with%3A%20self%20statusInfo%5D'),
+messageSends: ["class:", unescape("%2C"), "status", "contents:", "with:", "span", "statusInfo"],
+referencedClasses: []
+}),
+smalltalk.TestRunner);
+
+
+
 smalltalk.addMethod(
 '_inspect',
 smalltalk.method({

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 122 - 39
js/Kernel.deploy.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 158 - 58
js/Kernel.js


+ 0 - 469
js/SUnit.deploy.js

@@ -146,478 +146,9 @@ smalltalk.TestCase);
 
 
 
-smalltalk.addClass('ProgressBar', smalltalk.TabWidget, ['percent', 'progressDiv', 'div'], 'SUnit');
-smalltalk.addMethod(
-'_percent',
-smalltalk.method({
-selector: 'percent',
-fn: function (){
-var self=this;
-return (($receiver = self['@percent']) == nil || $receiver == undefined) ? (function(){return (0);})() : $receiver;
-return self;}
-}),
-smalltalk.ProgressBar);
-
-smalltalk.addMethod(
-'_percent_',
-smalltalk.method({
-selector: 'percent:',
-fn: function (aNumber){
-var self=this;
-self['@percent']=aNumber;
-return self;}
-}),
-smalltalk.ProgressBar);
-
-smalltalk.addMethod(
-'_renderOn_',
-smalltalk.method({
-selector: 'renderOn:',
-fn: function (html){
-var self=this;
-self['@div']=(function($rec){smalltalk.send($rec, "_class_", ["progress_bar"]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(html, "_div", []));
-smalltalk.send(self, "_renderProgressBar", []);
-return self;}
-}),
-smalltalk.ProgressBar);
-
-smalltalk.addMethod(
-'_renderProgressBar',
-smalltalk.method({
-selector: 'renderProgressBar',
-fn: function (){
-var self=this;
-smalltalk.send(self['@div'], "_contents_", [(function(html){return (function($rec){smalltalk.send($rec, "_class_", ["progress"]);return smalltalk.send($rec, "_style_", [smalltalk.send(smalltalk.send("width:", "__comma", [smalltalk.send(smalltalk.send(self, "_percent", []), "_asString", [])]), "__comma", [unescape("%25")])]);})(smalltalk.send(html, "_div", []));})]);
-return self;}
-}),
-smalltalk.ProgressBar);
-
-smalltalk.addMethod(
-'_updatePercent_',
-smalltalk.method({
-selector: 'updatePercent:',
-fn: function (aNumber){
-var self=this;
-smalltalk.send(self, "_percent_", [aNumber]);
-smalltalk.send(self, "_renderProgressBar", []);
-return self;}
-}),
-smalltalk.ProgressBar);
-
-
-
 smalltalk.addClass('TestFailure', smalltalk.Error, [], 'SUnit');
 
 
-smalltalk.addClass('TestRunner', smalltalk.TabWidget, ['selectedCategories', 'categoriesList', 'selectedClasses', 'classesList', 'selectedMethods', 'progressBar', 'methodsList', 'result', 'statusDiv'], 'SUnit');
-smalltalk.addMethod(
-'_label',
-smalltalk.method({
-selector: 'label',
-fn: function (){
-var self=this;
-return unescape("%5BTest%20runner%5D");
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_categories',
-smalltalk.method({
-selector: 'categories',
-fn: function (){
-var self=this;
-var categories=nil;
-categories=smalltalk.send((smalltalk.Array || Array), "_new", []);
-smalltalk.send(smalltalk.send(self, "_allClasses", []), "_do_", [(function(each){return (($receiver = smalltalk.send(categories, "_includes_", [smalltalk.send(each, "_category", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(categories, "_add_", [smalltalk.send(each, "_category", [])]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(categories, "_add_", [smalltalk.send(each, "_category", [])]);})]);})]);
-return smalltalk.send(categories, "_sort", []);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_classes',
-smalltalk.method({
-selector: 'classes',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(self, "_allClasses", []), "_select_", [(function(each){return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_includes_", [smalltalk.send(each, "_category", [])]);})]), "_sort_", [(function(a, b){return (($receiver = smalltalk.send(a, "_name", [])).klass === smalltalk.Number) ? $receiver >smalltalk.send(b, "_name", []) : smalltalk.send($receiver, "__gt", [smalltalk.send(b, "_name", [])]);})]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_selectedCategories',
-smalltalk.method({
-selector: 'selectedCategories',
-fn: function (){
-var self=this;
-return (($receiver = self['@selectedCategories']) == nil || $receiver == undefined) ? (function(){return self['@selectedCategories']=smalltalk.send((smalltalk.Array || Array), "_new", []);})() : $receiver;
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_allClasses',
-smalltalk.method({
-selector: 'allClasses',
-fn: function (){
-var self=this;
-return smalltalk.send((smalltalk.TestCase || TestCase), "_allSubclasses", []);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_selectedClasses',
-smalltalk.method({
-selector: 'selectedClasses',
-fn: function (){
-var self=this;
-return (($receiver = self['@selectedClasses']) == nil || $receiver == undefined) ? (function(){return self['@selectedClasses']=smalltalk.send((smalltalk.Array || Array), "_new", []);})() : $receiver;
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_progressBar',
-smalltalk.method({
-selector: 'progressBar',
-fn: function (){
-var self=this;
-return (($receiver = self['@progressBar']) == nil || $receiver == undefined) ? (function(){return self['@progressBar']=smalltalk.send((smalltalk.ProgressBar || ProgressBar), "_new", []);})() : $receiver;
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_selectedMethods',
-smalltalk.method({
-selector: 'selectedMethods',
-fn: function (){
-var self=this;
-return (($receiver = self['@selectedMethods']) == nil || $receiver == undefined) ? (function(){return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_collect_", [(function(each){return smalltalk.send(smalltalk.send(smalltalk.send(each, "_methodDictionary", []), "_keys", []), "_select_", [(function(key){return smalltalk.send(key, "_beginsWith_", ["test"]);})]);})]);})() : $receiver;
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_statusInfo',
-smalltalk.method({
-selector: 'statusInfo',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_printTotal", []), "__comma", [smalltalk.send(self, "_printPasses", [])]), "__comma", [smalltalk.send(self, "_printErrors", [])]), "__comma", [smalltalk.send(self, "_printFailures", [])]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_result',
-smalltalk.method({
-selector: 'result',
-fn: function (){
-var self=this;
-return self['@result'];
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_failedMethods',
-smalltalk.method({
-selector: 'failedMethods',
-fn: function (){
-var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_collect_", [(function(each){return (function($rec){smalltalk.send($rec, "_class_", ["failures"]);return smalltalk.send($rec, "_with_", [each]);})(smalltalk.send((typeof html == 'undefined' ? nil : html), "_li", []));})]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_selectAllCategories',
-smalltalk.method({
-selector: 'selectAllCategories',
-fn: function (){
-var self=this;
-smalltalk.send(smalltalk.send(self, "_categories", []), "_do_", [(function(each){return (($receiver = smalltalk.send(self['@selectedCategories'], "_includes_", [each])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_add_", [each]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_add_", [each]);})]);})]);
-(function($rec){smalltalk.send($rec, "_updateCategoriesList", []);return smalltalk.send($rec, "_updateClassesList", []);})(self);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_toggleCategory_',
-smalltalk.method({
-selector: 'toggleCategory:',
-fn: function (aCategory){
-var self=this;
-(($receiver = smalltalk.send(self, "_isSelectedCategory_", [aCategory])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self['@selectedCategories'], "_add_", [aCategory]);})() : (function(){return smalltalk.send(self['@selectedCategories'], "_remove_", [aCategory]);})()) : smalltalk.send($receiver, "_ifFalse_ifTrue_", [(function(){return smalltalk.send(self['@selectedCategories'], "_add_", [aCategory]);}), (function(){return smalltalk.send(self['@selectedCategories'], "_remove_", [aCategory]);})]);
-(function($rec){smalltalk.send($rec, "_updateCategoriesList", []);return smalltalk.send($rec, "_updateClassesList", []);})(self);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_toggleClass_',
-smalltalk.method({
-selector: 'toggleClass:',
-fn: function (aClass){
-var self=this;
-(($receiver = smalltalk.send(self, "_isSelectedClass_", [aClass])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self['@selectedClasses'], "_add_", [aClass]);})() : (function(){return smalltalk.send(self['@selectedClasses'], "_remove_", [aClass]);})()) : smalltalk.send($receiver, "_ifFalse_ifTrue_", [(function(){return smalltalk.send(self['@selectedClasses'], "_add_", [aClass]);}), (function(){return smalltalk.send(self['@selectedClasses'], "_remove_", [aClass]);})]);
-smalltalk.send(self, "_updateClassesList", []);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_selectAllClasses',
-smalltalk.method({
-selector: 'selectAllClasses',
-fn: function (){
-var self=this;
-smalltalk.send(smalltalk.send(self, "_classes", []), "_do_", [(function(each){return (($receiver = smalltalk.send(self['@selectedClasses'], "_includes_", [each])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_add_", [each]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_add_", [each]);})]);})]);
-(function($rec){smalltalk.send($rec, "_updateCategoriesList", []);return smalltalk.send($rec, "_updateClassesList", []);})(self);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_run_',
-smalltalk.method({
-selector: 'run:',
-fn: function (aCollection){
-var self=this;
-self['@result']=smalltalk.send((smalltalk.TestResult || TestResult), "_new", []);
-(function($rec){smalltalk.send($rec, "_updateStatusDiv", []);return smalltalk.send($rec, "_updateMethodsList", []);})(self);
-smalltalk.send(smalltalk.send(self, "_progressBar", []), "_updatePercent_", [(0)]);
-smalltalk.send(self['@result'], "_total_", [smalltalk.send(aCollection, "_inject_into_", [(0), (function(acc, each){return (($receiver = acc).klass === smalltalk.Number) ? $receiver +smalltalk.send(smalltalk.send(each, "_methods", []), "_size", []) : smalltalk.send($receiver, "__plus", [smalltalk.send(smalltalk.send(each, "_methods", []), "_size", [])]);})])]);
-smalltalk.send(aCollection, "_do_", [(function(each){return smalltalk.send((function(){smalltalk.send(each, "_runCaseFor_", [self['@result']]);smalltalk.send(smalltalk.send(self, "_progressBar", []), "_updatePercent_", [(($receiver = (($receiver = smalltalk.send(self['@result'], "_runs", [])).klass === smalltalk.Number) ? $receiver /smalltalk.send(self['@result'], "_total", []) : smalltalk.send($receiver, "__slash", [smalltalk.send(self['@result'], "_total", [])])).klass === smalltalk.Number) ? $receiver *(100) : smalltalk.send($receiver, "__star", [(100)])]);smalltalk.send(self, "_updateStatusDiv", []);return smalltalk.send(self, "_updateMethodsList", []);}), "_valueWithTimeout_", [(100)]);})]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_initialize',
-smalltalk.method({
-selector: 'initialize',
-fn: function (){
-var self=this;
-smalltalk.send(self, "_initialize", [], smalltalk.TabWidget);
-self['@result']=smalltalk.send((smalltalk.TestResult || TestResult), "_new", []);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_printErrors',
-smalltalk.method({
-selector: 'printErrors',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_size", []), "_asString", []), "__comma", [unescape("%20errors%2C%20")]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_printFailures',
-smalltalk.method({
-selector: 'printFailures',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", []), "_asString", []), "__comma", [" failures"]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_printPasses',
-smalltalk.method({
-selector: 'printPasses',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send((($receiver = smalltalk.send(smalltalk.send(self, "_result", []), "_total", [])).klass === smalltalk.Number) ? $receiver -(($receiver = smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_size", [])).klass === smalltalk.Number) ? $receiver +smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", []) : smalltalk.send($receiver, "__plus", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", [])]) : smalltalk.send($receiver, "__minus", [(($receiver = smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_size", [])).klass === smalltalk.Number) ? $receiver +smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", []) : smalltalk.send($receiver, "__plus", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", [])])]), "_asString", []), "__comma", [unescape("%20passes%2C%20")]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_printTotal',
-smalltalk.method({
-selector: 'printTotal',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_total", []), "_asString", []), "__comma", [unescape("%20runs%2C%20")]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderBoxOn_',
-smalltalk.method({
-selector: 'renderBoxOn:',
-fn: function (html){
-var self=this;
-(function($rec){smalltalk.send($rec, "_renderCategoriesOn_", [html]);smalltalk.send($rec, "_renderClassesOn_", [html]);return smalltalk.send($rec, "_renderResultsOn_", [html]);})(self);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderButtonsOn_',
-smalltalk.method({
-selector: 'renderButtonsOn:',
-fn: function (html){
-var self=this;
-(function($rec){smalltalk.send($rec, "_with_", ["Run selected"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_run_", [smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_collect_", [(function(each){return smalltalk.send(each, "_new", []);})])]);})]);})(smalltalk.send(html, "_button", []));
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderCategoriesOn_',
-smalltalk.method({
-selector: 'renderCategoriesOn:',
-fn: function (html){
-var self=this;
-self['@categoriesList']=smalltalk.send(smalltalk.send(html, "_ul", []), "_class_", ["jt_column sunit categories"]);
-smalltalk.send(self, "_updateCategoriesList", []);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderClassesOn_',
-smalltalk.method({
-selector: 'renderClassesOn:',
-fn: function (html){
-var self=this;
-self['@classesList']=smalltalk.send(smalltalk.send(html, "_ul", []), "_class_", ["jt_column sunit classes"]);
-smalltalk.send(self, "_updateClassesList", []);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderResultsOn_',
-smalltalk.method({
-selector: 'renderResultsOn:',
-fn: function (html){
-var self=this;
-self['@statusDiv']=smalltalk.send(html, "_div", []);
-smalltalk.send(html, "_with_", [smalltalk.send(self, "_progressBar", [])]);
-self['@methodsList']=smalltalk.send(smalltalk.send(html, "_ul", []), "_class_", ["jt_column sunit methods"]);
-smalltalk.send(self, "_updateMethodsList", []);
-smalltalk.send(self, "_updateStatusDiv", []);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderFailuresOn_',
-smalltalk.method({
-selector: 'renderFailuresOn:',
-fn: function (html){
-var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_do_", [(function(each){return (function($rec){smalltalk.send($rec, "_class_", ["failures"]);return smalltalk.send($rec, "_with_", [each]);})(smalltalk.send(html, "_li", []));})]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderErrorsOn_',
-smalltalk.method({
-selector: 'renderErrorsOn:',
-fn: function (html){
-var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_do_", [(function(each){return (function($rec){smalltalk.send($rec, "_class_", ["errors"]);return smalltalk.send($rec, "_with_", [each]);})(smalltalk.send(html, "_li", []));})]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_canBeClosed',
-smalltalk.method({
-selector: 'canBeClosed',
-fn: function (){
-var self=this;
-return true;
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_isSelectedClass_',
-smalltalk.method({
-selector: 'isSelectedClass:',
-fn: function (aClass){
-var self=this;
-return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_includes_", [aClass]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_isSelectedCategory_',
-smalltalk.method({
-selector: 'isSelectedCategory:',
-fn: function (aCategory){
-var self=this;
-return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_includes_", [aCategory]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_updateCategoriesList',
-smalltalk.method({
-selector: 'updateCategoriesList',
-fn: function (){
-var self=this;
-smalltalk.send(self['@categoriesList'], "_contents_", [(function(html){(function($rec){smalltalk.send($rec, "_class_", ["all"]);smalltalk.send($rec, "_with_", ["All"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectAllCategories", []);})]);})(smalltalk.send(html, "_li", []));return smalltalk.send(smalltalk.send(self, "_categories", []), "_do_", [(function(each){var li=nil;
-li=smalltalk.send(html, "_li", []);(($receiver = smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_includes_", [each])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(li, "_class_", ["selected"]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(li, "_class_", ["selected"]);})]);return (function($rec){smalltalk.send($rec, "_with_", [each]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_toggleCategory_", [each]);})]);})(li);})]);})]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_updateClassesList',
-smalltalk.method({
-selector: 'updateClassesList',
-fn: function (){
-var self=this;
-smalltalk.send(self['@classesList'], "_contents_", [(function(html){(($receiver = smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_isEmpty", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function($rec){smalltalk.send($rec, "_class_", ["all"]);smalltalk.send($rec, "_with_", ["All"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectAllClasses", []);})]);})(smalltalk.send(html, "_li", []));})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function($rec){smalltalk.send($rec, "_class_", ["all"]);smalltalk.send($rec, "_with_", ["All"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectAllClasses", []);})]);})(smalltalk.send(html, "_li", []));})]);return smalltalk.send(smalltalk.send(self, "_classes", []), "_do_", [(function(each){var li=nil;
-li=smalltalk.send(html, "_li", []);(($receiver = smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_includes_", [each])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(li, "_class_", ["selected"]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(li, "_class_", ["selected"]);})]);return (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send(each, "_name", [])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_toggleClass_", [each]);})]);})(li);})]);})]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_updateMethodsList',
-smalltalk.method({
-selector: 'updateMethodsList',
-fn: function (){
-var self=this;
-smalltalk.send(self['@methodsList'], "_contents_", [(function(html){smalltalk.send(self, "_renderFailuresOn_", [html]);return smalltalk.send(self, "_renderErrorsOn_", [html]);})]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_updateStatusDiv',
-smalltalk.method({
-selector: 'updateStatusDiv',
-fn: function (){
-var self=this;
-smalltalk.send(self['@statusDiv'], "_class_", [smalltalk.send("sunit status ", "__comma", [smalltalk.send(self['@result'], "_status", [])])]);
-smalltalk.send(self['@statusDiv'], "_contents_", [(function(html){return smalltalk.send(smalltalk.send(html, "_span", []), "_with_", [smalltalk.send(self, "_statusInfo", [])]);})]);
-return self;}
-}),
-smalltalk.TestRunner);
-
-
-
 smalltalk.addClass('TestResult', smalltalk.Object, ['timestamp', 'runs', 'errors', 'failures', 'total'], 'SUnit');
 smalltalk.addMethod(
 '_timestamp',

+ 0 - 629
js/SUnit.js

@@ -198,638 +198,9 @@ smalltalk.TestCase);
 
 
 
-smalltalk.addClass('ProgressBar', smalltalk.TabWidget, ['percent', 'progressDiv', 'div'], 'SUnit');
-smalltalk.addMethod(
-'_percent',
-smalltalk.method({
-selector: 'percent',
-category: 'accessing',
-fn: function (){
-var self=this;
-return (($receiver = self['@percent']) == nil || $receiver == undefined) ? (function(){return (0);})() : $receiver;
-return self;},
-source: unescape('percent%0A%09%5Epercent%20ifNil%3A%20%5B0%5D'),
-messageSends: ["ifNil:"],
-referencedClasses: []
-}),
-smalltalk.ProgressBar);
-
-smalltalk.addMethod(
-'_percent_',
-smalltalk.method({
-selector: 'percent:',
-category: 'accessing',
-fn: function (aNumber){
-var self=this;
-self['@percent']=aNumber;
-return self;},
-source: unescape('percent%3A%20aNumber%0A%09percent%20%3A%3D%20aNumber'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.ProgressBar);
-
-smalltalk.addMethod(
-'_renderOn_',
-smalltalk.method({
-selector: 'renderOn:',
-category: 'rendering',
-fn: function (html){
-var self=this;
-self['@div']=(function($rec){smalltalk.send($rec, "_class_", ["progress_bar"]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(html, "_div", []));
-smalltalk.send(self, "_renderProgressBar", []);
-return self;},
-source: unescape('renderOn%3A%20html%20%0A%09div%20%3A%3D%20html%20div%20%0A%09%09class%3A%20%27progress_bar%27%3B%0A%09%09yourself.%0A%09self%20renderProgressBar'),
-messageSends: ["class:", "yourself", "div", "renderProgressBar"],
-referencedClasses: []
-}),
-smalltalk.ProgressBar);
-
-smalltalk.addMethod(
-'_renderProgressBar',
-smalltalk.method({
-selector: 'renderProgressBar',
-category: 'rendering',
-fn: function (){
-var self=this;
-smalltalk.send(self['@div'], "_contents_", [(function(html){return (function($rec){smalltalk.send($rec, "_class_", ["progress"]);return smalltalk.send($rec, "_style_", [smalltalk.send(smalltalk.send("width:", "__comma", [smalltalk.send(smalltalk.send(self, "_percent", []), "_asString", [])]), "__comma", [unescape("%25")])]);})(smalltalk.send(html, "_div", []));})]);
-return self;},
-source: unescape('renderProgressBar%0A%09div%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%09html%20div%20%0A%09%09%09class%3A%20%27progress%27%3B%0A%09%09%09style%3A%20%27width%3A%27%2C%20self%20percent%20asString%2C%20%27%25%27%5D'),
-messageSends: ["contents:", "class:", "style:", unescape("%2C"), "asString", "percent", "div"],
-referencedClasses: []
-}),
-smalltalk.ProgressBar);
-
-smalltalk.addMethod(
-'_updatePercent_',
-smalltalk.method({
-selector: 'updatePercent:',
-category: 'updating',
-fn: function (aNumber){
-var self=this;
-smalltalk.send(self, "_percent_", [aNumber]);
-smalltalk.send(self, "_renderProgressBar", []);
-return self;},
-source: unescape('updatePercent%3A%20aNumber%0A%09self%20percent%3A%20aNumber.%0A%09self%20renderProgressBar'),
-messageSends: ["percent:", "renderProgressBar"],
-referencedClasses: []
-}),
-smalltalk.ProgressBar);
-
-
-
 smalltalk.addClass('TestFailure', smalltalk.Error, [], 'SUnit');
 
 
-smalltalk.addClass('TestRunner', smalltalk.TabWidget, ['selectedCategories', 'categoriesList', 'selectedClasses', 'classesList', 'selectedMethods', 'progressBar', 'methodsList', 'result', 'statusDiv'], 'SUnit');
-smalltalk.addMethod(
-'_label',
-smalltalk.method({
-selector: 'label',
-category: 'accessing',
-fn: function (){
-var self=this;
-return unescape("%5BTest%20runner%5D");
-return self;},
-source: unescape('label%0A%20%20%20%20%5E%27%5BTest%20runner%5D%27'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_categories',
-smalltalk.method({
-selector: 'categories',
-category: 'accessing',
-fn: function (){
-var self=this;
-var categories=nil;
-categories=smalltalk.send((smalltalk.Array || Array), "_new", []);
-smalltalk.send(smalltalk.send(self, "_allClasses", []), "_do_", [(function(each){return (($receiver = smalltalk.send(categories, "_includes_", [smalltalk.send(each, "_category", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(categories, "_add_", [smalltalk.send(each, "_category", [])]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(categories, "_add_", [smalltalk.send(each, "_category", [])]);})]);})]);
-return smalltalk.send(categories, "_sort", []);
-return self;},
-source: unescape('categories%0A%20%20%20%20%7C%20categories%20%7C%0A%20%20%20%20categories%20%3A%3D%20Array%20new.%0A%20%20%20%20self%20allClasses%20do%3A%20%5B%3Aeach%20%7C%0A%09%28categories%20includes%3A%20each%20category%29%20ifFalse%3A%20%5B%0A%09%20%20%20%20categories%20add%3A%20each%20category%5D%5D.%0A%20%20%20%20%5Ecategories%20sort'),
-messageSends: ["new", "do:", "allClasses", "ifFalse:", "includes:", "category", "add:", "sort"],
-referencedClasses: [smalltalk.Array]
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_classes',
-smalltalk.method({
-selector: 'classes',
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(self, "_allClasses", []), "_select_", [(function(each){return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_includes_", [smalltalk.send(each, "_category", [])]);})]), "_sort_", [(function(a, b){return (($receiver = smalltalk.send(a, "_name", [])).klass === smalltalk.Number) ? $receiver >smalltalk.send(b, "_name", []) : smalltalk.send($receiver, "__gt", [smalltalk.send(b, "_name", [])]);})]);
-return self;},
-source: unescape('classes%0A%20%20%20%20%5E%28self%20allClasses%20%0A%09select%3A%20%5B%3Aeach%20%7C%20self%20selectedCategories%20includes%3A%20each%20category%5D%29%0A%09sort%3A%20%5B%3Aa%20%3Ab%20%7C%20a%20name%20%3E%20b%20name%5D'),
-messageSends: ["sort:", "select:", "allClasses", "includes:", "selectedCategories", "category", unescape("%3E"), "name"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_selectedCategories',
-smalltalk.method({
-selector: 'selectedCategories',
-category: 'accessing',
-fn: function (){
-var self=this;
-return (($receiver = self['@selectedCategories']) == nil || $receiver == undefined) ? (function(){return self['@selectedCategories']=smalltalk.send((smalltalk.Array || Array), "_new", []);})() : $receiver;
-return self;},
-source: unescape('selectedCategories%0A%09%5EselectedCategories%20ifNil%3A%20%5BselectedCategories%20%3A%3D%20Array%20new%5D'),
-messageSends: ["ifNil:", "new"],
-referencedClasses: [smalltalk.Array]
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_allClasses',
-smalltalk.method({
-selector: 'allClasses',
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.send((smalltalk.TestCase || TestCase), "_allSubclasses", []);
-return self;},
-source: unescape('allClasses%0A%09%5ETestCase%20allSubclasses'),
-messageSends: ["allSubclasses"],
-referencedClasses: [smalltalk.TestCase]
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_selectedClasses',
-smalltalk.method({
-selector: 'selectedClasses',
-category: 'accessing',
-fn: function (){
-var self=this;
-return (($receiver = self['@selectedClasses']) == nil || $receiver == undefined) ? (function(){return self['@selectedClasses']=smalltalk.send((smalltalk.Array || Array), "_new", []);})() : $receiver;
-return self;},
-source: unescape('selectedClasses%0A%09%5EselectedClasses%20%20ifNil%3A%20%5BselectedClasses%20%3A%3D%20Array%20new%5D'),
-messageSends: ["ifNil:", "new"],
-referencedClasses: [smalltalk.Array]
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_progressBar',
-smalltalk.method({
-selector: 'progressBar',
-category: 'accessing',
-fn: function (){
-var self=this;
-return (($receiver = self['@progressBar']) == nil || $receiver == undefined) ? (function(){return self['@progressBar']=smalltalk.send((smalltalk.ProgressBar || ProgressBar), "_new", []);})() : $receiver;
-return self;},
-source: unescape('progressBar%0A%09%5EprogressBar%20ifNil%3A%20%5BprogressBar%20%3A%3D%20ProgressBar%20new%5D'),
-messageSends: ["ifNil:", "new"],
-referencedClasses: [smalltalk.ProgressBar]
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_selectedMethods',
-smalltalk.method({
-selector: 'selectedMethods',
-category: 'accessing',
-fn: function (){
-var self=this;
-return (($receiver = self['@selectedMethods']) == nil || $receiver == undefined) ? (function(){return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_collect_", [(function(each){return smalltalk.send(smalltalk.send(smalltalk.send(each, "_methodDictionary", []), "_keys", []), "_select_", [(function(key){return smalltalk.send(key, "_beginsWith_", ["test"]);})]);})]);})() : $receiver;
-return self;},
-source: unescape('selectedMethods%0A%09%5EselectedMethods%20ifNil%3A%20%5Bself%20selectedClasses%20collect%3A%20%5B%3Aeach%20%7C%0A%09%09each%20methodDictionary%20keys%20select%3A%20%5B%3Akey%20%7C%20%20key%20beginsWith%3A%20%27test%27%20%5D%5D%5D'),
-messageSends: ["ifNil:", "collect:", "selectedClasses", "select:", "keys", "methodDictionary", "beginsWith:"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_statusInfo',
-smalltalk.method({
-selector: 'statusInfo',
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_printTotal", []), "__comma", [smalltalk.send(self, "_printPasses", [])]), "__comma", [smalltalk.send(self, "_printErrors", [])]), "__comma", [smalltalk.send(self, "_printFailures", [])]);
-return self;},
-source: unescape('statusInfo%0A%09%5Eself%20printTotal%2C%20self%20printPasses%2C%20self%20printErrors%2C%20self%20printFailures'),
-messageSends: [unescape("%2C"), "printTotal", "printPasses", "printErrors", "printFailures"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_result',
-smalltalk.method({
-selector: 'result',
-category: 'accessing',
-fn: function (){
-var self=this;
-return self['@result'];
-return self;},
-source: unescape('result%0A%09%5Eresult'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_failedMethods',
-smalltalk.method({
-selector: 'failedMethods',
-category: 'accessing',
-fn: function (){
-var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_collect_", [(function(each){return (function($rec){smalltalk.send($rec, "_class_", ["failures"]);return smalltalk.send($rec, "_with_", [each]);})(smalltalk.send((typeof html == 'undefined' ? nil : html), "_li", []));})]);
-return self;},
-source: unescape('failedMethods%0A%09self%20result%20failures%20collect%3A%20%5B%3Aeach%20%7C%0A%09%09html%20li%20%0A%09%09%09class%3A%20%27failures%27%3B%0A%09%09%09with%3A%20each%5D'),
-messageSends: ["collect:", "failures", "result", "class:", "with:", "li"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_selectAllCategories',
-smalltalk.method({
-selector: 'selectAllCategories',
-category: 'actions',
-fn: function (){
-var self=this;
-smalltalk.send(smalltalk.send(self, "_categories", []), "_do_", [(function(each){return (($receiver = smalltalk.send(self['@selectedCategories'], "_includes_", [each])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_add_", [each]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_add_", [each]);})]);})]);
-(function($rec){smalltalk.send($rec, "_updateCategoriesList", []);return smalltalk.send($rec, "_updateClassesList", []);})(self);
-return self;},
-source: unescape('selectAllCategories%0A%09self%20categories%20do%3A%20%5B%3Aeach%20%7C%20%0A%09%09%28selectedCategories%20includes%3A%20each%29%20ifFalse%3A%20%5B%0A%09%09%09self%20selectedCategories%20add%3A%20each%5D%5D.%0A%09self%20%0A%09%20%20%20%20updateCategoriesList%3B%0A%09%20%20%20%20updateClassesList'),
-messageSends: ["do:", "categories", "ifFalse:", "includes:", "add:", "selectedCategories", "updateCategoriesList", "updateClassesList"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_toggleCategory_',
-smalltalk.method({
-selector: 'toggleCategory:',
-category: 'actions',
-fn: function (aCategory){
-var self=this;
-(($receiver = smalltalk.send(self, "_isSelectedCategory_", [aCategory])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self['@selectedCategories'], "_add_", [aCategory]);})() : (function(){return smalltalk.send(self['@selectedCategories'], "_remove_", [aCategory]);})()) : smalltalk.send($receiver, "_ifFalse_ifTrue_", [(function(){return smalltalk.send(self['@selectedCategories'], "_add_", [aCategory]);}), (function(){return smalltalk.send(self['@selectedCategories'], "_remove_", [aCategory]);})]);
-(function($rec){smalltalk.send($rec, "_updateCategoriesList", []);return smalltalk.send($rec, "_updateClassesList", []);})(self);
-return self;},
-source: unescape('toggleCategory%3A%20aCategory%0A%09%28self%20isSelectedCategory%3A%20aCategory%29%20%0A%09%09ifFalse%3A%20%5BselectedCategories%20add%3A%20aCategory%5D%0A%09%09ifTrue%3A%20%5BselectedCategories%20remove%3A%20aCategory%5D.%0A%09self%20%0A%09%20%20%20%20updateCategoriesList%3B%0A%09%20%20%20%20updateClassesList'),
-messageSends: ["ifFalse:ifTrue:", "isSelectedCategory:", "add:", "remove:", "updateCategoriesList", "updateClassesList"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_toggleClass_',
-smalltalk.method({
-selector: 'toggleClass:',
-category: 'actions',
-fn: function (aClass){
-var self=this;
-(($receiver = smalltalk.send(self, "_isSelectedClass_", [aClass])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self['@selectedClasses'], "_add_", [aClass]);})() : (function(){return smalltalk.send(self['@selectedClasses'], "_remove_", [aClass]);})()) : smalltalk.send($receiver, "_ifFalse_ifTrue_", [(function(){return smalltalk.send(self['@selectedClasses'], "_add_", [aClass]);}), (function(){return smalltalk.send(self['@selectedClasses'], "_remove_", [aClass]);})]);
-smalltalk.send(self, "_updateClassesList", []);
-return self;},
-source: unescape('toggleClass%3A%20aClass%0A%09%28self%20isSelectedClass%3A%20aClass%29%20%0A%09%09ifFalse%3A%20%5BselectedClasses%20add%3A%20aClass%5D%0A%09%09ifTrue%3A%20%5BselectedClasses%20remove%3A%20aClass%5D.%0A%09self%20%0A%09%20%20%20%20updateClassesList'),
-messageSends: ["ifFalse:ifTrue:", "isSelectedClass:", "add:", "remove:", "updateClassesList"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_selectAllClasses',
-smalltalk.method({
-selector: 'selectAllClasses',
-category: 'actions',
-fn: function (){
-var self=this;
-smalltalk.send(smalltalk.send(self, "_classes", []), "_do_", [(function(each){return (($receiver = smalltalk.send(self['@selectedClasses'], "_includes_", [each])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_add_", [each]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_add_", [each]);})]);})]);
-(function($rec){smalltalk.send($rec, "_updateCategoriesList", []);return smalltalk.send($rec, "_updateClassesList", []);})(self);
-return self;},
-source: unescape('selectAllClasses%0A%09self%20classes%20do%3A%20%5B%3Aeach%20%7C%20%0A%09%09%28selectedClasses%20includes%3A%20each%29%20ifFalse%3A%20%5B%0A%09%09%09self%20selectedClasses%20add%3A%20each%5D%5D.%0A%09self%20%0A%09%20%20%20%20updateCategoriesList%3B%0A%09%20%20%20%20updateClassesList'),
-messageSends: ["do:", "classes", "ifFalse:", "includes:", "add:", "selectedClasses", "updateCategoriesList", "updateClassesList"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_run_',
-smalltalk.method({
-selector: 'run:',
-category: 'actions',
-fn: function (aCollection){
-var self=this;
-self['@result']=smalltalk.send((smalltalk.TestResult || TestResult), "_new", []);
-(function($rec){smalltalk.send($rec, "_updateStatusDiv", []);return smalltalk.send($rec, "_updateMethodsList", []);})(self);
-smalltalk.send(smalltalk.send(self, "_progressBar", []), "_updatePercent_", [(0)]);
-smalltalk.send(self['@result'], "_total_", [smalltalk.send(aCollection, "_inject_into_", [(0), (function(acc, each){return (($receiver = acc).klass === smalltalk.Number) ? $receiver +smalltalk.send(smalltalk.send(each, "_methods", []), "_size", []) : smalltalk.send($receiver, "__plus", [smalltalk.send(smalltalk.send(each, "_methods", []), "_size", [])]);})])]);
-smalltalk.send(aCollection, "_do_", [(function(each){return smalltalk.send((function(){smalltalk.send(each, "_runCaseFor_", [self['@result']]);smalltalk.send(smalltalk.send(self, "_progressBar", []), "_updatePercent_", [(($receiver = (($receiver = smalltalk.send(self['@result'], "_runs", [])).klass === smalltalk.Number) ? $receiver /smalltalk.send(self['@result'], "_total", []) : smalltalk.send($receiver, "__slash", [smalltalk.send(self['@result'], "_total", [])])).klass === smalltalk.Number) ? $receiver *(100) : smalltalk.send($receiver, "__star", [(100)])]);smalltalk.send(self, "_updateStatusDiv", []);return smalltalk.send(self, "_updateMethodsList", []);}), "_valueWithTimeout_", [(100)]);})]);
-return self;},
-source: unescape('run%3A%20aCollection%0A%09result%20%3A%3D%20TestResult%20new.%0A%09self%20%0A%09%09updateStatusDiv%3B%0A%09%09updateMethodsList.%0A%09self%20progressBar%20updatePercent%3A%200.%0A%09result%20total%3A%20%28aCollection%20inject%3A%200%20into%3A%20%5B%3Aacc%20%3Aeach%20%7C%20acc%20+%20each%20methods%20size%5D%29.%0A%09aCollection%20do%3A%20%5B%3Aeach%20%7C%20%0A%09%09%5Beach%20runCaseFor%3A%20result.%0A%09%09self%20progressBar%20updatePercent%3A%20result%20runs%20/%20result%20total%20*%20100.%0A%09%09self%20updateStatusDiv.%0A%09%09self%20updateMethodsList%5D%20valueWithTimeout%3A%20100%5D.'),
-messageSends: ["new", "updateStatusDiv", "updateMethodsList", "updatePercent:", "progressBar", "total:", "inject:into:", unescape("+"), "size", "methods", "do:", "valueWithTimeout:", "runCaseFor:", unescape("*"), unescape("/"), "runs", "total"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_initialize',
-smalltalk.method({
-selector: 'initialize',
-category: 'initialization',
-fn: function (){
-var self=this;
-smalltalk.send(self, "_initialize", [], smalltalk.TabWidget);
-self['@result']=smalltalk.send((smalltalk.TestResult || TestResult), "_new", []);
-return self;},
-source: unescape('initialize%0A%09super%20initialize.%0A%09result%20%3A%3D%20TestResult%20new'),
-messageSends: ["initialize", "new"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_printErrors',
-smalltalk.method({
-selector: 'printErrors',
-category: 'printing',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_size", []), "_asString", []), "__comma", [unescape("%20errors%2C%20")]);
-return self;},
-source: unescape('printErrors%0A%09%5Eself%20result%20errors%20size%20asString%20%2C%20%27%20errors%2C%20%27'),
-messageSends: [unescape("%2C"), "asString", "size", "errors", "result"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_printFailures',
-smalltalk.method({
-selector: 'printFailures',
-category: 'printing',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", []), "_asString", []), "__comma", [" failures"]);
-return self;},
-source: unescape('printFailures%0A%09%5Eself%20result%20failures%20size%20asString%2C%20%27%20failures%27'),
-messageSends: [unescape("%2C"), "asString", "size", "failures", "result"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_printPasses',
-smalltalk.method({
-selector: 'printPasses',
-category: 'printing',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send((($receiver = smalltalk.send(smalltalk.send(self, "_result", []), "_total", [])).klass === smalltalk.Number) ? $receiver -(($receiver = smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_size", [])).klass === smalltalk.Number) ? $receiver +smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", []) : smalltalk.send($receiver, "__plus", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", [])]) : smalltalk.send($receiver, "__minus", [(($receiver = smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_size", [])).klass === smalltalk.Number) ? $receiver +smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", []) : smalltalk.send($receiver, "__plus", [smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_size", [])])]), "_asString", []), "__comma", [unescape("%20passes%2C%20")]);
-return self;},
-source: unescape('printPasses%0A%09%5E%28%28%28self%20result%20total%29%20-%20%28self%20result%20errors%20size%20+%20%28self%20result%20failures%20size%29%29%29%20asString%29%20%2C%20%27%20passes%2C%20%27'),
-messageSends: [unescape("%2C"), "asString", unescape("-"), "total", "result", unescape("+"), "size", "errors", "failures"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_printTotal',
-smalltalk.method({
-selector: 'printTotal',
-category: 'printing',
-fn: function (){
-var self=this;
-return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_total", []), "_asString", []), "__comma", [unescape("%20runs%2C%20")]);
-return self;},
-source: unescape('printTotal%0A%09%5Eself%20result%20total%20asString%2C%20%27%20runs%2C%20%27'),
-messageSends: [unescape("%2C"), "asString", "total", "result"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderBoxOn_',
-smalltalk.method({
-selector: 'renderBoxOn:',
-category: 'rendering',
-fn: function (html){
-var self=this;
-(function($rec){smalltalk.send($rec, "_renderCategoriesOn_", [html]);smalltalk.send($rec, "_renderClassesOn_", [html]);return smalltalk.send($rec, "_renderResultsOn_", [html]);})(self);
-return self;},
-source: unescape('renderBoxOn%3A%20html%0A%20%20%20%20self%20%0A%09renderCategoriesOn%3A%20html%3B%0A%09renderClassesOn%3A%20html%3B%0A%09renderResultsOn%3A%20html'),
-messageSends: ["renderCategoriesOn:", "renderClassesOn:", "renderResultsOn:"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderButtonsOn_',
-smalltalk.method({
-selector: 'renderButtonsOn:',
-category: 'rendering',
-fn: function (html){
-var self=this;
-(function($rec){smalltalk.send($rec, "_with_", ["Run selected"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_run_", [smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_collect_", [(function(each){return smalltalk.send(each, "_new", []);})])]);})]);})(smalltalk.send(html, "_button", []));
-return self;},
-source: unescape('renderButtonsOn%3A%20html%0A%20%20%20%20html%20button%0A%09with%3A%20%27Run%20selected%27%3B%0A%09onClick%3A%20%5Bself%20run%3A%20%28self%20selectedClasses%20collect%3A%20%5B%3Aeach%20%7C%20each%20new%5D%29%5D'),
-messageSends: ["with:", "onClick:", "run:", "collect:", "selectedClasses", "new", "button"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderCategoriesOn_',
-smalltalk.method({
-selector: 'renderCategoriesOn:',
-category: 'rendering',
-fn: function (html){
-var self=this;
-self['@categoriesList']=smalltalk.send(smalltalk.send(html, "_ul", []), "_class_", ["jt_column sunit categories"]);
-smalltalk.send(self, "_updateCategoriesList", []);
-return self;},
-source: unescape('renderCategoriesOn%3A%20html%0A%20%20%20%20%09categoriesList%20%3A%3D%20html%20ul%20class%3A%20%27jt_column%20sunit%20categories%27.%0A%09self%20updateCategoriesList'),
-messageSends: ["class:", "ul", "updateCategoriesList"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderClassesOn_',
-smalltalk.method({
-selector: 'renderClassesOn:',
-category: 'rendering',
-fn: function (html){
-var self=this;
-self['@classesList']=smalltalk.send(smalltalk.send(html, "_ul", []), "_class_", ["jt_column sunit classes"]);
-smalltalk.send(self, "_updateClassesList", []);
-return self;},
-source: unescape('renderClassesOn%3A%20html%0A%20%20%20%20%09classesList%20%3A%3D%20html%20ul%20class%3A%20%27jt_column%20sunit%20classes%27.%0A%09self%20updateClassesList'),
-messageSends: ["class:", "ul", "updateClassesList"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderResultsOn_',
-smalltalk.method({
-selector: 'renderResultsOn:',
-category: 'rendering',
-fn: function (html){
-var self=this;
-self['@statusDiv']=smalltalk.send(html, "_div", []);
-smalltalk.send(html, "_with_", [smalltalk.send(self, "_progressBar", [])]);
-self['@methodsList']=smalltalk.send(smalltalk.send(html, "_ul", []), "_class_", ["jt_column sunit methods"]);
-smalltalk.send(self, "_updateMethodsList", []);
-smalltalk.send(self, "_updateStatusDiv", []);
-return self;},
-source: unescape('renderResultsOn%3A%20html%0A%20%20%20%20%09statusDiv%20%3A%3D%20html%20div.%0A%09html%20with%3A%20self%20progressBar.%0A%20%20%20%09methodsList%20%3A%3D%20html%20ul%20class%3A%20%27jt_column%20sunit%20methods%27.%0A%09self%20updateMethodsList.%0A%09self%20updateStatusDiv'),
-messageSends: ["div", "with:", "progressBar", "class:", "ul", "updateMethodsList", "updateStatusDiv"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderFailuresOn_',
-smalltalk.method({
-selector: 'renderFailuresOn:',
-category: 'rendering',
-fn: function (html){
-var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_failures", []), "_do_", [(function(each){return (function($rec){smalltalk.send($rec, "_class_", ["failures"]);return smalltalk.send($rec, "_with_", [each]);})(smalltalk.send(html, "_li", []));})]);
-return self;},
-source: unescape('renderFailuresOn%3A%20html%0A%09self%20result%20failures%20do%3A%20%5B%3Aeach%20%7C%0A%09%09html%20li%20%0A%09%09%09class%3A%20%27failures%27%3B%0A%09%09%09with%3A%20each%5D'),
-messageSends: ["do:", "failures", "result", "class:", "with:", "li"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_renderErrorsOn_',
-smalltalk.method({
-selector: 'renderErrorsOn:',
-category: 'rendering',
-fn: function (html){
-var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send(self, "_result", []), "_errors", []), "_do_", [(function(each){return (function($rec){smalltalk.send($rec, "_class_", ["errors"]);return smalltalk.send($rec, "_with_", [each]);})(smalltalk.send(html, "_li", []));})]);
-return self;},
-source: unescape('renderErrorsOn%3A%20html%0A%09self%20result%20errors%20do%3A%20%5B%3Aeach%20%7C%0A%09%09html%20li%20%0A%09%09%09class%3A%20%27errors%27%3B%0A%09%09%09with%3A%20each%5D'),
-messageSends: ["do:", "errors", "result", "class:", "with:", "li"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_canBeClosed',
-smalltalk.method({
-selector: 'canBeClosed',
-category: 'testing',
-fn: function (){
-var self=this;
-return true;
-return self;},
-source: unescape('canBeClosed%0A%20%20%20%20%5Etrue'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_isSelectedClass_',
-smalltalk.method({
-selector: 'isSelectedClass:',
-category: 'testing',
-fn: function (aClass){
-var self=this;
-return smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_includes_", [aClass]);
-return self;},
-source: unescape('isSelectedClass%3A%20aClass%0A%09%5E%28self%20selectedClasses%20includes%3A%20aClass%29'),
-messageSends: ["includes:", "selectedClasses"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_isSelectedCategory_',
-smalltalk.method({
-selector: 'isSelectedCategory:',
-category: 'testing',
-fn: function (aCategory){
-var self=this;
-return smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_includes_", [aCategory]);
-return self;},
-source: unescape('isSelectedCategory%3A%20aCategory%0A%09%5E%28self%20selectedCategories%20includes%3A%20aCategory%29'),
-messageSends: ["includes:", "selectedCategories"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_updateCategoriesList',
-smalltalk.method({
-selector: 'updateCategoriesList',
-category: 'updating',
-fn: function (){
-var self=this;
-smalltalk.send(self['@categoriesList'], "_contents_", [(function(html){(function($rec){smalltalk.send($rec, "_class_", ["all"]);smalltalk.send($rec, "_with_", ["All"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectAllCategories", []);})]);})(smalltalk.send(html, "_li", []));return smalltalk.send(smalltalk.send(self, "_categories", []), "_do_", [(function(each){var li=nil;
-li=smalltalk.send(html, "_li", []);(($receiver = smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_includes_", [each])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(li, "_class_", ["selected"]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(li, "_class_", ["selected"]);})]);return (function($rec){smalltalk.send($rec, "_with_", [each]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_toggleCategory_", [each]);})]);})(li);})]);})]);
-return self;},
-source: unescape('updateCategoriesList%0A%20%20%20%20categoriesList%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%20%20%20%20html%20li%20%0A%09%09class%3A%20%27all%27%3B%0A%09%09with%3A%20%27All%27%3B%0A%09%09onClick%3A%20%5Bself%20selectAllCategories%5D.%0A%09self%20categories%20do%3A%20%5B%3Aeach%20%7C%7C%20li%20%7C%0A%09%20%20%20%20li%20%3A%3D%20html%20li.%0A%09%20%20%20%20%28self%20selectedCategories%20includes%3A%20each%29%20ifTrue%3A%20%5B%0A%09%09li%20class%3A%20%27selected%27%5D.%0A%09%20%20%20%20li%0A%09%09with%3A%20each%3B%0A%09%09onClick%3A%20%5Bself%20toggleCategory%3A%20each%5D%5D%5D'),
-messageSends: ["contents:", "class:", "with:", "onClick:", "selectAllCategories", "li", "do:", "categories", "ifTrue:", "includes:", "selectedCategories", "toggleCategory:"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_updateClassesList',
-smalltalk.method({
-selector: 'updateClassesList',
-category: 'updating',
-fn: function (){
-var self=this;
-smalltalk.send(self['@classesList'], "_contents_", [(function(html){(($receiver = smalltalk.send(smalltalk.send(self, "_selectedCategories", []), "_isEmpty", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function($rec){smalltalk.send($rec, "_class_", ["all"]);smalltalk.send($rec, "_with_", ["All"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectAllClasses", []);})]);})(smalltalk.send(html, "_li", []));})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function($rec){smalltalk.send($rec, "_class_", ["all"]);smalltalk.send($rec, "_with_", ["All"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectAllClasses", []);})]);})(smalltalk.send(html, "_li", []));})]);return smalltalk.send(smalltalk.send(self, "_classes", []), "_do_", [(function(each){var li=nil;
-li=smalltalk.send(html, "_li", []);(($receiver = smalltalk.send(smalltalk.send(self, "_selectedClasses", []), "_includes_", [each])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(li, "_class_", ["selected"]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(li, "_class_", ["selected"]);})]);return (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send(each, "_name", [])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_toggleClass_", [each]);})]);})(li);})]);})]);
-return self;},
-source: unescape('updateClassesList%0A%20%20%20%20classesList%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%28self%20selectedCategories%20isEmpty%29%20ifFalse%3A%20%5B%0A%09%09html%20li%0A%09%09%09class%3A%20%27all%27%3B%0A%09%09%09with%3A%20%27All%27%3B%0A%09%09%09onClick%3A%20%5Bself%20selectAllClasses%5D%5D.%0A%09self%20classes%20do%3A%20%5B%3Aeach%20%7C%7C%20li%20%7C%0A%09%09li%20%3A%3D%20html%20li.%0A%09%09%28self%20selectedClasses%20includes%3A%20each%29%20ifTrue%3A%20%5B%0A%09%09%09li%20class%3A%20%27selected%27%5D.%0A%09%09li%0A%09%09%09with%3A%20each%20name%3B%0A%09%09%09onClick%3A%20%5Bself%20toggleClass%3A%20each%5D%5D%5D'),
-messageSends: ["contents:", "ifFalse:", "isEmpty", "selectedCategories", "class:", "with:", "onClick:", "selectAllClasses", "li", "do:", "classes", "ifTrue:", "includes:", "selectedClasses", "name", "toggleClass:"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_updateMethodsList',
-smalltalk.method({
-selector: 'updateMethodsList',
-category: 'updating',
-fn: function (){
-var self=this;
-smalltalk.send(self['@methodsList'], "_contents_", [(function(html){smalltalk.send(self, "_renderFailuresOn_", [html]);return smalltalk.send(self, "_renderErrorsOn_", [html]);})]);
-return self;},
-source: unescape('updateMethodsList%0A%09methodsList%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%09self%20renderFailuresOn%3A%20html.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self%20renderErrorsOn%3A%20html%5D'),
-messageSends: ["contents:", "renderFailuresOn:", "renderErrorsOn:"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-smalltalk.addMethod(
-'_updateStatusDiv',
-smalltalk.method({
-selector: 'updateStatusDiv',
-category: 'updating',
-fn: function (){
-var self=this;
-smalltalk.send(self['@statusDiv'], "_class_", [smalltalk.send("sunit status ", "__comma", [smalltalk.send(self['@result'], "_status", [])])]);
-smalltalk.send(self['@statusDiv'], "_contents_", [(function(html){return smalltalk.send(smalltalk.send(html, "_span", []), "_with_", [smalltalk.send(self, "_statusInfo", [])]);})]);
-return self;},
-source: unescape('updateStatusDiv%0A%09statusDiv%20class%3A%20%27sunit%20status%20%27%2C%20result%20status.%0A%09statusDiv%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%09html%20span%20with%3A%20self%20statusInfo%5D'),
-messageSends: ["class:", unescape("%2C"), "status", "contents:", "with:", "span", "statusInfo"],
-referencedClasses: []
-}),
-smalltalk.TestRunner);
-
-
-
 smalltalk.addClass('TestResult', smalltalk.Object, ['timestamp', 'runs', 'errors', 'failures', 'total'], 'SUnit');
 smalltalk.addMethod(
 '_timestamp',

+ 826 - 0
js/TrySmalltalk.deploy.js

@@ -0,0 +1,826 @@
+smalltalk.addClass('TrySmalltalkWidget', smalltalk.Widget, ['workspace', 'contents', 'header'], 'TrySmalltalk');
+smalltalk.addMethod(
+'_renderOn_',
+smalltalk.method({
+selector: 'renderOn:',
+fn: function (html){
+var self=this;
+(function($rec){smalltalk.send($rec, "_class_", ["profStef"]);smalltalk.send($rec, "_with_", [(function(){return self['@header']=smalltalk.send(html, "_h2", []);})]);smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(self, "_workspace", []), "_renderOn_", [html]);})]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_renderButtonsOn_", [html]);})]);})(smalltalk.send(html, "_div", []));
+(function($rec){smalltalk.send($rec, "_widget_", [self]);return smalltalk.send($rec, "_showCurrentLesson", []);})(smalltalk.send((smalltalk.ProfStef || ProfStef), "_default", []));
+return self;}
+}),
+smalltalk.TrySmalltalkWidget);
+
+smalltalk.addMethod(
+'_workspace',
+smalltalk.method({
+selector: 'workspace',
+fn: function (){
+var self=this;
+return (($receiver = self['@workspace']) == nil || $receiver == undefined) ? (function(){return self['@workspace']=smalltalk.send((smalltalk.SourceArea || SourceArea), "_new", []);})() : $receiver;
+return self;}
+}),
+smalltalk.TrySmalltalkWidget);
+
+smalltalk.addMethod(
+'_contents_',
+smalltalk.method({
+selector: 'contents:',
+fn: function (aString){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_workspace", []), "_val_", [aString]);
+return self;}
+}),
+smalltalk.TrySmalltalkWidget);
+
+smalltalk.addMethod(
+'_contents',
+smalltalk.method({
+selector: 'contents',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_workspace", []), "_val", []);
+return self;}
+}),
+smalltalk.TrySmalltalkWidget);
+
+smalltalk.addMethod(
+'_renderButtonsOn_',
+smalltalk.method({
+selector: 'renderButtonsOn:',
+fn: function (html){
+var self=this;
+(function($rec){smalltalk.send($rec, "_with_", ["DoIt"]);smalltalk.send($rec, "_title_", [unescape("ctrl+d")]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(smalltalk.send(self, "_workspace", []), "_doIt", []);})]);})(smalltalk.send(html, "_button", []));
+(function($rec){smalltalk.send($rec, "_with_", ["PrintIt"]);smalltalk.send($rec, "_title_", [unescape("ctrl+p")]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(smalltalk.send(self, "_workspace", []), "_printIt", []);})]);})(smalltalk.send(html, "_button", []));
+(function($rec){smalltalk.send($rec, "_with_", ["InspectIt"]);smalltalk.send($rec, "_title_", [unescape("ctrl+i")]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(smalltalk.send(self, "_workspace", []), "_inspectIt", []);})]);})(smalltalk.send(html, "_button", []));
+return self;}
+}),
+smalltalk.TrySmalltalkWidget);
+
+smalltalk.addMethod(
+'_setTitle_',
+smalltalk.method({
+selector: 'setTitle:',
+fn: function (aString){
+var self=this;
+smalltalk.send(self['@header'], "_contents_", [(function(html){return smalltalk.send(html, "_with_", [aString]);})]);
+return self;}
+}),
+smalltalk.TrySmalltalkWidget);
+
+
+
+smalltalk.addClass('AbstractTutorial', smalltalk.Object, [], 'TrySmalltalk');
+smalltalk.addMethod(
+'_indexOfLesson_',
+smalltalk.method({
+selector: 'indexOfLesson:',
+fn: function (aSelector){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_tableOfContents", []), "_indexOf_", [aSelector]);
+return self;}
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_tableOfContents',
+smalltalk.method({
+selector: 'tableOfContents',
+fn: function (){
+var self=this;
+return ["welcome", "testLesson", "theEnd"];
+return self;}
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_welcome',
+smalltalk.method({
+selector: 'welcome',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Welcome", unescape("%22Hi%2C%20this%20is%20a%20test%20tutorial.%22")]);
+return self;}
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_testLesson',
+smalltalk.method({
+selector: 'testLesson',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Test Lesson", unescape("%22This%20lesson%20is%20a%20test%22")]);
+return self;}
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_theEnd',
+smalltalk.method({
+selector: 'theEnd',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["The End", unescape("%22And%20that%27d%20be%20pretty%20much%20it%20%3A%29%22")]);
+return self;}
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_lessonAt_',
+smalltalk.method({
+selector: 'lessonAt:',
+fn: function (anInteger){
+var self=this;
+var lessonSelector=nil;
+lessonSelector=smalltalk.send(smalltalk.send(self, "_tableOfContents", []), "_at_", [anInteger]);
+return smalltalk.send(self, "_perform_", [lessonSelector]);
+return self;}
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_size',
+smalltalk.method({
+selector: 'size',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_tableOfContents", []), "_size", []);
+return self;}
+}),
+smalltalk.AbstractTutorial);
+
+
+
+smalltalk.addClass('Lesson', smalltalk.Object, ['title', 'contents'], 'TrySmalltalk');
+smalltalk.addMethod(
+'_contents',
+smalltalk.method({
+selector: 'contents',
+fn: function (){
+var self=this;
+return (($receiver = self['@contents']) == nil || $receiver == undefined) ? (function(){return self['@contents']="";})() : $receiver;
+return self;}
+}),
+smalltalk.Lesson);
+
+smalltalk.addMethod(
+'_contents_',
+smalltalk.method({
+selector: 'contents:',
+fn: function (aString){
+var self=this;
+self['@contents']=aString;
+return self;}
+}),
+smalltalk.Lesson);
+
+smalltalk.addMethod(
+'_title_',
+smalltalk.method({
+selector: 'title:',
+fn: function (aString){
+var self=this;
+self['@title']=aString;
+return self;}
+}),
+smalltalk.Lesson);
+
+smalltalk.addMethod(
+'_title',
+smalltalk.method({
+selector: 'title',
+fn: function (){
+var self=this;
+return (($receiver = self['@title']) == nil || $receiver == undefined) ? (function(){return self['@title']="";})() : $receiver;
+return self;}
+}),
+smalltalk.Lesson);
+
+
+smalltalk.addMethod(
+'_title_contents_',
+smalltalk.method({
+selector: 'title:contents:',
+fn: function (aTitle, someContents){
+var self=this;
+return (function($rec){smalltalk.send($rec, "_title_", [aTitle]);return smalltalk.send($rec, "_contents_", [someContents]);})(smalltalk.send(self, "_new", []));
+return self;}
+}),
+smalltalk.Lesson.klass);
+
+
+smalltalk.addClass('TutorialPlayer', smalltalk.Object, ['tutorialPosition', 'tutorial'], 'TrySmalltalk');
+smalltalk.addMethod(
+'_currentLesson',
+smalltalk.method({
+selector: 'currentLesson',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_tutorial", []), "_lessonAt_", [smalltalk.send(self, "_tutorialPosition", [])]);
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_first',
+smalltalk.method({
+selector: 'first',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_rewind", []);
+return smalltalk.send(self, "_currentLesson", []);
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_last',
+smalltalk.method({
+selector: 'last',
+fn: function (){
+var self=this;
+self['@tutorialPosition']=smalltalk.send(self, "_size", []);
+return smalltalk.send(self, "_currentLesson", []);
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_next',
+smalltalk.method({
+selector: 'next',
+fn: function (){
+var self=this;
+(($receiver = (($receiver = smalltalk.send(self, "_tutorialPosition", [])).klass === smalltalk.Number) ? $receiver <smalltalk.send(self, "_size", []) : smalltalk.send($receiver, "__lt", [smalltalk.send(self, "_size", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return self['@tutorialPosition']=(($receiver = self['@tutorialPosition']).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return self['@tutorialPosition']=(($receiver = self['@tutorialPosition']).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)]);})]);
+return smalltalk.send(self, "_currentLesson", []);
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_previous',
+smalltalk.method({
+selector: 'previous',
+fn: function (){
+var self=this;
+(($receiver = (($receiver = self['@tutorialPosition']).klass === smalltalk.Number) ? $receiver >(1) : smalltalk.send($receiver, "__gt", [(1)])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return self['@tutorialPosition']=(($receiver = self['@tutorialPosition']).klass === smalltalk.Number) ? $receiver -(1) : smalltalk.send($receiver, "__minus", [(1)]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return self['@tutorialPosition']=(($receiver = self['@tutorialPosition']).klass === smalltalk.Number) ? $receiver -(1) : smalltalk.send($receiver, "__minus", [(1)]);})]);
+return smalltalk.send(self, "_currentLesson", []);
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_rewind',
+smalltalk.method({
+selector: 'rewind',
+fn: function (){
+var self=this;
+self['@tutorialPosition']=(1);
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_size',
+smalltalk.method({
+selector: 'size',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_tutorial", []), "_size", []);
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_tutorial',
+smalltalk.method({
+selector: 'tutorial',
+fn: function (){
+var self=this;
+return (($receiver = self['@tutorial']) == nil || $receiver == undefined) ? (function(){return self['@tutorial']=smalltalk.send((smalltalk.SmalltalkSyntaxTutorial || SmalltalkSyntaxTutorial), "_new", []);})() : $receiver;
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_tutorial_',
+smalltalk.method({
+selector: 'tutorial:',
+fn: function (aTutorial){
+var self=this;
+self['@tutorial']=aTutorial;
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_tutorialPosition',
+smalltalk.method({
+selector: 'tutorialPosition',
+fn: function (){
+var self=this;
+return (($receiver = self['@tutorialPosition']) == nil || $receiver == undefined) ? (function(){smalltalk.send(self, "_rewind", []);return self['@tutorialPosition'];})() : $receiver;
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_tutorialPosition_',
+smalltalk.method({
+selector: 'tutorialPosition:',
+fn: function (aTutorialPosition){
+var self=this;
+self['@tutorialPosition']=aTutorialPosition;
+return self;}
+}),
+smalltalk.TutorialPlayer);
+
+
+
+smalltalk.addClass('ProfStef', smalltalk.Object, ['tutorialPlayer', 'widget'], 'TrySmalltalk');
+smalltalk.addMethod(
+'_tutorialPlayer',
+smalltalk.method({
+selector: 'tutorialPlayer',
+fn: function (){
+var self=this;
+return (($receiver = self['@tutorialPlayer']) == nil || $receiver == undefined) ? (function(){return self['@tutorialPlayer']=smalltalk.send((smalltalk.TutorialPlayer || TutorialPlayer), "_new", []);})() : $receiver;
+return self;}
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_first',
+smalltalk.method({
+selector: 'first',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_first", []);
+return smalltalk.send(self, "_showCurrentLesson", []);
+return self;}
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_progress',
+smalltalk.method({
+selector: 'progress',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(unescape("%28"), "__comma", [smalltalk.send(self, "_tutorialPositionString", [])]), "__comma", [unescape("/")]), "__comma", [smalltalk.send(self, "_tutorialSizeString", [])]), "__comma", [unescape("%29")]);
+return self;}
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_tutorialPositionString',
+smalltalk.method({
+selector: 'tutorialPositionString',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_tutorialPosition", []), "_asString", []);
+return self;}
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_tutorialSizeString',
+smalltalk.method({
+selector: 'tutorialSizeString',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_size", []), "_asString", []);
+return self;}
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_next',
+smalltalk.method({
+selector: 'next',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_next", []);
+return smalltalk.send(self, "_showCurrentLesson", []);
+return self;}
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_previous',
+smalltalk.method({
+selector: 'previous',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_previous", []);
+return smalltalk.send(self, "_showCurrentLesson", []);
+return self;}
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_widget_',
+smalltalk.method({
+selector: 'widget:',
+fn: function (aWidget){
+var self=this;
+self['@widget']=aWidget;
+return self;}
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_showCurrentLesson',
+smalltalk.method({
+selector: 'showCurrentLesson',
+fn: function (){
+var self=this;
+var lesson=nil;
+lesson=smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_currentLesson", []);
+smalltalk.send(self['@widget'], "_contents_", [smalltalk.send(lesson, "_contents", [])]);
+smalltalk.send(self['@widget'], "_setTitle_", [smalltalk.send(smalltalk.send(smalltalk.send(lesson, "_title", []), "__comma", [" "]), "__comma", [smalltalk.send(self, "_progress", [])])]);
+return self;}
+}),
+smalltalk.ProfStef);
+
+
+smalltalk.ProfStef.klass.iVarNames = ['instance'];
+smalltalk.addMethod(
+'_first',
+smalltalk.method({
+selector: 'first',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_default", []), "_first", []);
+return self;}
+}),
+smalltalk.ProfStef.klass);
+
+smalltalk.addMethod(
+'_default',
+smalltalk.method({
+selector: 'default',
+fn: function (){
+var self=this;
+return (($receiver = self['@instance']) == nil || $receiver == undefined) ? (function(){return self['@instance']=smalltalk.send(self, "_new", []);})() : $receiver;
+return self;}
+}),
+smalltalk.ProfStef.klass);
+
+smalltalk.addMethod(
+'_previous',
+smalltalk.method({
+selector: 'previous',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_default", []), "_previous", []);
+return self;}
+}),
+smalltalk.ProfStef.klass);
+
+smalltalk.addMethod(
+'_next',
+smalltalk.method({
+selector: 'next',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_default", []), "_next", []);
+return self;}
+}),
+smalltalk.ProfStef.klass);
+
+smalltalk.addMethod(
+'_go',
+smalltalk.method({
+selector: 'go',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_first", []);
+return self;}
+}),
+smalltalk.ProfStef.klass);
+
+
+smalltalk.addClass('SmalltalkSyntaxTutorial', smalltalk.AbstractTutorial, [], 'TrySmalltalk');
+smalltalk.addMethod(
+'_tableOfContents',
+smalltalk.method({
+selector: 'tableOfContents',
+fn: function (){
+var self=this;
+return ["welcome", "doingVSPrinting", "printing", "basicTypesNumbers", "basicTypesString", "basicTypesArray", "basicTypesDynamicArray", "messageSyntaxUnary", "messageSyntaxBinary", "messageSyntaxKeyword", "messageSyntaxExecutionOrder", "messageSyntaxExecutionOrderParentheses", "mathematicalPrecedence", "messageSyntaxCascade", "messageSyntaxCascadeShouldNotBeHere", "blocks", "blocksAssignation", "conditionals", "loops", "iterators", "instanciation", "reflection", "reflectionContinued", "theEnd"];
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesArray',
+smalltalk.method({
+selector: 'basicTypesArray',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Array", unescape("%22Literal%20arrays%20are%20created%20at%20parse%20time%3A%22%0A%0A%23%281%202%203%29.%0A%0A%23%28%201%202%203%20%23%284%205%206%29%29%20size.%0A%0A%23%281%202%204%29%20isEmpty.%0A%0A%23%281%202%203%29%20first.%0A%0A%23%28%27hello%27%20%27Javascript%27%29%20at%3A%202%20put%3A%20%27Smalltalk%27%3B%20yourself.%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesCharacters',
+smalltalk.method({
+selector: 'basicTypesCharacters',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Characters", unescape("%22A%20Character%20can%20be%20instantiated%20using%20%24%20operator%3A%22%0A%0A%24A.%0A%0A%24A%20class.%0A%0A%24B%20charCode.%0A%0ACharacter%20cr.%0A%0ACharacter%20space.%0A%0A%22You%20can%20print%20all%20256%20characters%20of%20the%20ASCII%20extended%20set%3A%22%0A%0ACharacter%20allByteCharacters.%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesDynamicArray',
+smalltalk.method({
+selector: 'basicTypesDynamicArray',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Dynamic Array", unescape("%22Dynamic%20Arrays%20are%20created%20at%20execution%20time%3A%22%0A%0A%7B%20%282+3%29%20.%20%286*6%29%20%7D.%0A%0A%7B%20%282+3%29%20.%20%286*6%29%20.%20%27hello%27%2C%20%27%20Stef%27%7D%20size.%0A%0A%0A%7B%20ProfStef%20%7D%20first%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesNumbers',
+smalltalk.method({
+selector: 'basicTypesNumbers',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Numbers", unescape("%22You%20now%20know%20how%20to%20execute%20Smalltalk%20code.%20%0A%0ANow%20let%27s%20talk%20about%20basic%20objects.%0A%0A1%2C%202%2C%20100%2C%202/3%20...%20are%20Numbers%2C%20and%20respond%20to%20many%20messages%20evaluating%20mathematical%20expressions.%0AEvaluate%20these%20ones%3A%22%0A%0A2.%0A%0A%281/3%29.%0A%0A%281/3%29%20+%20%284/5%29.%0A%0A%2818/5%29%20rounded.%0A%0A1%20class.%0A%0A1%20negated.%0A%0A1%20negated%20negated.%0A%0A%281%20+%203%29%20odd.%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesString',
+smalltalk.method({
+selector: 'basicTypesString',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Strings", unescape("%22A%20String%20is%20a%20collection%20of%20characters.%20Use%20single%20quotes%20to%20create%20a%20String%20object.%20Print%20these%20expressions%3A%22%0A%0A%27ProfStef%27.%0A%0A%27ProfStef%27%20size.%0A%0A%27abc%27%20asUppercase.%0A%0A%27Hello%20World%27%20reversed.%20%0A%0A%22You%20can%20access%20each%20character%20using%20at%3A%20message%22%0A%0A%27ProfStef%27%20at%3A%201.%0A%0A%22String%20concatenation%20uses%20the%20comma%20operator%3A%22%0A%0A%27ProfStef%27%2C%20%27%20is%20cool%27.%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesSymbol',
+smalltalk.method({
+selector: 'basicTypesSymbol',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Symbols", unescape("%22A%20Symbol%20is%20a%20String%20which%20is%20guaranteed%20to%20be%20globally%20unique.%20%0A%0AThere%20is%20one%20and%20only%20one%20Symbol%20%23ProfStef.%20There%20may%20be%20several%20%27ProfStef%27%20String%20objects.%0A%0A%28Message%20%3D%3D%20returns%20true%20if%20the%20two%20objects%20are%20the%20SAME%29%22%0A%0A%27ProfStef%27%20asSymbol.%0A%0A%23ProfStef%20asString.%0A%0A%282%20asString%29%20%3D%3D%20%282%20asString%29.%0A%0A%282%20asString%29%20asSymbol%20%3D%3D%20%282%20asString%29%20asSymbol.%0A%0A%0A%28Smalltalk%20at%3A%20%23ProfStef%29%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_blocks',
+smalltalk.method({
+selector: 'blocks',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Blocks", unescape("%22Cascade%20is%20cool%20%21%20Let%27s%20talk%20about%20blocks.%0A%0ABlocks%20are%20anonymous%20methods%20that%20can%20be%20stored%20into%20variables%20and%20executed%20on%20demand.%0A%0ABlocks%20are%20delimited%20by%20square%20brackets%3A%20%5B%5D%22%0A%0A%5BTranscript%20open%5D.%0A%0A%22does%20not%20open%20a%20Transcript%20because%20the%20block%20is%20not%20executed.%0A%0AHere%20is%20a%20block%20that%20adds%202%20to%20its%20argument%20%28its%20argument%20is%20named%20x%29%3A%22%0A%0A%5B%3Ax%20%7C%20x+2%5D.%0A%0A%22We%20can%20execute%20a%20block%20by%20sending%20it%20value%20messages.%22%0A%0A%5B%3Ax%20%7C%20x+2%5D%20value%3A%205.%0A%0A%5BTranscript%20open%5D%20value.%0A%0A%5B%3Ax%20%7C%20x+2%5D%20value%3A%2010.%0A%0A%5B%3Ax%20%3Ay%7C%20x%20+%20y%5D%20value%3A3%20value%3A5.%0A%0A%5BProfStef%20next%5D%20value.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_blocksAssignation',
+smalltalk.method({
+selector: 'blocksAssignation',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Block assignation", unescape("%22Blocks%20can%20be%20assigned%20to%20a%20variable%20then%20executed%20later.%0A%0ANote%20that%20%7Cb%7C%20is%20the%20declaration%20of%20a%20variable%20named%20%27b%27%20and%20that%20%27%3A%3D%27%20assigns%20a%20value%20to%20a%20variable.%0A%0ASelect%20the%20three%20lines%20then%20Print%20It%3A%22%0A%0A%7Cb%7C%0Ab%20%3A%3D%20%5B%3Ax%20%7C%20x+2%5D.%0Ab%20value%3A%2012.%0A%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_conditionals',
+smalltalk.method({
+selector: 'conditionals',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Conditionals", unescape("%22Conditionals%20are%20just%20messages%20sent%20to%20Boolean%20objects%22%0A%0A1%20%3C%202%0A%20%20ifTrue%3A%20%5B100%5D%0A%20%20ifFalse%3A%20%5B42%5D.%0A%0A%22Here%20the%20message%20is%20ifTrue%3AifFalse%0A%0ATry%20this%3A%22%0A%0ATranscript%20open.%0A%0A3%20%3E%2010%20%0A%09ifTrue%3A%20%5BTranscript%20show%3A%20%27maybe%20there%27%27s%20a%20bug%20....%27%5D%0A%09ifFalse%3A%20%5BTranscript%20show%3A%20%27No%20%3A%203%20is%20less%20than%2010%27%5D.%0A%0A3%20%3D%203%20ifTrue%3A%20%5BProfStef%20next%5D.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_debugger',
+smalltalk.method({
+selector: 'debugger',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Debugger", unescape("%22The%20Debugger%20may%20be%20the%20most%20famous%20tool%20of%20Smalltalk%20environments.%20It%20will%20open%20as%20soon%20as%20an%20unmanaged%20Exception%20occurs.%20%0A%0AThe%20following%20code%20will%20open%20the%20debugger.%0A%0A***This%20should%20be%20rethought%20completely***%22%0A%0A%0A%20")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_doingVSPrinting',
+smalltalk.method({
+selector: 'doingVSPrinting',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Doing VS Printing: Doing", unescape("%22Cool%20%21%20%28I%20like%20to%20say%20Cooool%20%3A%29%20%29.%20You%27ve%20just%20executed%20a%20Smalltalk%20expression.%20More%20precisely%2C%20you%20sent%20the%20message%20%27next%27%20to%0AProfStef%20class%20%28it%27s%20me%20%21%29.%0A%0ANote%20you%20can%20run%20this%20tutorial%20again%20by%20evaluating%3A%20%27ProfStef%20go%27.%20%0A%27ProfStef%20previous%27%20returns%20to%20the%20previous%20lesson.%0A%0AYou%20can%20also%20Do%20It%20using%20the%20keyboard%20shortcut%20%27CTRL%20d%27%0A%0ATry%20to%20evaluate%20this%20expression%3A%22%0A%0Awindow%20alert%3A%20%27hello%20world%21%27.%0A%0A%22Then%20go%20to%20the%20next%20lesson%3A%22%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_instanciation',
+smalltalk.method({
+selector: 'instanciation',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Instanciation", unescape("%22Objects%20are%20instances%20of%20their%20class.%20Usually%2C%20we%20send%20the%20message%20%23new%20to%20a%20class%20for%20creating%20an%20instance%20of%20this%20class.%0A%0AFor%20example%2C%20let%27s%20create%20an%20instance%20of%20the%20class%20Array%3A%22%0A%0AArray%20new%0A%09add%3A%20%27Some%20text%27%3B%0A%09add%3A%203.%3B%0A%09yourself.%0A%0A%22See%20the%20array%20we%27ve%20created%3F%20Actually%2C%20%23%28%27Some%20text%27%203%29%20is%20just%20a%20shorthand%20for%20instantiating%20arrays.%22%0A%0A%22If%20we%20use%20a%20variable%20to%20keep%20track%20of%20this%20object%2C%20we%27ll%20be%20able%20to%20do%20stuff%20with%20it.%22%0A%0A%22The%20following%20code%20must%20be%20ran%20all%20at%20one%2C%20as%20the%20%27anArray%27%20variable%20will%20cease%20to%20exist%20once%20the%20execution%20finishes%3A%22%0A%0A%7CanArray%7C%0A%0AanArray%20%3A%3D%20Array%20new%0A%09add%3A%20%27Some%20text%27%3B%0A%09add%3A%203%3B%0A%09yourself%3B%0A%0ATranscript%20show%3A%20anArray%3B%20cr.%0A%0AanArray%20remove%3A%203.%0A%0ATranscript%20show%3A%20anArray%3B%20cr.%0A%0AanArray%20add%3A%20%27Some%20more%20text%21%27.%0A%0ATranscript%20show%3A%20anArray%3B%20cr.%0A%09%0A%22I%27ll%20put%20myself%20in%20an%20instance%20of%20a%20class%20named%20Dictionary%20and%20go%20to%20the%20next%20lesson%3A%22%0A%0A%28%28Dictionary%20new%20add%3A%20%28%27move%20on%21%27%20-%3E%20ProfStef%29%29%20at%3A%20%27move%20on%21%27%29%20next")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_iterators',
+smalltalk.method({
+selector: 'iterators',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Iterators", unescape("%22The%20message%20do%3A%20is%20sent%20to%20a%20collection%20of%20objects%20%28Array%2C%20Dictionary%2C%20String%2C%20etc%29%2C%20evaluating%20the%20block%20for%20each%20element.%0A%0AHere%20we%20want%20to%20print%20all%20the%20numbers%20on%20the%20Transcript%20%28a%20console%29%22%0A%0A%23%2811%2038%203%20-2%2010%29%20do%3A%20%5B%3Aeach%20%7C%0A%20%20%20%20%20Transcript%20show%3A%20each%20printString%3B%20cr%5D.%0A%0A%22Some%20other%20really%20nice%20iterators%22%0A%0A%23%2811%2038%203%20-2%2010%29%20collect%3A%20%5B%3Aeach%20%7C%20each%20negated%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20collect%3A%20%5B%3Aeach%20%7C%20each%20odd%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20select%3A%20%5B%3Aeach%20%7C%20each%20odd%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20select%3A%20%5B%3Aeach%20%7C%20each%20%3E%2010%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20reject%3A%20%5B%3Aeach%20%7C%20each%20%3E%2010%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20%0A%20%20%20%20%20do%3A%20%5B%3Aeach%20%7C%20Transcript%20show%3A%20each%20printString%5D%0A%20%20%20%20%20separatedBy%3A%20%5BTranscript%20show%3A%20%27.%27%5D.%0A%0A%0A%28Smalltalk%20current%20classes%20select%3A%20%5B%3AeachClass%20%7C%20eachClass%20name%20%3D%20%27ProfStef%27%5D%29%20do%3A%20%5B%3AeachProfstef%20%7C%20eachProfstef%20next%5D.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_loops',
+smalltalk.method({
+selector: 'loops',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Loops", unescape("%22Loops%20are%20high-level%20collection%20iterators%2C%20implemented%20as%20regular%20methods.%22%0A%0A%22Basic%20loops%3A%0A%20%20to%3Ado%3A%0A%20%20to%3Aby%3Ado%22%0A%0A1%20to%3A%20100%20do%3A%0A%20%20%5B%3Ai%20%7C%20Transcript%20show%3A%20i%20asString%3B%20cr%20%5D.%0A%0A1%20to%3A%20100%20by%3A%203%20do%3A%20%5B%3Ai%20%7C%20Transcript%20show%3A%20i%20asString%3B%20cr%5D.%0A%0A100%20to%3A%200%20by%3A%20-2%20do%3A%20%0A%20%20%20%20%5B%3Ai%20%7C%20Transcript%20show%3A%20i%20asString%3B%20cr%5D.%0A%0A1%20to%3A%201%20do%3A%20%5B%3Ai%20%7C%20ProfStef%20next%5D.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_mathematicalPrecedence',
+smalltalk.method({
+selector: 'mathematicalPrecedence',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Mathematical precedence", unescape("%22Traditional%20precedence%20rules%20from%20mathematics%20do%20not%20follow%20in%20Smalltalk.%22%0A%0A2%20*%2010%20+%202.%0A%0A%22Here%20the%20message%20*%20is%20sent%20to%202%2C%20which%20answers%2020%2C%20then%2020%20receive%20the%20message%20+%0A%0ARemember%20that%20all%20messages%20always%20follow%20a%20simple%20left-to-right%20precedence%20rule%2C%20*%20without%20exceptions%20*.%22%0A%0A2%20+%202%20*%2010.%0A%0A2%20+%20%282%20*%2010%29.%0A%0A8%20-%205%20/%202.%0A%0A%288%20-%205%29%20/%202.%0A%0A8%20-%20%285%20/%202%29.%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxBinary',
+smalltalk.method({
+selector: 'messageSyntaxBinary',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Binary messages", unescape("%22Binary%20messages%20have%20the%20following%20form%3A%0A%20%20%20%20anObject%20+%20anotherObject%22%0A%0A3%20*%202.%0A%0ADate%20today%20year%20%3D%202011.%0A%0Afalse%20%7C%20false.%0A%0Atrue%20%26%20true.%0A%0Atrue%20%26%20false.%0A%0A10%20@%20100.%0A%0A10%20%3C%3D%2012.%0A%0A%27ab%27%2C%20%27cd%27.%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxCascade',
+smalltalk.method({
+selector: 'messageSyntaxCascade',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Cascade", unescape("%22%3B%20is%20the%20cascade%20operator.%20It%27s%20useful%20to%20send%20message%20to%20the%20SAME%20receiver%0AOpen%20a%20Transcript%20%28console%29%3A%22%0A%0ATranscript%20open.%0A%0A%22Then%3A%22%0A%0ATranscript%20show%3A%20%27hello%27.%0ATranscript%20show%3A%20%27Smalltalk%27.%0ATranscript%20cr.%0A%0A%22is%20equivalent%20to%3A%22%0A%0ATranscript%20%0A%09%20%20%20show%3A%20%27hello%27%3B%0A%09%20%20%20show%3A%20%27Smalltalk%27%20%3B%0A%09%20%20%20cr.%0A%0A%22You%20can%20close%20the%20development%20tools%20by%20clicking%20on%20the%20red%20circle%20with%20a%20cross%20at%20the%20bottom%20left%20of%20the%20website.%0ATry%20to%20go%20to%20the%20next%20lesson%20with%20a%20cascade%20of%20two%20%27next%27%20messages%3A%22%0A%0AProfStef")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxCascadeShouldNotBeHere',
+smalltalk.method({
+selector: 'messageSyntaxCascadeShouldNotBeHere',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", [unescape("Lost%20%3F"), unescape("%22Hey%2C%20you%20should%20not%20be%20here%20%21%21%20%0A%0AGo%20back%20and%20use%20a%20cascade%20%21%22%0A%0AProfStef%20previous.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxExecutionOrder',
+smalltalk.method({
+selector: 'messageSyntaxExecutionOrder',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Execution order", unescape("%22Unary%20messages%20are%20executed%20first%2C%20then%20binary%20messages%20and%20finally%20keyword%20messages%3A%0A%20%20%20%20Unary%20%3E%20Binary%20%3E%20Keywords%22%0A%0A2.5%20+%203.8%20rounded.%0A%0A3%20max%3A%202%20+%202.%0A%20%20%0A%280@0%29%20class.%0A%0A0@0%20x%3A%20100.%0A%0A%280@0%20x%3A%20100%29%20class.%0A%0A%22Between%20messages%20of%20similar%20precedence%2C%20expressions%20are%20executed%20from%20left%20to%20right%22%0A%0A-12345%20negated%20asString%20reversed.%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxExecutionOrderParentheses',
+smalltalk.method({
+selector: 'messageSyntaxExecutionOrderParentheses',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Parentheses", unescape("%22Use%20parentheses%20to%20change%20order%20of%20evaluation%22%0A%0A%282.5%20+%203.8%29%20rounded.%0A%0A%283%20max%3A%202%29%20+%202.%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxKeyword',
+smalltalk.method({
+selector: 'messageSyntaxKeyword',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Keyword messages", unescape("%22Keyword%20Messages%20are%20messages%20with%20arguments.%20They%20have%20the%20following%20form%3A%0A%20%20%20%20anObject%20akey%3A%20anotherObject%20akey2%3A%20anotherObject2%22%0A%0A%27Web%20development%20is%20a%20good%20deal%20of%20pain%27%20copyFrom%3A%201%20to%3A%2030%0A%0A%22The%20message%20is%20copyFrom%3Ato%3A%20sent%20to%20the%20String%20%27Web%20development%20is%20a%20good%20deal%20of%20pain%27%22%0A%0A1%20max%3A%203.%0A%0AArray%20with%3A%20%27hello%27%20with%3A%202%20with%3A%20Smalltalk.%0A%0A%22The%20message%20is%20with%3Awith%3Awith%3A%20implemented%20on%20class%20Array.%20Note%20you%20can%20also%20write%22%0A%0AArray%0A%09with%3A%20%27Hi%20there%21%27%0A%09with%3A%202%0A%09with%3A%20Smalltalk.%0A%09%0AProfStef%20perform%3A%20%27next%27.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxUnary',
+smalltalk.method({
+selector: 'messageSyntaxUnary',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Unary messages", unescape("%22Messages%20are%20sent%20to%20objects.%20There%20are%20three%20types%20of%20message%3A%20Unary%2C%20Binary%20and%20Keyword.%0A%0AUnary%20messages%20have%20the%20following%20form%3A%0A%20%20%20%20anObject%20aMessage%20%0A%0AYou%27ve%20already%20sent%20unary%20messages.%20For%20example%3A%22%0A%0A1%20class.%0A%0Afalse%20not.%0A%0ADate%20today.%0A%0ANumber%20pi.%0A%0A%22And%20of%20course%3A%20%22%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_pharoEnvironment',
+smalltalk.method({
+selector: 'pharoEnvironment',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Pharo environment", unescape("%22Every%20Smalltalk%20system%20is%20full%20of%20objects.%20There%20are%20windows%2C%20text%2C%20numbers%2C%20dates%2C%20colors%2C%20points%20and%20much%20more.%20You%20can%20interact%20with%20objects%20in%20a%20much%20more%20direct%20way%20than%20is%20possible%20with%20other%20programming%20languages.%0A%0AEvery%20object%20understands%20the%20message%20%27explore%27.%20As%20a%20result%2C%20you%20get%20an%20Explorer%20window%20that%20shows%20details%20about%20the%20object.%22%0A%0ADate%20today%20explore.%0A%0A%22This%20shows%20that%20the%20date%20object%20consists%20of%20a%20point%20in%20time%20%28start%29%20and%20a%20duration%20%28one%20day%20long%29.%22%0A%0AProfStef%20explore.%0A%0A%22You%20see%2C%20ProfStef%20class%20has%20a%20lot%20of%20objects.%20Let%27s%20take%20a%20look%20at%20my%20code%3A%22%0A%0AProfStef%20browse.%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_printing',
+smalltalk.method({
+selector: 'printing',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Doing VS Printing: Printing", unescape("%22Now%20you%27re%20a%20Do%20It%20master%20%21%20Let%27s%20talk%20about%20printing.%20It%27s%20a%20Do%20It%20which%20prints%20the%20result%20next%20to%20the%20expression%20you%27ve%20selected.%0AFor%20example%2C%20select%20the%20text%20below%2C%20and%20click%20on%20%27PrintIt%27%3A%22%0A%0A1%20+%202.%0A%0A%22As%20with%20%27DoIt%27%2C%20there%20is%20also%20a%20shortcut%20to%20execute%20this%20command.%0A%0ATry%20CTRL-p%20on%20the%20following%20expressions%3A%22%0A%0ADate%20today.%0A%0A%22The%20result%20is%20selected%2C%20so%20you%20can%20erase%20it%20using%20the%20backspace%20key.%20Try%20it%20%21%22%0A%0ADate%20today%20asDateString.%0A%0ADate%20today%20asTimeString.%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_reflection',
+smalltalk.method({
+selector: 'reflection',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Reflection", unescape("%22You%20can%20inspect%20and%20change%20the%20system%20at%20runtime.%0A%0ATake%20a%20look%20at%20the%20source%20code%20of%20the%20method%20%23and%3A%20of%20the%20class%20Boolean%3A%22%0A%0A%28Boolean%20methodDictionary%20at%3A%20%27and%3A%27%29%20source.%0A%0A%22Or%20all%20the%20methods%20it%20sends%3A%22%0A%0A%28Boolean%20methodDictionary%20at%3A%20%27and%3A%27%29%20messageSends.%0A%0A%22Here%27s%20all%20the%20methods%20I%20implement%3A%22%0A%0AProfStef%20methodDictionary.%0A%0A%22Let%27s%20create%20a%20new%20method%20to%20go%20to%20the%20next%20lesson%3A%22%0A%0A%7CnewMethod%7C%0AnewMethod%20%3A%3D%20Compiler%20new%20load%3A%20%27goToNextLesson%20ProfStef%20next.%27%20forClass%3A%20ProfStef.%0AProfStef%20class%20addCompiledMethod%3A%20newMethod%0A%0A%22Wow%21%20I%20can%27t%20wait%20to%20use%20my%20new%20method%21%22%0A%0AProfStef%20goToNextLesson.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_reflectionContinued',
+smalltalk.method({
+selector: 'reflectionContinued',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Reflection continued", unescape("%22So%20cool%2C%20isn%27t%20it%20%3F%20%20Before%20going%20further%2C%20let%27s%20remove%20this%20method%3A%22%0A%0AProfStef%20class%20methodAt%3A%20%23goToNextLesson.%0A%0AProfStef%20class%20removeCompiledMethod%3A%20%28ProfStef%20class%20methodAt%3A%20%23goToNextLesson%29.%0A%0AProfStef%20class%20methodAt%3A%20%23goToNextLesson.%0A%0A%0A%22Then%20move%20forward%3A%22%0A%0AProfStef%20perform%3A%23next")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_theEnd',
+smalltalk.method({
+selector: 'theEnd',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", [unescape("Tutorial%20done%20%21"), unescape("%22This%20tutorial%20is%20done.%20Enjoy%20programming%20Smalltalk%20with%20JTalk.%20%0A%0AYou%20can%20run%20this%20tutorial%20again%20by%20evaluating%3A%20ProfStef%20go.%0A%0ASee%20you%20soon%20%21%22%0A")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_welcome',
+smalltalk.method({
+selector: 'welcome',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Welcome", unescape("%20%22Hello%21%20I%27m%20Professor%20Stef.%20%0A%0AYou%20must%20want%20me%20to%20help%20you%20learn%20Smalltalk.%0A%0ASo%20let%27s%20go%20to%20the%20first%20lesson.%20%20Select%20the%20text%20below%20and%20click%20on%20the%20%27DoIt%27%20button%22%0A%0AProfStef%20next.")]);
+return self;}
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+
+

+ 1114 - 0
js/TrySmalltalk.js

@@ -0,0 +1,1114 @@
+smalltalk.addClass('TrySmalltalkWidget', smalltalk.Widget, ['workspace', 'contents', 'header'], 'TrySmalltalk');
+smalltalk.addMethod(
+'_renderOn_',
+smalltalk.method({
+selector: 'renderOn:',
+category: 'rendering',
+fn: function (html){
+var self=this;
+(function($rec){smalltalk.send($rec, "_class_", ["profStef"]);smalltalk.send($rec, "_with_", [(function(){return self['@header']=smalltalk.send(html, "_h2", []);})]);smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(self, "_workspace", []), "_renderOn_", [html]);})]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_renderButtonsOn_", [html]);})]);})(smalltalk.send(html, "_div", []));
+(function($rec){smalltalk.send($rec, "_widget_", [self]);return smalltalk.send($rec, "_showCurrentLesson", []);})(smalltalk.send((smalltalk.ProfStef || ProfStef), "_default", []));
+return self;},
+source: unescape('renderOn%3A%20html%0A%09html%20div%20%0A%09%09class%3A%20%27profStef%27%3B%20%0A%09%09with%3A%20%5Bheader%20%3A%3D%20html%20h2%5D%3B%0A%09%09with%3A%20%5Bself%20workspace%20renderOn%3A%20html%5D%3B%0A%09%09with%3A%20%5Bself%20renderButtonsOn%3A%20html%5D.%0A%20%20%20%20%20%20%20%20%20%20ProfStef%20default%20%0A%09%09widget%3A%20self%3B%0A%09%09showCurrentLesson'),
+messageSends: ["class:", "with:", "h2", "renderOn:", "workspace", "renderButtonsOn:", "div", "widget:", "showCurrentLesson", "default"],
+referencedClasses: [smalltalk.nil]
+}),
+smalltalk.TrySmalltalkWidget);
+
+smalltalk.addMethod(
+'_workspace',
+smalltalk.method({
+selector: 'workspace',
+category: 'accessing',
+fn: function (){
+var self=this;
+return (($receiver = self['@workspace']) == nil || $receiver == undefined) ? (function(){return self['@workspace']=smalltalk.send((smalltalk.SourceArea || SourceArea), "_new", []);})() : $receiver;
+return self;},
+source: unescape('workspace%0A%09%5E%20workspace%20ifNil%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%09workspace%20%3A%3D%20SourceArea%20new%5D'),
+messageSends: ["ifNil:", "new"],
+referencedClasses: [smalltalk.SourceArea]
+}),
+smalltalk.TrySmalltalkWidget);
+
+smalltalk.addMethod(
+'_contents_',
+smalltalk.method({
+selector: 'contents:',
+category: 'accessing',
+fn: function (aString){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_workspace", []), "_val_", [aString]);
+return self;},
+source: unescape('contents%3A%20aString%0A%09self%20workspace%20val%3A%20aString'),
+messageSends: ["val:", "workspace"],
+referencedClasses: []
+}),
+smalltalk.TrySmalltalkWidget);
+
+smalltalk.addMethod(
+'_contents',
+smalltalk.method({
+selector: 'contents',
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_workspace", []), "_val", []);
+return self;},
+source: unescape('contents%0A%09%5Eself%20workspace%20val'),
+messageSends: ["val", "workspace"],
+referencedClasses: []
+}),
+smalltalk.TrySmalltalkWidget);
+
+smalltalk.addMethod(
+'_renderButtonsOn_',
+smalltalk.method({
+selector: 'renderButtonsOn:',
+category: 'rendering',
+fn: function (html){
+var self=this;
+(function($rec){smalltalk.send($rec, "_with_", ["DoIt"]);smalltalk.send($rec, "_title_", [unescape("ctrl+d")]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(smalltalk.send(self, "_workspace", []), "_doIt", []);})]);})(smalltalk.send(html, "_button", []));
+(function($rec){smalltalk.send($rec, "_with_", ["PrintIt"]);smalltalk.send($rec, "_title_", [unescape("ctrl+p")]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(smalltalk.send(self, "_workspace", []), "_printIt", []);})]);})(smalltalk.send(html, "_button", []));
+(function($rec){smalltalk.send($rec, "_with_", ["InspectIt"]);smalltalk.send($rec, "_title_", [unescape("ctrl+i")]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(smalltalk.send(self, "_workspace", []), "_inspectIt", []);})]);})(smalltalk.send(html, "_button", []));
+return self;},
+source: unescape('renderButtonsOn%3A%20html%0A%20%20%20%20html%20button%0A%09with%3A%20%27DoIt%27%3B%0A%09title%3A%20%27ctrl+d%27%3B%0A%09onClick%3A%20%5Bself%20workspace%20doIt%5D.%0A%20%20%20%20html%20button%0A%09with%3A%20%27PrintIt%27%3B%0A%09title%3A%20%27ctrl+p%27%3B%0A%09onClick%3A%20%5Bself%20workspace%20printIt%5D.%0A%20%20%20%20html%20button%0A%09with%3A%20%27InspectIt%27%3B%0A%09title%3A%20%27ctrl+i%27%3B%0A%09onClick%3A%20%5Bself%20workspace%20inspectIt%5D'),
+messageSends: ["with:", "title:", "onClick:", "doIt", "workspace", "button", "printIt", "inspectIt"],
+referencedClasses: []
+}),
+smalltalk.TrySmalltalkWidget);
+
+smalltalk.addMethod(
+'_setTitle_',
+smalltalk.method({
+selector: 'setTitle:',
+category: 'accessing',
+fn: function (aString){
+var self=this;
+smalltalk.send(self['@header'], "_contents_", [(function(html){return smalltalk.send(html, "_with_", [aString]);})]);
+return self;},
+source: unescape('setTitle%3A%20aString%0A%09header%20contents%3A%20%5B%3Ahtml%20%7C%20html%20with%3A%20aString%5D'),
+messageSends: ["contents:", "with:"],
+referencedClasses: []
+}),
+smalltalk.TrySmalltalkWidget);
+
+
+
+smalltalk.addClass('AbstractTutorial', smalltalk.Object, [], 'TrySmalltalk');
+smalltalk.addMethod(
+'_indexOfLesson_',
+smalltalk.method({
+selector: 'indexOfLesson:',
+category: 'not yet classified',
+fn: function (aSelector){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_tableOfContents", []), "_indexOf_", [aSelector]);
+return self;},
+source: unescape('indexOfLesson%3A%20aSelector%0A%09%5Eself%20tableOfContents%20indexOf%3A%20aSelector.'),
+messageSends: ["indexOf:", "tableOfContents"],
+referencedClasses: []
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_tableOfContents',
+smalltalk.method({
+selector: 'tableOfContents',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return ["welcome", "testLesson", "theEnd"];
+return self;},
+source: unescape('tableOfContents%0A%5E%20%23%28%0A%20%20%27welcome%27%0A%20%20%27testLesson%27%0A%20%20%27theEnd%27%0A%29'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_welcome',
+smalltalk.method({
+selector: 'welcome',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Welcome", unescape("%22Hi%2C%20this%20is%20a%20test%20tutorial.%22")]);
+return self;},
+source: unescape('welcome%0A%09%5E%20Lesson%0A%09%09title%3A%20%27Welcome%27%20%0A%09%09contents%3A%20%27%22Hi%2C%20this%20is%20a%20test%20tutorial.%22%27'),
+messageSends: ["title:contents:"],
+referencedClasses: []
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_testLesson',
+smalltalk.method({
+selector: 'testLesson',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Test Lesson", unescape("%22This%20lesson%20is%20a%20test%22")]);
+return self;},
+source: unescape('testLesson%0A%09%5E%20Lesson%0A%09%09title%3A%20%27Test%20Lesson%27%20%0A%09%09contents%3A%20%27%22This%20lesson%20is%20a%20test%22%27'),
+messageSends: ["title:contents:"],
+referencedClasses: []
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_theEnd',
+smalltalk.method({
+selector: 'theEnd',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["The End", unescape("%22And%20that%27d%20be%20pretty%20much%20it%20%3A%29%22")]);
+return self;},
+source: unescape('theEnd%0A%09%5E%20Lesson%0A%09%09title%3A%20%27The%20End%27%20%0A%09%09contents%3A%20%27%22And%20that%27%27d%20be%20pretty%20much%20it%20%3A%29%22%27'),
+messageSends: ["title:contents:"],
+referencedClasses: []
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_lessonAt_',
+smalltalk.method({
+selector: 'lessonAt:',
+category: 'not yet classified',
+fn: function (anInteger){
+var self=this;
+var lessonSelector=nil;
+lessonSelector=smalltalk.send(smalltalk.send(self, "_tableOfContents", []), "_at_", [anInteger]);
+return smalltalk.send(self, "_perform_", [lessonSelector]);
+return self;},
+source: unescape('lessonAt%3A%20anInteger%0A%09%7C%20lessonSelector%20%7C%0A%09lessonSelector%20%3A%3D%20self%20tableOfContents%20at%3A%20anInteger.%0A%09%5E%20self%20perform%3A%20lessonSelector.'),
+messageSends: ["at:", "tableOfContents", "perform:"],
+referencedClasses: []
+}),
+smalltalk.AbstractTutorial);
+
+smalltalk.addMethod(
+'_size',
+smalltalk.method({
+selector: 'size',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_tableOfContents", []), "_size", []);
+return self;},
+source: unescape('size%0A%09%5E%20self%20tableOfContents%20size'),
+messageSends: ["size", "tableOfContents"],
+referencedClasses: []
+}),
+smalltalk.AbstractTutorial);
+
+
+
+smalltalk.addClass('Lesson', smalltalk.Object, ['title', 'contents'], 'TrySmalltalk');
+smalltalk.addMethod(
+'_contents',
+smalltalk.method({
+selector: 'contents',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return (($receiver = self['@contents']) == nil || $receiver == undefined) ? (function(){return self['@contents']="";})() : $receiver;
+return self;},
+source: unescape('contents%0A%09%5E%20contents%20ifNil%3A%20%5Bcontents%20%3A%3D%20%27%27%5D'),
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.Lesson);
+
+smalltalk.addMethod(
+'_contents_',
+smalltalk.method({
+selector: 'contents:',
+category: 'not yet classified',
+fn: function (aString){
+var self=this;
+self['@contents']=aString;
+return self;},
+source: unescape('contents%3A%20aString%0A%09contents%20%3A%3D%20aString'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Lesson);
+
+smalltalk.addMethod(
+'_title_',
+smalltalk.method({
+selector: 'title:',
+category: 'not yet classified',
+fn: function (aString){
+var self=this;
+self['@title']=aString;
+return self;},
+source: unescape('title%3A%20aString%0A%09title%20%3A%3D%20aString'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Lesson);
+
+smalltalk.addMethod(
+'_title',
+smalltalk.method({
+selector: 'title',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return (($receiver = self['@title']) == nil || $receiver == undefined) ? (function(){return self['@title']="";})() : $receiver;
+return self;},
+source: unescape('title%0A%09%5E%20title%20ifNil%3A%20%5Btitle%20%3A%3D%20%27%27%5D'),
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.Lesson);
+
+
+smalltalk.addMethod(
+'_title_contents_',
+smalltalk.method({
+selector: 'title:contents:',
+category: 'not yet classified',
+fn: function (aTitle, someContents){
+var self=this;
+return (function($rec){smalltalk.send($rec, "_title_", [aTitle]);return smalltalk.send($rec, "_contents_", [someContents]);})(smalltalk.send(self, "_new", []));
+return self;},
+source: unescape('title%3A%20aTitle%20contents%3A%20someContents%0A%09%5E%20%28self%20new%29%0A%09%09title%3A%20aTitle%3B%0A%09%09contents%3A%20someContents'),
+messageSends: ["title:", "contents:", "new"],
+referencedClasses: []
+}),
+smalltalk.Lesson.klass);
+
+
+smalltalk.addClass('TutorialPlayer', smalltalk.Object, ['tutorialPosition', 'tutorial'], 'TrySmalltalk');
+smalltalk.addMethod(
+'_currentLesson',
+smalltalk.method({
+selector: 'currentLesson',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_tutorial", []), "_lessonAt_", [smalltalk.send(self, "_tutorialPosition", [])]);
+return self;},
+source: unescape('currentLesson%0A%09%5E%20self%20tutorial%20lessonAt%3A%20self%20tutorialPosition.'),
+messageSends: ["lessonAt:", "tutorial", "tutorialPosition"],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_first',
+smalltalk.method({
+selector: 'first',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_rewind", []);
+return smalltalk.send(self, "_currentLesson", []);
+return self;},
+source: unescape('first%0A%09self%20rewind.%0A%09%5E%20self%20currentLesson'),
+messageSends: ["rewind", "currentLesson"],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_last',
+smalltalk.method({
+selector: 'last',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+self['@tutorialPosition']=smalltalk.send(self, "_size", []);
+return smalltalk.send(self, "_currentLesson", []);
+return self;},
+source: unescape('last%0A%09tutorialPosition%20%3A%3D%20self%20size.%0A%09%5E%20self%20currentLesson'),
+messageSends: ["size", "currentLesson"],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_next',
+smalltalk.method({
+selector: 'next',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+(($receiver = (($receiver = smalltalk.send(self, "_tutorialPosition", [])).klass === smalltalk.Number) ? $receiver <smalltalk.send(self, "_size", []) : smalltalk.send($receiver, "__lt", [smalltalk.send(self, "_size", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return self['@tutorialPosition']=(($receiver = self['@tutorialPosition']).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return self['@tutorialPosition']=(($receiver = self['@tutorialPosition']).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)]);})]);
+return smalltalk.send(self, "_currentLesson", []);
+return self;},
+source: unescape('next%0A%09self%20tutorialPosition%20%3C%20self%20size%0A%09%09ifTrue%3A%20%5BtutorialPosition%20%3A%3D%20tutorialPosition%20+%201%5D.%0A%09%5E%20self%20currentLesson'),
+messageSends: ["ifTrue:", unescape("%3C"), "tutorialPosition", "size", unescape("+"), "currentLesson"],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_previous',
+smalltalk.method({
+selector: 'previous',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+(($receiver = (($receiver = self['@tutorialPosition']).klass === smalltalk.Number) ? $receiver >(1) : smalltalk.send($receiver, "__gt", [(1)])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return self['@tutorialPosition']=(($receiver = self['@tutorialPosition']).klass === smalltalk.Number) ? $receiver -(1) : smalltalk.send($receiver, "__minus", [(1)]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return self['@tutorialPosition']=(($receiver = self['@tutorialPosition']).klass === smalltalk.Number) ? $receiver -(1) : smalltalk.send($receiver, "__minus", [(1)]);})]);
+return smalltalk.send(self, "_currentLesson", []);
+return self;},
+source: unescape('previous%0A%09tutorialPosition%20%3E%20%201%20ifTrue%3A%20%5BtutorialPosition%20%3A%3D%20tutorialPosition%20%20-%201%5D.%0A%09%5E%20self%20currentLesson'),
+messageSends: ["ifTrue:", unescape("%3E"), unescape("-"), "currentLesson"],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_rewind',
+smalltalk.method({
+selector: 'rewind',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+self['@tutorialPosition']=(1);
+return self;},
+source: unescape('rewind%0A%09tutorialPosition%20%3A%3D%201.'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_size',
+smalltalk.method({
+selector: 'size',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_tutorial", []), "_size", []);
+return self;},
+source: unescape('size%0A%09%5E%20self%20tutorial%20size'),
+messageSends: ["size", "tutorial"],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_tutorial',
+smalltalk.method({
+selector: 'tutorial',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return (($receiver = self['@tutorial']) == nil || $receiver == undefined) ? (function(){return self['@tutorial']=smalltalk.send((smalltalk.SmalltalkSyntaxTutorial || SmalltalkSyntaxTutorial), "_new", []);})() : $receiver;
+return self;},
+source: unescape('tutorial%0A%09%5E%20tutorial%20%20ifNil%3A%20%5Btutorial%20%3A%3D%20SmalltalkSyntaxTutorial%20new%5D'),
+messageSends: ["ifNil:", "new"],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_tutorial_',
+smalltalk.method({
+selector: 'tutorial:',
+category: 'not yet classified',
+fn: function (aTutorial){
+var self=this;
+self['@tutorial']=aTutorial;
+return self;},
+source: unescape('tutorial%3A%20aTutorial%0A%09tutorial%20%3A%3D%20aTutorial'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_tutorialPosition',
+smalltalk.method({
+selector: 'tutorialPosition',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return (($receiver = self['@tutorialPosition']) == nil || $receiver == undefined) ? (function(){smalltalk.send(self, "_rewind", []);return self['@tutorialPosition'];})() : $receiver;
+return self;},
+source: unescape('tutorialPosition%20%0A%09%5E%20tutorialPosition%20%20ifNil%3A%20%5B%0A%09%09self%20rewind.%0A%09%09tutorialPosition.%0A%09%5D.'),
+messageSends: ["ifNil:", "rewind"],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+smalltalk.addMethod(
+'_tutorialPosition_',
+smalltalk.method({
+selector: 'tutorialPosition:',
+category: 'not yet classified',
+fn: function (aTutorialPosition){
+var self=this;
+self['@tutorialPosition']=aTutorialPosition;
+return self;},
+source: unescape('tutorialPosition%3A%20aTutorialPosition%20%0A%09tutorialPosition%20%3A%3D%20aTutorialPosition'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.TutorialPlayer);
+
+
+
+smalltalk.addClass('ProfStef', smalltalk.Object, ['tutorialPlayer', 'widget'], 'TrySmalltalk');
+smalltalk.addMethod(
+'_tutorialPlayer',
+smalltalk.method({
+selector: 'tutorialPlayer',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return (($receiver = self['@tutorialPlayer']) == nil || $receiver == undefined) ? (function(){return self['@tutorialPlayer']=smalltalk.send((smalltalk.TutorialPlayer || TutorialPlayer), "_new", []);})() : $receiver;
+return self;},
+source: unescape('tutorialPlayer%0A%09%5E%20tutorialPlayer%20ifNil%3A%20%5BtutorialPlayer%20%3A%3D%20TutorialPlayer%20new%5D'),
+messageSends: ["ifNil:", "new"],
+referencedClasses: [smalltalk.TutorialPlayer]
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_first',
+smalltalk.method({
+selector: 'first',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_first", []);
+return smalltalk.send(self, "_showCurrentLesson", []);
+return self;},
+source: unescape('first%0A%09self%20tutorialPlayer%20first.%0A%09%5E%20self%20showCurrentLesson.'),
+messageSends: ["first", "tutorialPlayer", "showCurrentLesson"],
+referencedClasses: []
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_progress',
+smalltalk.method({
+selector: 'progress',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(unescape("%28"), "__comma", [smalltalk.send(self, "_tutorialPositionString", [])]), "__comma", [unescape("/")]), "__comma", [smalltalk.send(self, "_tutorialSizeString", [])]), "__comma", [unescape("%29")]);
+return self;},
+source: unescape('progress%0A%09%5E%20%27%28%27%2C%20self%20tutorialPositionString%2C%20%27/%27%2C%20self%20tutorialSizeString%2C%20%27%29%27.'),
+messageSends: [unescape("%2C"), "tutorialPositionString", "tutorialSizeString"],
+referencedClasses: []
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_tutorialPositionString',
+smalltalk.method({
+selector: 'tutorialPositionString',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_tutorialPosition", []), "_asString", []);
+return self;},
+source: unescape('tutorialPositionString%0A%09%5E%20self%20tutorialPlayer%20tutorialPosition%20asString.'),
+messageSends: ["asString", "tutorialPosition", "tutorialPlayer"],
+referencedClasses: []
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_tutorialSizeString',
+smalltalk.method({
+selector: 'tutorialSizeString',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_size", []), "_asString", []);
+return self;},
+source: unescape('tutorialSizeString%0A%09%5E%20self%20tutorialPlayer%20size%20asString'),
+messageSends: ["asString", "size", "tutorialPlayer"],
+referencedClasses: []
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_next',
+smalltalk.method({
+selector: 'next',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_next", []);
+return smalltalk.send(self, "_showCurrentLesson", []);
+return self;},
+source: unescape('next%0A%09self%20tutorialPlayer%20next.%0A%09%5E%20self%20showCurrentLesson.'),
+messageSends: ["next", "tutorialPlayer", "showCurrentLesson"],
+referencedClasses: []
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_previous',
+smalltalk.method({
+selector: 'previous',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_previous", []);
+return smalltalk.send(self, "_showCurrentLesson", []);
+return self;},
+source: unescape('previous%0A%09self%20tutorialPlayer%20previous.%0A%09%5E%20self%20showCurrentLesson.'),
+messageSends: ["previous", "tutorialPlayer", "showCurrentLesson"],
+referencedClasses: []
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_widget_',
+smalltalk.method({
+selector: 'widget:',
+category: 'not yet classified',
+fn: function (aWidget){
+var self=this;
+self['@widget']=aWidget;
+return self;},
+source: unescape('widget%3A%20aWidget%0A%09widget%20%3A%3D%20aWidget'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ProfStef);
+
+smalltalk.addMethod(
+'_showCurrentLesson',
+smalltalk.method({
+selector: 'showCurrentLesson',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+var lesson=nil;
+lesson=smalltalk.send(smalltalk.send(self, "_tutorialPlayer", []), "_currentLesson", []);
+smalltalk.send(self['@widget'], "_contents_", [smalltalk.send(lesson, "_contents", [])]);
+smalltalk.send(self['@widget'], "_setTitle_", [smalltalk.send(smalltalk.send(smalltalk.send(lesson, "_title", []), "__comma", [" "]), "__comma", [smalltalk.send(self, "_progress", [])])]);
+return self;},
+source: unescape('showCurrentLesson%0A%09%7C%20lesson%20%7C%0A%09lesson%20%3A%3D%20self%20tutorialPlayer%20currentLesson.%0A%09widget%20contents%3A%20lesson%20contents.%0A%09widget%20setTitle%3A%20lesson%20title%20%2C%20%27%20%27%20%2C%20self%20progress.'),
+messageSends: ["currentLesson", "tutorialPlayer", "contents:", "contents", "setTitle:", unescape("%2C"), "title", "progress"],
+referencedClasses: []
+}),
+smalltalk.ProfStef);
+
+
+smalltalk.ProfStef.klass.iVarNames = ['instance'];
+smalltalk.addMethod(
+'_first',
+smalltalk.method({
+selector: 'first',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_default", []), "_first", []);
+return self;},
+source: unescape('first%0A%09%5E%20self%20default%20first.'),
+messageSends: ["first", "default"],
+referencedClasses: []
+}),
+smalltalk.ProfStef.klass);
+
+smalltalk.addMethod(
+'_default',
+smalltalk.method({
+selector: 'default',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return (($receiver = self['@instance']) == nil || $receiver == undefined) ? (function(){return self['@instance']=smalltalk.send(self, "_new", []);})() : $receiver;
+return self;},
+source: unescape('default%20%0A%09%5E%20instance%20ifNil%3A%20%5Binstance%20%3A%3D%20self%20new%5D'),
+messageSends: ["ifNil:", "new"],
+referencedClasses: []
+}),
+smalltalk.ProfStef.klass);
+
+smalltalk.addMethod(
+'_previous',
+smalltalk.method({
+selector: 'previous',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_default", []), "_previous", []);
+return self;},
+source: unescape('previous%0A%09%5E%20self%20default%20previous.'),
+messageSends: ["previous", "default"],
+referencedClasses: []
+}),
+smalltalk.ProfStef.klass);
+
+smalltalk.addMethod(
+'_next',
+smalltalk.method({
+selector: 'next',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_default", []), "_next", []);
+return self;},
+source: unescape('next%0A%09%5E%20self%20default%20next.'),
+messageSends: ["next", "default"],
+referencedClasses: []
+}),
+smalltalk.ProfStef.klass);
+
+smalltalk.addMethod(
+'_go',
+smalltalk.method({
+selector: 'go',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_first", []);
+return self;},
+source: unescape('go%0A%09self%20first.'),
+messageSends: ["first"],
+referencedClasses: []
+}),
+smalltalk.ProfStef.klass);
+
+
+smalltalk.addClass('SmalltalkSyntaxTutorial', smalltalk.AbstractTutorial, [], 'TrySmalltalk');
+smalltalk.addMethod(
+'_tableOfContents',
+smalltalk.method({
+selector: 'tableOfContents',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return ["welcome", "doingVSPrinting", "printing", "basicTypesNumbers", "basicTypesString", "basicTypesArray", "basicTypesDynamicArray", "messageSyntaxUnary", "messageSyntaxBinary", "messageSyntaxKeyword", "messageSyntaxExecutionOrder", "messageSyntaxExecutionOrderParentheses", "mathematicalPrecedence", "messageSyntaxCascade", "messageSyntaxCascadeShouldNotBeHere", "blocks", "blocksAssignation", "conditionals", "loops", "iterators", "instanciation", "reflection", "reflectionContinued", "theEnd"];
+return self;},
+source: unescape('tableOfContents%0A%5E%20%23%28%09%27welcome%27%0A%09%27doingVSPrinting%27%0A%09%27printing%27%0A%0A%09%27basicTypesNumbers%27%0A%09%22%27basicTypesCharacters%27%22%0A%09%27basicTypesString%27%0A%09%22%27basicTypesSymbol%27%22%0A%09%27basicTypesArray%27%0A%09%27basicTypesDynamicArray%27%0A%0A%09%27messageSyntaxUnary%27%0A%09%27messageSyntaxBinary%27%0A%09%27messageSyntaxKeyword%27%0A%09%27messageSyntaxExecutionOrder%27%0A%09%27messageSyntaxExecutionOrderParentheses%27%0A%09%27mathematicalPrecedence%27%0A%09%27messageSyntaxCascade%27%0A%09%27messageSyntaxCascadeShouldNotBeHere%27%0A%0A%09%27blocks%27%0A%09%27blocksAssignation%27%0A%09%27conditionals%27%0A%09%27loops%27%0A%09%27iterators%27%0A%0A%09%27instanciation%27%0A%0A%09%27reflection%27%0A%09%27reflectionContinued%27%0A%09%22%27pharoEnvironment%27%22%0A%0A%09%22%27debugger%27%22%0A%09%27theEnd%27%20%29'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesArray',
+smalltalk.method({
+selector: 'basicTypesArray',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Array", unescape("%22Literal%20arrays%20are%20created%20at%20parse%20time%3A%22%0A%0A%23%281%202%203%29.%0A%0A%23%28%201%202%203%20%23%284%205%206%29%29%20size.%0A%0A%23%281%202%204%29%20isEmpty.%0A%0A%23%281%202%203%29%20first.%0A%0A%23%28%27hello%27%20%27Javascript%27%29%20at%3A%202%20put%3A%20%27Smalltalk%27%3B%20yourself.%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('basicTypesArray%0A%09%5E%20Lesson%0Atitle%3A%20%27Basic%20types%3A%20Array%27%20%0Acontents%3A%20%0A%27%22Literal%20arrays%20are%20created%20at%20parse%20time%3A%22%0A%0A%23%281%202%203%29.%0A%0A%23%28%201%202%203%20%23%284%205%206%29%29%20size.%0A%0A%23%281%202%204%29%20isEmpty.%0A%0A%23%281%202%203%29%20first.%0A%0A%23%28%27%27hello%27%27%20%27%27Javascript%27%27%29%20at%3A%202%20put%3A%20%27%27Smalltalk%27%27%3B%20yourself.%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesCharacters',
+smalltalk.method({
+selector: 'basicTypesCharacters',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Characters", unescape("%22A%20Character%20can%20be%20instantiated%20using%20%24%20operator%3A%22%0A%0A%24A.%0A%0A%24A%20class.%0A%0A%24B%20charCode.%0A%0ACharacter%20cr.%0A%0ACharacter%20space.%0A%0A%22You%20can%20print%20all%20256%20characters%20of%20the%20ASCII%20extended%20set%3A%22%0A%0ACharacter%20allByteCharacters.%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('basicTypesCharacters%0A%09%5E%20Lesson%0Atitle%3A%20%27Basic%20types%3A%20Characters%27%20%0Acontents%3A%20%0A%27%22A%20Character%20can%20be%20instantiated%20using%20%24%20operator%3A%22%0A%0A%24A.%0A%0A%24A%20class.%0A%0A%24B%20charCode.%0A%0ACharacter%20cr.%0A%0ACharacter%20space.%0A%0A%22You%20can%20print%20all%20256%20characters%20of%20the%20ASCII%20extended%20set%3A%22%0A%0ACharacter%20allByteCharacters.%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesDynamicArray',
+smalltalk.method({
+selector: 'basicTypesDynamicArray',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Dynamic Array", unescape("%22Dynamic%20Arrays%20are%20created%20at%20execution%20time%3A%22%0A%0A%7B%20%282+3%29%20.%20%286*6%29%20%7D.%0A%0A%7B%20%282+3%29%20.%20%286*6%29%20.%20%27hello%27%2C%20%27%20Stef%27%7D%20size.%0A%0A%0A%7B%20ProfStef%20%7D%20first%20next.")]);
+return self;},
+source: unescape('basicTypesDynamicArray%0A%09%5E%20Lesson%0Atitle%3A%20%27Basic%20types%3A%20Dynamic%20Array%27%20%0Acontents%3A%20%0A%27%22Dynamic%20Arrays%20are%20created%20at%20execution%20time%3A%22%0A%0A%7B%20%282+3%29%20.%20%286*6%29%20%7D.%0A%0A%7B%20%282+3%29%20.%20%286*6%29%20.%20%27%27hello%27%27%2C%20%27%27%20Stef%27%27%7D%20size.%0A%0A%0A%7B%20ProfStef%20%7D%20first%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesNumbers',
+smalltalk.method({
+selector: 'basicTypesNumbers',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Numbers", unescape("%22You%20now%20know%20how%20to%20execute%20Smalltalk%20code.%20%0A%0ANow%20let%27s%20talk%20about%20basic%20objects.%0A%0A1%2C%202%2C%20100%2C%202/3%20...%20are%20Numbers%2C%20and%20respond%20to%20many%20messages%20evaluating%20mathematical%20expressions.%0AEvaluate%20these%20ones%3A%22%0A%0A2.%0A%0A%281/3%29.%0A%0A%281/3%29%20+%20%284/5%29.%0A%0A%2818/5%29%20rounded.%0A%0A1%20class.%0A%0A1%20negated.%0A%0A1%20negated%20negated.%0A%0A%281%20+%203%29%20odd.%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('basicTypesNumbers%0A%09%5E%20Lesson%0Atitle%3A%20%27Basic%20types%3A%20Numbers%27%20%0Acontents%3A%20%0A%27%22You%20now%20know%20how%20to%20execute%20Smalltalk%20code.%20%0A%0ANow%20let%27%27s%20talk%20about%20basic%20objects.%0A%0A1%2C%202%2C%20100%2C%202/3%20...%20are%20Numbers%2C%20and%20respond%20to%20many%20messages%20evaluating%20mathematical%20expressions.%0AEvaluate%20these%20ones%3A%22%0A%0A2.%0A%0A%281/3%29.%0A%0A%281/3%29%20+%20%284/5%29.%0A%0A%2818/5%29%20rounded.%0A%0A1%20class.%0A%0A1%20negated.%0A%0A1%20negated%20negated.%0A%0A%281%20+%203%29%20odd.%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesString',
+smalltalk.method({
+selector: 'basicTypesString',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Strings", unescape("%22A%20String%20is%20a%20collection%20of%20characters.%20Use%20single%20quotes%20to%20create%20a%20String%20object.%20Print%20these%20expressions%3A%22%0A%0A%27ProfStef%27.%0A%0A%27ProfStef%27%20size.%0A%0A%27abc%27%20asUppercase.%0A%0A%27Hello%20World%27%20reversed.%20%0A%0A%22You%20can%20access%20each%20character%20using%20at%3A%20message%22%0A%0A%27ProfStef%27%20at%3A%201.%0A%0A%22String%20concatenation%20uses%20the%20comma%20operator%3A%22%0A%0A%27ProfStef%27%2C%20%27%20is%20cool%27.%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('basicTypesString%0A%09%5E%20Lesson%0Atitle%3A%20%27Basic%20types%3A%20Strings%27%20%0Acontents%3A%20%0A%27%22A%20String%20is%20a%20collection%20of%20characters.%20Use%20single%20quotes%20to%20create%20a%20String%20object.%20Print%20these%20expressions%3A%22%0A%0A%27%27ProfStef%27%27.%0A%0A%27%27ProfStef%27%27%20size.%0A%0A%27%27abc%27%27%20asUppercase.%0A%0A%27%27Hello%20World%27%27%20reversed.%20%0A%0A%22You%20can%20access%20each%20character%20using%20at%3A%20message%22%0A%0A%27%27ProfStef%27%27%20at%3A%201.%0A%0A%22String%20concatenation%20uses%20the%20comma%20operator%3A%22%0A%0A%27%27ProfStef%27%27%2C%20%27%27%20is%20cool%27%27.%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_basicTypesSymbol',
+smalltalk.method({
+selector: 'basicTypesSymbol',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Basic types: Symbols", unescape("%22A%20Symbol%20is%20a%20String%20which%20is%20guaranteed%20to%20be%20globally%20unique.%20%0A%0AThere%20is%20one%20and%20only%20one%20Symbol%20%23ProfStef.%20There%20may%20be%20several%20%27ProfStef%27%20String%20objects.%0A%0A%28Message%20%3D%3D%20returns%20true%20if%20the%20two%20objects%20are%20the%20SAME%29%22%0A%0A%27ProfStef%27%20asSymbol.%0A%0A%23ProfStef%20asString.%0A%0A%282%20asString%29%20%3D%3D%20%282%20asString%29.%0A%0A%282%20asString%29%20asSymbol%20%3D%3D%20%282%20asString%29%20asSymbol.%0A%0A%0A%28Smalltalk%20at%3A%20%23ProfStef%29%20next.")]);
+return self;},
+source: unescape('basicTypesSymbol%0A%09%5E%20Lesson%0Atitle%3A%20%27Basic%20types%3A%20Symbols%27%20%0Acontents%3A%20%0A%27%22A%20Symbol%20is%20a%20String%20which%20is%20guaranteed%20to%20be%20globally%20unique.%20%0A%0AThere%20is%20one%20and%20only%20one%20Symbol%20%23ProfStef.%20There%20may%20be%20several%20%27%27ProfStef%27%27%20String%20objects.%0A%0A%28Message%20%3D%3D%20returns%20true%20if%20the%20two%20objects%20are%20the%20SAME%29%22%0A%0A%27%27ProfStef%27%27%20asSymbol.%0A%0A%23ProfStef%20asString.%0A%0A%282%20asString%29%20%3D%3D%20%282%20asString%29.%0A%0A%282%20asString%29%20asSymbol%20%3D%3D%20%282%20asString%29%20asSymbol.%0A%0A%0A%28Smalltalk%20at%3A%20%23ProfStef%29%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_blocks',
+smalltalk.method({
+selector: 'blocks',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Blocks", unescape("%22Cascade%20is%20cool%20%21%20Let%27s%20talk%20about%20blocks.%0A%0ABlocks%20are%20anonymous%20methods%20that%20can%20be%20stored%20into%20variables%20and%20executed%20on%20demand.%0A%0ABlocks%20are%20delimited%20by%20square%20brackets%3A%20%5B%5D%22%0A%0A%5BTranscript%20open%5D.%0A%0A%22does%20not%20open%20a%20Transcript%20because%20the%20block%20is%20not%20executed.%0A%0AHere%20is%20a%20block%20that%20adds%202%20to%20its%20argument%20%28its%20argument%20is%20named%20x%29%3A%22%0A%0A%5B%3Ax%20%7C%20x+2%5D.%0A%0A%22We%20can%20execute%20a%20block%20by%20sending%20it%20value%20messages.%22%0A%0A%5B%3Ax%20%7C%20x+2%5D%20value%3A%205.%0A%0A%5BTranscript%20open%5D%20value.%0A%0A%5B%3Ax%20%7C%20x+2%5D%20value%3A%2010.%0A%0A%5B%3Ax%20%3Ay%7C%20x%20+%20y%5D%20value%3A3%20value%3A5.%0A%0A%5BProfStef%20next%5D%20value.")]);
+return self;},
+source: unescape('blocks%0A%09%5E%20Lesson%0Atitle%3A%20%27Blocks%27%20%0Acontents%3A%20%0A%27%22Cascade%20is%20cool%20%21%20Let%27%27s%20talk%20about%20blocks.%0A%0ABlocks%20are%20anonymous%20methods%20that%20can%20be%20stored%20into%20variables%20and%20executed%20on%20demand.%0A%0ABlocks%20are%20delimited%20by%20square%20brackets%3A%20%5B%5D%22%0A%0A%5BTranscript%20open%5D.%0A%0A%22does%20not%20open%20a%20Transcript%20because%20the%20block%20is%20not%20executed.%0A%0AHere%20is%20a%20block%20that%20adds%202%20to%20its%20argument%20%28its%20argument%20is%20named%20x%29%3A%22%0A%0A%5B%3Ax%20%7C%20x+2%5D.%0A%0A%22We%20can%20execute%20a%20block%20by%20sending%20it%20value%20messages.%22%0A%0A%5B%3Ax%20%7C%20x+2%5D%20value%3A%205.%0A%0A%5BTranscript%20open%5D%20value.%0A%0A%5B%3Ax%20%7C%20x+2%5D%20value%3A%2010.%0A%0A%5B%3Ax%20%3Ay%7C%20x%20+%20y%5D%20value%3A3%20value%3A5.%0A%0A%5BProfStef%20next%5D%20value.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_blocksAssignation',
+smalltalk.method({
+selector: 'blocksAssignation',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Block assignation", unescape("%22Blocks%20can%20be%20assigned%20to%20a%20variable%20then%20executed%20later.%0A%0ANote%20that%20%7Cb%7C%20is%20the%20declaration%20of%20a%20variable%20named%20%27b%27%20and%20that%20%27%3A%3D%27%20assigns%20a%20value%20to%20a%20variable.%0A%0ASelect%20the%20three%20lines%20then%20Print%20It%3A%22%0A%0A%7Cb%7C%0Ab%20%3A%3D%20%5B%3Ax%20%7C%20x+2%5D.%0Ab%20value%3A%2012.%0A%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('blocksAssignation%0A%09%5E%20Lesson%0Atitle%3A%20%27Block%20assignation%27%20%0Acontents%3A%20%0A%27%22Blocks%20can%20be%20assigned%20to%20a%20variable%20then%20executed%20later.%0A%0ANote%20that%20%7Cb%7C%20is%20the%20declaration%20of%20a%20variable%20named%20%27%27b%27%27%20and%20that%20%27%27%3A%3D%27%27%20assigns%20a%20value%20to%20a%20variable.%0A%0ASelect%20the%20three%20lines%20then%20Print%20It%3A%22%0A%0A%7Cb%7C%0Ab%20%3A%3D%20%5B%3Ax%20%7C%20x+2%5D.%0Ab%20value%3A%2012.%0A%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_conditionals',
+smalltalk.method({
+selector: 'conditionals',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Conditionals", unescape("%22Conditionals%20are%20just%20messages%20sent%20to%20Boolean%20objects%22%0A%0A1%20%3C%202%0A%20%20ifTrue%3A%20%5B100%5D%0A%20%20ifFalse%3A%20%5B42%5D.%0A%0A%22Here%20the%20message%20is%20ifTrue%3AifFalse%0A%0ATry%20this%3A%22%0A%0ATranscript%20open.%0A%0A3%20%3E%2010%20%0A%09ifTrue%3A%20%5BTranscript%20show%3A%20%27maybe%20there%27%27s%20a%20bug%20....%27%5D%0A%09ifFalse%3A%20%5BTranscript%20show%3A%20%27No%20%3A%203%20is%20less%20than%2010%27%5D.%0A%0A3%20%3D%203%20ifTrue%3A%20%5BProfStef%20next%5D.")]);
+return self;},
+source: unescape('conditionals%0A%09%5E%20Lesson%0Atitle%3A%20%27Conditionals%27%20%0Acontents%3A%20%0A%27%22Conditionals%20are%20just%20messages%20sent%20to%20Boolean%20objects%22%0A%0A1%20%3C%202%0A%20%20ifTrue%3A%20%5B100%5D%0A%20%20ifFalse%3A%20%5B42%5D.%0A%0A%22Here%20the%20message%20is%20ifTrue%3AifFalse%0A%0ATry%20this%3A%22%0A%0ATranscript%20open.%0A%0A3%20%3E%2010%20%0A%09ifTrue%3A%20%5BTranscript%20show%3A%20%27%27maybe%20there%27%27%27%27s%20a%20bug%20....%27%27%5D%0A%09ifFalse%3A%20%5BTranscript%20show%3A%20%27%27No%20%3A%203%20is%20less%20than%2010%27%27%5D.%0A%0A3%20%3D%203%20ifTrue%3A%20%5BProfStef%20next%5D.%27.'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_debugger',
+smalltalk.method({
+selector: 'debugger',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Debugger", unescape("%22The%20Debugger%20may%20be%20the%20most%20famous%20tool%20of%20Smalltalk%20environments.%20It%20will%20open%20as%20soon%20as%20an%20unmanaged%20Exception%20occurs.%20%0A%0AThe%20following%20code%20will%20open%20the%20debugger.%0A%0A***This%20should%20be%20rethought%20completely***%22%0A%0A%0A%20")]);
+return self;},
+source: unescape('debugger%0A%09%5E%20Lesson%0Atitle%3A%20%27Debugger%27%20%0Acontents%3A%20%27%22The%20Debugger%20may%20be%20the%20most%20famous%20tool%20of%20Smalltalk%20environments.%20It%20will%20open%20as%20soon%20as%20an%20unmanaged%20Exception%20occurs.%20%0A%0AThe%20following%20code%20will%20open%20the%20debugger.%0A%0A***This%20should%20be%20rethought%20completely***%22%0A%0A%0A%20%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_doingVSPrinting',
+smalltalk.method({
+selector: 'doingVSPrinting',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Doing VS Printing: Doing", unescape("%22Cool%20%21%20%28I%20like%20to%20say%20Cooool%20%3A%29%20%29.%20You%27ve%20just%20executed%20a%20Smalltalk%20expression.%20More%20precisely%2C%20you%20sent%20the%20message%20%27next%27%20to%0AProfStef%20class%20%28it%27s%20me%20%21%29.%0A%0ANote%20you%20can%20run%20this%20tutorial%20again%20by%20evaluating%3A%20%27ProfStef%20go%27.%20%0A%27ProfStef%20previous%27%20returns%20to%20the%20previous%20lesson.%0A%0AYou%20can%20also%20Do%20It%20using%20the%20keyboard%20shortcut%20%27CTRL%20d%27%0A%0ATry%20to%20evaluate%20this%20expression%3A%22%0A%0Awindow%20alert%3A%20%27hello%20world%21%27.%0A%0A%22Then%20go%20to%20the%20next%20lesson%3A%22%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('doingVSPrinting%20%0A%09%5E%20Lesson%0Atitle%3A%20%27Doing%20VS%20Printing%3A%20Doing%27%20%0Acontents%3A%20%0A%27%22Cool%20%21%20%28I%20like%20to%20say%20Cooool%20%3A%29%20%29.%20You%27%27ve%20just%20executed%20a%20Smalltalk%20expression.%20More%20precisely%2C%20you%20sent%20the%20message%20%27%27next%27%27%20to%0AProfStef%20class%20%28it%27%27s%20me%20%21%29.%0A%0ANote%20you%20can%20run%20this%20tutorial%20again%20by%20evaluating%3A%20%27%27ProfStef%20go%27%27.%20%0A%27%27ProfStef%20previous%27%27%20returns%20to%20the%20previous%20lesson.%0A%0AYou%20can%20also%20Do%20It%20using%20the%20keyboard%20shortcut%20%27%27CTRL%20d%27%27%0A%0ATry%20to%20evaluate%20this%20expression%3A%22%0A%0Awindow%20alert%3A%20%27%27hello%20world%21%27%27.%0A%0A%22Then%20go%20to%20the%20next%20lesson%3A%22%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_instanciation',
+smalltalk.method({
+selector: 'instanciation',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Instanciation", unescape("%22Objects%20are%20instances%20of%20their%20class.%20Usually%2C%20we%20send%20the%20message%20%23new%20to%20a%20class%20for%20creating%20an%20instance%20of%20this%20class.%0A%0AFor%20example%2C%20let%27s%20create%20an%20instance%20of%20the%20class%20Array%3A%22%0A%0AArray%20new%0A%09add%3A%20%27Some%20text%27%3B%0A%09add%3A%203.%3B%0A%09yourself.%0A%0A%22See%20the%20array%20we%27ve%20created%3F%20Actually%2C%20%23%28%27Some%20text%27%203%29%20is%20just%20a%20shorthand%20for%20instantiating%20arrays.%22%0A%0A%22If%20we%20use%20a%20variable%20to%20keep%20track%20of%20this%20object%2C%20we%27ll%20be%20able%20to%20do%20stuff%20with%20it.%22%0A%0A%22The%20following%20code%20must%20be%20ran%20all%20at%20one%2C%20as%20the%20%27anArray%27%20variable%20will%20cease%20to%20exist%20once%20the%20execution%20finishes%3A%22%0A%0A%7CanArray%7C%0A%0AanArray%20%3A%3D%20Array%20new%0A%09add%3A%20%27Some%20text%27%3B%0A%09add%3A%203%3B%0A%09yourself%3B%0A%0ATranscript%20show%3A%20anArray%3B%20cr.%0A%0AanArray%20remove%3A%203.%0A%0ATranscript%20show%3A%20anArray%3B%20cr.%0A%0AanArray%20add%3A%20%27Some%20more%20text%21%27.%0A%0ATranscript%20show%3A%20anArray%3B%20cr.%0A%09%0A%22I%27ll%20put%20myself%20in%20an%20instance%20of%20a%20class%20named%20Dictionary%20and%20go%20to%20the%20next%20lesson%3A%22%0A%0A%28%28Dictionary%20new%20add%3A%20%28%27move%20on%21%27%20-%3E%20ProfStef%29%29%20at%3A%20%27move%20on%21%27%29%20next")]);
+return self;},
+source: unescape('instanciation%0A%09%5E%20Lesson%0Atitle%3A%20%27Instanciation%27%20%0Acontents%3A%20%0A%27%22Objects%20are%20instances%20of%20their%20class.%20Usually%2C%20we%20send%20the%20message%20%23new%20to%20a%20class%20for%20creating%20an%20instance%20of%20this%20class.%0A%0AFor%20example%2C%20let%27%27s%20create%20an%20instance%20of%20the%20class%20Array%3A%22%0A%0AArray%20new%0A%09add%3A%20%27%27Some%20text%27%27%3B%0A%09add%3A%203.%3B%0A%09yourself.%0A%0A%22See%20the%20array%20we%27%27ve%20created%3F%20Actually%2C%20%23%28%27%27Some%20text%27%27%203%29%20is%20just%20a%20shorthand%20for%20instantiating%20arrays.%22%0A%0A%22If%20we%20use%20a%20variable%20to%20keep%20track%20of%20this%20object%2C%20we%27%27ll%20be%20able%20to%20do%20stuff%20with%20it.%22%0A%0A%22The%20following%20code%20must%20be%20ran%20all%20at%20one%2C%20as%20the%20%27%27anArray%27%27%20variable%20will%20cease%20to%20exist%20once%20the%20execution%20finishes%3A%22%0A%0A%7CanArray%7C%0A%0AanArray%20%3A%3D%20Array%20new%0A%09add%3A%20%27%27Some%20text%27%27%3B%0A%09add%3A%203%3B%0A%09yourself%3B%0A%0ATranscript%20show%3A%20anArray%3B%20cr.%0A%0AanArray%20remove%3A%203.%0A%0ATranscript%20show%3A%20anArray%3B%20cr.%0A%0AanArray%20add%3A%20%27%27Some%20more%20text%21%27%27.%0A%0ATranscript%20show%3A%20anArray%3B%20cr.%0A%09%0A%22I%27%27ll%20put%20myself%20in%20an%20instance%20of%20a%20class%20named%20Dictionary%20and%20go%20to%20the%20next%20lesson%3A%22%0A%0A%28%28Dictionary%20new%20add%3A%20%28%27%27move%20on%21%27%27%20-%3E%20ProfStef%29%29%20at%3A%20%27%27move%20on%21%27%27%29%20next%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_iterators',
+smalltalk.method({
+selector: 'iterators',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Iterators", unescape("%22The%20message%20do%3A%20is%20sent%20to%20a%20collection%20of%20objects%20%28Array%2C%20Dictionary%2C%20String%2C%20etc%29%2C%20evaluating%20the%20block%20for%20each%20element.%0A%0AHere%20we%20want%20to%20print%20all%20the%20numbers%20on%20the%20Transcript%20%28a%20console%29%22%0A%0A%23%2811%2038%203%20-2%2010%29%20do%3A%20%5B%3Aeach%20%7C%0A%20%20%20%20%20Transcript%20show%3A%20each%20printString%3B%20cr%5D.%0A%0A%22Some%20other%20really%20nice%20iterators%22%0A%0A%23%2811%2038%203%20-2%2010%29%20collect%3A%20%5B%3Aeach%20%7C%20each%20negated%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20collect%3A%20%5B%3Aeach%20%7C%20each%20odd%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20select%3A%20%5B%3Aeach%20%7C%20each%20odd%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20select%3A%20%5B%3Aeach%20%7C%20each%20%3E%2010%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20reject%3A%20%5B%3Aeach%20%7C%20each%20%3E%2010%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20%0A%20%20%20%20%20do%3A%20%5B%3Aeach%20%7C%20Transcript%20show%3A%20each%20printString%5D%0A%20%20%20%20%20separatedBy%3A%20%5BTranscript%20show%3A%20%27.%27%5D.%0A%0A%0A%28Smalltalk%20current%20classes%20select%3A%20%5B%3AeachClass%20%7C%20eachClass%20name%20%3D%20%27ProfStef%27%5D%29%20do%3A%20%5B%3AeachProfstef%20%7C%20eachProfstef%20next%5D.")]);
+return self;},
+source: unescape('iterators%0A%09%5E%20Lesson%0Atitle%3A%20%27Iterators%27%20%0Acontents%3A%20%0A%27%22The%20message%20do%3A%20is%20sent%20to%20a%20collection%20of%20objects%20%28Array%2C%20Dictionary%2C%20String%2C%20etc%29%2C%20evaluating%20the%20block%20for%20each%20element.%0A%0AHere%20we%20want%20to%20print%20all%20the%20numbers%20on%20the%20Transcript%20%28a%20console%29%22%0A%0A%23%2811%2038%203%20-2%2010%29%20do%3A%20%5B%3Aeach%20%7C%0A%20%20%20%20%20Transcript%20show%3A%20each%20printString%3B%20cr%5D.%0A%0A%22Some%20other%20really%20nice%20iterators%22%0A%0A%23%2811%2038%203%20-2%2010%29%20collect%3A%20%5B%3Aeach%20%7C%20each%20negated%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20collect%3A%20%5B%3Aeach%20%7C%20each%20odd%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20select%3A%20%5B%3Aeach%20%7C%20each%20odd%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20select%3A%20%5B%3Aeach%20%7C%20each%20%3E%2010%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20reject%3A%20%5B%3Aeach%20%7C%20each%20%3E%2010%5D.%0A%0A%23%2811%2038%203%20-2%2010%29%20%0A%20%20%20%20%20do%3A%20%5B%3Aeach%20%7C%20Transcript%20show%3A%20each%20printString%5D%0A%20%20%20%20%20separatedBy%3A%20%5BTranscript%20show%3A%20%27%27.%27%27%5D.%0A%0A%0A%28Smalltalk%20current%20classes%20select%3A%20%5B%3AeachClass%20%7C%20eachClass%20name%20%3D%20%27%27ProfStef%27%27%5D%29%20do%3A%20%5B%3AeachProfstef%20%7C%20eachProfstef%20next%5D.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_loops',
+smalltalk.method({
+selector: 'loops',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Loops", unescape("%22Loops%20are%20high-level%20collection%20iterators%2C%20implemented%20as%20regular%20methods.%22%0A%0A%22Basic%20loops%3A%0A%20%20to%3Ado%3A%0A%20%20to%3Aby%3Ado%22%0A%0A1%20to%3A%20100%20do%3A%0A%20%20%5B%3Ai%20%7C%20Transcript%20show%3A%20i%20asString%3B%20cr%20%5D.%0A%0A1%20to%3A%20100%20by%3A%203%20do%3A%20%5B%3Ai%20%7C%20Transcript%20show%3A%20i%20asString%3B%20cr%5D.%0A%0A100%20to%3A%200%20by%3A%20-2%20do%3A%20%0A%20%20%20%20%5B%3Ai%20%7C%20Transcript%20show%3A%20i%20asString%3B%20cr%5D.%0A%0A1%20to%3A%201%20do%3A%20%5B%3Ai%20%7C%20ProfStef%20next%5D.")]);
+return self;},
+source: unescape('loops%0A%09%5E%20Lesson%0Atitle%3A%20%27Loops%27%20%0Acontents%3A%20%0A%27%22Loops%20are%20high-level%20collection%20iterators%2C%20implemented%20as%20regular%20methods.%22%0A%0A%22Basic%20loops%3A%0A%20%20to%3Ado%3A%0A%20%20to%3Aby%3Ado%22%0A%0A1%20to%3A%20100%20do%3A%0A%20%20%5B%3Ai%20%7C%20Transcript%20show%3A%20i%20asString%3B%20cr%20%5D.%0A%0A1%20to%3A%20100%20by%3A%203%20do%3A%20%5B%3Ai%20%7C%20Transcript%20show%3A%20i%20asString%3B%20cr%5D.%0A%0A100%20to%3A%200%20by%3A%20-2%20do%3A%20%0A%20%20%20%20%5B%3Ai%20%7C%20Transcript%20show%3A%20i%20asString%3B%20cr%5D.%0A%0A1%20to%3A%201%20do%3A%20%5B%3Ai%20%7C%20ProfStef%20next%5D.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_mathematicalPrecedence',
+smalltalk.method({
+selector: 'mathematicalPrecedence',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Mathematical precedence", unescape("%22Traditional%20precedence%20rules%20from%20mathematics%20do%20not%20follow%20in%20Smalltalk.%22%0A%0A2%20*%2010%20+%202.%0A%0A%22Here%20the%20message%20*%20is%20sent%20to%202%2C%20which%20answers%2020%2C%20then%2020%20receive%20the%20message%20+%0A%0ARemember%20that%20all%20messages%20always%20follow%20a%20simple%20left-to-right%20precedence%20rule%2C%20*%20without%20exceptions%20*.%22%0A%0A2%20+%202%20*%2010.%0A%0A2%20+%20%282%20*%2010%29.%0A%0A8%20-%205%20/%202.%0A%0A%288%20-%205%29%20/%202.%0A%0A8%20-%20%285%20/%202%29.%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('mathematicalPrecedence%0A%09%5E%20Lesson%0Atitle%3A%20%27Mathematical%20precedence%27%0Acontents%3A%20%0A%27%22Traditional%20precedence%20rules%20from%20mathematics%20do%20not%20follow%20in%20Smalltalk.%22%0A%0A2%20*%2010%20+%202.%0A%0A%22Here%20the%20message%20*%20is%20sent%20to%202%2C%20which%20answers%2020%2C%20then%2020%20receive%20the%20message%20+%0A%0ARemember%20that%20all%20messages%20always%20follow%20a%20simple%20left-to-right%20precedence%20rule%2C%20*%20without%20exceptions%20*.%22%0A%0A2%20+%202%20*%2010.%0A%0A2%20+%20%282%20*%2010%29.%0A%0A8%20-%205%20/%202.%0A%0A%288%20-%205%29%20/%202.%0A%0A8%20-%20%285%20/%202%29.%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxBinary',
+smalltalk.method({
+selector: 'messageSyntaxBinary',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Binary messages", unescape("%22Binary%20messages%20have%20the%20following%20form%3A%0A%20%20%20%20anObject%20+%20anotherObject%22%0A%0A3%20*%202.%0A%0ADate%20today%20year%20%3D%202011.%0A%0Afalse%20%7C%20false.%0A%0Atrue%20%26%20true.%0A%0Atrue%20%26%20false.%0A%0A10%20@%20100.%0A%0A10%20%3C%3D%2012.%0A%0A%27ab%27%2C%20%27cd%27.%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('messageSyntaxBinary%0A%09%5E%20Lesson%0Atitle%3A%20%27Message%20syntax%3A%20Binary%20messages%27%20%0Acontents%3A%20%0A%27%22Binary%20messages%20have%20the%20following%20form%3A%0A%20%20%20%20anObject%20+%20anotherObject%22%0A%0A3%20*%202.%0A%0ADate%20today%20year%20%3D%202011.%0A%0Afalse%20%7C%20false.%0A%0Atrue%20%26%20true.%0A%0Atrue%20%26%20false.%0A%0A10%20@%20100.%0A%0A10%20%3C%3D%2012.%0A%0A%27%27ab%27%27%2C%20%27%27cd%27%27.%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxCascade',
+smalltalk.method({
+selector: 'messageSyntaxCascade',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Cascade", unescape("%22%3B%20is%20the%20cascade%20operator.%20It%27s%20useful%20to%20send%20message%20to%20the%20SAME%20receiver%0AOpen%20a%20Transcript%20%28console%29%3A%22%0A%0ATranscript%20open.%0A%0A%22Then%3A%22%0A%0ATranscript%20show%3A%20%27hello%27.%0ATranscript%20show%3A%20%27Smalltalk%27.%0ATranscript%20cr.%0A%0A%22is%20equivalent%20to%3A%22%0A%0ATranscript%20%0A%09%20%20%20show%3A%20%27hello%27%3B%0A%09%20%20%20show%3A%20%27Smalltalk%27%20%3B%0A%09%20%20%20cr.%0A%0A%22You%20can%20close%20the%20development%20tools%20by%20clicking%20on%20the%20red%20circle%20with%20a%20cross%20at%20the%20bottom%20left%20of%20the%20website.%0ATry%20to%20go%20to%20the%20next%20lesson%20with%20a%20cascade%20of%20two%20%27next%27%20messages%3A%22%0A%0AProfStef")]);
+return self;},
+source: unescape('messageSyntaxCascade%0A%09%5E%20Lesson%0Atitle%3A%20%27Message%20syntax%3A%20Cascade%27%20%0Acontents%3A%20%0A%27%22%3B%20is%20the%20cascade%20operator.%20It%27%27s%20useful%20to%20send%20message%20to%20the%20SAME%20receiver%0AOpen%20a%20Transcript%20%28console%29%3A%22%0A%0ATranscript%20open.%0A%0A%22Then%3A%22%0A%0ATranscript%20show%3A%20%27%27hello%27%27.%0ATranscript%20show%3A%20%27%27Smalltalk%27%27.%0ATranscript%20cr.%0A%0A%22is%20equivalent%20to%3A%22%0A%0ATranscript%20%0A%09%20%20%20show%3A%20%27%27hello%27%27%3B%0A%09%20%20%20show%3A%20%27%27Smalltalk%27%27%20%3B%0A%09%20%20%20cr.%0A%0A%22You%20can%20close%20the%20development%20tools%20by%20clicking%20on%20the%20red%20circle%20with%20a%20cross%20at%20the%20bottom%20left%20of%20the%20website.%0ATry%20to%20go%20to%20the%20next%20lesson%20with%20a%20cascade%20of%20two%20%27%27next%27%27%20messages%3A%22%0A%0AProfStef%27.'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxCascadeShouldNotBeHere',
+smalltalk.method({
+selector: 'messageSyntaxCascadeShouldNotBeHere',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", [unescape("Lost%20%3F"), unescape("%22Hey%2C%20you%20should%20not%20be%20here%20%21%21%20%0A%0AGo%20back%20and%20use%20a%20cascade%20%21%22%0A%0AProfStef%20previous.")]);
+return self;},
+source: unescape('messageSyntaxCascadeShouldNotBeHere%0A%09%5E%20Lesson%0Atitle%3A%20%27Lost%20%3F%27%20%0Acontents%3A%20%0A%27%22Hey%2C%20you%20should%20not%20be%20here%20%21%21%20%0A%0AGo%20back%20and%20use%20a%20cascade%20%21%22%0A%0AProfStef%20previous.%27.'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxExecutionOrder',
+smalltalk.method({
+selector: 'messageSyntaxExecutionOrder',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Execution order", unescape("%22Unary%20messages%20are%20executed%20first%2C%20then%20binary%20messages%20and%20finally%20keyword%20messages%3A%0A%20%20%20%20Unary%20%3E%20Binary%20%3E%20Keywords%22%0A%0A2.5%20+%203.8%20rounded.%0A%0A3%20max%3A%202%20+%202.%0A%20%20%0A%280@0%29%20class.%0A%0A0@0%20x%3A%20100.%0A%0A%280@0%20x%3A%20100%29%20class.%0A%0A%22Between%20messages%20of%20similar%20precedence%2C%20expressions%20are%20executed%20from%20left%20to%20right%22%0A%0A-12345%20negated%20asString%20reversed.%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('messageSyntaxExecutionOrder%0A%09%5E%20Lesson%0Atitle%3A%20%27Message%20syntax%3A%20Execution%20order%27%20%0Acontents%3A%20%0A%27%22Unary%20messages%20are%20executed%20first%2C%20then%20binary%20messages%20and%20finally%20keyword%20messages%3A%0A%20%20%20%20Unary%20%3E%20Binary%20%3E%20Keywords%22%0A%0A2.5%20+%203.8%20rounded.%0A%0A3%20max%3A%202%20+%202.%0A%20%20%0A%280@0%29%20class.%0A%0A0@0%20x%3A%20100.%0A%0A%280@0%20x%3A%20100%29%20class.%0A%0A%22Between%20messages%20of%20similar%20precedence%2C%20expressions%20are%20executed%20from%20left%20to%20right%22%0A%0A-12345%20negated%20asString%20reversed.%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxExecutionOrderParentheses',
+smalltalk.method({
+selector: 'messageSyntaxExecutionOrderParentheses',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Parentheses", unescape("%22Use%20parentheses%20to%20change%20order%20of%20evaluation%22%0A%0A%282.5%20+%203.8%29%20rounded.%0A%0A%283%20max%3A%202%29%20+%202.%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('messageSyntaxExecutionOrderParentheses%0A%09%5E%20Lesson%0Atitle%3A%20%27Message%20syntax%3A%20Parentheses%27%0Acontents%3A%20%0A%27%22Use%20parentheses%20to%20change%20order%20of%20evaluation%22%0A%0A%282.5%20+%203.8%29%20rounded.%0A%0A%283%20max%3A%202%29%20+%202.%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxKeyword',
+smalltalk.method({
+selector: 'messageSyntaxKeyword',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Keyword messages", unescape("%22Keyword%20Messages%20are%20messages%20with%20arguments.%20They%20have%20the%20following%20form%3A%0A%20%20%20%20anObject%20akey%3A%20anotherObject%20akey2%3A%20anotherObject2%22%0A%0A%27Web%20development%20is%20a%20good%20deal%20of%20pain%27%20copyFrom%3A%201%20to%3A%2030%0A%0A%22The%20message%20is%20copyFrom%3Ato%3A%20sent%20to%20the%20String%20%27Web%20development%20is%20a%20good%20deal%20of%20pain%27%22%0A%0A1%20max%3A%203.%0A%0AArray%20with%3A%20%27hello%27%20with%3A%202%20with%3A%20Smalltalk.%0A%0A%22The%20message%20is%20with%3Awith%3Awith%3A%20implemented%20on%20class%20Array.%20Note%20you%20can%20also%20write%22%0A%0AArray%0A%09with%3A%20%27Hi%20there%21%27%0A%09with%3A%202%0A%09with%3A%20Smalltalk.%0A%09%0AProfStef%20perform%3A%20%27next%27.")]);
+return self;},
+source: unescape('messageSyntaxKeyword%0A%09%5E%20Lesson%0Atitle%3A%20%27Message%20syntax%3A%20Keyword%20messages%27%20%0Acontents%3A%20%0A%27%22Keyword%20Messages%20are%20messages%20with%20arguments.%20They%20have%20the%20following%20form%3A%0A%20%20%20%20anObject%20akey%3A%20anotherObject%20akey2%3A%20anotherObject2%22%0A%0A%27%27Web%20development%20is%20a%20good%20deal%20of%20pain%27%27%20copyFrom%3A%201%20to%3A%2030%0A%0A%22The%20message%20is%20copyFrom%3Ato%3A%20sent%20to%20the%20String%20%27%27Web%20development%20is%20a%20good%20deal%20of%20pain%27%27%22%0A%0A1%20max%3A%203.%0A%0AArray%20with%3A%20%27%27hello%27%27%20with%3A%202%20with%3A%20Smalltalk.%0A%0A%22The%20message%20is%20with%3Awith%3Awith%3A%20implemented%20on%20class%20Array.%20Note%20you%20can%20also%20write%22%0A%0AArray%0A%09with%3A%20%27%27Hi%20there%21%27%27%0A%09with%3A%202%0A%09with%3A%20Smalltalk.%0A%09%0AProfStef%20perform%3A%20%27%27next%27%27.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_messageSyntaxUnary',
+smalltalk.method({
+selector: 'messageSyntaxUnary',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Message syntax: Unary messages", unescape("%22Messages%20are%20sent%20to%20objects.%20There%20are%20three%20types%20of%20message%3A%20Unary%2C%20Binary%20and%20Keyword.%0A%0AUnary%20messages%20have%20the%20following%20form%3A%0A%20%20%20%20anObject%20aMessage%20%0A%0AYou%27ve%20already%20sent%20unary%20messages.%20For%20example%3A%22%0A%0A1%20class.%0A%0Afalse%20not.%0A%0ADate%20today.%0A%0ANumber%20pi.%0A%0A%22And%20of%20course%3A%20%22%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('messageSyntaxUnary%0A%09%5E%20Lesson%0Atitle%3A%20%27Message%20syntax%3A%20Unary%20messages%27%20%0Acontents%3A%20%0A%27%22Messages%20are%20sent%20to%20objects.%20There%20are%20three%20types%20of%20message%3A%20Unary%2C%20Binary%20and%20Keyword.%0A%0AUnary%20messages%20have%20the%20following%20form%3A%0A%20%20%20%20anObject%20aMessage%20%0A%0AYou%27%27ve%20already%20sent%20unary%20messages.%20For%20example%3A%22%0A%0A1%20class.%0A%0Afalse%20not.%0A%0ADate%20today.%0A%0ANumber%20pi.%0A%0A%22And%20of%20course%3A%20%22%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_pharoEnvironment',
+smalltalk.method({
+selector: 'pharoEnvironment',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Pharo environment", unescape("%22Every%20Smalltalk%20system%20is%20full%20of%20objects.%20There%20are%20windows%2C%20text%2C%20numbers%2C%20dates%2C%20colors%2C%20points%20and%20much%20more.%20You%20can%20interact%20with%20objects%20in%20a%20much%20more%20direct%20way%20than%20is%20possible%20with%20other%20programming%20languages.%0A%0AEvery%20object%20understands%20the%20message%20%27explore%27.%20As%20a%20result%2C%20you%20get%20an%20Explorer%20window%20that%20shows%20details%20about%20the%20object.%22%0A%0ADate%20today%20explore.%0A%0A%22This%20shows%20that%20the%20date%20object%20consists%20of%20a%20point%20in%20time%20%28start%29%20and%20a%20duration%20%28one%20day%20long%29.%22%0A%0AProfStef%20explore.%0A%0A%22You%20see%2C%20ProfStef%20class%20has%20a%20lot%20of%20objects.%20Let%27s%20take%20a%20look%20at%20my%20code%3A%22%0A%0AProfStef%20browse.%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('pharoEnvironment%0A%09%5E%20Lesson%0Atitle%3A%20%27Pharo%20environment%27%20%0Acontents%3A%20%0A%27%22Every%20Smalltalk%20system%20is%20full%20of%20objects.%20There%20are%20windows%2C%20text%2C%20numbers%2C%20dates%2C%20colors%2C%20points%20and%20much%20more.%20You%20can%20interact%20with%20objects%20in%20a%20much%20more%20direct%20way%20than%20is%20possible%20with%20other%20programming%20languages.%0A%0AEvery%20object%20understands%20the%20message%20%27%27explore%27%27.%20As%20a%20result%2C%20you%20get%20an%20Explorer%20window%20that%20shows%20details%20about%20the%20object.%22%0A%0ADate%20today%20explore.%0A%0A%22This%20shows%20that%20the%20date%20object%20consists%20of%20a%20point%20in%20time%20%28start%29%20and%20a%20duration%20%28one%20day%20long%29.%22%0A%0AProfStef%20explore.%0A%0A%22You%20see%2C%20ProfStef%20class%20has%20a%20lot%20of%20objects.%20Let%27%27s%20take%20a%20look%20at%20my%20code%3A%22%0A%0AProfStef%20browse.%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_printing',
+smalltalk.method({
+selector: 'printing',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Doing VS Printing: Printing", unescape("%22Now%20you%27re%20a%20Do%20It%20master%20%21%20Let%27s%20talk%20about%20printing.%20It%27s%20a%20Do%20It%20which%20prints%20the%20result%20next%20to%20the%20expression%20you%27ve%20selected.%0AFor%20example%2C%20select%20the%20text%20below%2C%20and%20click%20on%20%27PrintIt%27%3A%22%0A%0A1%20+%202.%0A%0A%22As%20with%20%27DoIt%27%2C%20there%20is%20also%20a%20shortcut%20to%20execute%20this%20command.%0A%0ATry%20CTRL-p%20on%20the%20following%20expressions%3A%22%0A%0ADate%20today.%0A%0A%22The%20result%20is%20selected%2C%20so%20you%20can%20erase%20it%20using%20the%20backspace%20key.%20Try%20it%20%21%22%0A%0ADate%20today%20asDateString.%0A%0ADate%20today%20asTimeString.%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('printing%20%0A%09%5E%20Lesson%0Atitle%3A%20%27Doing%20VS%20Printing%3A%20Printing%27%20%0Acontents%3A%20%0A%27%22Now%20you%27%27re%20a%20Do%20It%20master%20%21%20Let%27%27s%20talk%20about%20printing.%20It%27%27s%20a%20Do%20It%20which%20prints%20the%20result%20next%20to%20the%20expression%20you%27%27ve%20selected.%0AFor%20example%2C%20select%20the%20text%20below%2C%20and%20click%20on%20%27%27PrintIt%27%27%3A%22%0A%0A1%20+%202.%0A%0A%22As%20with%20%27%27DoIt%27%27%2C%20there%20is%20also%20a%20shortcut%20to%20execute%20this%20command.%0A%0ATry%20CTRL-p%20on%20the%20following%20expressions%3A%22%0A%0ADate%20today.%0A%0A%22The%20result%20is%20selected%2C%20so%20you%20can%20erase%20it%20using%20the%20backspace%20key.%20Try%20it%20%21%22%0A%0ADate%20today%20asDateString.%0A%0ADate%20today%20asTimeString.%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_reflection',
+smalltalk.method({
+selector: 'reflection',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Reflection", unescape("%22You%20can%20inspect%20and%20change%20the%20system%20at%20runtime.%0A%0ATake%20a%20look%20at%20the%20source%20code%20of%20the%20method%20%23and%3A%20of%20the%20class%20Boolean%3A%22%0A%0A%28Boolean%20methodDictionary%20at%3A%20%27and%3A%27%29%20source.%0A%0A%22Or%20all%20the%20methods%20it%20sends%3A%22%0A%0A%28Boolean%20methodDictionary%20at%3A%20%27and%3A%27%29%20messageSends.%0A%0A%22Here%27s%20all%20the%20methods%20I%20implement%3A%22%0A%0AProfStef%20methodDictionary.%0A%0A%22Let%27s%20create%20a%20new%20method%20to%20go%20to%20the%20next%20lesson%3A%22%0A%0A%7CnewMethod%7C%0AnewMethod%20%3A%3D%20Compiler%20new%20load%3A%20%27goToNextLesson%20ProfStef%20next.%27%20forClass%3A%20ProfStef.%0AProfStef%20class%20addCompiledMethod%3A%20newMethod%0A%0A%22Wow%21%20I%20can%27t%20wait%20to%20use%20my%20new%20method%21%22%0A%0AProfStef%20goToNextLesson.")]);
+return self;},
+source: unescape('reflection%0A%09%5E%20Lesson%0Atitle%3A%20%27Reflection%27%20%0Acontents%3A%20%0A%27%22You%20can%20inspect%20and%20change%20the%20system%20at%20runtime.%0A%0ATake%20a%20look%20at%20the%20source%20code%20of%20the%20method%20%23and%3A%20of%20the%20class%20Boolean%3A%22%0A%0A%28Boolean%20methodDictionary%20at%3A%20%27%27and%3A%27%27%29%20source.%0A%0A%22Or%20all%20the%20methods%20it%20sends%3A%22%0A%0A%28Boolean%20methodDictionary%20at%3A%20%27%27and%3A%27%27%29%20messageSends.%0A%0A%22Here%27%27s%20all%20the%20methods%20I%20implement%3A%22%0A%0AProfStef%20methodDictionary.%0A%0A%22Let%27%27s%20create%20a%20new%20method%20to%20go%20to%20the%20next%20lesson%3A%22%0A%0A%7CnewMethod%7C%0AnewMethod%20%3A%3D%20Compiler%20new%20load%3A%20%27%27goToNextLesson%20ProfStef%20next.%27%27%20forClass%3A%20ProfStef.%0AProfStef%20class%20addCompiledMethod%3A%20newMethod%0A%0A%22Wow%21%20I%20can%27%27t%20wait%20to%20use%20my%20new%20method%21%22%0A%0AProfStef%20goToNextLesson.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_reflectionContinued',
+smalltalk.method({
+selector: 'reflectionContinued',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Reflection continued", unescape("%22So%20cool%2C%20isn%27t%20it%20%3F%20%20Before%20going%20further%2C%20let%27s%20remove%20this%20method%3A%22%0A%0AProfStef%20class%20methodAt%3A%20%23goToNextLesson.%0A%0AProfStef%20class%20removeCompiledMethod%3A%20%28ProfStef%20class%20methodAt%3A%20%23goToNextLesson%29.%0A%0AProfStef%20class%20methodAt%3A%20%23goToNextLesson.%0A%0A%0A%22Then%20move%20forward%3A%22%0A%0AProfStef%20perform%3A%23next")]);
+return self;},
+source: unescape('reflectionContinued%0A%09%5E%20Lesson%0Atitle%3A%20%27Reflection%20continued%27%20%0Acontents%3A%20%0A%27%22So%20cool%2C%20isn%27%27t%20it%20%3F%20%20Before%20going%20further%2C%20let%27%27s%20remove%20this%20method%3A%22%0A%0AProfStef%20class%20methodAt%3A%20%23goToNextLesson.%0A%0AProfStef%20class%20removeCompiledMethod%3A%20%28ProfStef%20class%20methodAt%3A%20%23goToNextLesson%29.%0A%0AProfStef%20class%20methodAt%3A%20%23goToNextLesson.%0A%0A%0A%22Then%20move%20forward%3A%22%0A%0AProfStef%20perform%3A%23next%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_theEnd',
+smalltalk.method({
+selector: 'theEnd',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", [unescape("Tutorial%20done%20%21"), unescape("%22This%20tutorial%20is%20done.%20Enjoy%20programming%20Smalltalk%20with%20JTalk.%20%0A%0AYou%20can%20run%20this%20tutorial%20again%20by%20evaluating%3A%20ProfStef%20go.%0A%0ASee%20you%20soon%20%21%22%0A")]);
+return self;},
+source: unescape('theEnd%0A%09%5E%20Lesson%0Atitle%3A%20%27Tutorial%20done%20%21%27%20%0Acontents%3A%20%0A%27%22This%20tutorial%20is%20done.%20Enjoy%20programming%20Smalltalk%20with%20JTalk.%20%0A%0AYou%20can%20run%20this%20tutorial%20again%20by%20evaluating%3A%20ProfStef%20go.%0A%0ASee%20you%20soon%20%21%22%0A%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+smalltalk.addMethod(
+'_welcome',
+smalltalk.method({
+selector: 'welcome',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.Lesson || Lesson), "_title_contents_", ["Welcome", unescape("%20%22Hello%21%20I%27m%20Professor%20Stef.%20%0A%0AYou%20must%20want%20me%20to%20help%20you%20learn%20Smalltalk.%0A%0ASo%20let%27s%20go%20to%20the%20first%20lesson.%20%20Select%20the%20text%20below%20and%20click%20on%20the%20%27DoIt%27%20button%22%0A%0AProfStef%20next.")]);
+return self;},
+source: unescape('welcome%0A%09%5E%20Lesson%0Atitle%3A%20%27Welcome%27%20%0Acontents%3A%20%0A%27%20%22Hello%21%20I%27%27m%20Professor%20Stef.%20%0A%0AYou%20must%20want%20me%20to%20help%20you%20learn%20Smalltalk.%0A%0ASo%20let%27%27s%20go%20to%20the%20first%20lesson.%20%20Select%20the%20text%20below%20and%20click%20on%20the%20%27%27DoIt%27%27%20button%22%0A%0AProfStef%20next.%27'),
+messageSends: ["title:contents:"],
+referencedClasses: [smalltalk.Lesson]
+}),
+smalltalk.SmalltalkSyntaxTutorial);
+
+
+

+ 191 - 17
js/parser.js

@@ -22,6 +22,8 @@ smalltalk.parser = (function(){
         "className": parse_className,
         "classReference": parse_classReference,
         "comments": parse_comments,
+        "dynamicArray": parse_dynamicArray,
+        "dynamicDictionary": parse_dynamicDictionary,
         "expression": parse_expression,
         "expressionList": parse_expressionList,
         "expressions": parse_expressions,
@@ -1087,6 +1089,168 @@ smalltalk.parser = (function(){
         
         
         
+        cache[cacheKey] = {
+          nextPos: pos,
+          result:  result0
+        };
+        return result0;
+      }
+      
+      function parse_dynamicArray() {
+        var cacheKey = 'dynamicArray@' + pos;
+        var cachedResult = cache[cacheKey];
+        if (cachedResult) {
+          pos = cachedResult.nextPos;
+          return cachedResult.result;
+        }
+        
+        
+        var savedPos0 = pos;
+        var savedPos1 = pos;
+        if (input.substr(pos, 1) === "{") {
+          var result3 = "{";
+          pos += 1;
+        } else {
+          var result3 = null;
+          if (reportMatchFailures) {
+            matchFailed("\"{\"");
+          }
+        }
+        if (result3 !== null) {
+          var result4 = parse_ws();
+          if (result4 !== null) {
+            var result8 = parse_expressions();
+            var result5 = result8 !== null ? result8 : '';
+            if (result5 !== null) {
+              var result6 = parse_ws();
+              if (result6 !== null) {
+                if (input.substr(pos, 1) === "}") {
+                  var result7 = "}";
+                  pos += 1;
+                } else {
+                  var result7 = null;
+                  if (reportMatchFailures) {
+                    matchFailed("\"}\"");
+                  }
+                }
+                if (result7 !== null) {
+                  var result1 = [result3, result4, result5, result6, result7];
+                } else {
+                  var result1 = null;
+                  pos = savedPos1;
+                }
+              } else {
+                var result1 = null;
+                pos = savedPos1;
+              }
+            } else {
+              var result1 = null;
+              pos = savedPos1;
+            }
+          } else {
+            var result1 = null;
+            pos = savedPos1;
+          }
+        } else {
+          var result1 = null;
+          pos = savedPos1;
+        }
+        var result2 = result1 !== null
+          ? (function(expressions) {
+          	       	  return smalltalk.DynamicArrayNode._new()
+          		        ._nodes_(expressions)
+          		  })(result1[2])
+          : null;
+        if (result2 !== null) {
+          var result0 = result2;
+        } else {
+          var result0 = null;
+          pos = savedPos0;
+        }
+        
+        
+        
+        cache[cacheKey] = {
+          nextPos: pos,
+          result:  result0
+        };
+        return result0;
+      }
+      
+      function parse_dynamicDictionary() {
+        var cacheKey = 'dynamicDictionary@' + pos;
+        var cachedResult = cache[cacheKey];
+        if (cachedResult) {
+          pos = cachedResult.nextPos;
+          return cachedResult.result;
+        }
+        
+        
+        var savedPos0 = pos;
+        var savedPos1 = pos;
+        if (input.substr(pos, 2) === "#{") {
+          var result3 = "#{";
+          pos += 2;
+        } else {
+          var result3 = null;
+          if (reportMatchFailures) {
+            matchFailed("\"#{\"");
+          }
+        }
+        if (result3 !== null) {
+          var result4 = parse_ws();
+          if (result4 !== null) {
+            var result8 = parse_expressions();
+            var result5 = result8 !== null ? result8 : '';
+            if (result5 !== null) {
+              var result6 = parse_ws();
+              if (result6 !== null) {
+                if (input.substr(pos, 1) === "}") {
+                  var result7 = "}";
+                  pos += 1;
+                } else {
+                  var result7 = null;
+                  if (reportMatchFailures) {
+                    matchFailed("\"}\"");
+                  }
+                }
+                if (result7 !== null) {
+                  var result1 = [result3, result4, result5, result6, result7];
+                } else {
+                  var result1 = null;
+                  pos = savedPos1;
+                }
+              } else {
+                var result1 = null;
+                pos = savedPos1;
+              }
+            } else {
+              var result1 = null;
+              pos = savedPos1;
+            }
+          } else {
+            var result1 = null;
+            pos = savedPos1;
+          }
+        } else {
+          var result1 = null;
+          pos = savedPos1;
+        }
+        var result2 = result1 !== null
+          ? (function(expressions) {
+          	       	  return smalltalk.DynamicDictionaryNode._new()
+          		        ._nodes_(expressions)
+          		  })(result1[2])
+          : null;
+        if (result2 !== null) {
+          var result0 = result2;
+        } else {
+          var result0 = null;
+          pos = savedPos0;
+        }
+        
+        
+        
         cache[cacheKey] = {
           nextPos: pos,
           result:  result0
@@ -1103,27 +1267,37 @@ smalltalk.parser = (function(){
         }
         
         
-        var result5 = parse_number();
-        if (result5 !== null) {
-          var result0 = result5;
+        var result7 = parse_number();
+        if (result7 !== null) {
+          var result0 = result7;
         } else {
-          var result4 = parse_literalArray();
-          if (result4 !== null) {
-            var result0 = result4;
+          var result6 = parse_literalArray();
+          if (result6 !== null) {
+            var result0 = result6;
           } else {
-            var result3 = parse_string();
-            if (result3 !== null) {
-              var result0 = result3;
+            var result5 = parse_dynamicDictionary();
+            if (result5 !== null) {
+              var result0 = result5;
             } else {
-              var result2 = parse_symbol();
-              if (result2 !== null) {
-                var result0 = result2;
+              var result4 = parse_dynamicArray();
+              if (result4 !== null) {
+                var result0 = result4;
               } else {
-                var result1 = parse_block();
-                if (result1 !== null) {
-                  var result0 = result1;
+                var result3 = parse_string();
+                if (result3 !== null) {
+                  var result0 = result3;
                 } else {
-                  var result0 = null;;
+                  var result2 = parse_symbol();
+                  if (result2 !== null) {
+                    var result0 = result2;
+                  } else {
+                    var result1 = parse_block();
+                    if (result1 !== null) {
+                      var result0 = result1;
+                    } else {
+                      var result0 = null;;
+                    };
+                  };
                 };
               };
             };
@@ -3721,4 +3895,4 @@ smalltalk.parser = (function(){
   result.SyntaxError.prototype = Error.prototype;
   
   return result;
-})();
+})();

+ 10 - 1
js/parser.pegjs

@@ -25,7 +25,15 @@ literalArray   = "#(" ws lits:(lit:literal ws {return lit._value()})* ws ")" {
 		  return smalltalk.ValueNode._new()
                	   	._value_(lits)
                	 }
-literal        = number / literalArray / string / symbol / block
+dynamicArray   = "{" ws expressions:expressions? ws "}" {
+	       	  return smalltalk.DynamicArrayNode._new()
+		        ._nodes_(expressions)
+		  }
+dynamicDictionary = "#{" ws expressions: expressions? ws "}" {
+	       	  return smalltalk.DynamicDictionaryNode._new()
+		        ._nodes_(expressions)
+		  }
+literal        = number / literalArray / dynamicDictionary / dynamicArray / string / symbol / block
 
 
 variable       = identifier:identifier {
@@ -36,6 +44,7 @@ classReference = className:className {
 		  return smalltalk.ClassReferenceNode._new()
 		  	._value_(className)
 		  }
+
 reference      = variable / classReference
 
 keywordPair    = key:keyword ws arg:binarySend ws {return {key:key, arg: arg}}

+ 44 - 0
st/Compiler.st

@@ -704,6 +704,14 @@ visitJSStatementNode: aNode
 	    nextPutAll: 'function(){';
 	    nextPutAll: aNode source;
 	    nextPutAll: '})()'
+!
+
+visitDynamicArrayNode: aNode
+	self visitNode: aNode
+!
+
+visitDynamicDictionaryNode: aNode
+	self visitNode: aNode
 ! !
 
 NodeVisitor subclass: #Compiler
@@ -1306,6 +1314,22 @@ send: aSelector to: aReceiver arguments: aCollection superSend: aBoolean
 		aBoolean ifTrue: [
 			str nextPutAll: ', smalltalk.', (self classNameFor: self currentClass superclass)].
 		str nextPutAll: ')']
+!
+
+visitDynamicArrayNode: aNode
+	stream nextPutAll: '['.
+	aNode nodes 
+		do: [:each | self visit: each]
+		separatedBy: [stream nextPutAll: ','].
+	stream nextPutAll: ']'
+!
+
+visitDynamicDictionaryNode: aNode
+	stream nextPutAll: 'smalltalk.Dictionary._fromPairs_(['.
+		aNode nodes 
+			do: [:each | self visit: each]
+			separatedBy: [stream nextPutAll: ','].
+		stream nextPutAll: '])'
 ! !
 
 Compiler class instanceVariableNames: 'performOptimizations'!
@@ -1339,3 +1363,23 @@ Object subclass: #DoIt
 	instanceVariableNames: ''
 	category: 'Compiler'!
 
+Node subclass: #DynamicArrayNode
+	instanceVariableNames: ''
+	category: 'Compiler'!
+
+!DynamicArrayNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitDynamicArrayNode: self
+! !
+
+Node subclass: #DynamicDictionaryNode
+	instanceVariableNames: ''
+	category: 'Compiler'!
+
+!DynamicDictionaryNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	aVisitor visitDynamicDictionaryNode: self
+! !
+

+ 281 - 2
st/IDE.st

@@ -103,7 +103,8 @@ initialize
 	addClass: 'jtalkBody'.
     self 
 	addTab: Transcript current;
-	addTab: Workspace new.
+	addTab: Workspace new;
+	addTab: TestRunner new.
     self selectTab: self tabs last.
     self 
 	onResize: [self updateBodyMargin; updatePosition];
@@ -335,7 +336,9 @@ Transcript class instanceVariableNames: 'current'!
 !Transcript class methodsFor: 'instance creation'!
 
 open
-    self current open
+    TabManager current 
+	open;
+	selectTab: self current
 !
 
 new
@@ -1657,6 +1660,282 @@ initialize
 	self register
 ! !
 
+TabWidget subclass: #ProgressBar
+	instanceVariableNames: 'percent progressDiv div'
+	category: 'IDE'!
+
+!ProgressBar methodsFor: 'accessing'!
+
+percent
+	^percent ifNil: [0]
+!
+
+percent: aNumber
+	percent := aNumber
+! !
+
+!ProgressBar methodsFor: 'rendering'!
+
+renderOn: html 
+	div := html div 
+		class: 'progress_bar';
+		yourself.
+	self renderProgressBar
+!
+
+renderProgressBar
+	div contents: [:html |
+		html div 
+			class: 'progress';
+			style: 'width:', self percent asString, '%']
+! !
+
+!ProgressBar methodsFor: 'updating'!
+
+updatePercent: aNumber
+	self percent: aNumber.
+	self renderProgressBar
+! !
+
+TabWidget subclass: #TestRunner
+	instanceVariableNames: 'selectedCategories categoriesList selectedClasses classesList selectedMethods progressBar methodsList result statusDiv'
+	category: 'IDE'!
+
+!TestRunner methodsFor: 'accessing'!
+
+label
+    ^'[Test runner]'
+!
+
+categories
+    | categories |
+    categories := Array new.
+    self allClasses do: [:each |
+	(categories includes: each category) ifFalse: [
+	    categories add: each category]].
+    ^categories sort
+!
+
+classes
+    ^(self allClasses 
+	select: [:each | self selectedCategories includes: each category])
+	sort: [:a :b | a name > b name]
+!
+
+selectedCategories
+	^selectedCategories ifNil: [selectedCategories := Array new]
+!
+
+allClasses
+	^TestCase allSubclasses
+!
+
+selectedClasses
+	^selectedClasses  ifNil: [selectedClasses := Array new]
+!
+
+progressBar
+	^progressBar ifNil: [progressBar := ProgressBar new]
+!
+
+selectedMethods
+	^selectedMethods ifNil: [self selectedClasses collect: [:each |
+		each methodDictionary keys select: [:key |  key beginsWith: 'test' ]]]
+!
+
+statusInfo
+	^self printTotal, self printPasses, self printErrors, self printFailures
+!
+
+result
+	^result
+!
+
+failedMethods
+	self result failures collect: [:each |
+		html li 
+			class: 'failures';
+			with: each]
+! !
+
+!TestRunner methodsFor: 'actions'!
+
+selectAllCategories
+	self categories do: [:each | 
+		(selectedCategories includes: each) ifFalse: [
+			self selectedCategories add: each]].
+	self 
+	    updateCategoriesList;
+	    updateClassesList
+!
+
+toggleCategory: aCategory
+	(self isSelectedCategory: aCategory) 
+		ifFalse: [selectedCategories add: aCategory]
+		ifTrue: [selectedCategories remove: aCategory].
+	self 
+	    updateCategoriesList;
+	    updateClassesList
+!
+
+toggleClass: aClass
+	(self isSelectedClass: aClass) 
+		ifFalse: [selectedClasses add: aClass]
+		ifTrue: [selectedClasses remove: aClass].
+	self 
+	    updateClassesList
+!
+
+selectAllClasses
+	self classes do: [:each | 
+		(selectedClasses includes: each) ifFalse: [
+			self selectedClasses add: each]].
+	self 
+	    updateCategoriesList;
+	    updateClassesList
+!
+
+run: aCollection
+	result := TestResult new.
+	self 
+		updateStatusDiv;
+		updateMethodsList.
+	self progressBar updatePercent: 0.
+	result total: (aCollection inject: 0 into: [:acc :each | acc + each methods size]).
+	aCollection do: [:each | 
+		[each runCaseFor: result.
+		self progressBar updatePercent: result runs / result total * 100.
+		self updateStatusDiv.
+		self updateMethodsList] valueWithTimeout: 100].
+! !
+
+!TestRunner methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	result := TestResult new
+! !
+
+!TestRunner methodsFor: 'printing'!
+
+printErrors
+	^self result errors size asString , ' errors, '
+!
+
+printFailures
+	^self result failures size asString, ' failures'
+!
+
+printPasses
+	^(((self result total) - (self result errors size + (self result failures size))) asString) , ' passes, '
+!
+
+printTotal
+	^self result total asString, ' runs, '
+! !
+
+!TestRunner methodsFor: 'rendering'!
+
+renderBoxOn: html
+    self 
+	renderCategoriesOn: html;
+	renderClassesOn: html;
+	renderResultsOn: html
+!
+
+renderButtonsOn: html
+    html button
+	with: 'Run selected';
+	onClick: [self run: (self selectedClasses collect: [:each | each new])]
+!
+
+renderCategoriesOn: html
+    	categoriesList := html ul class: 'jt_column sunit categories'.
+	self updateCategoriesList
+!
+
+renderClassesOn: html
+    	classesList := html ul class: 'jt_column sunit classes'.
+	self updateClassesList
+!
+
+renderResultsOn: html
+    	statusDiv := html div.
+	html with: self progressBar.
+   	methodsList := html ul class: 'jt_column sunit methods'.
+	self updateMethodsList.
+	self updateStatusDiv
+!
+
+renderFailuresOn: html
+	self result failures do: [:each |
+		html li 
+			class: 'failures';
+			with: each]
+!
+
+renderErrorsOn: html
+	self result errors do: [:each |
+		html li 
+			class: 'errors';
+			with: each]
+! !
+
+!TestRunner methodsFor: 'testing'!
+
+isSelectedClass: aClass
+	^(self selectedClasses includes: aClass)
+!
+
+isSelectedCategory: aCategory
+	^(self selectedCategories includes: aCategory)
+! !
+
+!TestRunner methodsFor: 'updating'!
+
+updateCategoriesList
+    categoriesList contents: [:html |
+	    html li 
+		class: 'all';
+		with: 'All';
+		onClick: [self selectAllCategories].
+	self categories do: [:each || li |
+	    li := html li.
+	    (self selectedCategories includes: each) ifTrue: [
+		li class: 'selected'].
+	    li
+		with: each;
+		onClick: [self toggleCategory: each]]]
+!
+
+updateClassesList
+    classesList contents: [:html |
+	(self selectedCategories isEmpty) ifFalse: [
+		html li
+			class: 'all';
+			with: 'All';
+			onClick: [self selectAllClasses]].
+	self classes do: [:each || li |
+		li := html li.
+		(self selectedClasses includes: each) ifTrue: [
+			li class: 'selected'].
+		li
+			with: each name;
+			onClick: [self toggleClass: each]]]
+!
+
+updateMethodsList
+	methodsList contents: [:html |
+		self renderFailuresOn: html.
+                self renderErrorsOn: html]
+!
+
+updateStatusDiv
+	statusDiv class: 'sunit status ', result status.
+	statusDiv contents: [:html |
+		html span with: self statusInfo]
+! !
+
 !Object methodsFor: '*IDE'!
 
 inspect

+ 141 - 18
st/Kernel.st

@@ -2,6 +2,11 @@ nil subclass: #Object
 	instanceVariableNames: ''
 	category: 'Kernel'!
 
+!Object methodsFor: ''!
+
+foo ^ self
+! !
+
 !Object methodsFor: 'accessing'!
 
 yourself
@@ -272,14 +277,24 @@ basicParse: aString
 !
 
 parse: aString
-	| result |
-	self try: [result := self basicParse: aString] catch: [:ex | (self parseError: ex) signal].
+	| result | 
+	self try: [result := self basicParse: aString] catch: [:ex | (self parseError: ex parsing: aString) signal].
 	^result
 !
 
-parseError: anException
-	<return smalltalk.Error._new()
-		._messageText_('Parse error on line ' + anException.line + ' column ' + anException.column + ' : ' + anException.message)>
+parseError: anException parsing: aString
+	| row col message lines badLine code |
+	<row = anException.line;
+	col = anException.column;
+	message = anException.message;>.
+	lines := aString lines.
+	badLine := lines at: row.
+	badLine := (badLine copyFrom: 1 to: col - 1), ' ===>', (badLine copyFrom:  col to: badLine size).
+	lines at: row put: badLine.
+	code := String streamContents: [:s |
+                                        lines withIndexDo: [:l :i |
+                                                   s nextPutAll: i asString, ': ', l, String lf]].
+	^ Error new messageText: ('Parse error on line ' , row , ' column ' , col , ' : ' , message , ' Below is code with line numbers and ===> marker inserted:' , String lf, code)
 ! !
 
 Smalltalk class instanceVariableNames: 'current'!
@@ -409,7 +424,20 @@ methodsFor: aString stamp: aStamp
 !
 
 commentStamp: aStamp prior: prior
-         "Ignored right now."
+        ^self commentStamp
+! !
+
+!Behavior methodsFor: 'compiling'!
+
+compile: aString
+	self compile: aString category: ''
+!
+
+compile: aString category: anotherString
+	| method |
+	method := Compiler new load: aString forClass: self.
+	method category: anotherString.
+	self addCompiledMethod: method
 ! !
 
 !Behavior methodsFor: 'instance creation'!
@@ -796,6 +824,12 @@ new
 
 applyTo: anObject arguments: aCollection
 	<return self.apply(anObject, aCollection)>
+!
+
+timeToRun
+	"Answer the number of milliseconds taken to execute this block."
+
+	^ Date millisecondsToRun: self
 ! !
 
 !BlockClosure methodsFor: 'timeout/interval'!
@@ -1402,6 +1436,22 @@ indexOf: anObject ifAbsent: aBlock
 		}
 		return aBlock();
 	>
+!
+
+indexOf: anObject startingAt: start ifAbsent: aBlock
+	<
+		for(var i=start-1;i<self.length;i++){
+			if(self[i].__eq(anObject)) {return i+1}
+		}
+		return aBlock();
+	>
+!
+
+indexOf: anObject startingAt: start
+	"Answer the index of the first occurence of anElement after start
+	within the receiver. If the receiver does not contain anElement, 
+	answer 0."
+	^self indexOf: anObject startingAt: start ifAbsent: [0]
 ! !
 
 !SequenceableCollection methodsFor: 'adding'!
@@ -1414,6 +1464,12 @@ addLast: anObject
 	self add: anObject
 ! !
 
+!SequenceableCollection methodsFor: 'converting'!
+
+reversed
+	self subclassResponsibility
+! !
+
 !SequenceableCollection methodsFor: 'copying'!
 
 copyFrom: anIndex to: anotherIndex
@@ -1533,18 +1589,6 @@ asNumber
 	<return Number(self)>
 !
 
-asParser
-    	^PPStringParser new string: self
-!
-
-asChoiceParser
-    	^PPChoiceParser withAll: (self asArray collect: [:each | each asParser])
-!
-
-asCharacterParser
-    	^PPCharacterParser new string: self
-!
-
 asJSONObject
 	^self
 !
@@ -1555,6 +1599,10 @@ asLowercase
 
 asUppercase
 	<return self.toUpperCase()>
+!
+
+reversed
+	<return self.split("").reverse().join("")>
 ! !
 
 !String methodsFor: 'copying'!
@@ -1639,6 +1687,68 @@ join: aCollection
 		streamContents: [:stream | aCollection
 				do: [:each | stream nextPutAll: each asString] 
 				separatedBy: [stream nextPutAll: self]]
+!
+
+lineIndicesDo: aBlock
+	"execute aBlock with 3 arguments for each line:
+	- start index of line
+	- end index of line without line delimiter
+	- end index of line including line delimiter(s) CR, LF or CRLF"
+	
+	| cr lf start sz nextLF nextCR |
+	start := 1.
+	sz := self size.
+	cr := String cr.
+	nextCR := self indexOf: cr startingAt: 1.
+	lf := String lf.
+	nextLF := self indexOf: lf startingAt: 1.
+	[ start <= sz ] whileTrue: [
+		(nextLF = 0 and: [ nextCR = 0 ])
+			ifTrue: [ "No more CR, nor LF, the string is over"
+					aBlock value: start value: sz value: sz.
+					^self ].
+		(nextCR = 0 or: [ 0 < nextLF and: [ nextLF < nextCR ] ])
+			ifTrue: [ "Found a LF"
+					aBlock value: start value: nextLF - 1 value: nextLF.
+					start := 1 + nextLF.
+					nextLF := self indexOf: lf startingAt: start ]
+			ifFalse: [ 1 + nextCR = nextLF
+				ifTrue: [ "Found a CR-LF pair"
+					aBlock value: start value: nextCR - 1 value: nextLF.
+					start := 1 + nextLF.
+					nextCR := self indexOf: cr startingAt: start.
+					nextLF := self indexOf: lf startingAt: start ]
+				ifFalse: [ "Found a CR"
+					aBlock value: start value: nextCR - 1 value: nextCR.
+					start := 1 + nextCR.
+					nextCR := self indexOf: cr startingAt: start ]]]
+!
+
+linesDo: aBlock
+	"Execute aBlock with each line in this string. The terminating line
+	delimiters CR, LF or CRLF pairs are not included in what is passed to aBlock"
+
+	self lineIndicesDo: [:start :endWithoutDelimiters :end |
+		aBlock value: (self copyFrom: start to: endWithoutDelimiters)]
+!
+
+lines
+	"Answer an array of lines composing this receiver without the line ending delimiters."
+
+	| lines |
+	lines := Array new.
+	self linesDo: [:aLine | lines add: aLine].
+	^lines
+!
+
+lineNumber: anIndex
+	"Answer a string containing the characters in the given line number."
+
+	| lineCount |
+	lineCount := 0.
+	self lineIndicesDo: [:start :endWithoutDelimiters :end |
+		(lineCount := lineCount + 1) = anIndex ifTrue: [^self copyFrom: start to: endWithoutDelimiters]].
+	^nil
 ! !
 
 !String methodsFor: 'testing'!
@@ -1749,6 +1859,10 @@ asJavascript
 
 asJSONObject
 	^self collect: [:each | each asJSONObject]
+!
+
+reversed
+	<return self._copy().reverse()>
 ! !
 
 !Array methodsFor: 'copying'!
@@ -2119,6 +2233,15 @@ printString
                                  ]
 ! !
 
+!Dictionary class methodsFor: 'instance creation'!
+
+fromPairs: aCollection
+	| dict |
+	dict := self new.
+	aCollection do: [:each | dict add: each].
+	^dict
+! !
+
 Object subclass: #ClassBuilder
 	instanceVariableNames: ''
 	category: 'Kernel'!

+ 0 - 280
st/SUnit.st

@@ -76,290 +76,10 @@ assert: aBoolean description: aString
 	aBoolean ifFalse: [self signalFailure: aString]
 ! !
 
-TabWidget subclass: #ProgressBar
-	instanceVariableNames: 'percent progressDiv div'
-	category: 'SUnit'!
-
-!ProgressBar methodsFor: 'accessing'!
-
-percent
-	^percent ifNil: [0]
-!
-
-percent: aNumber
-	percent := aNumber
-! !
-
-!ProgressBar methodsFor: 'rendering'!
-
-renderOn: html 
-	div := html div 
-		class: 'progress_bar';
-		yourself.
-	self renderProgressBar
-!
-
-renderProgressBar
-	div contents: [:html |
-		html div 
-			class: 'progress';
-			style: 'width:', self percent asString, '%']
-! !
-
-!ProgressBar methodsFor: 'updating'!
-
-updatePercent: aNumber
-	self percent: aNumber.
-	self renderProgressBar
-! !
-
 Error subclass: #TestFailure
 	instanceVariableNames: ''
 	category: 'SUnit'!
 
-TabWidget subclass: #TestRunner
-	instanceVariableNames: 'selectedCategories categoriesList selectedClasses classesList selectedMethods progressBar methodsList result statusDiv'
-	category: 'SUnit'!
-
-!TestRunner methodsFor: 'accessing'!
-
-label
-    ^'[Test runner]'
-!
-
-categories
-    | categories |
-    categories := Array new.
-    self allClasses do: [:each |
-	(categories includes: each category) ifFalse: [
-	    categories add: each category]].
-    ^categories sort
-!
-
-classes
-    ^(self allClasses 
-	select: [:each | self selectedCategories includes: each category])
-	sort: [:a :b | a name > b name]
-!
-
-selectedCategories
-	^selectedCategories ifNil: [selectedCategories := Array new]
-!
-
-allClasses
-	^TestCase allSubclasses
-!
-
-selectedClasses
-	^selectedClasses  ifNil: [selectedClasses := Array new]
-!
-
-progressBar
-	^progressBar ifNil: [progressBar := ProgressBar new]
-!
-
-selectedMethods
-	^selectedMethods ifNil: [self selectedClasses collect: [:each |
-		each methodDictionary keys select: [:key |  key beginsWith: 'test' ]]]
-!
-
-statusInfo
-	^self printTotal, self printPasses, self printErrors, self printFailures
-!
-
-result
-	^result
-!
-
-failedMethods
-	self result failures collect: [:each |
-		html li 
-			class: 'failures';
-			with: each]
-! !
-
-!TestRunner methodsFor: 'actions'!
-
-selectAllCategories
-	self categories do: [:each | 
-		(selectedCategories includes: each) ifFalse: [
-			self selectedCategories add: each]].
-	self 
-	    updateCategoriesList;
-	    updateClassesList
-!
-
-toggleCategory: aCategory
-	(self isSelectedCategory: aCategory) 
-		ifFalse: [selectedCategories add: aCategory]
-		ifTrue: [selectedCategories remove: aCategory].
-	self 
-	    updateCategoriesList;
-	    updateClassesList
-!
-
-toggleClass: aClass
-	(self isSelectedClass: aClass) 
-		ifFalse: [selectedClasses add: aClass]
-		ifTrue: [selectedClasses remove: aClass].
-	self 
-	    updateClassesList
-!
-
-selectAllClasses
-	self classes do: [:each | 
-		(selectedClasses includes: each) ifFalse: [
-			self selectedClasses add: each]].
-	self 
-	    updateCategoriesList;
-	    updateClassesList
-!
-
-run: aCollection
-	result := TestResult new.
-	self 
-		updateStatusDiv;
-		updateMethodsList.
-	self progressBar updatePercent: 0.
-	result total: (aCollection inject: 0 into: [:acc :each | acc + each methods size]).
-	aCollection do: [:each | 
-		[each runCaseFor: result.
-		self progressBar updatePercent: result runs / result total * 100.
-		self updateStatusDiv.
-		self updateMethodsList] valueWithTimeout: 100].
-! !
-
-!TestRunner methodsFor: 'initialization'!
-
-initialize
-	super initialize.
-	result := TestResult new
-! !
-
-!TestRunner methodsFor: 'printing'!
-
-printErrors
-	^self result errors size asString , ' errors, '
-!
-
-printFailures
-	^self result failures size asString, ' failures'
-!
-
-printPasses
-	^(((self result total) - (self result errors size + (self result failures size))) asString) , ' passes, '
-!
-
-printTotal
-	^self result total asString, ' runs, '
-! !
-
-!TestRunner methodsFor: 'rendering'!
-
-renderBoxOn: html
-    self 
-	renderCategoriesOn: html;
-	renderClassesOn: html;
-	renderResultsOn: html
-!
-
-renderButtonsOn: html
-    html button
-	with: 'Run selected';
-	onClick: [self run: (self selectedClasses collect: [:each | each new])]
-!
-
-renderCategoriesOn: html
-    	categoriesList := html ul class: 'jt_column sunit categories'.
-	self updateCategoriesList
-!
-
-renderClassesOn: html
-    	classesList := html ul class: 'jt_column sunit classes'.
-	self updateClassesList
-!
-
-renderResultsOn: html
-    	statusDiv := html div.
-	html with: self progressBar.
-   	methodsList := html ul class: 'jt_column sunit methods'.
-	self updateMethodsList.
-	self updateStatusDiv
-!
-
-renderFailuresOn: html
-	self result failures do: [:each |
-		html li 
-			class: 'failures';
-			with: each]
-!
-
-renderErrorsOn: html
-	self result errors do: [:each |
-		html li 
-			class: 'errors';
-			with: each]
-! !
-
-!TestRunner methodsFor: 'testing'!
-
-canBeClosed
-    ^true
-!
-
-isSelectedClass: aClass
-	^(self selectedClasses includes: aClass)
-!
-
-isSelectedCategory: aCategory
-	^(self selectedCategories includes: aCategory)
-! !
-
-!TestRunner methodsFor: 'updating'!
-
-updateCategoriesList
-    categoriesList contents: [:html |
-	    html li 
-		class: 'all';
-		with: 'All';
-		onClick: [self selectAllCategories].
-	self categories do: [:each || li |
-	    li := html li.
-	    (self selectedCategories includes: each) ifTrue: [
-		li class: 'selected'].
-	    li
-		with: each;
-		onClick: [self toggleCategory: each]]]
-!
-
-updateClassesList
-    classesList contents: [:html |
-	(self selectedCategories isEmpty) ifFalse: [
-		html li
-			class: 'all';
-			with: 'All';
-			onClick: [self selectAllClasses]].
-	self classes do: [:each || li |
-		li := html li.
-		(self selectedClasses includes: each) ifTrue: [
-			li class: 'selected'].
-		li
-			with: each name;
-			onClick: [self toggleClass: each]]]
-!
-
-updateMethodsList
-	methodsList contents: [:html |
-		self renderFailuresOn: html.
-                self renderErrorsOn: html]
-!
-
-updateStatusDiv
-	statusDiv class: 'sunit status ', result status.
-	statusDiv contents: [:html |
-		html span with: self statusInfo]
-! !
-
 Object subclass: #TestResult
 	instanceVariableNames: 'timestamp runs errors failures total'
 	category: 'SUnit'!

+ 925 - 0
st/TrySmalltalk.st

@@ -0,0 +1,925 @@
+Widget subclass: #TrySmalltalkWidget
+	instanceVariableNames: 'workspace contents header'
+	category: 'TrySmalltalk'!
+
+!TrySmalltalkWidget methodsFor: 'accessing'!
+
+workspace
+	^ workspace ifNil: [
+          	workspace := SourceArea new]
+!
+
+contents: aString
+	self workspace val: aString
+!
+
+contents
+	^self workspace val
+!
+
+setTitle: aString
+	header contents: [:html | html with: aString]
+! !
+
+!TrySmalltalkWidget methodsFor: 'rendering'!
+
+renderOn: html
+	html div 
+		class: 'profStef'; 
+		with: [header := html h2];
+		with: [self workspace renderOn: html];
+		with: [self renderButtonsOn: html].
+          ProfStef default 
+		widget: self;
+		showCurrentLesson
+!
+
+renderButtonsOn: html
+    html button
+	with: 'DoIt';
+	title: 'ctrl+d';
+	onClick: [self workspace doIt].
+    html button
+	with: 'PrintIt';
+	title: 'ctrl+p';
+	onClick: [self workspace printIt].
+    html button
+	with: 'InspectIt';
+	title: 'ctrl+i';
+	onClick: [self workspace inspectIt]
+! !
+
+Object subclass: #AbstractTutorial
+	instanceVariableNames: ''
+	category: 'TrySmalltalk'!
+
+!AbstractTutorial methodsFor: 'not yet classified'!
+
+indexOfLesson: aSelector
+	^self tableOfContents indexOf: aSelector.
+!
+
+tableOfContents
+^ #(
+  'welcome'
+  'testLesson'
+  'theEnd'
+)
+!
+
+welcome
+	^ Lesson
+		title: 'Welcome' 
+		contents: '"Hi, this is a test tutorial."'
+!
+
+testLesson
+	^ Lesson
+		title: 'Test Lesson' 
+		contents: '"This lesson is a test"'
+!
+
+theEnd
+	^ Lesson
+		title: 'The End' 
+		contents: '"And that''d be pretty much it :)"'
+!
+
+lessonAt: anInteger
+	| lessonSelector |
+	lessonSelector := self tableOfContents at: anInteger.
+	^ self perform: lessonSelector.
+!
+
+size
+	^ self tableOfContents size
+! !
+
+Object subclass: #Lesson
+	instanceVariableNames: 'title contents'
+	category: 'TrySmalltalk'!
+
+!Lesson methodsFor: 'not yet classified'!
+
+contents
+	^ contents ifNil: [contents := '']
+!
+
+contents: aString
+	contents := aString
+!
+
+title: aString
+	title := aString
+!
+
+title
+	^ title ifNil: [title := '']
+! !
+
+!Lesson class methodsFor: 'not yet classified'!
+
+title: aTitle contents: someContents
+	^ (self new)
+		title: aTitle;
+		contents: someContents
+! !
+
+Object subclass: #TutorialPlayer
+	instanceVariableNames: 'tutorialPosition tutorial'
+	category: 'TrySmalltalk'!
+
+!TutorialPlayer methodsFor: 'not yet classified'!
+
+currentLesson
+	^ self tutorial lessonAt: self tutorialPosition.
+!
+
+first
+	self rewind.
+	^ self currentLesson
+!
+
+last
+	tutorialPosition := self size.
+	^ self currentLesson
+!
+
+next
+	self tutorialPosition < self size
+		ifTrue: [tutorialPosition := tutorialPosition + 1].
+	^ self currentLesson
+!
+
+previous
+	tutorialPosition >  1 ifTrue: [tutorialPosition := tutorialPosition  - 1].
+	^ self currentLesson
+!
+
+rewind
+	tutorialPosition := 1.
+!
+
+size
+	^ self tutorial size
+!
+
+tutorial
+	^ tutorial  ifNil: [tutorial := SmalltalkSyntaxTutorial new]
+!
+
+tutorial: aTutorial
+	tutorial := aTutorial
+!
+
+tutorialPosition 
+	^ tutorialPosition  ifNil: [
+		self rewind.
+		tutorialPosition.
+	].
+!
+
+tutorialPosition: aTutorialPosition 
+	tutorialPosition := aTutorialPosition
+! !
+
+Object subclass: #ProfStef
+	instanceVariableNames: 'tutorialPlayer widget'
+	category: 'TrySmalltalk'!
+
+!ProfStef methodsFor: 'not yet classified'!
+
+tutorialPlayer
+	^ tutorialPlayer ifNil: [tutorialPlayer := TutorialPlayer new]
+!
+
+first
+	self tutorialPlayer first.
+	^ self showCurrentLesson.
+!
+
+progress
+	^ '(', self tutorialPositionString, '/', self tutorialSizeString, ')'.
+!
+
+tutorialPositionString
+	^ self tutorialPlayer tutorialPosition asString.
+!
+
+tutorialSizeString
+	^ self tutorialPlayer size asString
+!
+
+next
+	self tutorialPlayer next.
+	^ self showCurrentLesson.
+!
+
+previous
+	self tutorialPlayer previous.
+	^ self showCurrentLesson.
+!
+
+widget: aWidget
+	widget := aWidget
+!
+
+showCurrentLesson
+	| lesson |
+	lesson := self tutorialPlayer currentLesson.
+	widget contents: lesson contents.
+	widget setTitle: lesson title , ' ' , self progress.
+! !
+
+ProfStef class instanceVariableNames: 'instance'!
+
+!ProfStef class methodsFor: 'not yet classified'!
+
+first
+	^ self default first.
+!
+
+default 
+	^ instance ifNil: [instance := self new]
+!
+
+previous
+	^ self default previous.
+!
+
+next
+	^ self default next.
+!
+
+go
+	self first.
+! !
+
+AbstractTutorial subclass: #SmalltalkSyntaxTutorial
+	instanceVariableNames: ''
+	category: 'TrySmalltalk'!
+
+!SmalltalkSyntaxTutorial methodsFor: 'not yet classified'!
+
+tableOfContents
+^ #(	'welcome'
+	'doingVSPrinting'
+	'printing'
+
+	'basicTypesNumbers'
+	"'basicTypesCharacters'"
+	'basicTypesString'
+	"'basicTypesSymbol'"
+	'basicTypesArray'
+	'basicTypesDynamicArray'
+
+	'messageSyntaxUnary'
+	'messageSyntaxBinary'
+	'messageSyntaxKeyword'
+	'messageSyntaxExecutionOrder'
+	'messageSyntaxExecutionOrderParentheses'
+	'mathematicalPrecedence'
+	'messageSyntaxCascade'
+	'messageSyntaxCascadeShouldNotBeHere'
+
+	'blocks'
+	'blocksAssignation'
+	'conditionals'
+	'loops'
+	'iterators'
+
+	'instanciation'
+
+	'reflection'
+	'reflectionContinued'
+	"'pharoEnvironment'"
+
+	"'debugger'"
+	'theEnd' )
+!
+
+basicTypesArray
+	^ Lesson
+title: 'Basic types: Array' 
+contents: 
+'"Literal arrays are created at parse time:"
+
+#(1 2 3).
+
+#( 1 2 3 #(4 5 6)) size.
+
+#(1 2 4) isEmpty.
+
+#(1 2 3) first.
+
+#(''hello'' ''Javascript'') at: 2 put: ''Smalltalk''; yourself.
+
+ProfStef next.'
+!
+
+basicTypesCharacters
+	^ Lesson
+title: 'Basic types: Characters' 
+contents: 
+'"A Character can be instantiated using $ operator:"
+
+$A.
+
+$A class.
+
+$B charCode.
+
+Character cr.
+
+Character space.
+
+"You can print all 256 characters of the ASCII extended set:"
+
+Character allByteCharacters.
+
+ProfStef next.'
+!
+
+basicTypesDynamicArray
+	^ Lesson
+title: 'Basic types: Dynamic Array' 
+contents: 
+'"Dynamic Arrays are created at execution time:"
+
+{ (2+3) . (6*6) }.
+
+{ (2+3) . (6*6) . ''hello'', '' Stef''} size.
+
+
+{ ProfStef } first next.'
+!
+
+basicTypesNumbers
+	^ Lesson
+title: 'Basic types: Numbers' 
+contents: 
+'"You now know how to execute Smalltalk code. 
+
+Now let''s talk about basic objects.
+
+1, 2, 100, 2/3 ... are Numbers, and respond to many messages evaluating mathematical expressions.
+Evaluate these ones:"
+
+2.
+
+(1/3).
+
+(1/3) + (4/5).
+
+(18/5) rounded.
+
+1 class.
+
+1 negated.
+
+1 negated negated.
+
+(1 + 3) odd.
+
+ProfStef next.'
+!
+
+basicTypesString
+	^ Lesson
+title: 'Basic types: Strings' 
+contents: 
+'"A String is a collection of characters. Use single quotes to create a String object. Print these expressions:"
+
+''ProfStef''.
+
+''ProfStef'' size.
+
+''abc'' asUppercase.
+
+''Hello World'' reversed. 
+
+"You can access each character using at: message"
+
+''ProfStef'' at: 1.
+
+"String concatenation uses the comma operator:"
+
+''ProfStef'', '' is cool''.
+
+ProfStef next.'
+!
+
+basicTypesSymbol
+	^ Lesson
+title: 'Basic types: Symbols' 
+contents: 
+'"A Symbol is a String which is guaranteed to be globally unique. 
+
+There is one and only one Symbol #ProfStef. There may be several ''ProfStef'' String objects.
+
+(Message == returns true if the two objects are the SAME)"
+
+''ProfStef'' asSymbol.
+
+#ProfStef asString.
+
+(2 asString) == (2 asString).
+
+(2 asString) asSymbol == (2 asString) asSymbol.
+
+
+(Smalltalk at: #ProfStef) next.'
+!
+
+blocks
+	^ Lesson
+title: 'Blocks' 
+contents: 
+'"Cascade is cool !! Let''s talk about blocks.
+
+Blocks are anonymous methods that can be stored into variables and executed on demand.
+
+Blocks are delimited by square brackets: []"
+
+[Transcript open].
+
+"does not open a Transcript because the block is not executed.
+
+Here is a block that adds 2 to its argument (its argument is named x):"
+
+[:x | x+2].
+
+"We can execute a block by sending it value messages."
+
+[:x | x+2] value: 5.
+
+[Transcript open] value.
+
+[:x | x+2] value: 10.
+
+[:x :y| x + y] value:3 value:5.
+
+[ProfStef next] value.'
+!
+
+blocksAssignation
+	^ Lesson
+title: 'Block assignation' 
+contents: 
+'"Blocks can be assigned to a variable then executed later.
+
+Note that |b| is the declaration of a variable named ''b'' and that '':='' assigns a value to a variable.
+
+Select the three lines then Print It:"
+
+|b|
+b := [:x | x+2].
+b value: 12.
+
+
+ProfStef next.'
+!
+
+conditionals
+	^ Lesson
+title: 'Conditionals' 
+contents: 
+'"Conditionals are just messages sent to Boolean objects"
+
+1 < 2
+  ifTrue: [100]
+  ifFalse: [42].
+
+"Here the message is ifTrue:ifFalse
+
+Try this:"
+
+Transcript open.
+
+3 > 10 
+	ifTrue: [Transcript show: ''maybe there''''s a bug ....'']
+	ifFalse: [Transcript show: ''No : 3 is less than 10''].
+
+3 = 3 ifTrue: [ProfStef next].'.
+!
+
+debugger
+	^ Lesson
+title: 'Debugger' 
+contents: '"The Debugger may be the most famous tool of Smalltalk environments. It will open as soon as an unmanaged Exception occurs. 
+
+The following code will open the debugger.
+
+***This should be rethought completely***"
+
+
+ '
+!
+
+doingVSPrinting 
+	^ Lesson
+title: 'Doing VS Printing: Doing' 
+contents: 
+'"Cool !! (I like to say Cooool :) ). You''ve just executed a Smalltalk expression. More precisely, you sent the message ''next'' to
+ProfStef class (it''s me !!).
+
+Note you can run this tutorial again by evaluating: ''ProfStef go''. 
+''ProfStef previous'' returns to the previous lesson.
+
+You can also Do It using the keyboard shortcut ''CTRL d''
+
+Try to evaluate this expression:"
+
+window alert: ''hello world!!''.
+
+"Then go to the next lesson:"
+
+ProfStef next.'
+!
+
+instanciation
+	^ Lesson
+title: 'Instanciation' 
+contents: 
+'"Objects are instances of their class. Usually, we send the message #new to a class for creating an instance of this class.
+
+For example, let''s create an instance of the class Array:"
+
+Array new
+	add: ''Some text'';
+	add: 3.;
+	yourself.
+
+"See the array we''ve created? Actually, #(''Some text'' 3) is just a shorthand for instantiating arrays."
+
+"If we use a variable to keep track of this object, we''ll be able to do stuff with it."
+
+"The following code must be ran all at one, as the ''anArray'' variable will cease to exist once the execution finishes:"
+
+|anArray|
+
+anArray := Array new
+	add: ''Some text'';
+	add: 3;
+	yourself;
+
+Transcript show: anArray; cr.
+
+anArray remove: 3.
+
+Transcript show: anArray; cr.
+
+anArray add: ''Some more text!!''.
+
+Transcript show: anArray; cr.
+	
+"I''ll put myself in an instance of a class named Dictionary and go to the next lesson:"
+
+((Dictionary new add: (''move on!!'' -> ProfStef)) at: ''move on!!'') next'
+!
+
+iterators
+	^ Lesson
+title: 'Iterators' 
+contents: 
+'"The message do: is sent to a collection of objects (Array, Dictionary, String, etc), evaluating the block for each element.
+
+Here we want to print all the numbers on the Transcript (a console)"
+
+#(11 38 3 -2 10) do: [:each |
+     Transcript show: each printString; cr].
+
+"Some other really nice iterators"
+
+#(11 38 3 -2 10) collect: [:each | each negated].
+
+#(11 38 3 -2 10) collect: [:each | each odd].
+
+#(11 38 3 -2 10) select: [:each | each odd].
+
+#(11 38 3 -2 10) select: [:each | each > 10].
+
+#(11 38 3 -2 10) reject: [:each | each > 10].
+
+#(11 38 3 -2 10) 
+     do: [:each | Transcript show: each printString]
+     separatedBy: [Transcript show: ''.''].
+
+
+(Smalltalk current classes select: [:eachClass | eachClass name = ''ProfStef'']) do: [:eachProfstef | eachProfstef next].'
+!
+
+loops
+	^ Lesson
+title: 'Loops' 
+contents: 
+'"Loops are high-level collection iterators, implemented as regular methods."
+
+"Basic loops:
+  to:do:
+  to:by:do"
+
+1 to: 100 do:
+  [:i | Transcript show: i asString; cr ].
+
+1 to: 100 by: 3 do: [:i | Transcript show: i asString; cr].
+
+100 to: 0 by: -2 do: 
+    [:i | Transcript show: i asString; cr].
+
+1 to: 1 do: [:i | ProfStef next].'
+!
+
+mathematicalPrecedence
+	^ Lesson
+title: 'Mathematical precedence'
+contents: 
+'"Traditional precedence rules from mathematics do not follow in Smalltalk."
+
+2 * 10 + 2.
+
+"Here the message * is sent to 2, which answers 20, then 20 receive the message +
+
+Remember that all messages always follow a simple left-to-right precedence rule, * without exceptions *."
+
+2 + 2 * 10.
+
+2 + (2 * 10).
+
+8 - 5 / 2.
+
+(8 - 5) / 2.
+
+8 - (5 / 2).
+
+ProfStef next.'
+!
+
+messageSyntaxBinary
+	^ Lesson
+title: 'Message syntax: Binary messages' 
+contents: 
+'"Binary messages have the following form:
+    anObject + anotherObject"
+
+3 * 2.
+
+Date today year = 2011.
+
+false | false.
+
+true & true.
+
+true & false.
+
+10 @ 100.
+
+10 <= 12.
+
+''ab'', ''cd''.
+
+ProfStef next.'
+!
+
+messageSyntaxCascade
+	^ Lesson
+title: 'Message syntax: Cascade' 
+contents: 
+'"; is the cascade operator. It''s useful to send message to the SAME receiver
+Open a Transcript (console):"
+
+Transcript open.
+
+"Then:"
+
+Transcript show: ''hello''.
+Transcript show: ''Smalltalk''.
+Transcript cr.
+
+"is equivalent to:"
+
+Transcript 
+	   show: ''hello'';
+	   show: ''Smalltalk'' ;
+	   cr.
+
+"You can close the development tools by clicking on the red circle with a cross at the bottom left of the website.
+Try to go to the next lesson with a cascade of two ''next'' messages:"
+
+ProfStef'.
+!
+
+messageSyntaxCascadeShouldNotBeHere
+	^ Lesson
+title: 'Lost ?' 
+contents: 
+'"Hey, you should not be here !!!! 
+
+Go back and use a cascade !!"
+
+ProfStef previous.'.
+!
+
+messageSyntaxExecutionOrder
+	^ Lesson
+title: 'Message syntax: Execution order' 
+contents: 
+'"Unary messages are executed first, then binary messages and finally keyword messages:
+    Unary > Binary > Keywords"
+
+2.5 + 3.8 rounded.
+
+3 max: 2 + 2.
+  
+(0@0) class.
+
+0@0 x: 100.
+
+(0@0 x: 100) class.
+
+"Between messages of similar precedence, expressions are executed from left to right"
+
+-12345 negated asString reversed.
+
+ProfStef next.'
+!
+
+messageSyntaxExecutionOrderParentheses
+	^ Lesson
+title: 'Message syntax: Parentheses'
+contents: 
+'"Use parentheses to change order of evaluation"
+
+(2.5 + 3.8) rounded.
+
+(3 max: 2) + 2.
+
+ProfStef next.'
+!
+
+messageSyntaxKeyword
+	^ Lesson
+title: 'Message syntax: Keyword messages' 
+contents: 
+'"Keyword Messages are messages with arguments. They have the following form:
+    anObject akey: anotherObject akey2: anotherObject2"
+
+''Web development is a good deal of pain'' copyFrom: 1 to: 30
+
+"The message is copyFrom:to: sent to the String ''Web development is a good deal of pain''"
+
+1 max: 3.
+
+Array with: ''hello'' with: 2 with: Smalltalk.
+
+"The message is with:with:with: implemented on class Array. Note you can also write"
+
+Array
+	with: ''Hi there!!''
+	with: 2
+	with: Smalltalk.
+	
+ProfStef perform: ''next''.'
+!
+
+messageSyntaxUnary
+	^ Lesson
+title: 'Message syntax: Unary messages' 
+contents: 
+'"Messages are sent to objects. There are three types of message: Unary, Binary and Keyword.
+
+Unary messages have the following form:
+    anObject aMessage 
+
+You''ve already sent unary messages. For example:"
+
+1 class.
+
+false not.
+
+Date today.
+
+Number pi.
+
+"And of course: "
+
+ProfStef next.'
+!
+
+pharoEnvironment
+	^ Lesson
+title: 'Pharo environment' 
+contents: 
+'"Every Smalltalk system is full of objects. There are windows, text, numbers, dates, colors, points and much more. You can interact with objects in a much more direct way than is possible with other programming languages.
+
+Every object understands the message ''explore''. As a result, you get an Explorer window that shows details about the object."
+
+Date today explore.
+
+"This shows that the date object consists of a point in time (start) and a duration (one day long)."
+
+ProfStef explore.
+
+"You see, ProfStef class has a lot of objects. Let''s take a look at my code:"
+
+ProfStef browse.
+
+ProfStef next.'
+!
+
+printing 
+	^ Lesson
+title: 'Doing VS Printing: Printing' 
+contents: 
+'"Now you''re a Do It master !! Let''s talk about printing. It''s a Do It which prints the result next to the expression you''ve selected.
+For example, select the text below, and click on ''PrintIt'':"
+
+1 + 2.
+
+"As with ''DoIt'', there is also a shortcut to execute this command.
+
+Try CTRL-p on the following expressions:"
+
+Date today.
+
+"The result is selected, so you can erase it using the backspace key. Try it !!"
+
+Date today asDateString.
+
+Date today asTimeString.
+
+ProfStef next.'
+!
+
+reflection
+	^ Lesson
+title: 'Reflection' 
+contents: 
+'"You can inspect and change the system at runtime.
+
+Take a look at the source code of the method #and: of the class Boolean:"
+
+(Boolean methodDictionary at: ''and:'') source.
+
+"Or all the methods it sends:"
+
+(Boolean methodDictionary at: ''and:'') messageSends.
+
+"Here''s all the methods I implement:"
+
+ProfStef methodDictionary.
+
+"Let''s create a new method to go to the next lesson:"
+
+|newMethod|
+newMethod := Compiler new load: ''goToNextLesson ProfStef next.'' forClass: ProfStef.
+ProfStef class addCompiledMethod: newMethod
+
+"Wow!! I can''t wait to use my new method!!"
+
+ProfStef goToNextLesson.'
+!
+
+reflectionContinued
+	^ Lesson
+title: 'Reflection continued' 
+contents: 
+'"So cool, isn''t it ?  Before going further, let''s remove this method:"
+
+ProfStef class methodAt: #goToNextLesson.
+
+ProfStef class removeCompiledMethod: (ProfStef class methodAt: #goToNextLesson).
+
+ProfStef class methodAt: #goToNextLesson.
+
+
+"Then move forward:"
+
+ProfStef perform:#next'
+!
+
+theEnd
+	^ Lesson
+title: 'Tutorial done !!' 
+contents: 
+'"This tutorial is done. Enjoy programming Smalltalk with JTalk. 
+
+You can run this tutorial again by evaluating: ProfStef go.
+
+See you soon !!"
+'
+!
+
+welcome
+	^ Lesson
+title: 'Welcome' 
+contents: 
+' "Hello!! I''m Professor Stef. 
+
+You must want me to help you learn Smalltalk.
+
+So let''s go to the first lesson.  Select the text below and click on the ''DoIt'' button"
+
+ProfStef next.'
+! !
+

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott