@@ -0,0 +1,2102 @@
1+
2+var Guid = function() {
3+ var counter = 0;
4+ var guid = function() { counter += 1; return counter; };
5+ return {guid : guid};
6+}();
7+var Foreign = function() {
8+ var JavaScript = function() {
9+ function castJSBoolToBool(b) { return b; }
10+ function castBoolToJSBool(b) { return b; }
11+
12+ function castJSNumberToFloat(n) { return n; }
13+ function castFloatToJSNumber(n) { return n; }
14+
15+ function castJSNumberToInt(n) { return ~~n; }
16+ function castIntToJSNumber(n) { return n; }
17+
18+ function castJSElementToElement(w) { return Element.jsElement(w); }
19+ function castElementToJSElement(elem) { return elem; }
20+
21+ function castJSArrayToList(arr) {
22+ var list = ["Nil"];
23+ for (var i = arr.length; i--; ) {
24+ list = [ "Cons", arr[i], list ];
25+ }
26+ return list;
27+ }
28+ function castListToJSArray(list) {
29+ var a = [];
30+ while (list[0] === "Cons") {
31+ a.push(list[1]);
32+ list = list[2];
33+ }
34+ return a;
35+ }
36+
37+ var castJSStringToString = castJSArrayToList;
38+ function castStringToJSString(str) {
39+ if (typeof str === "string") return str;
40+ return castListToJSArray(str).join('');
41+ }
42+
43+ function fromTuple(t) { return t.slice(1); }
44+ function toTuple(a) { return a.unshift("Tuple" + a.length); }
45+
46+ return {castJSBoolToBool:castJSBoolToBool,
47+ castBoolToJSBool:castBoolToJSBool,
48+ castJSNumberToFloat:castJSNumberToFloat,
49+ castFloatToJSNumber:castFloatToJSNumber,
50+ castJSNumberToInt:castJSNumberToInt,
51+ castIntToJSNumber:castIntToJSNumber,
52+ Experimental : {castJSElementToElement:castJSElementToElement,
53+ castElementToJSElement:castElementToJSElement},
54+ castJSArrayToList:castJSArrayToList,
55+ castListToJSArray:castListToJSArray,
56+ castJSStringToString:castJSStringToString,
57+ castStringToJSString:castStringToJSString,
58+ castTupleToJSTuple2:fromTuple,
59+ castTupleToJSTuple3:fromTuple,
60+ castTupleToJSTuple4:fromTuple,
61+ castTupleToJSTuple5:fromTuple,
62+ castJSTupleToTuple2:toTuple,
63+ castJSTupleToTuple3:toTuple,
64+ castJSTupleToTuple4:toTuple,
65+ castJSTupleToTuple5:toTuple
66+ };
67+ }();
68+ return {JavaScript:JavaScript};
69+}();
70+var Value = function(){
71+
72+ var eq = function(x,y) {
73+ if (typeof x === "object") {
74+ if (x === y) return true;
75+ if (x.length !== y.length) return false;
76+ for (var i = x.length; i--; ) {
77+ if (!eq(x[i],y[i])) return false;
78+ }
79+ return true;
80+ }
81+ return x === y;
82+ };
83+
84+ var Tuple = function() {
85+ var len = arguments.length;
86+ var arr = new Array(len+1);
87+ arr[0] = "Tuple" + arguments.length;
88+ for (var i = len; i--; ) {
89+ arr[i+1] = arguments[i];
90+ }
91+ return arr;
92+ };
93+
94+ var listToArray = function(list) {
95+ var arr = [];
96+ while (list[0] === "Cons") {
97+ arr.push(list[1]);
98+ list = list[2];
99+ }
100+ return arr;
101+ };
102+
103+ var properEscape = function(str) {
104+ str.replace('"', """);
105+ str.replace("&", "&");
106+ str.replace("'", "'");
107+ str.replace("<", "<");
108+ str.replace(">", ">");
109+ return str;
110+ };
111+
112+ var toText = function(elmList) {
113+ if (typeof elmList === "string") return elmList;
114+ var a = [];
115+ while (elmList[0] === "Cons") {
116+ a.push(elmList[1]);
117+ elmList = elmList[2];
118+ }
119+ return properEscape(a.join(''));
120+ };
121+
122+ var toString = function(v) {
123+ if (typeof v === "boolean") {
124+ return v ? "True" : "False";
125+ } else if (typeof v === "number") {
126+ return v+"";
127+ } else if (v[0]) {
128+ if (v[0].substring(0,5) === "Tuple") {
129+ var output = "";
130+ for (var i = v.length; --i; ) {
131+ output = "," + toString(v[i]) + output;
132+ }
133+ if (output[0] === ",") output = output.substring(1);
134+ return "("+output+")";
135+ } else if (v[0] === "Cons") {
136+ var start = (typeof v[1] === "string") ? '"' : "[";
137+ var end = (typeof v[1] === "string") ? '"' : "]";
138+ var div = (typeof v[1] === "string") ? "" : ",";
139+ var output = start + toString(v[1]);
140+ v = v[2];
141+ while (true) {
142+ if (v[0] === "Cons") {
143+ output += div + toString(v[1]);
144+ v = v[2];
145+ } else {
146+ return output + end;
147+ }
148+ }
149+ } else if (v[0] === "Nil") {
150+ return "[]";
151+ } else {
152+ var output = "";
153+ for (var i = v.length; --i; ) {
154+ output = " " + toString(v[i]) + output
155+ }
156+ output = v[0] + output;
157+ return (v.length > 1) ? "(" + output + ")" : output;
158+ }
159+ }
160+ return v+"";
161+ };
162+ var show = function(v) {
163+ return Text.monospace(properEscape(toString(v)));
164+ };
165+ var append = function(xs,ys) {
166+ if (typeof xs === "string" && typeof ys === "string") {
167+ return xs.concat(ys);
168+ }
169+ if (xs[0] === "Nil") {
170+ return ys;
171+ }
172+ var root = ["Cons", xs[1], ["Nil"]];
173+ var curr = root;
174+ xs = xs[2];
175+ while (xs[0]==="Cons") {
176+ curr[2] = ["Cons", xs[1], ["Nil"]];
177+ xs = xs[2];
178+ curr = curr[2];
179+ }
180+ curr[2] = ys;
181+ return root;
182+ };
183+
184+ var str = function(s) {
185+ var out = ["Nil"];
186+ for (var i = s.length; i--; ) {
187+ out = ["Cons", s[i], out];
188+ }
189+ return out;
190+ };
191+
192+ return {eq:eq,
193+ str:str,
194+ show:show,
195+ Tuple:Tuple,
196+ append:append,
197+ listToArray:listToArray,
198+ toText : toText,
199+ properEscape : properEscape};
200+}();var List = function() {
201+
202+ var throwError = function(f) {
203+ throw "Function '" + f + "' expecting a list!";
204+ }
205+
206+ function length(xs) {
207+ var out = 0;
208+ while (xs[0] === "Cons") {
209+ out += 1;
210+ xs = xs[2];
211+ }
212+ return out;
213+ };
214+ var reverse = foldl(function(x_72) {
215+ return function(y_73) {
216+ return["Cons", x_72, y_73]
217+ }
218+ })(["Nil"]);
219+ var concat = foldr(function(x_74) {
220+ return function(y_75) {
221+ return Value.append(x_74, y_75)
222+ }
223+ })(["Nil"]);
224+ var and = foldl(function(x_77) {
225+ return function(y_78) {
226+ return x_77 && y_78
227+ }
228+ })(true);
229+ var or = foldl(function(x_79) {
230+ return function(y_80) {
231+ return x_79 || y_80
232+ }
233+ })(false);
234+ var sum = foldl(function(x_89) {
235+ return function(y_90) {
236+ return x_89 + y_90
237+ }
238+ })(0);
239+ var product = foldl(function(x_91) {
240+ return function(y_92) {
241+ return x_91 * y_92
242+ }
243+ })(1);
244+ var maximum = foldl1(function(x) { return function(y) { return Math.max(x,y) } });
245+ var minimum = foldl1(function(x) { return function(y) { return Math.min(x,y) } });
246+ function head(v) {
247+ if (v[0] !== "Cons") {
248+ throw "Error: 'head' only accepts lists of length greater than one.";
249+ }
250+ return v[1];
251+ }
252+ function tail(v) {
253+ if (v[0] !== "Cons") {
254+ throw "Error: 'tail' only accepts lists of length greater than one.";
255+ }
256+ return v[2];
257+ }
258+ function last(v) {
259+ if (v[0] !== "Cons") {
260+ throw "Error: 'last' only accepts lists of length greater than one.";
261+ }
262+ var out = v[1];
263+ while (v[0] === "Cons") {
264+ out = v[1];
265+ v = v[2];
266+ }
267+ return out;
268+ }
269+ function map(f) {
270+ return function(xs) {
271+ if (xs[0] === "Nil") { return xs; }
272+ if (xs[0] !== "Cons") { throwError('map'); }
273+ var root = ["Cons", f(xs[1]), ["Nil"]];
274+ var curr = root;
275+ xs = xs[2];
276+ while (xs[0]==="Cons") {
277+ curr[2] = ["Cons", f(xs[1]), ["Nil"]];
278+ xs = xs[2];
279+ curr = curr[2];
280+ }
281+ return root;
282+ }
283+ }
284+ function foldl(f) {
285+ return function(b) {
286+ return function(xs) {
287+ var acc = b;
288+ if (xs[0] === "Nil") { return acc; }
289+ if (xs[0] !== "Cons") { throwError('foldl'); }
290+ while (xs[0] === "Cons") {
291+ acc = f(xs[1])(acc);
292+ xs = xs[2];
293+ }
294+ return acc;
295+ }
296+ }
297+ }
298+ function foldr(f) {
299+ return function(b) {
300+ return function(xs) {
301+ var acc = b;
302+ if (xs[0] === "Nil") { return acc; }
303+ if (xs[0] !== "Cons") { throwError('foldr'); }
304+ var arr = [];
305+ while (xs[0] === "Cons") {
306+ arr.push(xs[1]);
307+ xs = xs[2];
308+ }
309+ for (var i = arr.length; i--; ) {
310+ acc = f(arr[i])(acc);
311+ }
312+ return acc;
313+ }
314+ }
315+ }
316+ function foldl1(f_49) {
317+ return function(_temp_50) {
318+ return function(v) {
319+ if("Cons" !== v[0]) {
320+ return undefined
321+ }else {
322+ var x_51 = v[1];
323+ var xs_52 = v[2];
324+ return foldl(f_49)(x_51)(xs_52)
325+ }
326+ }(_temp_50)
327+ }
328+ }
329+ function foldr1(f) {
330+ return function(xs) {
331+ if (xs[0] === "Nil") { throw "'foldr1' requires an non-empty list." }
332+ if (xs[0] !== "Cons") { throwError('foldr1'); }
333+ var arr = [];
334+ while (xs[0] === "Cons") {
335+ arr.push(xs[1]);
336+ xs = xs[2];
337+ }
338+ var acc = arr.pop();
339+ for (var i = arr.length; i--; ) {
340+ acc = f(arr[i])(acc);
341+ }
342+ return acc;
343+ }
344+ }
345+ function scanl(f) {
346+ return function(b) {
347+ return function(xs) {
348+ if (xs[0] === "Nil") { return ["Cons",b,["Nil"]]; }
349+ if (xs[0] !== "Cons") { throwError('scanl'); }
350+ var arr = [b];
351+ while (xs[0] === "Cons") {
352+ b = f(xs[1])(b);
353+ arr.push(b);
354+ xs = xs[2];
355+ }
356+ var out = ["Nil"];
357+ for (var i = arr.length; i--; ) {
358+ out = ["Cons", arr[i], out];
359+ }
360+ return out;
361+ }
362+ }
363+ }
364+ function scanl1(f) {
365+ return function(xs) {
366+ if (xs[0] !== "Cons") {
367+ throw "Error: 'scanl1' requires a list of at least length 1.";
368+ }
369+ return scanl(f)(xs[1])(xs[2]);
370+ }
371+ }
372+ function filter(pred) {
373+ return function(xs) {
374+ if (xs[0] === "Nil") { return xs; }
375+ if (xs[0] !== "Cons") { throwError('filter'); }
376+ var arr = [];
377+ while (xs[0] === "Cons") {
378+ if (pred(xs[1])) { arr.push(xs[1]); }
379+ xs = xs[2];
380+ }
381+ var out = ["Nil"];
382+ for (var i = arr.length; i--; ) {
383+ out = ["Cons", arr[i], out];
384+ }
385+ return out;
386+ }
387+ }
388+ function concatMap(f_76) {
389+ return function(x) {
390+ return concat(map(f_76)(x))
391+ }
392+ }
393+ function forall(pred) {
394+ return foldl(function(x) { return function(acc) {
395+ return acc && pred(x);
396+ };})(true);
397+ }
398+ function exists(pred) {
399+ return foldl(function(x) { return function(acc) {
400+ return acc || pred(x);
401+ };})(false);
402+ }
403+ function partition(pred_93) {
404+ return function(lst_94) {
405+ return function() {
406+ var v = lst_94;
407+ var c = [function(v) {
408+ if("Nil" !== v[0]) {
409+ return undefined
410+ }else {
411+ return["Tuple2", ["Nil"], ["Nil"]]
412+ }
413+ }, function(v) {
414+ if("Cons" !== v[0]) {
415+ return undefined
416+ }else {
417+ var x_95 = v[1];
418+ var xs_96 = v[2];
419+ return function(v) {
420+ if("Tuple2" !== v[0]) {
421+ return undefined
422+ }else {
423+ var as_97 = v[1];
424+ var bs_98 = v[2];
425+ return pred_93(x_95) ? ["Tuple2", ["Cons", x_95, as_97], bs_98] : ["Tuple2", as_97, ["Cons", x_95, bs_98]]
426+ }
427+ }(partition(pred_93)(xs_96))
428+ }
429+ }];
430+ for(var i = c.length;i--;) {
431+ var r = c[i](v);
432+ if(r !== undefined) {
433+ return r
434+ }
435+ }
436+ }()
437+ }
438+ }
439+ function zipWith(f) {
440+ return function(listA) {
441+ return function(listB) {
442+ if (listA[0] === "Nil" || listB[0] === "Nil") { return ["Nil"]; }
443+ if (listA[0] !== "Cons" || listB[0] !== "Cons") { throwError('zipWith'); }
444+ var arr = [];
445+ while (listA[0] === "Cons" && listB[0] === "Cons") {
446+ arr.push(f(listA[1])(listB[1]));
447+ listA = listA[2];
448+ listB = listB[2];
449+ }
450+ var out = ["Nil"];
451+ for (var i = arr.length; i--; ) {
452+ out = ["Cons", arr[i], out];
453+ }
454+ return out;
455+ }
456+ }
457+ }
458+ function zip(listA) {
459+ return function(listB) {
460+ if (listA[0] === "Nil" || listB[0] === "Nil") { return ["Nil"]; }
461+ if (listA[0] !== "Cons" || listB[0] !== "Cons") { throwError('zip'); }
462+ var arr = [];
463+ while (listA[0] === "Cons" && listB[0] === "Cons") {
464+ arr.push(["Tuple2", listA[1], listB[1]]);
465+ listA = listA[2];
466+ listB = listB[2];
467+ }
468+ var out = ["Nil"];
469+ for (var i = arr.length; i--; ) {
470+ out = ["Cons", arr[i], out];
471+ }
472+ return out;
473+ }
474+ }
475+ function unzip(pairs_112) {
476+ return function() {
477+ var v = pairs_112;
478+ var c = [function(v) {
479+ if("Nil" !== v[0]) {
480+ return undefined
481+ }else {
482+ return["Tuple2", ["Nil"], ["Nil"]]
483+ }
484+ }, function(v) {
485+ if("Cons" !== v[0]) {
486+ return undefined
487+ }else {
488+ var p_113 = v[1];
489+ var ps_114 = v[2];
490+ return function(v) {
491+ if("Tuple2" !== v[0]) {
492+ return undefined
493+ }else {
494+ if("Tuple2" !== v[1][0]) {
495+ return undefined
496+ }else {
497+ var x_115 = v[1][1];
498+ var y_116 = v[1][2];
499+ if("Tuple2" !== v[2][0]) {
500+ return undefined
501+ }else {
502+ var xs_117 = v[2][1];
503+ var ys_118 = v[2][2];
504+ return["Tuple2", ["Cons", x_115, xs_117], ["Cons", y_116, ys_118]]
505+ }
506+ }
507+ }
508+ }(["Tuple2", p_113, unzip(ps_114)])
509+ }
510+ }];
511+ for(var i = c.length;i--;) {
512+ var r = c[i](v);
513+ if(r !== undefined) {
514+ return r
515+ }
516+ }
517+ }()
518+ }
519+ function intersperse(sep_119) {
520+ return function(xs_120) {
521+ return function() {
522+ var v = xs_120;
523+ var c = [function(v) {
524+ if("Nil" !== v[0]) {
525+ return undefined
526+ }else {
527+ return["Nil"]
528+ }
529+ }, function(v) {
530+ if("Cons" !== v[0]) {
531+ return undefined
532+ }else {
533+ var a_124 = v[1];
534+ if("Nil" !== v[2][0]) {
535+ return undefined
536+ }else {
537+ return["Cons", a_124, ["Nil"]]
538+ }
539+ }
540+ }, function(v) {
541+ if("Cons" !== v[0]) {
542+ return undefined
543+ }else {
544+ var a_121 = v[1];
545+ if("Cons" !== v[2][0]) {
546+ return undefined
547+ }else {
548+ var b_122 = v[2][1];
549+ var cs_123 = v[2][2];
550+ return["Cons", a_121, ["Cons", sep_119, intersperse(sep_119)(["Cons", b_122, cs_123])]]
551+ }
552+ }
553+ }];
554+ for(var i = c.length;i--;) {
555+ var r = c[i](v);
556+ if(r !== undefined) {
557+ return r
558+ }
559+ }
560+ }()
561+ }
562+ }
563+ function intercalate(sep_125) {
564+ return function(xs_126) {
565+ return function() {
566+ var v = xs_126;
567+ var c = [function(v) {
568+ if("Nil" !== v[0]) {
569+ return undefined
570+ }else {
571+ return["Nil"]
572+ }
573+ }, function(v) {
574+ if("Cons" !== v[0]) {
575+ return undefined
576+ }else {
577+ var a_130 = v[1];
578+ if("Nil" !== v[2][0]) {
579+ return undefined
580+ }else {
581+ return a_130
582+ }
583+ }
584+ }, function(v) {
585+ if("Cons" !== v[0]) {
586+ return undefined
587+ }else {
588+ var a_127 = v[1];
589+ if("Cons" !== v[2][0]) {
590+ return undefined
591+ }else {
592+ var b_128 = v[2][1];
593+ var cs_129 = v[2][2];
594+ return Value.append(a_127, Value.append(sep_125, intercalate(sep_125)(["Cons", b_128, cs_129])))
595+ }
596+ }
597+ }];
598+ for(var i = c.length;i--;) {
599+ var r = c[i](v);
600+ if(r !== undefined) {
601+ return r
602+ }
603+ }
604+ }()
605+ }
606+ }
607+ function sort(xs) {
608+ if (xs[0] === "Nil") { return xs; }
609+ if (xs[0] !== "Cons") { throwError('sort'); }
610+ var arr = [];
611+ while (xs[0] === "Cons") {
612+ arr.push(xs[1]);
613+ xs = xs[2];
614+ }
615+ arr.sort(function(a,b) { return a - b});
616+ var out = ["Nil"];
617+ for (var i = arr.length; i--; ) {
618+ out = [ "Cons", arr[i], out ];
619+ }
620+ return out;
621+ }
622+ function take(n) { return function(xs) {
623+ if (n <= 0) { return ["Nil"]; }
624+ if (xs[0] === "Nil") { return xs; }
625+ if (xs[0] !== "Cons") { throwError('take'); }
626+ var out = [ "Cons", xs[1], ["Nil"] ];
627+ var temp = out;
628+ xs = xs[2];
629+ --n;
630+ while (xs[0] === "Cons" && n > 0) {
631+ temp[2] = [ "Cons", xs[1], ["Nil"] ];
632+ temp = temp[2];
633+ xs = xs[2];
634+ --n;
635+ }
636+ return out;
637+ };
638+ }
639+ function drop(n) { return function(xs) {
640+ if (xs[0] === "Nil") { return xs; }
641+ if (xs[0] !== "Cons") { throwError('drop'); }
642+ while (xs[0] === "Cons" && n > 0) {
643+ xs = xs[2];
644+ --n;
645+ }
646+ return xs;
647+ };
648+ }
649+ return {head:head,
650+ tail:tail,
651+ last:last,
652+ map:map,
653+ foldl:foldl,
654+ foldr:foldr,
655+ foldl1:foldl1,
656+ foldr1:foldr1,
657+ scanl:scanl,
658+ scanl1:scanl1,
659+ filter:filter,
660+ length:length,
661+ reverse:reverse,
662+ concat:concat,
663+ concatMap:concatMap,
664+ and:and,
665+ or:or,
666+ forall:forall,
667+ exists:exists,
668+ sum:sum,
669+ product:product,
670+ maximum:maximum,
671+ minimum:minimum,
672+ partition:partition,
673+ zipWith:zipWith,
674+ zip:zip,
675+ unzip:unzip,
676+ intersperse:intersperse,
677+ intercalate:intercalate,
678+ sort:sort,
679+ take:take,
680+ drop:drop};
681+}();
682+var Data = function() {
683+
684+var Char = function() {
685+ return {fromCode : function(c) { return String.fromCharCode(c); },
686+ toCode : function(c) { return c.charCodeAt(0); },
687+ toUpper : function(c) { return c.toUpperCase(); },
688+ toLower : function(c) { return c.toLowerCase(); },
689+ toLocaleUpper : function(c) { return c.toLocaleUpperCase(); },
690+ toLocaleLower : function(c) { return c.toLocaleLowerCase(); }
691+ };
692+}();
693+
694+var Maybe = function() {
695+ function consMaybe(x) { return function(xs) {
696+ if (x[0] === "Just") return ["Cons", x[1], xs];
697+ return xs;
698+ };
699+ }
700+ function fromMaybe(b) { return function(m) {
701+ if (m[0] === "Just") return m[1];
702+ return b;
703+ };
704+ }
705+ function mapCons(f) { return function(y) { return function(xs) {
706+ var x = f(y);
707+ if (x[0] === "Just") return ["Cons", x[1], xs];
708+ return xs;
709+ };
710+ };
711+ }
712+ function maybe(b) { return function(f) { return function(m) {
713+ if (m[0] === "Just") return f(m[1]);
714+ return b;
715+ };
716+ };
717+ }
718+
719+ return {Just : function(x) { return ["Just",x]; },
720+ Nothing : ["Nothing"],
721+ catMaybes : List.foldr(consMaybe)(["Nil"]),
722+ isJust : function(m) { return m[0] === "Just"; },
723+ isNothing : function(m) { return m[0] === "Nothing"; },
724+ fromMaybe : fromMaybe,
725+ consMaybe : consMaybe,
726+ mapMaybe : function(f) { return List.foldr(mapCons(f))(["Nil"]); },
727+ maybe : maybe
728+ };
729+}();
730+
731+/*
732+var String = function() {
733+
734+ function append(s1) { return function(s2) {
735+ return s1.concat(s2);
736+ };
737+ }
738+ function map(f) { return function(s) {
739+ for (var i = s.length; i--; ) { s[i] = f(s[i]); }
740+ };
741+ }
742+
743+ function intercalate(sep) { return function(ss) {
744+ return Value.listToArray(ss).join(sep);
745+ };
746+ }
747+ function intersperse(sep) { return function(s) {
748+ return s.split("").join(sep);
749+ };
750+ }
751+
752+ function foldl(f) { return function(b) { return function(s) {
753+ var acc = b;
754+ for (var i = 0, len = s.length; i < len; ++i) { acc = f(s[i])(acc); }
755+ return acc;
756+ };
757+ };
758+ }
759+ function foldr(f) { return function(b) { return function(s) {
760+ var acc = b;
761+ for (var i = s.length; i--; ) { acc = f(s[i])(acc); }
762+ return acc;
763+ };
764+ };
765+ }
766+
767+ function concatMap(f) { return function(s) {
768+ var a = s.split("");
769+ for (var i = a.length; i--; ) { a[i] = f(a[i]); }
770+ return a.join("");
771+ };
772+ }
773+
774+ function forall(pred) { return function(s) {
775+ for (var i = s.length; i--; ) { if (!pred(s[i])) {return false}; }
776+ return true;
777+ };
778+ }
779+ function exists(pred) { return function(s) {
780+ for (var i = s.length; i--; ) { if (pred(s[i])) {return true}; }
781+ return false;
782+ };
783+ }
784+
785+ return {cons : append,
786+ snoc : append,
787+ head : function(s) { return s[0]; },
788+ last : function(s) { return s[s.length-1]; },
789+ tail : function(s) { return s.slice(1); },
790+ length : function(s) { return s.length; },
791+ map : map,
792+ intercalate : intercalate,
793+ intersperse : intersperse,
794+ reverse : function(s) { return s.split("").reverse().join(""); },
795+ toLower : function(s) { return s.toLowerCase(); },
796+ toUpper : function(s) { return s.toUpperCase(); },
797+ foldl : foldl,
798+ foldr : foldr,
799+ concat : function(ss) { return Value.listToArray(ss).join(""); },
800+ concatMap : concatMap,
801+ forall : forall,
802+ exists : exists,
803+ //filter : filter,
804+ //take:,
805+ //drop:,
806+ toText : Value.toText,
807+ properEscape : Value.properEscape
808+ };
809+}();
810+*/
811+return {String: {toText:Value.toText, properEscape:Value.properEscape},
812+ Char:Char,
813+ Maybe:Maybe,
814+ List:List
815+ };
816+}();
817+var Color = function() {
818+
819+ var create = function(r,g,b,a) {
820+ return { r: r,
821+ g: g,
822+ b: b,
823+ a: a };
824+ };
825+
826+ var extract = function(c) {
827+ if (c.a === 1) {
828+ return 'rgb(' + c.r + ',' + c.g + ',' + c.b + ')';
829+ }
830+ return 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + c.a + ')';
831+ };
832+
833+ var rgba = function(r) { return function(g) { return function(b) {
834+ return function(a) { return create(r,g,b,a); }; }; };
835+ };
836+
837+ var rgb = function(r) { return function(g) { return function(b) {
838+ return create(r,g,b,1); }; };
839+ };
840+ return {black: create( 0, 0, 0,1),
841+ white: create(255,255,255,1),
842+ red : create(255, 0, 0,1),
843+ green: create( 0,255, 0,1),
844+ blue : create( 0, 0,255,1),
845+
846+ gray : create(128,128,128,1),
847+ grey : create(128,128,128,1),
848+
849+ yellow : create(255,255, 0,1),
850+ cyan : create( 0,255,255,1),
851+ magenta : create(255, 0,255,1),
852+
853+ rgba : rgba,
854+ rgb : rgb,
855+ Internal : { extract:extract }
856+ };
857+}();
858+var Element = function() {
859+ var newElement = function(elementType) {
860+ var e = document.createElement(elementType);
861+ e.id = Guid.guid();
862+ e.style.padding = "0";
863+ e.style.margin = "0";
864+ return e;
865+ };
866+ var addTo = function(container, elem) {
867+ container.appendChild(clone(elem));
868+ };
869+ var clone = function(e) {
870+ return e;
871+ };
872+ var divify = function(e) {
873+ var div = newElement('div');
874+ addTo(div, e);
875+ return div;
876+ };
877+
878+ var rectangle = function(w) { return function(h) {
879+ var e = newElement('div');
880+ e.isElmLeaf = true;
881+ e.style.width = w + "px";
882+ e.style.height = h + "px";
883+ return e;
884+ };
885+ };
886+
887+ var makeText = function(w) { return function(pos) { return function(txt) {
888+ var e = newElement('div');
889+ e.isElmLeaf = true;
890+ e.isElmText = true;
891+ e.innerHTML = txt;
892+ e.style.textAlign = pos;
893+ if (w > 0) e.style.width = w + "px";
894+ return e;
895+ };
896+ };
897+ };
898+ var correctTextSize = function(e) {
899+ var w = e.style.width ? e.style.width.slice(0,-2) : 0;
900+
901+ var t = newElement('div');
902+ t.innerHTML = e.innerHTML;
903+ t.style.textAlign = e.style.textAlign;
904+ if (w > 0) { t.style.width = w + "px"; }
905+
906+ t.style.visibility = "hidden";
907+ t.style.styleFloat = "left";
908+ t.style.cssFloat = "left";
909+
910+ document.body.appendChild(t);
911+ var cStyle = window.getComputedStyle(t);
912+ if (w <= 0) e.style.width = cStyle.getPropertyValue("width");
913+ e.style.height = cStyle.getPropertyValue("height");
914+ document.body.removeChild(t);
915+ };
916+
917+ var link = function (href) { return function (e) {
918+ var a = newElement('a');
919+ a.href = Text.fromString(href);
920+ addTo(a,e);
921+ return divify(a);
922+ };
923+ };
924+
925+ var text = makeText(0)('left');
926+ var plainText = function(str) {
927+ return makeText(0)("left")(Data.String.toText(str)); };
928+ var justifiedText = makeText(0)('justify');
929+ var centeredText = makeText(0)('center');
930+ var rightedText = makeText(0)('right');
931+ var asText = function(v) { return makeText(0)("left")(Value.show(v)); };
932+
933+ var image = function(src) {
934+ var img = newElement('img');
935+ img.isElmLeaf = true;
936+ img.onload = function() {
937+ if (img.style.width === "" && this.width > 0) {
938+ img.style.width = img.width = this.width + "px";
939+ }
940+ if (img.style.height === "" && this.height > 0) {
941+ img.style.height = img.height = this.height + "px";
942+ }
943+ Dispatcher.adjust()
944+ };
945+ img.src = Data.String.toText(src);
946+ img.name = img.src;
947+ return img;
948+ };
949+ var fittedImage = function(w) { return function(h) { return function(src) {
950+ var canvas = newElement('canvas');
951+ canvas.style.width = w + 'px';
952+ canvas.style.height = h + 'px';
953+ canvas.width = w;
954+ canvas.height = h;
955+ canvas.innerHTML = "Your browser does not support the canvas element.";
956+ canvas.isElmLeaf = true;
957+
958+ var img = newElement('img');
959+ img.onload = function() {
960+ if (canvas.getContext) {
961+ var ctx = canvas.getContext('2d');
962+ var sx = 0, sy = 0, sWidth = this.width, sHeight = this.height;
963+ if (w / h > this.width / this.height) {
964+ sHeight = this.width * h / w;
965+ sy = (this.height - sHeight) / 2
966+ } else {
967+ sWidth = this.height * w / h;
968+ sx = (this.width - sWidth) / 2
969+ }
970+ ctx.drawImage(img, sx, sy, sWidth, sHeight,
971+ 0,0, canvas.width, canvas.height);
972+ }
973+ };
974+ img.src = Data.String.toText(src);
975+ return canvas;
976+ };
977+ };
978+ };
979+
980+ var video = function(src) {
981+ src = Data.String.toText(src);
982+ var e = newElement('video');
983+ e.controls = "controls";
984+ var source = newElement('source');
985+ source.src = src;
986+ source.type = "video/" + src.substring(src.length - 3, src.length);
987+ addTo(e, source);
988+ e.isElmLeaf = true;
989+ return e;
990+ };
991+ var audio = function(src) {
992+ src = Data.String.toString(src);
993+ var e = newElement('video');
994+ e.controls = "controls";
995+ var source = newElement('source');
996+ source.src = src;
997+ source.type = "audio/" + src.substring(src.length - 3, src.length);
998+ addTo(e, source);
999+ e.isElmLeaf = true;
1000+ return e;
1001+ };
1002+ var collage = function(w) { return function(h) { return function(cflist) {
1003+ var canvas = newElement('canvas');
1004+ canvas.style.width = w + 'px';
1005+ canvas.style.height = h + 'px';
1006+ canvas.width = w;
1007+ canvas.height = h;
1008+ if (canvas.getContext) {
1009+ var ctx = canvas.getContext('2d');
1010+ ctx.clearRect(0,0, canvas.width, canvas.height);
1011+ while (cflist[0] === "Cons") {
1012+ ctx = cflist[1](ctx);
1013+ cflist = cflist[2];
1014+ }
1015+ return canvas;
1016+ }
1017+ canvas.innerHTML = "Your browser does not support the canvas element.";
1018+ canvas.isElmLeaf = true;
1019+ return canvas;
1020+ };
1021+ };
1022+ };
1023+
1024+ var goDown = function(e) {
1025+ return e.tagName === "DIV" ? e : divify(e);
1026+ };
1027+ var goRight = function(e) {
1028+ e.style.styleFloat = "left";
1029+ e.style.cssFloat = "left";
1030+ return e;
1031+ };
1032+ var goIn = function(e) {
1033+ e.style.position = 'absolute';
1034+ return e;
1035+ };
1036+ var flowWith = function(dir, f, elist) {
1037+ var container = newElement('div');
1038+ for (var i = elist.length; i--; ) {
1039+ addTo(container, f(elist[i]));
1040+ }
1041+ container.elmFlowDirection = dir;
1042+ return container;
1043+ };
1044+
1045+ var flow = function(direction) { return function(elist) {
1046+ var arr = [];
1047+ while (elist[0] === "Cons") {
1048+ arr.push(elist[1]);
1049+ elist = elist[2];
1050+ }
1051+ if (direction >= 3) arr.reverse();
1052+ var f = function(x) { return x; };
1053+ var dir = direction % 3;
1054+ if (dir == 0) return flowWith("Y", goDown , arr);
1055+ if (dir == 1) return flowWith("X", goRight, arr);
1056+ if (dir == 2) return flowWith("Z", goIn , arr);
1057+ };
1058+ };
1059+
1060+ var beside = function(a) { return function(b) {
1061+ return flow(4)(["Cons",a,["Cons",b,["Nil"]]]); }; };
1062+ var above = function(a) { return function(b) {
1063+ return flow(3)(["Cons",a,["Cons",b,["Nil"]]]); }; };
1064+ var below = function(a) { return function(b) {
1065+ return flow(0)(["Cons",a,["Cons",b,["Nil"]]]); }; };
1066+
1067+ var box = function(pos) { return function(e) {
1068+ e.style.position = "absolute";
1069+ e.style.margin = "auto";
1070+ var x = (pos - 1) % 3;
1071+ var y = (pos - 1) / 3;
1072+ if (x < 2) e.style.left = 0;
1073+ if (x > 0) e.style.right = 0;
1074+ if (y < 2) e.style.top = 0;
1075+ if (y > 0) e.style.bottom = 0;
1076+ var div = newElement('div');
1077+ div.style.position = "relative";
1078+ addTo(div,e);
1079+ return div;
1080+ };
1081+ };
1082+
1083+ var width = function(w) { return function(e) {
1084+ if (e.tagName === "A") {
1085+ width(w)(e.firstChild);
1086+ return e;
1087+ }
1088+ if (e.hasOwnProperty('isElmText')) {
1089+ var d = makeText(w)(e.style.textAlign)(e.innerHTML);
1090+ e.style.height = d.style.height;
1091+ }
1092+ e.style.width = w + "px";
1093+ return e;
1094+ };
1095+ };
1096+ var height = function(h) { return function(e) {
1097+ (e.tagName === "A" ? e.firstChild : e).style.height = h + "px";
1098+ return e;
1099+ };
1100+ };
1101+ var size = function(w) { return function(h) { return function(e) {
1102+ var d = e.tagName === "A" ? e.firstChild : e;
1103+ d.style.width = w + "px";
1104+ d.style.height = h + "px";
1105+ return e;
1106+ };
1107+ };
1108+ };
1109+
1110+ var color = function(c) { return function(e) {
1111+ e.style.backgroundColor = Color.Internal.extract(c);
1112+ return e;
1113+ };
1114+ };
1115+ var opacity = function(value) { return function(e) {
1116+ e.style.opacity = value;
1117+ return e;
1118+ };
1119+ };
1120+
1121+ var jsElement = function(w) { return function(h) { return function(elem) {
1122+ var e = newElement('div');
1123+ e.isElmLeaf = true;
1124+ e.style.width = w + "px";
1125+ e.style.height = h + "px";
1126+ addTo(e,elem);
1127+ return e;
1128+ };
1129+ };
1130+ };
1131+
1132+ return {text : text,
1133+ image : image,
1134+ fittedImage : fittedImage,
1135+ video : video,
1136+ audio : audio,
1137+ collage : collage,
1138+ flow : flow,
1139+ layers : flow(2),
1140+ rectangle : rectangle,
1141+
1142+ beside : beside,
1143+ above : above,
1144+ below : below,
1145+ box : box,
1146+
1147+ width : width,
1148+ height : height,
1149+ size : size,
1150+ color : color,
1151+ opacity : opacity,
1152+
1153+ link : link,
1154+ asText : asText,
1155+ plainText : plainText,
1156+ justifiedText : justifiedText,
1157+ centeredText : centeredText,
1158+ rightedText : rightedText,
1159+
1160+ // directions
1161+ up : 0,
1162+ left : 1,
1163+ inward : 2,
1164+ down : 3,
1165+ right : 4,
1166+ outward : 5,
1167+
1168+ correctTextSize : correctTextSize,
1169+ jsElement : jsElement
1170+ };
1171+}();
1172+
1173+
1174+
1175+var Text = function() {
1176+ var fromString = function(elmList) {
1177+ if (typeof elmList === "string") return elmList;
1178+ var a = [];
1179+ while (elmList[0] === "Cons") {
1180+ a.push(elmList[1]);
1181+ elmList = elmList[2];
1182+ }
1183+ return Data.String.properEscape(a.join(''));
1184+ };
1185+
1186+ var addTag = function(tag) { return function(text) {
1187+ return '<' + tag + ' style="padding:0;margin:0">' + text + '</' + tag + '>';
1188+ };
1189+ };
1190+ var addStyle = function(style, value) { return function(text) {
1191+ return "<span style='" + style + ":" + value + "'>" + text + "</span>";
1192+ };
1193+ };
1194+
1195+ var typeface = function(name) { return addStyle('font-family', name); };
1196+ var size = function(px) {
1197+ return addStyle('font-size', px + 'px');
1198+ };
1199+ var header = addTag('h1');
1200+ var height = function(h) { return addStyle('font-size', h+'em'); }
1201+ var italic = addStyle('font-style', 'italic');
1202+ var bold = addTag('b');
1203+ var color = function(c) {
1204+ return addStyle('color', Color.Internal.extract(c));
1205+ };
1206+ var underline = addStyle('text-decoration', 'underline');
1207+ var overline = addStyle('text-decoration', 'overline');
1208+ var strikeThrough = addStyle('text-decoration', 'line-through');
1209+ var link = function(href) { return function(text) {
1210+ return "<a href='" + fromString(href) + "'>" + text + "</a>";
1211+ };
1212+ };
1213+
1214+ return {fromString : fromString,
1215+ toText: fromString,
1216+ header : header,
1217+ height : height,
1218+ italic : italic,
1219+ bold : bold,
1220+ underline : underline,
1221+ overline : overline,
1222+ strikeThrough : strikeThrough,
1223+ monospace : typeface('monospace'),
1224+ color : color,
1225+ link : link };
1226+}();
1227+var Shape = function() {
1228+
1229+ var create = function(center, ps, theta, s) {
1230+ return { center: center, points: ps, theta: theta, scale: s };
1231+ };
1232+
1233+ //// Construction ////
1234+
1235+ var polygon = function(ps) { return function(center) {
1236+ var parr = [];
1237+ while (ps[0] === "Cons") {
1238+ parr.push([ps[1][1], ps[1][2]]);
1239+ ps = ps[2];
1240+ }
1241+ center = [center[1], center[2]];
1242+ return create(center, parr, 0, 1);
1243+ };
1244+};
1245+ var ngon = function(n) { return function(r) { return function(center) {
1246+ var ps = [];
1247+ for (var i = n; i--;) {
1248+ ps.push([r * Math.cos(Math.PI * 2 * i/n),
1249+ r * Math.sin(Math.PI * 2 * i/n)]);
1250+ }
1251+ center = [center[1], center[2]];
1252+ return create(center, ps, 0, 1);
1253+ };
1254+ };
1255+};
1256+ var rect = function(w) { return function(h) { return function(center) {
1257+ var ps = [[- w/2, - h/2],
1258+ [ w/2, - h/2],
1259+ [ w/2, h/2],
1260+ [- w/2, h/2]];
1261+ center = [center[1], center[2]];
1262+ return create(center, ps, 0, 1);
1263+ };
1264+ };
1265+ };
1266+ var oval = function(w) { return function(h) { return function(center) {
1267+ var ps = [];
1268+ for (var theta = 2 * Math.PI; theta > 0; theta -= Math.PI /50) {
1269+ ps.push([w/2 * Math.cos(theta), h/2 * Math.sin(theta)]);
1270+ }
1271+ center = [center[1], center[2]];
1272+ return create(center, ps, 0, 1);
1273+ };
1274+ };
1275+ };
1276+
1277+//// Transforms ////
1278+
1279+ var move = function(x) { return function(y) { return function(shape) {
1280+ var newCenter = [x + shape.center[0],y + shape.center[1]];
1281+ return create(newCenter, shape.points, shape.theta, shape.scale);
1282+ };
1283+ };
1284+ };
1285+ var rotate = function(theta) { return function(shape) {
1286+ var newTheta = shape.theta + 2 * Math.PI * theta;
1287+ return create(shape.center, shape.points, newTheta, shape.scale);
1288+ };
1289+ };
1290+ var scale = function(s) { return function(shape) {
1291+ return create(shape.center, shape.points, shape.theta, shape.scale * s);
1292+ };
1293+ };
1294+
1295+
1296+ //// Atomize ////
1297+
1298+ var draw = function(fill) {
1299+ return function(color) { return function(shape) { return function(ctx) {
1300+ ctx.save();
1301+ ctx.translate(shape.center[0], shape.center[1]);
1302+ ctx.rotate(shape.theta);
1303+ ctx.scale(shape.scale, shape.scale);
1304+ ctx.beginPath();
1305+ var points = shape.points;
1306+ ctx.moveTo(points[0][0], points[0][1]);
1307+ for (var i = points.length; i--; ) {
1308+ ctx.lineTo(points[i][0], points[i][1]);
1309+ }
1310+ ctx.closePath();
1311+ if (fill) {
1312+ ctx.fillStyle = Color.Internal.extract(color);
1313+ ctx.fill();
1314+ } else {
1315+ ctx.strokeStyle = Color.Internal.extract(color);
1316+ ctx.stroke();
1317+ }
1318+ ctx.restore();
1319+ return ctx;
1320+ };
1321+ };
1322+ };
1323+ };
1324+
1325+ var customOutline = function(p) {
1326+ return function(c) { return function(shape) {
1327+ shape.points.push(shape.points[0]);
1328+ return Line.customLine(p)(c)(shape);
1329+ };
1330+ };
1331+ };
1332+ return {polygon:polygon, ngon:ngon, rect:rect, oval:oval,
1333+ move:move, rotate:rotate, scale:scale,
1334+ filled:draw(true), outlined:draw(false), customOutline:customOutline };
1335+}();
1336+var Line = function() {
1337+
1338+ var pair = function(a,b) { return [a,b]; };
1339+
1340+ var create = function(center, ps, theta, s) {
1341+ return { center: center, points: ps, theta: theta, scale: s };
1342+ };
1343+
1344+
1345+ //// Construction ////
1346+
1347+ var line = function(ps) {
1348+ var parr = [];
1349+ while (ps[0] === "Cons") {
1350+ parr.push(pair(ps[1][1], ps[1][2]));
1351+ ps = ps[2];
1352+ }
1353+ return create(pair(0,0), parr, 0, 1);
1354+ };
1355+
1356+ //// Atomize ////
1357+
1358+ var solid = function(color) { return function(line) { return function(ctx) {
1359+ ctx.save();
1360+ ctx.beginPath();
1361+ ctx.translate(line.center[0], line.center[1]);
1362+ ctx.rotate(line.theta);
1363+ ctx.scale(line.scale, line.scale);
1364+ var points = line.points;
1365+ var i = points.length;
1366+ ctx.moveTo(points[i-1][0], points[i-1][1]);
1367+ while (i--) {
1368+ ctx.lineTo(points[i][0], points[i][1]);
1369+ }
1370+ ctx.strokeStyle = Color.Internal.extract(color);
1371+ ctx.stroke();
1372+ ctx.restore();
1373+ return ctx;
1374+ };
1375+ };
1376+ };
1377+
1378+ var customLine = function(pattern) {
1379+ return function(color) { return function(line) {
1380+ if (typeof pattern[0] === "string") {
1381+ var temp = [];
1382+ while (pattern[0] === "Cons") {
1383+ temp.push(pattern[1]);
1384+ pattern = pattern[2];
1385+ }
1386+ pattern = temp;
1387+ }
1388+ if (pattern.length === 0) { pattern = [8,4]; }
1389+ return function(ctx) {
1390+ ctx.save();
1391+ ctx.beginPath();
1392+ ctx.translate(line.center[0], line.center[1]);
1393+ ctx.rotate(line.theta);
1394+ ctx.scale(line.scale, line.scale);
1395+ customLineHelp(ctx, pattern, line.points);
1396+ ctx.strokeStyle = Color.Internal.extract(color);
1397+ ctx.stroke();
1398+ ctx.restore();
1399+ return ctx;
1400+ };
1401+ };
1402+ };
1403+ };
1404+ var customLineHelp = function(ctx, pattern, points) {
1405+ var i = points.length - 1;
1406+ var x0 = points[i][0], y0 = points[i][1];
1407+ var x1=0, y1=0, dx=0, dy=0, remaining=0, nx=0, ny=0;
1408+ var pindex = 0, plen = pattern.length;
1409+ var draw = true, segmentLength = pattern[0];
1410+ ctx.moveTo(x0,y0);
1411+ while (i--) {
1412+ x1 = points[i][0]; y1 = points[i][1];
1413+ dx = x1 - x0; dy = y1 - y0;
1414+ remaining = Math.sqrt(dx * dx + dy * dy);
1415+ while (segmentLength <= remaining) {
1416+ x0 += dx * segmentLength / remaining;
1417+ y0 += dy * segmentLength / remaining;
1418+ ctx[draw ? 'lineTo' : 'moveTo'](x0, y0);
1419+ // update starting position
1420+ dx = x1 - x0; dy = y1 - y0;
1421+ remaining = Math.sqrt(dx * dx + dy * dy);
1422+ // update pattern
1423+ draw = !draw;
1424+ pindex = (pindex + 1) % plen;
1425+ segmentLength = pattern[pindex];
1426+ }
1427+ if (remaining > 0) {
1428+ ctx[draw ? 'lineTo' : 'moveTo'](x1, y1);
1429+ segmentLength -= remaining;
1430+ }
1431+ x0 = x1; y0 = y1;
1432+ }
1433+ };
1434+
1435+ return {line:line, customLine:customLine, solid:solid,
1436+ dashed: customLine([8,4]), dotted: customLine([3,3]) };
1437+}();
1438+
1439+var Elm = function() {
1440+ var send = function(node, timestep, changed) {
1441+ var kids = node.kids;
1442+ for (var i = kids.length; i--; ) {
1443+ kids[i].recv(timestep, changed, node.id);
1444+ }
1445+ };
1446+ var input = function(base) {
1447+ this.id = Guid.guid();
1448+ this.value = base;
1449+ this.kids = [];
1450+ this.recv = function(timestep, eid, v) {
1451+ var changed = eid === this.id;
1452+ if (changed) { this.value = v; }
1453+ send(this, timestep, changed);
1454+ };
1455+ Dispatcher.inputs.push(this);
1456+ };
1457+ var lift = function(func,args) {
1458+ this.id = Guid.guid();
1459+ this.value = null;
1460+ this.kids = [];
1461+ this.inbox = {};
1462+
1463+ args.reverse();
1464+ this.recalc = function() {
1465+ var f = func;
1466+ for (var i = args.length; i--; ) {
1467+ f = f(args[i].value);
1468+ }
1469+ this.value = f;
1470+ };
1471+ this.recalc();
1472+
1473+ this.recv = function(timestep, changed, parentID) {
1474+ if (!this.inbox.hasOwnProperty(timestep)) {
1475+ this.inbox[timestep] = { changed: false, count: 0 };
1476+ }
1477+ var box = this.inbox[timestep];
1478+ box.count += 1;
1479+ if (changed) { box.changed = true; }
1480+ if (box.count == args.length) {
1481+ if (box.changed) { this.recalc() }
1482+ send(this, timestep, box.changed);
1483+ delete this.inbox[timestep];
1484+ }
1485+ };
1486+ for (var i = args.length; i--; ) {
1487+ args[i].kids.push(this);
1488+ }
1489+ };
1490+ var fold = function(func,base,input) {
1491+ this.id = Guid.guid();
1492+ this.value = base;
1493+ this.kids = [];
1494+ this.recv = function(timestep, changed, parentID) {
1495+ if (changed) { this.value = func(input.value)(this.value); }
1496+ send(this, timestep, changed);
1497+ };
1498+ input.kids.push(this);
1499+ };
1500+
1501+ var dropIf = function(pred,base,input) {
1502+ this.id = Guid.guid();
1503+ this.value = pred(input.value) ? base : input.value;
1504+ this.kids = [];
1505+ this.recv = function(timestep, changed, parentID) {
1506+ var chng = changed && !pred(input.value);
1507+ if (chng) { this.value = input.value; }
1508+ send(this, timestep, chng);
1509+ };
1510+ input.kids.push(this);
1511+ };
1512+ var dropRepeats = function(input) {
1513+ this.id = Guid.guid();
1514+ this.value = input.value;
1515+ this.kids = [];
1516+ this.recv = function(timestep, changed, parentID) {
1517+ var chng = changed && !eq(this.value,input.value);
1518+ if (chng) { this.value = input.value; }
1519+ send(this, timestep, chng);
1520+ };
1521+ input.kids.push(this);
1522+ };
1523+
1524+ var dropWhen = function(s1) { return function(b) { return function(s2) {
1525+ var pairs = new lift(function(x){return function(y){return [x,y];};},[s1,s2]);
1526+ var dropped = new dropIf(function(p){return p[0];},[true,b],pairs);
1527+ return new lift(function(p){return p[1];},[dropped]); }; };
1528+ };
1529+
1530+ var sampleOn = function(s1,s2) {
1531+ this.id = Guid.guid();
1532+ this.value = s2.value;
1533+ this.kids = [];
1534+ this.inbox = {};
1535+
1536+ this.recv = function(timestep, changed, parentID) {
1537+ var chng = changed && parentID === s1.id;
1538+ if (chng) { this.value = s2.value; }
1539+ send(this, timestep, chng);
1540+ };
1541+ s1.kids.push(this);
1542+ s2.kids.push(this);
1543+ };
1544+
1545+ return {Input: function(x) {return new input(x);},
1546+ Lift: function(f,xs){return new lift(f,xs);},
1547+ Fold: function(f,b,x){return new fold(f,b,x);},
1548+ keepIf : function(pred) { return function(base) { return function(sig) {
1549+ return new dropIf(function(x) { return !pred(x)},base,sig); }; }; },
1550+ dropIf : function(pred) { return function(base) { return function(sig) {
1551+ return new dropIf(pred,base,sig); }; }; },
1552+ keepWhen : function(s) { return dropWhen(new lift(function(b){return !b;},[s])); },
1553+ dropWhen : dropWhen,
1554+ dropRepeats : function(s) { return new dropRepeats(s);},
1555+ sampleOn : function(s1) { return function(s2) { return new sampleOn(s1,s2); }; }
1556+ };
1557+}();
1558+
1559+var Dispatcher = function() {
1560+ var program = null;
1561+ var timestep = 0;
1562+ var inputs = [];
1563+
1564+ var correctSize = function(e) {
1565+ var kids = e.childNodes;
1566+ var len = kids.length;
1567+ if (e.hasOwnProperty('isElmLeaf')) {
1568+ if (e.hasOwnProperty('isElmText')) { Element.correctTextSize(e); }
1569+ var w = e.style.width === "" ?
1570+ 0 : e.style.width.slice(0,-2) - 0;
1571+ var h = e.style.height === "" ?
1572+ 0 : e.style.height.slice(0,-2) - 0;
1573+ return [w, h];
1574+ }
1575+ if (len === 1) {
1576+ var dim = correctSize(kids[0]);
1577+ if (e.style.width !== "") { dim[0] = e.style.width.slice(0,-2) - 0; }
1578+ if (e.style.height !== "") { dim[1] = e.style.height.slice(0,-2) - 0; }
1579+ if (dim[0] !== 0) { e.style.width = dim[0] + "px"; }
1580+ if (dim[1] !== 0) { e.style.height = dim[1] + "px"; }
1581+ return dim;
1582+ }
1583+ var wmax = 0, hmax = 0, wsum = 0, hsum = 0;
1584+ var hasWidth = true, hasHeight = true, dim = null;
1585+ while (len--) {
1586+ dim = correctSize(kids[len]);
1587+ wmax = Math.max(wmax, dim[0]);
1588+ hmax = Math.max(hmax, dim[1]);
1589+ wsum += dim[0];
1590+ hsum += dim[1];
1591+ hasWidth = hasWidth && dim[0] > 0;
1592+ hasHeight = hasHeight && dim[1] > 0;
1593+ }
1594+ var w = wmax, h = hmax, dir = e.elmFlowDirection;
1595+ if (dir === "X") { w = hasWidth ? wsum : 0; }
1596+ if (dir === "Y") { h = hasHeight ? hsum : 0; }
1597+ if (w > 0) e.style.width = w + "px";
1598+ if (h > 0) e.style.height = h + "px";
1599+ return [w,h];
1600+ };
1601+
1602+ var initialize = function() {
1603+ program = ElmCode.main();
1604+ if (!program.hasOwnProperty('recv')) {
1605+ program = Elm.Input(program);
1606+ }
1607+ var content = document.getElementById('content');
1608+ content.appendChild(program.value);
1609+ adjust();
1610+ var w = document.getElementById('widthChecker').offsetWidth;
1611+ if (w !== window.innerWidth) {
1612+ Dispatcher.notify(Window.dimensions.id, Value.Tuple(w, window.innerHeight));
1613+ }
1614+ program = Elm.Lift(function(value) {
1615+ var content = document.getElementById('content');
1616+ var kid = content.children[0]
1617+ content.replaceChild(value, kid);
1618+ delete kid;
1619+ adjust();
1620+ return value;
1621+ }, [program]);
1622+ };
1623+ var adjust = function() {
1624+ var content = document.getElementById('content');
1625+ correctSize(content.children[0]);
1626+ }
1627+ var notify = function(id, v) {
1628+ timestep += 1;
1629+ for (var i = inputs.length; i--; ) {
1630+ inputs[i].recv(timestep, id, v);
1631+ }
1632+ };
1633+ return {initialize:initialize, notify:notify, adjust:adjust, inputs:inputs};
1634+}();
1635+var Signal = function() {
1636+ function toElmString(str) {
1637+ var out = ["Nil"];
1638+ for (var i = str.length; i--; ) {
1639+ out = ["Cons", str[i], out];
1640+ }
1641+ return out;
1642+ }
1643+ var addListener = function() {
1644+ if(document.addEventListener) {
1645+ return function(element, event, handler) {
1646+ element.addEventListener(event, handler, false);
1647+ };
1648+ }
1649+ else {
1650+ return function(element, event, handler) {
1651+ element.attachEvent('on' + event, handler);
1652+ };
1653+ }
1654+ }();
1655+
1656+ var Mouse = function() {
1657+ var position = Elm.Input(Value.Tuple(0,0));
1658+ var isDown = Elm.Input(false);
1659+ var isClicked = Elm.Input(false);
1660+ var clicks = Elm.Input(Value.Tuple());
1661+
1662+ function getXY(e) {
1663+ var posx = 0;
1664+ var posy = 0;
1665+ if (!e) var e = window.event;
1666+ if (e.pageX || e.pageY) {
1667+ posx = e.pageX;
1668+ posy = e.pageY;
1669+ } else if (e.clientX || e.clientY) {
1670+ posx = e.clientX + document.body.scrollLeft +
1671+ document.documentElement.scrollLeft;
1672+ posy = e.clientY + document.body.scrollTop +
1673+ document.documentElement.scrollTop;
1674+ }
1675+ return Value.Tuple(posx, posy);
1676+ }
1677+
1678+ addListener(document, 'click', function(e) {
1679+ Dispatcher.notify(isClicked.id, true);
1680+ Dispatcher.notify(clicks.id, Value.Tuple());
1681+ Dispatcher.notify(isClicked.id, false);
1682+ });
1683+ addListener(document, 'mousedown', function(e) {
1684+ Dispatcher.notify(isDown.id, true); });
1685+ addListener(document, 'mouseup', function(e) {
1686+ Dispatcher.notify(isDown.id, false); });
1687+ addListener(document, 'mousemove', function(e) {
1688+ Dispatcher.notify(position.id, getXY(e)); });
1689+ var clickedOn = function(elem) {
1690+ var click = Elm.Input(false);
1691+ addListener(elem, 'click', function(e) {
1692+ Dispatcher.notify(click.id, true);
1693+ Dispatcher.notify(click.id, false);
1694+ });
1695+ return Value.Tuple(elem, click);
1696+ };
1697+ return {position: position,
1698+ x: Elm.Lift(function(p){return p[1];},[position]),
1699+ y: Elm.Lift(function(p){return p[2];},[position]),
1700+ isClicked: isClicked,
1701+ isDown: isDown,
1702+ clicks: clicks,
1703+ isClickedOn: clickedOn
1704+ };
1705+ }();
1706+
1707+ var Time = function() {
1708+ var every = function(t) {
1709+ t *= 1000;
1710+ var clock = Elm.Input(0);
1711+ var time = 0;
1712+ setInterval(function() {
1713+ time += t;
1714+ Dispatcher.notify(clock.id, time/1000);
1715+ }, t);
1716+ return clock;
1717+ };
1718+ var after = function(t) {
1719+ t *= 1000;
1720+ var thread = Elm.Input(false);
1721+ setTimeout(function() { Dispatcher.notify(thread.id, true); }, t);
1722+ return thread;
1723+ };
1724+ var before = function(t) {
1725+ t *= 1000;
1726+ var thread = Elm.Input(true);
1727+ setTimeout(function() { Dispatcher.notify(thread.id, false); }, t);
1728+ return thread;
1729+ };
1730+ return {every:every,after:after,before:before};
1731+ }();
1732+
1733+ var Window = function() {
1734+ var dimensions = Elm.Input(Value.Tuple(window.innerWidth,window.innerHeight));
1735+ addListener(window, 'resize', function(e) {
1736+ var w = document.getElementById('widthChecker').offsetWidth;
1737+ Dispatcher.notify(dimensions.id, Value.Tuple(w, window.innerHeight));
1738+ });
1739+ return {dimensions:dimensions,
1740+ width : Elm.Lift(function(p){return p[1];},[dimensions]),
1741+ height: Elm.Lift(function(p){return p[2];},[dimensions]) };
1742+ }();
1743+
1744+ var Keyboard = { Raw : function() {
1745+ var keysDown = Elm.Input(["Nil"]);
1746+ var charPressed = Elm.Input(["Nothing"]);
1747+ function remove(x,xs) {
1748+ if (xs[0] === "Nil") return xs;
1749+ if (xs[1] === x) return xs[2];
1750+ return ["Cons", xs[1], remove(x,xs[2])];
1751+ }
1752+ function has(x,xs) {
1753+ while (xs[0] !== "Nil") {
1754+ if (xs[1] === x) return true;
1755+ xs = xs[2];
1756+ }
1757+ return false;
1758+ }
1759+ addListener(document, 'keydown', function(e) {
1760+ if (has(e.keyCode, keysDown.value)) return;
1761+ Dispatcher.notify(keysDown.id, ["Cons", e.keyCode, keysDown.value]);
1762+ });
1763+ addListener(document, 'keyup', function(e) {
1764+ var codes = remove(e.keyCode, keysDown.value)
1765+ Dispatcher.notify(keysDown.id, codes);
1766+ });
1767+ addListener(window, 'blur', function(e) {
1768+ Dispatcher.notify(keysDown.id, ["Nil"]);
1769+ });
1770+ addListener(document, 'keypress', function(e) {
1771+ Dispatcher.notify(charPressed.id, ["Just",e.charCode || e.keyCode]);
1772+ Dispatcher.notify(charPressed.id, ["Nothing"]);
1773+ });
1774+ return {keysDown:keysDown,
1775+ charPressed:charPressed};
1776+ }()
1777+ };
1778+
1779+ var HTTP = function() {
1780+ var fetch = function(how) { return function(url) {
1781+ var thread = Elm.Input(["Waiting"]);
1782+ var request = {};
1783+ if (window.XMLHttpRequest) { request = new XMLHttpRequest(); }
1784+ else if (window.ActiveXObject) { request = new ActiveXObject("Microsoft.XMLHTTP"); }
1785+ request.onreadystatechange = function(e) {
1786+ if (request.readyState === 4) {
1787+ Dispatcher.notify(thread.id,
1788+ request.status === 200
1789+ ? ["Success", toElmString(request.responseText)]
1790+ : ["Failure", request.status, toElmString(request.statusText)]);
1791+ }
1792+ };
1793+ request.open(how, Data.String.toText(url), true);
1794+ request.send(null);
1795+ return thread;
1796+ };
1797+ };
1798+ var fetches = function(how) { return function(input) {
1799+ var output = Elm.Input(["Nothing"]);
1800+ var fetcher = Elm.Lift(update, [input]);
1801+ var combine = Elm.Lift(function(x) { return function(y) { return x; } }, [output,fetcher]);
1802+ function update(strOpt) {
1803+ if (strOpt[0] !== "Just") {
1804+ try { Dispatcher.notify(output.id, ["Nothing"]); } catch(e) {}
1805+ return [];
1806+ }
1807+ try {
1808+ Dispatcher.notify(output.id, ["Just", ["Waiting"]]);
1809+ } catch(e) { output.value = ["Just", ["Waiting"]]; }
1810+ var request = {};
1811+ if (window.XMLHttpRequest) { request = new XMLHttpRequest(); }
1812+ else if (window.ActiveXObject) { request = new ActiveXObject("Microsoft.XMLHTTP"); }
1813+ request.onreadystatechange = function(e) {
1814+ if (request.readyState === 4) {
1815+ Dispatcher.notify(output.id,
1816+ ["Just", request.status === 200
1817+ ? ["Success", toElmString(request.responseText)]
1818+ : ["Failure", request.status, toElmString(request.statusText)]]);
1819+ }
1820+ };
1821+ request.open(how, Data.String.toText(strOpt[1]), true);
1822+ request.send(null);
1823+ return [];
1824+ }
1825+ return combine;
1826+ };
1827+ };
1828+ return {get : fetch("GET"), post : fetch("POST"),
1829+ gets : fetches("GET"), posts : fetches("POST")
1830+ };
1831+ }();
1832+ var Random = function() {
1833+ var inRange = function(min) { return function(max) {
1834+ return Elm.Input(Math.floor(Math.random() * (max-min+1)) + min);
1835+ };
1836+ };
1837+ var randomize = function(min) { return function(max) { return function(signal) {
1838+ return Elm.Lift(function(x) { return Math.floor(Math.random() * (max-min+1)) + min;},[signal]);
1839+ };
1840+ };
1841+ };
1842+ return { inRange:inRange, randomize:randomize };
1843+ }();
1844+ var Input = function() {
1845+ var newTextInput = function(elem, ghostText) {
1846+ elem.isElmLeaf = true;
1847+ var str = Elm.Input(["Nil"]);
1848+ addListener(elem, 'keyup', function(e) {
1849+ Dispatcher.notify(str.id, toElmString(elem.value));
1850+ elem.focus();
1851+ });
1852+ return Value.Tuple(elem, str);
1853+ };
1854+ var newElement = function(name) {
1855+ var e = document.createElement(name);
1856+ e.id = Guid.guid();
1857+ return e;
1858+ };
1859+ var textArea = function(cols) { return function(rows) {
1860+ var textarea = newElement('textarea');
1861+ textarea.rows = rows;
1862+ textarea.cols = cols;
1863+ return newTextInput(textarea, "");
1864+ };
1865+ };
1866+ var textField = function(ghostText) {
1867+ var field = newElement('input');
1868+ field.type = 'text';
1869+ return newTextInput(field, ghostText);
1870+ };
1871+ var password = function(ghostText) {
1872+ var field = newElement('input');
1873+ field.type = 'password';
1874+ return newTextInput(field, ghostText);
1875+ };
1876+ var checkbox = function(checked) {
1877+ var box = newElement('input');
1878+ box.type = 'checkbox';
1879+ box.checked = checked;
1880+ var status = Elm.Input(checked);
1881+ addListener(box, 'change', function(e) {
1882+ Dispatcher.notify(status.id, box.checked);
1883+ });
1884+ return Value.Tuple(box, status);
1885+ };
1886+ var dropDown = function(options) {
1887+ var slct = newElement('select');
1888+ var opts = [];
1889+ while (options[0] === "Cons") {
1890+ var opt = newElement('option');
1891+ var str = Text.toText(options[1][1]);
1892+ opt.value = str;
1893+ opt.innerHTML = str;
1894+ slct.appendChild(opt);
1895+ opts.push(options[1][2]);
1896+ options = options[2];
1897+ }
1898+ var status = Elm.Input(opts[0]);
1899+ addListener(slct, 'change', function(e) {
1900+ Dispatcher.notify(status.id, opts[slct.selectedIndex]);
1901+ });
1902+ return Value.Tuple(slct, status);
1903+ };
1904+ var stringDropDown = function(opts) {
1905+ return dropDown(List.map (function(x) {return Value.Tuple(x,x);}) (opts));
1906+ };
1907+ var button = function(name) {
1908+ var b = newElement('input');
1909+ b.type = "button";
1910+ b.value = Text.toText(name);
1911+ var press = Elm.Input(false);
1912+ addListener(b, 'click', function(e) {
1913+ Dispatcher.notify(press.id, true);
1914+ Dispatcher.notify(press.id, false);
1915+ });
1916+ return Value.Tuple(b,press);
1917+ };
1918+ return {textArea:textArea, textField:textField,
1919+ password:password, checkbox:checkbox,
1920+ dropDown:dropDown, stringDropDown:stringDropDown,
1921+ button:button};
1922+ }();
1923+
1924+ return {addListener:addListener,
1925+ Mouse:Mouse,
1926+ Keyboard:Keyboard,
1927+ Time:Time,
1928+ Window:Window,
1929+ HTTP:HTTP,
1930+ Random:Random,
1931+ Input:Input,
1932+ constant : function(v) { return Elm.Input(v); },
1933+ lift : function(f){return function(e){return Elm.Lift(f,[e]);};},
1934+ lift2 : function(f) { return function(e1) { return function(e2) {
1935+ return Elm.Lift(f, [e1,e2]); }; }; },
1936+ lift3 : function(f) { return function(e1) { return function(e2) {
1937+ return function(e3){return Elm.Lift(f,[e1,e2,e3]);};};};},
1938+ lift4 : function(f) { return function(e1) { return function(e2) {
1939+ return function(e3) { return function(e4) {
1940+ return Elm.Lift(f, [e1,e2,e3,e4]); }; }; }; }; },
1941+ foldp : function(f) { return function(b) { return function(e) {
1942+ return Elm.Fold(f,b,e); }; }; },
1943+ count : function(sig){return Elm.Fold(function(_){return function(c){return c+1;};},0,sig)},
1944+ keepIf : Elm.keepIf,
1945+ dropIf : Elm.dropIf,
1946+ keepWhen : Elm.keepWhen,
1947+ dropWhen : Elm.dropWhen,
1948+ dropRepeats : Elm.dropRepeats,
1949+ sampleOn : Elm.sampleOn
1950+ };
1951+}();
1952+var Prelude = function() {
1953+ var mod = function(x) { return function(y) {
1954+ var r = x % y;
1955+ var m = x==0 ? 0 : (y>0 ? (x>=0 ? r : r+y) : -mod(-x)(-y));
1956+ return m == y ? 0 : m;
1957+ }; };
1958+
1959+ var min = function(x) { return function(y) { return Math.min(x,y); }; };
1960+ var max = function(x) { return function(y) { return Math.max(x,y); }; };
1961+
1962+ var flip=function(f){return function(x){return function(y){return f(y)(x);};};};
1963+ var clamp = function(lo) { return function(hi) {
1964+ return function(x) { return Math.min(hi, Math.max(lo, x)); };
1965+ };
1966+ };
1967+ var curry = function(f) { return function(x) { return function(y) {
1968+ return f(["Tuple2",x,y]); }; };
1969+ };
1970+ var uncurry = function(f) { return function(p) {
1971+ if (p[0] !== "Tuple2") {
1972+ throw "Function was uncurry'd but was not given a pair.";
1973+ }
1974+ return f(p[1])(p[2]); };
1975+ };
1976+
1977+ var logBase=function(b){return function(x){return Math.log(x)/Math.log(b);};};
1978+
1979+ return {id : function(x) { return x; },
1980+ not : function(b) { return !b; },
1981+ fst : function(p) { return p[1]; },
1982+ snd : function(p) { return p[2]; },
1983+ rem : function(x) { return function(y) { return x % y; }; },
1984+ sqrt : Math.sqrt,
1985+ abs : Math.abs,
1986+ pi : Math.PI,
1987+ sin : Math.sin,
1988+ cos : Math.cos,
1989+ tan : Math.tan,
1990+ asin : Math.asin,
1991+ acos : Math.acos,
1992+ atan : Math.atan,
1993+ mod : mod,
1994+ min : min,
1995+ max : max,
1996+ flip : flip,
1997+ clamp : clamp,
1998+ curry : curry,
1999+ uncurry : uncurry,
2000+ logBase : logBase,
2001+ Just : Data.Maybe.Just,
2002+ Nothing : Data.Maybe.Nothing,
2003+ maybe : Data.Maybe.maybe,
2004+ map : Data.List.map,
2005+ filter : Data.List.filter,
2006+ head : Data.List.head,
2007+ tail : Data.List.tail,
2008+ last : Data.List.last,
2009+ length : Data.List.length,
2010+ reverse : Data.List.reverse,
2011+ foldr : Data.List.foldr,
2012+ foldr1 : Data.List.foldr1,
2013+ foldl : Data.List.foldl,
2014+ foldl1 : Data.List.foldl1,
2015+ and : Data.List.and,
2016+ or : Data.List.or,
2017+ forall : Data.List.forall,
2018+ exists : Data.List.exists,
2019+ sum : Data.List.sum,
2020+ product : Data.List.product,
2021+ concat : Data.List.concat,
2022+ concatMap : Data.List.concatMap,
2023+ maximum : Data.List.maximum,
2024+ minimum : Data.List.minimum,
2025+ scanl : Data.List.scanl,
2026+ scanl1 : Data.List.scanl1,
2027+ take : Data.List.take,
2028+ drop : Data.List.drop,
2029+ lift : Signal.lift,
2030+ lift2 : Signal.lift2,
2031+ lift3 : Signal.lift3,
2032+ lift4 : Signal.lift4,
2033+ foldp : Signal.foldp,
2034+ constant : Signal.constant,
2035+ count : Signal.count,
2036+ keepIf : Signal.keepIf,
2037+ dropIf : Signal.dropIf,
2038+ keepWhen : Signal.keepWhen,
2039+ dropWhen : Signal.dropWhen,
2040+ dropRepeats : Signal.dropRepeats,
2041+ sampleOn : Signal.sampleOn
2042+ };
2043+}();
2044+var eq = Value.eq;
2045+
2046+Signal.addListener(document, 'elm_log', function(e) { console.log(e.value); });
2047+Signal.addListener(document, 'elm_title', function(e) { document.title = e.value; });
2048+Signal.addListener(document, 'elm_redirect', function(e) {
2049+ if (e.value.length > 0) { window.location = e.value; }
2050+ });
2051+
2052+var includeGlobal = this;
2053+(function() {
2054+ var include = function(library) {
2055+ for (var i in library) {
2056+ if (i === 'Internal') continue;
2057+ try {
2058+ includeGlobal[i] = library[i];
2059+ } catch (err) {
2060+ if (i === 'length') {
2061+ includeGlobal.execScript('var length;');
2062+ length = library[i];
2063+ continue;
2064+ }
2065+ }
2066+ }
2067+ };
2068+ var includeAs = function(name) { return function(library) {
2069+ includeGlobal[name] = includeGlobal[name] || {};
2070+ for (var i in library) {
2071+ if (i === 'Internal') continue;
2072+ includeGlobal[name][i] = library[i];
2073+ }
2074+ };
2075+ };
2076+ include (Element);
2077+ include (Text);
2078+
2079+ color = Element.color;
2080+ height = Element.height;
2081+ show = Value.show;
2082+
2083+ include (Color);
2084+ include (Shape);
2085+ include (Line);
2086+
2087+ includeAs ('Time') (Signal.Time);
2088+ includeAs ('Mouse') (Signal.Mouse);
2089+ includeAs ('Keyboard') (Signal.Keyboard);
2090+ includeAs ('Window') (Signal.Window);
2091+ includeAs ('HTTP') (Signal.HTTP);
2092+ includeAs ('Input') (Signal.Input);
2093+ includeAs ('Random') (Signal.Random);
2094+
2095+}());
2096+
2097+var ElmCode = {};
2098+ElmCode.Data = Data;
2099+ElmCode.Signal = Signal;
2100+ElmCode.Data.List = List;
2101+ElmCode.Foreign = Foreign;
2102+ElmCode.Prelude = Prelude;