/* beyond.js by Dan Shappir and Sjoerd Visscher For more information see http://w3future.com/html/beyondJS */ var beyondVer = 1.00; var _FP = Function.prototype; if ( typeof(parseInt.apply) != "function" ) { _FP.apply = function(obj, args) { var s, tmp; if ( obj ) { tmp = "__tmp__"; // + Math.random(); switch ( typeof(obj) ) { case "string": s = "'" + obj.replace(_FP.apply.re, "\\'") + "'"; _SP[tmp] = this; break; case "number": s = "(" + obj + ")"; _NP[tmp] = this; break; default: s = "obj"; obj[tmp] = this; break; } s = "var r = " + s + "." + tmp + "("; } else s = "var r = this("; for ( var i = 0 ; i < args.length ; ++i ) s += "args[" + i + "],"; s = ( args.length ? s.slice(0, -1) : s ) + ");"; eval(s); return r; }; _FP.apply.re = /\'/g; _FP.call = function(obj) { return this.apply(obj, Array.from(arguments).slice(1)); }; } function isUndefined(x) { var t = typeof(x); return t == "undefined" || t == "unknown"; } function isDefined(x) { return !isUndefined(x); } Object.propertyNames = function(x, a) { if ( !a ) a = []; for ( var i in x ) a.append(i); return a; }; Object.propertyValues = function(x, a) { return Object.propertyNames(x).collect(a, Function.from(x, null)); }; Object.toArray = function(x) { return Object.propertyNames(x).zip(Object.propertyValues(x)); }; Object.from = function(n, v, x) { if ( !x ) x = {}; var length = Math.min(n.length, v.length); for ( var i = 0 ; i < length ; ++i ) x[n[i]] = v[i]; return x; }; _FP.force = function() { return "returnValue" in this ? this.returnValue : this.returnValue = this.call(); }; _FP.delayed = function() { return Function.from(this.curry(arguments), "force"); }; _FP.caching = function() { var self = this; var map = {}; return function() { var s = Array.from(arguments).toString(); return isDefined(map[s]) ? map[s] : map[s] = self.apply(this, arguments); }.withArgString(this); }; _FP.withArgString = function(x) { if ( !x ) return this; if ( typeof(x) != "string" ) x = Function.argString(x); var self = this; eval("function __withArgString__(" + x + ") { return self.apply(this, arguments); }"); return __withArgString__; }; _FP.curry = function(m) { var self = this; var map = arguments.length != 1 || !m || typeof(m) != "object" ? arguments : m; function createApplyArg(x) { var val = map[x]; if ( val && val.asArgNameFlag ) { args.append(val.toString()); return val.toString(); } var arg = "__curry__.map['" + x + "']"; if ( typeof(val) == "function" && val.asValueFlag ) { var list = addArgs(val); if ( list.length ) list = "," + list; arg += ".call(this" + list + ")"; } return arg; } function addArgs(f) { var args = Function.argString(f); if ( !args ) return ""; args.split(_FP.curry.re).foreach(function(arg) { if ( argSet.addToSet(arg) ) extraArgs.append(arg); }); return args; } var origargs = Function.argString(this); origargs = origargs ? origargs.split(_FP.curry.re) : []; if ( map !== m && origargs.length < arguments.length ) origargs.length = arguments.length; var args = [], extraArgs = [], argSet = new stringSet; var applyArgs = origargs.collect(function(a, i) { if ( isUndefined(a) ) { if ( isDefined(map[i]) ) return createApplyArg(i); a = "arg" + i; args.append(a); return a; } if ( isDefined(map[a]) ) return createApplyArg(a); if ( isDefined(map[i]) ) return createApplyArg(i); if ( isDefined(map[i - self.length]) ) return createApplyArg(i - self.length); args.append(a); return a; }); eval("function __curry__(" + args.concat(extraArgs).join(",") + ") {" + "return self.apply(this, " + (applyArgs.length == 1 ? "[].append(" + applyArgs[0] + ")" : "[" + applyArgs.join(",") + "]") + "); }"); __curry__.map = map; return __curry__; }; _FP.curry.re = /\s*,\s*/; _FP.using = function() { return this.curry(Array.from(arguments).collect(select.curry("typeof", { "function" : function(x) { return x.asValue(); }, "string" : function(x) { return x.asArgName(); }, "undefined" : function(x) { return x; } }))); }; _FP.andThen = function(f) { eval("function first(" + Function.argString(this) + ") { return g.first.apply(this, arguments); }"); function second(x) { return g.second.apply ? g.second.apply(this, arguments) : g.second(x); } var g = second.using(first); g.first = this; g.second = typeof(f) != "string" ? f : Function.from(null, f); return g; }; _FP.andReturn = function(v) { return this.andThen(Function.from(v)); }; _FP.replace = function(orig, replace) { if ( !replace ) replace = Function.NOP; if ( this.second == orig ) this.second = replace; else for ( var f = this ; f.second ; f = f.second ) if ( f.first == orig ) f.first = replace; return this; }; _FP.strict = function(args) { var self = this, type = typeof(args), length; if ( type == "number" ) length = args; if ( type != "string" ) args = Function.argString(this); if ( type != "number" ) length = args.split(",").length; return function() { return self.apply(this, Array.from(arguments).head(length)); }.withArgString(args); }; _FP.delay = function(iMilliSeconds) { var self = this; if ( !iMilliSeconds ) iMilliSeconds = 0; return function() { var args = arguments; return window.setTimeout(function() { self.apply(this, args); }, iMilliSeconds); }.withArgString(this); }; _FP.asValue = function() { var f = this.curry({}); f.asValueFlag = true; return f; }; _FP.toMethod = function() { return this.using(Function.This); }; _FP.gate = function(cond, els) { var gate = function() { return ( typeof(gate.cond) == "function" ? gate.cond.apply(this, arguments) : gate.cond ) ? gate.then.apply(this, arguments) : typeof(gate.els) == "function" ? gate.els.apply(this, arguments) : gate.els; }.withArgString(this); gate.cond = cond; gate.then = this; gate.els = els; return gate; }; _FP.loop = function(cond) { var loop = function() { while ( select("typeof", { "function" : function(x) { return x.apply(this, arguments); }, "number" : function() { return loop.cond--; }, "undefined" : isDefined(loop.cond) ? loop.cond : true }, loop.cond) ) { var r = loop.action.apply(this, arguments); if ( isDefined(r) ) return r; } }.withArgString(this); loop.cond = cond; loop.action = this; return loop; }; _FP.factory = function() { var self = this; return function() { return eval("new self(" + (0).upTo(arguments.length-1).join2("arguments[", ",", "]") + ")"); }.withArgString(this); }; Function.argString = function(f) { var result = ("" + f).match(Function.argString.re); return result ? result[1] : null; }; Function.argString.re = /\(([^)]*)/; Function.NOP = function() { if ( arguments.length > 0 ) return arguments[0]; }; Function.This = function() { return this; }; Function.args = function() { return Array.from(arguments); }; Function.invoke = function(f) { return f(); }; Function.event = function(e) { return e ? e : event; }; Function.from = function(obj, field, args) { var f; if ( isUndefined(obj) || obj === null ) { f = function(obj) { return Function.from(obj, f.field, args).apply(obj, Array.from(arguments).slice(1)); }; if ( args && args.length ) f = f.withArgString("obj," + args); } else if ( isUndefined(field) ) { if ( !args ) args = Function.argString(obj); if ( typeof(args) != "string" ) f = function() { return f.obj; }; else f = function() { return f.obj.apply(this, arguments); }.withArgString(args); } else if ( field === null ) f = function(x) { return f.obj[x]; }; else if ( typeof(field) == "function" ) f = function() { return f.field.apply(f.obj, arguments); }.withArgString(args ? args : Function.argString(field)); else { if ( !args ) args = Function.argString(obj[field]); if ( typeof(args) != "string" ) f = function() { if ( f.field.search(/\s/) > -1 ) return f.obj[f.field]; return eval("f.obj." + f.field); }; else f = function() { if ( f.field.search(/\s/) > -1 ) return f.obj[f.field].apply(f.obj, arguments); var s = "f.obj." + f.field + "("; Array.from(arguments).foreach(function(v, i) { s += "arguments[" + i + "],"; }); return eval(( arguments.length ? s.slice(0, -1) : s ) + ");"); }.withArgString(args); } f.obj = obj; f.field = field; return f; } Function.set = function(obj, property) { var f; if ( isUndefined(obj) || obj === null ) f = function(obj, value) { return Function.set(obj, f.property).call(this, value); }; else if ( isUndefined(property) ) f = function(property, value) { return Function.set(f.obj, property).call(this, value); }; else f = function(value) { if ( f.property.search(/\s/) > -1 ) f.obj[f.property] = value; else eval("f.obj." + f.property + " = value"); return value; } f.obj = obj; f.property = property; return f; } var _AP = Array.prototype; if ( typeof(_AP.push) != "function" ) _AP.push = function() { for ( var i = 0 ; i < arguments.length ; ++i ) this[this.length] = arguments[i]; return this.length; } if ( typeof(_AP.pop) != "function" ) _AP.pop = function() { if ( this.length ) { var item = this[this.length-1]; --this.length; return item; } } if ( typeof(_AP.shift) != "function" ) _AP.shift = function() { this.foreach(function(v, i, self) { self[i] = self[i+1]; }); --this.length; return this; } if ( typeof(_AP.unshift) != "function" ) _AP.unshift = function() { var self = this; Array.from(arguments).concat(this).foreach(function(v, i) { self[i] = v; }); return this; } if ( typeof(_AP.splice) != "function" ) _AP.splice = function(start, deleteCount) { var a = start > 0 ? this.slice(0, start) : []; a = a.concat(Array.from(arguments).slice(2), this.slice(start+deleteCount)); var self = this, deleted = this.slice(start, start+deleteCount); a.foreach(function(v, i) { self[i] = v; }); this.length = a.length; return deleted; } _AP.head = function(length) { return isUndefined(length) ? this[0] : this.slice(0, length); }; _AP.tail = function(start) { return this.slice(start ? start : 1); }; _AP.itemAt = function(i) { return this[i]; }; _AP.isEmpty = function() { return this.length === 0; }; _AP.empty = function() { this.length = 0; return this; }; _AP.order = function(f) { if ( !f ) f = function(a, b) { return a < b ? -1 : a > b ? 1 : 0; }; return this.sort(function(a, b) { var r = 0; a.zip(b).foreach(function(pair) { if ( r = f(pair[0], pair[1]) ) return false; }); return r; }); }; _AP.join2 = function(prefix, infix, postfix) { if ( isUndefined(prefix) || prefix === null ) prefix = ""; if ( isUndefined(infix) || infix === null ) infix = ""; if ( isUndefined(postfix) || postfix === null ) postfix = ""; var r = this.join(postfix + infix + prefix); return r.length ? prefix + r + postfix : r; }; _AP.append = function() { for ( var i = 0 ; i < arguments.length ; ++i ) if ( isDefined(arguments[i]) ) this[this.length] = arguments[i]; return this; }; _AP.extend = function(x) { if ( isDefined(x) ) { if ( x.constructor == Array || typeof(x.foreach) != "function") this.concat(x); else { var self = this; x.foreach(function(v) { self.append(v); }); } } return this; }; _AP.feed = function(x) { x.extend(this); return this; }; _AP.foreach = function(f) { for ( var i = 0 ; i < this.length ; ++i ) if ( f(this[i], i, this) === false ) return i; }; _AP.coalesce = function(r, f) { if ( isUndefined(f) ) { f = arguments[0]; r = arguments[1]; } if ( typeof(f) == "string" ) f = f.asMethod(); this.foreach(function(v, i, self) { var t = f(r, v, i, self); if ( isDefined(t) ) r = t; }); return r; }; _AP.fold = function(r, f) { if ( isUndefined(f) ) { f = arguments[0]; r = arguments[1]; } if ( typeof(f) == "string" ) f = f.toFunction(); return this.coalesce(r, function(r, v) { return isDefined(r) ? f(r, v) : v; }); }; _AP.foldr = function(r, f) { if ( isUndefined(f) ) { f = arguments[0]; r = arguments[1]; } if ( typeof(f) == "string" ) f = f.toFunction(); return this.fold(r, function(r, v) { return f(v, r); }); }; _AP.collect = function(a, f) { if ( isUndefined(f) ) { f = arguments[0]; a = arguments[1]; } if ( typeof(f) == "string" ) f = f.asMethod(); if ( !a ) a = this.constructor ? new this.constructor : []; return this.coalesce(a, function(r, v, i, self) { return r.append(f(v, i, self)); }); }; _AP.call = function(f) { this.foreach(f); return this; }; _AP.asLongAs = function(a, f) { if ( isUndefined(f) ) { f = arguments[0]; a = arguments[1]; } if ( f.constructor === RegExp ) f = Function.from(f, "test"); if ( !a ) a = this.constructor ? new this.constructor : []; this.foreach(function(v, i, self) { if ( !f(v, i, self) ) return false; a.append(v); }); return a; }; _AP.filter = function(f, other) { if ( f.constructor === RegExp ) f = Function.from(f, "test"); return this.collect(other ? function(v, i, a) { if ( f(v, i, a) ) return v; other.append(v); } : function(v, i, a) { if ( f(v, i, a) ) return v; } ); }; _AP.search = function(f) { if ( f.constructor === RegExp ) f = Function.from(f, "test"); else if ( typeof(f) != "function" ) { var x = f; f = function(y) { return y === x; }; } var result = this.foreach(function(v, i, self) { return !f(v, i, self); }); return typeof(result) == "number" ? result : -1; }; _AP.indexOf = function(pattern) { if ( typeof(pattern.foreach) != "function" ) pattern = [].append(pattern); var result = this.foreach(function(v, i, self) { return -1 !== pattern.foreach(function(v) { return v === self[i++]; }); }); return typeof(result) == "number" ? result : -1; }; _AP.inverse = function() { return this.collect(function(v) { return typeof(v.reverse) == "function" ? v.reverse() : v; }).reverse(); } _AP.flush = function(f) { for ( ; this.length ; this.shift() ) if ( f(this[0], this) === false ) break; return this; }; _AP.split = function(f) { if ( f.constructor === RegExp ) f = Function.from(f, "test"); else if ( typeof(f) != "function" ) f = "===".curry({ 0 : f }); var a = [[]], index = 0; this.foreach(function(v) { if ( f(v) ) a[++index] = []; else a[index].append(v); }); return a; }; _AP.zip = function() { var result = this.collect(function(v) { return Function.args(v); }); Array.from(arguments).foreach(function(a) { if ( !a || isUndefined(a.foreach) ) a = Function.args(v); var last = 0; if ( IsUndefined(a.foreach(function(v, i) { var x = result.itemAt(i); if ( isUndefined(x) ) return false; x.push(v); last = i; })) ) { if ( isDefined(result.length) ) result.length = last+1; else result = result.slice(0, last+1); } }); return result; }; _AP.zipWith = function(f) { if ( typeof(f) == "string" ) f = f.toFunction(); return this.zip.apply(this, Array.from(arguments).tail()).collect(function(v) { return f.apply(null, v); }); }; _AP.spread = function() { return this.coalesce([], "extend"); }; Array.from = function(x) { if ( typeof(x.toArray) == "function" ) { x = x.toArray(); if ( this === Array ) return x; } if ( typeof(x.foreach) == "function" ) { var a = new this; x.foreach(function(v) { a.push(v); }); return a; } if ( typeof(x.length) == "number" ) { var a = new this; if ( typeof(x) != "string" ) for ( i = 0 ; i < x.length ; ++i ) a.push(x[i]); else for ( i = 0 ; i < x.length ; ++i ) a.push(x.charAt(i)); return a; } return (new this).push(x); } Array.fill = function(f, a) { if ( !a ) a = new this; var i = a.length; if ( !i ) i = 0; for ( ; ; ++i ) { var v = f(i, a); if ( isUndefined(v) ) return a; a.append(v); } }; Array.recurse = function(f, resultIfEmpty) { if ( isUndefined(resultIfEmpty) ) resultIfEmpty = new this; return function(x) { return this.isEmpty() ? typeof(resultIfEmpty) == "function" ? resultIfEmpty(x) : resultIfEmpty : f(this.head(), this.tail(), x); }; }; _AP.equals = Array.recurse(function(h, t, x) { return typeof(x.head) == "function" && typeof(x.tail) == "function" && ( typeof(h.equals) == "function" ? h.equals(x.head()) : h == x.head() ) && t.equals(x.tail()); }, Function.from(null, "isEmpty") ); function iteratable(x) { var p = x.prototype; if ( !p || p == Object ) p = x; else { if ( typeof(p.push) == "function" ) { if ( !x.from ) x.from = Array.from; } if ( typeof(p.append) == "function" ) { if ( !x.fill ) x.fill = Array.fill; } } if ( typeof(p.foreach) == "function" ) { if ( !p.coalesce ) p.coalesce = _AP.coalesce; if ( !p.fold ) p.fold = _AP.fold; if ( !p.foldr ) p.foldr = _AP.foldr; if ( !p.collect ) p.collect = _AP.collect; if ( !p.filter ) p.filter = _AP.filter; if ( !p.search ) p.search = _AP.search; } } var _NP = Number.prototype; _NP.times = function(f, counter) { counter = counter || 0; for ( var i = 0 ; i < this ; ++i ) f(counter++); }; _NP.upTo = function(target, step) { if ( !step ) step = 1; var a = []; for ( var i = this.valueOf() ; i <= target ; i += step ) a.append(i); return a; }; _NP.downTo = function(target, step) { if ( !step ) step = 1; var a = []; for ( var i = this.valueOf() ; i >= target ; i -= step ) a.append(i); return a; }; _NP.to = function(target, step) { return this < target ? this.upTo(target, step) : this.downTo(target, step); }; _NP.chr = function() { return String.fromCharCode(this); }; var _SP = String.prototype; _SP.itemAt = String.charAt; _SP.asc = function() { return this.charCodeAt(0); }; _SP.to = function(target, step) { return this.asc().to(target.toString().asc(), step).collect(Function.from(null, "chr")); }; _SP.toFunctionUnary = function() { eval("function __unary__(op) { return " + this + " op; }"); __unary__.op = this; return __unary__; }; _SP.toFunctionBinary = function() { eval("function __binary__(op1, op2) { return op1 " + this + " op2; }"); __binary__.op = this; return __binary__; }; _SP.toFunction = function() { return ",!,~,++,--,new,delete,typeof,void,".indexOf("," + this + ",") > -1 ? this.toFunctionUnary() : this.toFunctionBinary(); }; _SP.toMethod = function() { return this.toFunction().toMethod(); }; _SP.apply = function(obj, args) { return this.toFunction().apply(obj, args); }; _SP.call = function(obj) { return this.toFunction().apply(obj, Array.from(arguments).slice(1)); }; _SP.curry = function() { return _FP.curry.apply(this.toFunction(), arguments); }; _SP.using = function() { return _FP.using.apply(this.toFunction(), arguments); }; _SP.asArgName = function() { var self = this; return { toString : function() { return self; }, asArgNameFlag : true }; }; _SP.asMethod = function(args) { eval("function __method__(obj) { return obj." + this + ".apply(obj, Array.from(arguments).slice(1)); }"); return args ? __method__.withArgString("obj," + args) : __method__; }; _SP.asMethodUsing = function() { var args = (1).upTo(arguments.length).collect(function(v) { return "arg" + v; }).join(","); return _FP.curry.apply(this.asMethod(args), (new Array(1)).concat(Array.from(arguments))); }; var _RP = RegExp.prototype; _RP.iterate = function(s, f) { var sre = this.toString(), sep = sre.lastIndexOf("/"); var re = new RegExp(sre.slice(1, sep), sre.slice(sep+1) + "g"); for ( var a ; a = re.exec(s) ; ) if ( f(a, s, re) === false ) return a; return null; }; _RP.not = function() { return "!".using(Function.from(this, "test", "str")); }; if ( typeof(Enumerator) == "function" && typeof(Enumerator.prototype) == "object" ) { var _EP = Enumerator.prototype; _EP.foreach = function(f) { for ( this.moveFirst() ; !this.atEnd() ; this.moveNext() ) if ( f(this.item(), this) === false ) return this.item(); return null; }; iteratable(Enumerator); } function select(prep, map, selector) { if ( arguments.length < 3 ) { selector = map; map = prep; prep = arguments[2]; } var r; switch ( typeof(prep) ) { case "string": prep = prep.toFunction(); case "function": case "object": if ( prep ) { r = map[prep(selector, this)]; break; } default: r = map[selector]; } if ( isUndefined(r) ) r = map[r]; return typeof(r) == "function" ? r.call(this, selector, prep) : r; } function stringSet(initItems) { if ( initItems ) this.addToSet.apply(this, initItems); } stringSet.prototype = { addToSet : function(item) { var set = this; return Array.from(arguments).coalesce(false, function(r, item) { return !set[item] ? set[item] = true : r; }); }, foreach : function(f) { for ( var item in this ) if ( this[item] !== stringSet.prototype[item] && f(item, this) === false ) return item; return null; }, mergeSet : function(set) { return Array.from(this).concat(Array.from(set)).toStringSet(); }, include : function() { return "&&".using( Function.from(this, null), Function.from(stringSet.prototype, null).andThen(isUndefined)); }, exclude : function() { return this.include().andThen("!".toFunctionUnary()); } }; _AP.toStringSet = function() { return new stringSet(this); }; Math.even = function(n) { return n % 2 == 0; }; Math.odd = function(n) { return n % 2 != 0; }; var ff = isUndefined(ff) ? Function.from : ff; function debugAlert(x) { if ( debugAlert.on ) Array.from(arguments).foreach(alert); if ( arguments.length > 0 ) return x; } debugAlert.on = true;