aboutsummaryrefslogtreecommitdiffstats
path: root/release/build/js/base2.js
diff options
context:
space:
mode:
Diffstat (limited to 'release/build/js/base2.js')
-rw-r--r--release/build/js/base2.js978
1 files changed, 978 insertions, 0 deletions
diff --git a/release/build/js/base2.js b/release/build/js/base2.js
new file mode 100644
index 000000000..08f091404
--- /dev/null
+++ b/release/build/js/base2.js
@@ -0,0 +1,978 @@
+// timestamp: Tue, 01 May 2007 19:13:00
+/*
+ base2.js - copyright 2007, Dean Edwards
+ http://www.opensource.org/licenses/mit-license
+*/
+
+var base2 = {};
+
+// You know, writing a javascript library is awfully time consuming.
+
+new function(_) { //////////////////// BEGIN: CLOSURE ////////////////////
+
+// =========================================================================
+// base2/Base.js
+// =========================================================================
+
+// version 1.1
+
+var Base = function() {
+ // call this method from any other method to invoke that method's ancestor
+};
+
+Base.prototype = {
+ extend: function(source) {
+ if (arguments.length > 1) { // extending with a name/value pair
+ var ancestor = this[source];
+ var value = arguments[1];
+ if (typeof value == "function" && ancestor && /\bbase\b/.test(value)) {
+ var method = value;
+ value = function() { // override
+ var previous = this.base;
+ this.base = ancestor;
+ var returnValue = method.apply(this, arguments);
+ this.base = previous;
+ return returnValue;
+ };
+ value.method = method;
+ value.ancestor = ancestor;
+ }
+ this[source] = value;
+ } else if (source) { // extending with an object literal
+ var extend = Base.prototype.extend;
+ if (Base._prototyping) {
+ var key, i = 0, members = ["constructor", "toString", "valueOf"];
+ while (key = members[i++]) if (source[key] != Object.prototype[key]) {
+ extend.call(this, key, source[key]);
+ }
+ } else if (typeof this != "function") {
+ // if the object has a customised extend() method then use it
+ extend = this.extend || extend;
+ }
+ // copy each of the source object's properties to this object
+ for (key in source) if (!Object.prototype[key]) {
+ extend.call(this, key, source[key]);
+ }
+ }
+ return this;
+ },
+
+ base: Base
+};
+
+Base.extend = function(_instance, _static) { // subclass
+ var extend = Base.prototype.extend;
+
+ // build the prototype
+ Base._prototyping = true;
+ var proto = new this;
+ extend.call(proto, _instance);
+ delete Base._prototyping;
+
+ // create the wrapper for the constructor function
+ var constructor = proto.constructor;
+ var klass = proto.constructor = function() {
+ if (!Base._prototyping) {
+ if (this._constructing || this.constructor == klass) { // instantiation
+ this._constructing = true;
+ constructor.apply(this, arguments);
+ delete this._constructing;
+ } else { // casting
+ var object = arguments[0];
+ if (object != null) {
+ (object.extend || extend).call(object, proto);
+ }
+ return object;
+ }
+ }
+ };
+
+ // build the class interface
+ for (var i in Base) klass[i] = this[i];
+ klass.ancestor = this;
+ klass.base = Base.base;
+ klass.prototype = proto;
+ klass.toString = this.toString;
+ extend.call(klass, _static);
+ // class initialisation
+ if (typeof klass.init == "function") klass.init();
+ return klass;
+};
+
+// initialise
+Base = Base.extend({
+ constructor: function() {
+ this.extend(arguments[0]);
+ }
+}, {
+ ancestor: Object,
+ base: Base,
+
+ implement: function(_interface) {
+ if (typeof _interface == "function") {
+ // if it's a function, call it
+ _interface(this.prototype);
+ } else {
+ // add the interface using the extend() method
+ this.prototype.extend(_interface);
+ }
+ return this;
+ }
+});
+
+// =========================================================================
+// lang/main.js
+// =========================================================================
+
+var Legacy = typeof $Legacy == "undefined" ? {} : $Legacy;
+
+var K = function(k) {return k};
+
+var assert = function(condition, message, Err) {
+ if (!condition) {
+ throw new (Err || Error)(message || "Assertion failed.");
+ }
+};
+
+var assertType = function(object, type, message) {
+ if (type) {
+ var condition = typeof type == "function" ? instanceOf(object, type) : typeof object == type;
+ assert(condition, message || "Invalid type.", TypeError);
+ }
+};
+
+var copy = function(object) {
+ var fn = new Function;
+ fn.prototype = object;
+ return new fn;
+};
+
+var format = function(string) {
+ // replace %n with arguments[n]
+ // e.g. format("%1 %2%3 %2a %1%3", "she", "se", "lls");
+ // ==> "she sells sea shells"
+ // only supports nine replacements: %1 - %9
+ var args = arguments;
+ return String(string).replace(/%([1-9])/g, function(match, index) {
+ return index < args.length ? args[index] : match;
+ });
+};
+
+var $instanceOf = Legacy.instanceOf || new Function("o,k", "return o instanceof k");
+var instanceOf = function(object, klass) {
+ assertType(klass, "function", "Invalid 'instanceOf' operand.");
+ if ($instanceOf(object, klass)) return true;
+ // handle exceptions where the target object originates from another frame
+ // this is handy for JSON parsing (amongst other things)
+ if (object != null) switch (klass) {
+ case Object:
+ return true;
+ case Number:
+ case Boolean:
+ case Function:
+ case String:
+ return typeof object == typeof klass.prototype.valueOf();
+ case Array:
+ // this is the only troublesome one
+ return !!(object.join && object.splice && !arguments.callee(object, Function));
+ case Date:
+ return !!object.getTimezoneOffset;
+ case RegExp:
+ return String(object.constructor.prototype) == String(new RegExp);
+ }
+ return false;
+};
+
+var match = function(string, expression) {
+ // same as String.match() except that this function will return an empty
+ // array if there is no match
+ return String(string).match(expression) || [];
+};
+
+var RESCAPE = /([\/()[\]{}|*+-.,^$?\\])/g;
+var rescape = function(string) {
+ // make a string safe for creating a RegExp
+ return String(string).replace(RESCAPE, "\\$1");
+};
+
+var $slice = Array.prototype.slice;
+var slice = function(object) {
+ // slice an array-like object
+ return $slice.apply(object, $slice.call(arguments, 1));
+};
+
+var TRIM = /^\s+|\s+$/g;
+var trim = function(string) {
+ return String(string).replace(TRIM, "");
+};
+
+// =========================================================================
+// lang/extend.js
+// =========================================================================
+
+var base = function(object, args) {
+ // invoke the base method with all supplied arguments
+ return object.base.apply(object, args);
+};
+
+var extend = function(object) {
+ assert(object != Object.prototype, "Object.prototype is verboten!");
+ return Base.prototype.extend.apply(object, slice(arguments, 1));
+};
+
+// =========================================================================
+// lang/assignID.js
+// =========================================================================
+
+var $ID = 1;
+var assignID = function(object) {
+ // assign a unique id
+ if (!object.base2ID) object.base2ID = "b2_" + $ID++;
+ return object.base2ID;
+};
+
+// =========================================================================
+// lang/forEach.js
+// =========================================================================
+
+if (typeof StopIteration == "undefined") {
+ StopIteration = new Error("StopIteration");
+}
+
+var forEach = function(object, block, context) {
+ if (object == null) return;
+ if (typeof object == "function") {
+ // functions are a special case
+ var fn = Function;
+ } else if (typeof object.forEach == "function" && object.forEach != arguments.callee) {
+ // the object implements a custom forEach method
+ object.forEach(block, context);
+ return;
+ } else if (typeof object.length == "number") {
+ // the object is array-like
+ forEach.Array(object, block, context);
+ return;
+ }
+ forEach.Function(fn || Object, object, block, context);
+};
+
+// these are the two core enumeration methods. all other forEach methods
+// eventually call one of these two.
+
+forEach.Array = function(array, block, context) {
+ var i, length = array.length; // preserve
+ if (typeof array == "string") {
+ for (i = 0; i < length; i++) {
+ block.call(context, array.charAt(i), i, array);
+ }
+ } else {
+ for (i = 0; i < length; i++) {
+ block.call(context, array[i], i, array);
+ }
+ }
+};
+
+forEach.Function = Legacy.forEach || function(fn, object, block, context) {
+ // enumerate an object and compare its keys with fn's prototype
+ for (var key in object) {
+ if (fn.prototype[key] === undefined) {
+ block.call(context, object[key], key, object);
+ }
+ }
+};
+
+// =========================================================================
+// base2/Base/forEach.js
+// =========================================================================
+
+Base.forEach = function(object, block, context) {
+ forEach.Function(this, object, block, context);
+};
+
+// =========================================================================
+// base2/../Function.js
+// =========================================================================
+
+// some browsers don't define this
+
+Function.prototype.prototype = {};
+
+
+// =========================================================================
+// base2/../String.js
+// =========================================================================
+
+// fix String.replace (Safari/IE5.0)
+
+if ("".replace(/^/, String)) {
+ extend(String.prototype, "replace", function(expression, replacement) {
+ if (typeof replacement == "function") { // Safari doesn't like functions
+ if (instanceOf(expression, RegExp)) {
+ var regexp = expression;
+ var global = regexp.global;
+ if (global == null) global = /(g|gi)$/.test(regexp);
+ // we have to convert global RexpExps for exec() to work consistently
+ if (global) regexp = new RegExp(regexp.source); // non-global
+ } else {
+ regexp = new RegExp(rescape(expression));
+ }
+ var match, string = this, result = "";
+ while (string && (match = regexp.exec(string))) {
+ result += string.slice(0, match.index) + replacement.apply(this, match);
+ string = string.slice(match.index + match[0].length);
+ if (!global) break;
+ }
+ return result + string;
+ } else {
+ return base(this, arguments);
+ }
+ });
+}
+
+// =========================================================================
+// base2/Abstract.js
+// =========================================================================
+
+var Abstract = Base.extend({
+ constructor: function() {
+ throw new TypeError("Class cannot be instantiated.");
+ }
+});
+
+// =========================================================================
+// base2/Module.js
+// =========================================================================
+
+// based on ruby's Module class and Mozilla's Array generics:
+// http://www.ruby-doc.org/core/classes/Module.html
+// http://developer.mozilla.org/en/docs/New_in_JavaScript_1.6#Array_and_String_generics
+
+// A Module is used as the basis for creating interfaces that can be
+// applied to other classes. *All* properties and methods are static.
+// When a module is used as a mixin, methods defined on what would normally be
+// the instance interface become instance methods of the target object.
+
+// Modules cannot be instantiated. Static properties and methods are inherited.
+
+var Module = Abstract.extend(null, {
+ extend: function(_interface, _static) {
+ // extend a module to create a new module
+ var module = this.base();
+ // inherit static methods
+ forEach (this, function(property, name) {
+ if (!Module[name] && name != "init") {
+ extend(module, name, property);
+ }
+ });
+ // implement module (instance AND static) methods
+ module.implement(_interface);
+ // implement static properties and methods
+ extend(module, _static);
+ // Make the submarine noises Larry!
+ if (typeof module.init == "function") module.init();
+ return module;
+ },
+
+ implement: function(_interface) {
+ // implement an interface on BOTH the instance and static interfaces
+ var module = this;
+ if (typeof _interface == "function") {
+ module.base(_interface);
+ forEach (_interface, function(property, name) {
+ if (!Module[name] && name != "init") {
+ extend(module, name, property);
+ }
+ });
+ } else {
+ // create the instance interface
+ Base.forEach (extend({}, _interface), function(property, name) {
+ // instance methods call the equivalent static method
+ if (typeof property == "function") {
+ property = function() {
+ base; // force inheritance
+ return module[name].apply(module, [this].concat(slice(arguments)));
+ };
+ }
+ if (!Module[name]) extend(this, name, property);
+ }, module.prototype);
+ // add the static interface
+ extend(module, _interface);
+ }
+ return module;
+ }
+});
+
+
+// =========================================================================
+// base2/Enumerable.js
+// =========================================================================
+
+var Enumerable = Module.extend({
+ every: function(object, test, context) {
+ var result = true;
+ try {
+ this.forEach (object, function(value, key) {
+ result = test.call(context, value, key, object);
+ if (!result) throw StopIteration;
+ });
+ } catch (error) {
+ if (error != StopIteration) throw error;
+ }
+ return !!result; // cast to boolean
+ },
+
+ filter: function(object, test, context) {
+ return this.reduce(object, function(result, value, key) {
+ if (test.call(context, value, key, object)) {
+ result[result.length] = value;
+ }
+ return result;
+ }, new Array2);
+ },
+
+ invoke: function(object, method) {
+ // apply a method to each item in the enumerated object
+ var args = slice(arguments, 2);
+ return this.map(object, (typeof method == "function") ? function(item) {
+ if (item != null) return method.apply(item, args);
+ } : function(item) {
+ if (item != null) return item[method].apply(item, args);
+ });
+ },
+
+ map: function(object, block, context) {
+ var result = new Array2;
+ this.forEach (object, function(value, key) {
+ result[result.length] = block.call(context, value, key, object);
+ });
+ return result;
+ },
+
+ pluck: function(object, key) {
+ return this.map(object, function(item) {
+ if (item != null) return item[key];
+ });
+ },
+
+ reduce: function(object, block, result, context) {
+ this.forEach (object, function(value, key) {
+ result = block.call(context, result, value, key, object);
+ });
+ return result;
+ },
+
+ some: function(object, test, context) {
+ return !this.every(object, function(value, key) {
+ return !test.call(context, value, key, object);
+ });
+ }
+}, {
+ forEach: forEach
+});
+
+// =========================================================================
+// base2/Array2.js
+// =========================================================================
+
+// The IArray module implements all Array methods.
+// This module is not public but its methods are accessible through the Array2 object (below).
+
+var IArray = Module.extend({
+ combine: function(keys, values) {
+ // combine two arrays to make a hash
+ if (!values) values = keys;
+ return this.reduce(keys, function(object, key, index) {
+ object[key] = values[index];
+ return object;
+ }, {});
+ },
+
+ copy: function(array) {
+ return this.concat(array);
+ },
+
+ contains: function(array, item) {
+ return this.indexOf(array, item) != -1;
+ },
+
+ forEach: forEach.Array,
+
+ indexOf: function(array, item, fromIndex) {
+ var length = array.length;
+ if (fromIndex == null) {
+ fromIndex = 0;
+ } else if (fromIndex < 0) {
+ fromIndex = Math.max(0, length + fromIndex);
+ }
+ for (var i = fromIndex; i < length; i++) {
+ if (array[i] === item) return i;
+ }
+ return -1;
+ },
+
+ insertAt: function(array, item, index) {
+ this.splice(array, index, 0, item);
+ return item;
+ },
+
+ insertBefore: function(array, item, before) {
+ var index = this.indexOf(array, before);
+ if (index == -1) this.push(array, item);
+ else this.splice(array, index, 0, item);
+ return item;
+ },
+
+ lastIndexOf: function(array, item, fromIndex) {
+ var length = array.length;
+ if (fromIndex == null) {
+ fromIndex = length - 1;
+ } else if (from < 0) {
+ fromIndex = Math.max(0, length + fromIndex);
+ }
+ for (var i = fromIndex; i >= 0; i--) {
+ if (array[i] === item) return i;
+ }
+ return -1;
+ },
+
+ remove: function(array, item) {
+ var index = this.indexOf(array, item);
+ if (index != -1) this.removeAt(array, index);
+ return item;
+ },
+
+ removeAt: function(array, index) {
+ var item = array[index];
+ this.splice(array, index, 1);
+ return item;
+ }
+});
+
+IArray.prototype.forEach = function(block, context) {
+ forEach.Array(this, block, context);
+};
+
+IArray.implement(Enumerable);
+
+forEach ("concat,join,pop,push,reverse,shift,slice,sort,splice,unshift".split(","), function(name) {
+ IArray[name] = function(array) {
+ return Array.prototype[name].apply(array, slice(arguments, 1));
+ };
+});
+
+// create a faux constructor that augments the built-in Array object
+var Array2 = function() {
+ return IArray(this.constructor == IArray ? Array.apply(null, arguments) : arguments[0]);
+};
+// expose IArray.prototype so that it can be extended
+Array2.prototype = IArray.prototype;
+
+forEach (IArray, function(method, name, proto) {
+ if (Array[name]) {
+ IArray[name] = Array[name];
+ delete IArray.prototype[name];
+ }
+ Array2[name] = IArray[name];
+});
+
+// =========================================================================
+// base2/Hash.js
+// =========================================================================
+
+var HASH = "#" + Number(new Date);
+var KEYS = HASH + "keys";
+var VALUES = HASH + "values";
+
+var Hash = Base.extend({
+ constructor: function(values) {
+ this[KEYS] = new Array2;
+ this[VALUES] = {};
+ this.merge(values);
+ },
+
+ copy: function() {
+ var copy = new this.constructor(this);
+ Base.forEach (this, function(property, name) {
+ if (typeof property != "function" && name.charAt(0) != "#") {
+ copy[name] = property;
+ }
+ });
+ return copy;
+ },
+
+ // ancient browsers throw an error when we use "in" as an operator
+ // so we must create the function dynamically
+ exists: Legacy.exists || new Function("k", format("return('%1'+k)in this['%2']", HASH, VALUES)),
+
+ fetch: function(key) {
+ return this[VALUES][HASH + key];
+ },
+
+ forEach: function(block, context) {
+ forEach (this[KEYS], function(key) {
+ block.call(context, this.fetch(key), key, this);
+ }, this);
+ },
+
+ keys: function(index, length) {
+ var keys = this[KEYS] || new Array2;
+ switch (arguments.length) {
+ case 0: return keys.copy();
+ case 1: return keys[index];
+ default: return keys.slice(index, length);
+ }
+ },
+
+ merge: function(values) {
+ forEach (arguments, function(values) {
+ forEach (values, function(value, key) {
+ this.store(key, value);
+ }, this);
+ }, this);
+ return this;
+ },
+
+ remove: function(key) {
+ var value = this.fetch(key);
+ this[KEYS].remove(String(key));
+ delete this[VALUES][HASH + key];
+ return value;
+ },
+
+ store: function(key, value) {
+ if (arguments.length == 1) value = key;
+ // only store the key for a new entry
+ if (!this.exists(key)) {
+ this[KEYS].push(String(key));
+ }
+ // create the new entry (or overwrite the old entry)
+ this[VALUES][HASH + key] = value;
+ return value;
+ },
+
+ toString: function() {
+ return String(this[KEYS]);
+ },
+
+ union: function(values) {
+ return this.merge.apply(this.copy(), arguments);
+ },
+
+ values: function(index, length) {
+ var values = this.map(K);
+ switch (arguments.length) {
+ case 0: return values;
+ case 1: return values[index];
+ default: return values.slice(index, length);
+ }
+ }
+});
+
+Hash.implement(Enumerable);
+
+// =========================================================================
+// base2/Collection.js
+// =========================================================================
+
+// A Hash that is more array-like (accessible by index).
+
+// Collection classes have a special (optional) property: Item
+// The Item property points to a constructor function.
+// Members of the collection must be an instance of Item.
+// e.g.
+// var Dates = Collection.extend(); // create a collection class
+// Dates.Item = Date; // only JavaScript Date objects allowed as members
+// var appointments = new Dates(); // instantiate the class
+// appointments.add(appointmentId, new Date); // add a date
+// appointments.add(appointmentId, "tomorrow"); // ERROR!
+
+// The static create() method is responsible for all construction of collection items.
+// Instance methods that add new items (add, store, insertAt, replaceAt) pass *all* of their arguments
+// to the static create() method. If you want to modify the way collection items are
+// created then you only need to override this method for custom collections.
+
+var Collection = Hash.extend({
+ add: function(key, item) {
+ // Duplicates not allowed using add().
+ // - but you can still overwrite entries using store()
+ assert(!this.exists(key), "Duplicate key.");
+ return this.store.apply(this, arguments);
+ },
+
+ count: function() {
+ return this[KEYS].length;
+ },
+
+ indexOf: function(key) {
+ return this[KEYS].indexOf(String(key));
+ },
+
+ insertAt: function(index, key, item) {
+ assert(!this.exists(key), "Duplicate key.");
+ this[KEYS].insertAt(index, String(key));
+ return this.store.apply(this, slice(arguments, 1));
+ },
+
+ item: function(index) {
+ return this.fetch(this[KEYS][index]);
+ },
+
+ removeAt: function(index) {
+ return this.remove(this[KEYS][index]);
+ },
+
+ reverse: function() {
+ this[KEYS].reverse();
+ return this;
+ },
+
+ sort: function(compare) {
+ if (compare) {
+ var self = this;
+ this[KEYS].sort(function(key1, key2) {
+ return compare(self.fetch(key1), self.fetch(key2), key1, key2);
+ });
+ } else this[KEYS].sort();
+ return this;
+ },
+
+ store: function(key, item) {
+ if (arguments.length == 1) item = key;
+ item = this.constructor.create.apply(this.constructor, arguments);
+ return this.base(key, item);
+ },
+
+ storeAt: function(index, item) {
+ //-dean: get rid of this?
+ assert(index < this.count(), "Index out of bounds.");
+ arguments[0] = this[KEYS][index];
+ return this.store.apply(this, arguments);
+ }
+}, {
+ Item: null, // if specified, all members of the Collection must be instances of Item
+
+ create: function(key, item) {
+ if (this.Item && !instanceOf(item, this.Item)) {
+ item = new this.Item(key, item);
+ }
+ return item;
+ },
+
+ extend: function(_instance, _static) {
+ var klass = this.base(_instance);
+ klass.create = this.create;
+ extend(klass, _static);
+ if (!klass.Item) {
+ klass.Item = this.Item;
+ } else if (typeof klass.Item != "function") {
+ klass.Item = (this.Item || Base).extend(klass.Item);
+ }
+ if (typeof klass.init == "function") klass.init();
+ return klass;
+ }
+});
+
+// =========================================================================
+// base2/RegGrp.js
+// =========================================================================
+
+var RegGrp = Collection.extend({
+ constructor: function(values, flags) {
+ this.base(values);
+ if (typeof flags == "string") {
+ this.global = /g/.test(flags);
+ this.ignoreCase = /i/.test(flags);
+ }
+ },
+
+ global: true, // global is the default setting
+ ignoreCase: false,
+
+ exec: function(string, replacement) {
+ if (arguments.length == 1) {
+ var keys = this[KEYS];
+ var values = this[VALUES];
+ replacement = function(match) {
+ if (!match) return "";
+ var offset = 1, i = 0;
+ // loop through the values
+ while (match = values[HASH + keys[i++]]) {
+ // do we have a result?
+ if (arguments[offset]) {
+ var replacement = match.replacement;
+ switch (typeof replacement) {
+ case "function":
+ return replacement.apply(null, slice(arguments, offset));
+ case "number":
+ return arguments[offset + replacement];
+ default:
+ return replacement;
+ }
+ // no? then skip over references to sub-expressions
+ } else offset += match.length + 1;
+ }
+ };
+ }
+ var flags = (this.global ? "g" : "") + (this.ignoreCase ? "i" : "");
+ return String(string).replace(new RegExp(this, flags), replacement);
+ },
+
+ test: function(string) {
+ return this.exec(string) != string;
+ },
+
+ toString: function() {
+ var length = 0;
+ return "(" + this.map(function(item) {
+ // fix back references
+ var expression = String(item).replace(/\\(\d+)/g, function($, index) {
+ return "\\" + (1 + Number(index) + length);
+ });
+ length += item.length + 1;
+ return expression;
+ }).join(")|(") + ")";
+ }
+}, {
+ IGNORE: "$0",
+
+ init: function() {
+ forEach ("add,exists,fetch,remove,store".split(","), function(name) {
+ extend(this, name, function(expression) {
+ if (instanceOf(expression, RegExp)) {
+ expression = expression.source;
+ }
+ return base(this, arguments);
+ });
+ }, this.prototype);
+ }
+});
+
+// =========================================================================
+// base2/RegGrp/Item.js
+// =========================================================================
+
+RegGrp.Item = Base.extend({
+ constructor: function(expression, replacement) {
+ var ESCAPE = /\\./g;
+ var STRING = /(['"])\1\+(.*)\+\1\1$/;
+
+ expression = instanceOf(expression, RegExp) ? expression.source : String(expression);
+
+ if (typeof replacement == "number") replacement = String(replacement);
+ else if (replacement == null) replacement = "";
+
+ // count the number of sub-expressions
+ // - add one because each pattern is itself a sub-expression
+ this.length = match(expression.replace(ESCAPE, "").replace(/\[[^\]]+\]/g, ""), /\(/g).length;
+
+ // does the pattern use sub-expressions?
+ if (typeof replacement == "string" && /\$(\d+)/.test(replacement)) {
+ // a simple lookup? (e.g. "$2")
+ if (/^\$\d+$/.test(replacement)) {
+ // store the index (used for fast retrieval of matched strings)
+ replacement = parseInt(replacement.slice(1));
+ } else { // a complicated lookup (e.g. "Hello $2 $1")
+ // build a function to do the lookup
+ var i = this.length + 1;
+ var Q = /'/.test(replacement.replace(ESCAPE, "")) ? '"' : "'";
+ replacement = replacement.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\$(\d+)/g, Q +
+ "+(arguments[$1]||" + Q+Q + ")+" + Q);
+ replacement = new Function("return " + Q + replacement.replace(STRING, "$1") + Q);
+ }
+ }
+ this.replacement = replacement;
+ this.toString = function() {
+ return expression || "";
+ };
+ },
+
+ length: 0,
+ replacement: ""
+});
+
+// =========================================================================
+// base2/Namespace.js
+// =========================================================================
+
+var Namespace = Base.extend({
+ constructor: function(_private, _public) {
+ this.extend(_public);
+ this.toString = function() {
+ return format("[base2.%1]", this.name);
+ };
+
+ // initialise
+ if (typeof this.init == "function") this.init();
+
+ if (this.name != "base2") {
+ this.namespace = format("var %1=base2.%1;", this.name);
+ }
+
+ var namespace = "var base=" + base + ";";
+ var imports = ("base2,lang," + this.imports).split(",");
+ _private.imports = Enumerable.reduce(imports, function(namespace, name) {
+ if (base2[name]) namespace += base2[name].namespace;
+ return namespace;
+ }, namespace);
+
+ var namespace = format("base2.%1=%1;", this.name);
+ var exports = this.exports.split(",");
+ _private.exports = Enumerable.reduce(exports, function(namespace, name) {
+ if (name) {
+ this.namespace += format("var %2=%1.%2;", this.name, name);
+ namespace += format("if(!%1.%2)%1.%2=%2;base2.%2=%1.%2;", this.name, name);
+ }
+ return namespace;
+ }, namespace, this);
+
+ if (this.name != "base2") {
+ base2.namespace += format("var %1=base2.%1;", this.name);
+ }
+ },
+
+ exports: "",
+ imports: "",
+ namespace: "",
+ name: ""
+});
+
+base2 = new Namespace(this, {
+ name: "base2",
+ version: "0.8 (alpha)",
+ exports: "Base,Abstract,Module,Enumerable,Array2,Hash,Collection,RegGrp,Namespace"
+});
+
+base2.toString = function() {
+ return "[base2]";
+};
+
+eval(this.exports);
+
+// =========================================================================
+// base2/lang/namespace.js
+// =========================================================================
+
+var lang = new Namespace(this, {
+ name: "lang",
+ version: base2.version,
+ exports: "K,assert,assertType,assignID,copy,instanceOf,extend,format,forEach,match,rescape,slice,trim",
+
+ init: function() {
+ this.extend = extend;
+ // add the Enumerable methods to the lang object
+ forEach (Enumerable.prototype, function(method, name) {
+ if (!Module[name]) {
+ this[name] = function() {
+ return Enumerable[name].apply(Enumerable, arguments);
+ };
+ this.exports += "," + name;
+ }
+ }, this);
+ }
+});
+
+eval(this.exports);
+
+base2.namespace += lang.namespace;
+
+}; //////////////////// END: CLOSURE /////////////////////////////////////