/*
---
MooTools: the javascript framework
web build:
- http://mootools.net/core/76bf47062d6c1983d66ce47ad66aa0e0
packager build:
- packager build Core/Core Core/Array Core/String Core/Number Core/Function Core/Object Core/Event Core/Browser Core/Class Core/Class.Extras Core/Slick.Parser Core/Slick.Finder Core/Element Core/Element.Style Core/Element.Event Core/Element.Delegation Core/Element.Dimensions Core/Fx Core/Fx.CSS Core/Fx.Tween Core/Fx.Morph Core/Fx.Transitions Core/Request Core/Request.HTML Core/Request.JSON Core/Cookie Core/JSON Core/DOMReady Core/Swiff
...
*/
/*
---
name: Core
description: The heart of MooTools.
license: MIT-style license.
copyright: Copyright (c) 2006-2012 [Valerio Proietti](http://mad4milk.net/).
authors: The MooTools production team (http://mootools.net/developers/)
inspiration:
- Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)
- Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php)
provides: [Core, MooTools, Type, typeOf, instanceOf, Native]
...
*/
(function () {
this.MooTools = {
version: "1.4.5",
build: "ab8ea8824dc3b24b6666867a2c4ed58ebb762cf0",
};
// typeOf, instanceOf
var typeOf = (this.typeOf = function (item) {
if (item == null) return "null";
if (item.$family != null) return item.$family();
if (item.nodeName) {
if (item.nodeType == 1) return "element";
if (item.nodeType == 3)
return /\S/.test(item.nodeValue) ? "textnode" : "whitespace";
} else if (typeof item.length == "number") {
if (item.callee) return "arguments";
if ("item" in item) return "collection";
}
return typeof item;
});
var instanceOf = (this.instanceOf = function (item, object) {
if (item == null) return false;
var constructor = item.$constructor || item.constructor;
while (constructor) {
if (constructor === object) return true;
constructor = constructor.parent;
}
/**/
if (!item.hasOwnProperty) return false;
/**/
return item instanceof object;
});
// Function overloading
var Function = this.Function;
var enumerables = true;
for (var i in { toString: 1 }) enumerables = null;
if (enumerables)
enumerables = [
"hasOwnProperty",
"valueOf",
"isPrototypeOf",
"propertyIsEnumerable",
"toLocaleString",
"toString",
"constructor",
];
Function.prototype.overloadSetter = function (usePlural) {
var self = this;
return function (a, b) {
if (a == null) return this;
if (usePlural || typeof a != "string") {
for (var k in a) self.call(this, k, a[k]);
if (enumerables)
for (var i = enumerables.length; i--; ) {
k = enumerables[i];
if (a.hasOwnProperty(k)) self.call(this, k, a[k]);
}
} else {
self.call(this, a, b);
}
return this;
};
};
Function.prototype.overloadGetter = function (usePlural) {
var self = this;
return function (a) {
var args, result;
if (typeof a != "string") args = a;
else if (arguments.length > 1) args = arguments;
else if (usePlural) args = [a];
if (args) {
result = {};
for (var i = 0; i < args.length; i++)
result[args[i]] = self.call(this, args[i]);
} else {
result = self.call(this, a);
}
return result;
};
};
Function.prototype.extend = function (key, value) {
this[key] = value;
}.overloadSetter();
Function.prototype.implement = function (key, value) {
this.prototype[key] = value;
}.overloadSetter();
// From
var slice = Array.prototype.slice;
Function.from = function (item) {
return typeOf(item) == "function"
? item
: function () {
return item;
};
};
Array.from = function (item) {
if (item == null) return [];
return Type.isEnumerable(item) && typeof item != "string"
? typeOf(item) == "array"
? item
: slice.call(item)
: [item];
};
Number.from = function (item) {
var number = parseFloat(item);
return isFinite(number) ? number : null;
};
String.from = function (item) {
return item + "";
};
// hide, protect
Function.implement({
hide: function () {
this.$hidden = true;
return this;
},
protect: function () {
this.$protected = true;
return this;
},
});
// Type
var Type = (this.Type = function (name, object) {
if (name) {
var lower = name.toLowerCase();
var typeCheck = function (item) {
return typeOf(item) == lower;
};
Type["is" + name] = typeCheck;
if (object != null) {
object.prototype.$family = function () {
return lower;
}.hide();
//<1.2compat>
object.type = typeCheck;
//1.2compat>
}
}
if (object == null) return null;
object.extend(this);
object.$constructor = Type;
object.prototype.$constructor = object;
return object;
});
var toString = Object.prototype.toString;
Type.isEnumerable = function (item) {
return (
item != null &&
typeof item.length == "number" &&
toString.call(item) != "[object Function]"
);
};
var hooks = {};
var hooksOf = function (object) {
var type = typeOf(object.prototype);
return hooks[type] || (hooks[type] = []);
};
var implement = function (name, method) {
if (method && method.$hidden) return;
var hooks = hooksOf(this);
for (var i = 0; i < hooks.length; i++) {
var hook = hooks[i];
if (typeOf(hook) == "type") implement.call(hook, name, method);
else hook.call(this, name, method);
}
var previous = this.prototype[name];
if (previous == null || !previous.$protected) this.prototype[name] = method;
if (this[name] == null && typeOf(method) == "function")
extend.call(this, name, function (item) {
return method.apply(item, slice.call(arguments, 1));
});
};
var extend = function (name, method) {
if (method && method.$hidden) return;
var previous = this[name];
if (previous == null || !previous.$protected) this[name] = method;
};
Type.implement({
implement: implement.overloadSetter(),
extend: extend.overloadSetter(),
alias: function (name, existing) {
implement.call(this, name, this.prototype[existing]);
}.overloadSetter(),
mirror: function (hook) {
hooksOf(this).push(hook);
return this;
},
});
new Type("Type", Type);
// Default Types
var force = function (name, object, methods) {
var isType = object != Object,
prototype = object.prototype;
if (isType) object = new Type(name, object);
for (var i = 0, l = methods.length; i < l; i++) {
var key = methods[i],
generic = object[key],
proto = prototype[key];
if (generic) generic.protect();
if (isType && proto) object.implement(key, proto.protect());
}
if (isType) {
var methodsEnumerable = prototype.propertyIsEnumerable(methods[0]);
object.forEachMethod = function (fn) {
if (!methodsEnumerable)
for (var i = 0, l = methods.length; i < l; i++) {
fn.call(prototype, prototype[methods[i]], methods[i]);
}
for (var key in prototype) fn.call(prototype, prototype[key], key);
};
}
return force;
};
force("String", String, [
"charAt",
"charCodeAt",
"concat",
"indexOf",
"lastIndexOf",
"match",
"quote",
"replace",
"search",
"slice",
"split",
"substr",
"substring",
"trim",
"toLowerCase",
"toUpperCase",
])("Array", Array, [
"pop",
"push",
"reverse",
"shift",
"sort",
"splice",
"unshift",
"concat",
"join",
"slice",
"indexOf",
"lastIndexOf",
"filter",
"forEach",
"every",
"map",
"some",
"reduce",
"reduceRight",
])("Number", Number, [
"toExponential",
"toFixed",
"toLocaleString",
"toPrecision",
])("Function", Function, ["apply", "call", "bind"])("RegExp", RegExp, [
"exec",
"test",
])("Object", Object, [
"create",
"defineProperty",
"defineProperties",
"keys",
"getPrototypeOf",
"getOwnPropertyDescriptor",
"getOwnPropertyNames",
"preventExtensions",
"isExtensible",
"seal",
"isSealed",
"freeze",
"isFrozen",
])("Date", Date, ["now"]);
Object.extend = extend.overloadSetter();
Date.extend("now", function () {
return +new Date();
});
new Type("Boolean", Boolean);
// fixes NaN returning as Number
Number.prototype.$family = function () {
return isFinite(this) ? "number" : "null";
}.hide();
// Number.random
Number.extend("random", function (min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
});
// forEach, each
var hasOwnProperty = Object.prototype.hasOwnProperty;
Object.extend("forEach", function (object, fn, bind) {
for (var key in object) {
if (hasOwnProperty.call(object, key))
fn.call(bind, object[key], key, object);
}
});
Object.each = Object.forEach;
Array.implement({
forEach: function (fn, bind) {
for (var i = 0, l = this.length; i < l; i++) {
if (i in this) fn.call(bind, this[i], i, this);
}
},
each: function (fn, bind) {
Array.forEach(this, fn, bind);
return this;
},
});
// Array & Object cloning, Object merging and appending
var cloneOf = function (item) {
switch (typeOf(item)) {
case "array":
return item.clone();
case "object":
return Object.clone(item);
default:
return item;
}
};
Array.implement("clone", function () {
var i = this.length,
clone = new Array(i);
while (i--) clone[i] = cloneOf(this[i]);
return clone;
});
var mergeOne = function (source, key, current) {
switch (typeOf(current)) {
case "object":
if (typeOf(source[key]) == "object") Object.merge(source[key], current);
else source[key] = Object.clone(current);
break;
case "array":
source[key] = current.clone();
break;
default:
source[key] = current;
}
return source;
};
Object.extend({
merge: function (source, k, v) {
if (typeOf(k) == "string") return mergeOne(source, k, v);
for (var i = 1, l = arguments.length; i < l; i++) {
var object = arguments[i];
for (var key in object) mergeOne(source, key, object[key]);
}
return source;
},
clone: function (object) {
var clone = {};
for (var key in object) clone[key] = cloneOf(object[key]);
return clone;
},
append: function (original) {
for (var i = 1, l = arguments.length; i < l; i++) {
var extended = arguments[i] || {};
for (var key in extended) original[key] = extended[key];
}
return original;
},
});
// Object-less types
["Object", "WhiteSpace", "TextNode", "Collection", "Arguments"].each(
function (name) {
new Type(name);
},
);
// Unique ID
var UID = Date.now();
String.extend("uniqueID", function () {
return (UID++).toString(36);
});
//<1.2compat>
var Hash = (this.Hash = new Type("Hash", function (object) {
if (typeOf(object) == "hash") object = Object.clone(object.getClean());
for (var key in object) this[key] = object[key];
return this;
}));
Hash.implement({
forEach: function (fn, bind) {
Object.forEach(this, fn, bind);
},
getClean: function () {
var clean = {};
for (var key in this) {
if (this.hasOwnProperty(key)) clean[key] = this[key];
}
return clean;
},
getLength: function () {
var length = 0;
for (var key in this) {
if (this.hasOwnProperty(key)) length++;
}
return length;
},
});
Hash.alias("each", "forEach");
Object.type = Type.isObject;
var Native = (this.Native = function (properties) {
return new Type(properties.name, properties.initialize);
});
Native.type = Type.type;
Native.implement = function (objects, methods) {
for (var i = 0; i < objects.length; i++) objects[i].implement(methods);
return Native;
};
var arrayType = Array.type;
Array.type = function (item) {
return instanceOf(item, Array) || arrayType(item);
};
this.$A = function (item) {
return Array.from(item).slice();
};
this.$arguments = function (i) {
return function () {
return arguments[i];
};
};
this.$chk = function (obj) {
return !!(obj || obj === 0);
};
this.$clear = function (timer) {
clearTimeout(timer);
clearInterval(timer);
return null;
};
this.$defined = function (obj) {
return obj != null;
};
this.$each = function (iterable, fn, bind) {
var type = typeOf(iterable);
(type == "arguments" ||
type == "collection" ||
type == "array" ||
type == "elements"
? Array
: Object
).each(iterable, fn, bind);
};
this.$empty = function () {};
this.$extend = function (original, extended) {
return Object.append(original, extended);
};
this.$H = function (object) {
return new Hash(object);
};
this.$merge = function () {
var args = Array.slice(arguments);
args.unshift({});
return Object.merge.apply(null, args);
};
this.$lambda = Function.from;
this.$mixin = Object.merge;
this.$random = Number.random;
this.$splat = Array.from;
this.$time = Date.now;
this.$type = function (object) {
var type = typeOf(object);
if (type == "elements") return "array";
return type == "null" ? false : type;
};
this.$unlink = function (object) {
switch (typeOf(object)) {
case "object":
return Object.clone(object);
case "array":
return Array.clone(object);
case "hash":
return new Hash(object);
default:
return object;
}
};
//1.2compat>
})();
/*
---
name: Array
description: Contains Array Prototypes like each, contains, and erase.
license: MIT-style license.
requires: Type
provides: Array
...
*/
Array.implement({
/**/
every: function (fn, bind) {
for (var i = 0, l = this.length >>> 0; i < l; i++) {
if (i in this && !fn.call(bind, this[i], i, this)) return false;
}
return true;
},
filter: function (fn, bind) {
var results = [];
for (var value, i = 0, l = this.length >>> 0; i < l; i++)
if (i in this) {
value = this[i];
if (fn.call(bind, value, i, this)) results.push(value);
}
return results;
},
indexOf: function (item, from) {
var length = this.length >>> 0;
for (
var i = from < 0 ? Math.max(0, length + from) : from || 0;
i < length;
i++
) {
if (this[i] === item) return i;
}
return -1;
},
map: function (fn, bind) {
var length = this.length >>> 0,
results = Array(length);
for (var i = 0; i < length; i++) {
if (i in this) results[i] = fn.call(bind, this[i], i, this);
}
return results;
},
some: function (fn, bind) {
for (var i = 0, l = this.length >>> 0; i < l; i++) {
if (i in this && fn.call(bind, this[i], i, this)) return true;
}
return false;
},
/*!ES5>*/
clean: function () {
return this.filter(function (item) {
return item != null;
});
},
invoke: function (methodName) {
var args = Array.slice(arguments, 1);
return this.map(function (item) {
return item[methodName].apply(item, args);
});
},
associate: function (keys) {
var obj = {},
length = Math.min(this.length, keys.length);
for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
return obj;
},
link: function (object) {
var result = {};
for (var i = 0, l = this.length; i < l; i++) {
for (var key in object) {
if (object[key](this[i])) {
result[key] = this[i];
delete object[key];
break;
}
}
}
return result;
},
contains: function (item, from) {
return this.indexOf(item, from) != -1;
},
append: function (array) {
this.push.apply(this, array);
return this;
},
getLast: function () {
return this.length ? this[this.length - 1] : null;
},
getRandom: function () {
return this.length ? this[Number.random(0, this.length - 1)] : null;
},
include: function (item) {
if (!this.contains(item)) this.push(item);
return this;
},
combine: function (array) {
for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
return this;
},
erase: function (item) {
for (var i = this.length; i--; ) {
if (this[i] === item) this.splice(i, 1);
}
return this;
},
empty: function () {
this.length = 0;
return this;
},
flatten: function () {
var array = [];
for (var i = 0, l = this.length; i < l; i++) {
var type = typeOf(this[i]);
if (type == "null") continue;
array = array.concat(
type == "array" ||
type == "collection" ||
type == "arguments" ||
instanceOf(this[i], Array)
? Array.flatten(this[i])
: this[i],
);
}
return array;
},
pick: function () {
for (var i = 0, l = this.length; i < l; i++) {
if (this[i] != null) return this[i];
}
return null;
},
hexToRgb: function (array) {
if (this.length != 3) return null;
var rgb = this.map(function (value) {
if (value.length == 1) value += value;
return value.toInt(16);
});
return array ? rgb : "rgb(" + rgb + ")";
},
rgbToHex: function (array) {
if (this.length < 3) return null;
if (this.length == 4 && this[3] == 0 && !array) return "transparent";
var hex = [];
for (var i = 0; i < 3; i++) {
var bit = (this[i] - 0).toString(16);
hex.push(bit.length == 1 ? "0" + bit : bit);
}
return array ? hex : "#" + hex.join("");
},
});
//<1.2compat>
Array.alias("extend", "append");
var $pick = function () {
return Array.from(arguments).pick();
};
//1.2compat>
/*
---
name: String
description: Contains String Prototypes like camelCase, capitalize, test, and toInt.
license: MIT-style license.
requires: Type
provides: String
...
*/
String.implement({
test: function (regex, params) {
return (
typeOf(regex) == "regexp" ? regex : new RegExp("" + regex, params)
).test(this);
},
contains: function (string, separator) {
return separator
? (separator + this + separator).indexOf(separator + string + separator) >
-1
: String(this).indexOf(string) > -1;
},
trim: function () {
return String(this).replace(/^\s+|\s+$/g, "");
},
clean: function () {
return String(this).replace(/\s+/g, " ").trim();
},
camelCase: function () {
return String(this).replace(/-\D/g, function (match) {
return match.charAt(1).toUpperCase();
});
},
hyphenate: function () {
return String(this).replace(/[A-Z]/g, function (match) {
return "-" + match.charAt(0).toLowerCase();
});
},
capitalize: function () {
return String(this).replace(/\b[a-z]/g, function (match) {
return match.toUpperCase();
});
},
escapeRegExp: function () {
return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
},
toInt: function (base) {
return parseInt(this, base || 10);
},
toFloat: function () {
return parseFloat(this);
},
hexToRgb: function (array) {
var hex = String(this).match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
return hex ? hex.slice(1).hexToRgb(array) : null;
},
rgbToHex: function (array) {
var rgb = String(this).match(/\d{1,3}/g);
return rgb ? rgb.rgbToHex(array) : null;
},
substitute: function (object, regexp) {
return String(this).replace(
regexp || /\\?\{([^{}]+)\}/g,
function (match, name) {
if (match.charAt(0) == "\\") return match.slice(1);
return object[name] != null ? object[name] : "";
},
);
},
});
/*
---
name: Number
description: Contains Number Prototypes like limit, round, times, and ceil.
license: MIT-style license.
requires: Type
provides: Number
...
*/
Number.implement({
limit: function (min, max) {
return Math.min(max, Math.max(min, this));
},
round: function (precision) {
precision = Math.pow(10, precision || 0).toFixed(
precision < 0 ? -precision : 0,
);
return Math.round(this * precision) / precision;
},
times: function (fn, bind) {
for (var i = 0; i < this; i++) fn.call(bind, i, this);
},
toFloat: function () {
return parseFloat(this);
},
toInt: function (base) {
return parseInt(this, base || 10);
},
});
Number.alias("each", "times");
(function (math) {
var methods = {};
math.each(function (name) {
if (!Number[name])
methods[name] = function () {
return Math[name].apply(null, [this].concat(Array.from(arguments)));
};
});
Number.implement(methods);
})([
"abs",
"acos",
"asin",
"atan",
"atan2",
"ceil",
"cos",
"exp",
"floor",
"log",
"max",
"min",
"pow",
"sin",
"sqrt",
"tan",
]);
/*
---
name: Function
description: Contains Function Prototypes like create, bind, pass, and delay.
license: MIT-style license.
requires: Type
provides: Function
...
*/
Function.extend({
attempt: function () {
for (var i = 0, l = arguments.length; i < l; i++) {
try {
return arguments[i]();
} catch (e) {}
}
return null;
},
});
Function.implement({
attempt: function (args, bind) {
try {
return this.apply(bind, Array.from(args));
} catch (e) {}
return null;
},
/**/
bind: function (that) {
var self = this,
args = arguments.length > 1 ? Array.slice(arguments, 1) : null,
F = function () {};
var bound = function () {
var context = that,
length = arguments.length;
if (this instanceof bound) {
F.prototype = self.prototype;
context = new F();
}
var result =
!args && !length
? self.call(context)
: self.apply(
context,
args && length
? args.concat(Array.slice(arguments))
: args || arguments,
);
return context == that ? result : context;
};
return bound;
},
/*!ES5-bind>*/
pass: function (args, bind) {
var self = this;
if (args != null) args = Array.from(args);
return function () {
return self.apply(bind, args || arguments);
};
},
delay: function (delay, bind, args) {
return setTimeout(this.pass(args == null ? [] : args, bind), delay);
},
periodical: function (periodical, bind, args) {
return setInterval(this.pass(args == null ? [] : args, bind), periodical);
},
});
//<1.2compat>
delete Function.prototype.bind;
Function.implement({
create: function (options) {
var self = this;
options = options || {};
return function (event) {
var args = options.arguments;
args =
args != null
? Array.from(args)
: Array.slice(arguments, options.event ? 1 : 0);
if (options.event) args = [event || window.event].extend(args);
var returns = function () {
return self.apply(options.bind || null, args);
};
if (options.delay) return setTimeout(returns, options.delay);
if (options.periodical) return setInterval(returns, options.periodical);
if (options.attempt) return Function.attempt(returns);
return returns();
};
},
bind: function (bind, args) {
var self = this;
if (args != null) args = Array.from(args);
return function () {
return self.apply(bind, args || arguments);
};
},
bindWithEvent: function (bind, args) {
var self = this;
if (args != null) args = Array.from(args);
return function (event) {
return self.apply(bind, args == null ? arguments : [event].concat(args));
};
},
run: function (args, bind) {
return this.apply(bind, Array.from(args));
},
});
if (Object.create == Function.prototype.create) Object.create = null;
var $try = Function.attempt;
//1.2compat>
/*
---
name: Object
description: Object generic methods
license: MIT-style license.
requires: Type
provides: [Object, Hash]
...
*/
(function () {
var hasOwnProperty = Object.prototype.hasOwnProperty;
Object.extend({
subset: function (object, keys) {
var results = {};
for (var i = 0, l = keys.length; i < l; i++) {
var k = keys[i];
if (k in object) results[k] = object[k];
}
return results;
},
map: function (object, fn, bind) {
var results = {};
for (var key in object) {
if (hasOwnProperty.call(object, key))
results[key] = fn.call(bind, object[key], key, object);
}
return results;
},
filter: function (object, fn, bind) {
var results = {};
for (var key in object) {
var value = object[key];
if (
hasOwnProperty.call(object, key) &&
fn.call(bind, value, key, object)
)
results[key] = value;
}
return results;
},
every: function (object, fn, bind) {
for (var key in object) {
if (
hasOwnProperty.call(object, key) &&
!fn.call(bind, object[key], key)
)
return false;
}
return true;
},
some: function (object, fn, bind) {
for (var key in object) {
if (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key))
return true;
}
return false;
},
keys: function (object) {
var keys = [];
for (var key in object) {
if (hasOwnProperty.call(object, key)) keys.push(key);
}
return keys;
},
values: function (object) {
var values = [];
for (var key in object) {
if (hasOwnProperty.call(object, key)) values.push(object[key]);
}
return values;
},
getLength: function (object) {
return Object.keys(object).length;
},
keyOf: function (object, value) {
for (var key in object) {
if (hasOwnProperty.call(object, key) && object[key] === value)
return key;
}
return null;
},
contains: function (object, value) {
return Object.keyOf(object, value) != null;
},
toQueryString: function (object, base) {
var queryString = [];
Object.each(object, function (value, key) {
if (base) key = base + "[" + key + "]";
var result;
switch (typeOf(value)) {
case "object":
result = Object.toQueryString(value, key);
break;
case "array":
var qs = {};
value.each(function (val, i) {
qs[i] = val;
});
result = Object.toQueryString(qs, key);
break;
default:
result = key + "=" + encodeURIComponent(value);
}
if (value != null) queryString.push(result);
});
return queryString.join("&");
},
});
})();
//<1.2compat>
Hash.implement({
has: Object.prototype.hasOwnProperty,
keyOf: function (value) {
return Object.keyOf(this, value);
},
hasValue: function (value) {
return Object.contains(this, value);
},
extend: function (properties) {
Hash.each(
properties || {},
function (value, key) {
Hash.set(this, key, value);
},
this,
);
return this;
},
combine: function (properties) {
Hash.each(
properties || {},
function (value, key) {
Hash.include(this, key, value);
},
this,
);
return this;
},
erase: function (key) {
if (this.hasOwnProperty(key)) delete this[key];
return this;
},
get: function (key) {
return this.hasOwnProperty(key) ? this[key] : null;
},
set: function (key, value) {
if (!this[key] || this.hasOwnProperty(key)) this[key] = value;
return this;
},
empty: function () {
Hash.each(
this,
function (value, key) {
delete this[key];
},
this,
);
return this;
},
include: function (key, value) {
if (this[key] == null) this[key] = value;
return this;
},
map: function (fn, bind) {
return new Hash(Object.map(this, fn, bind));
},
filter: function (fn, bind) {
return new Hash(Object.filter(this, fn, bind));
},
every: function (fn, bind) {
return Object.every(this, fn, bind);
},
some: function (fn, bind) {
return Object.some(this, fn, bind);
},
getKeys: function () {
return Object.keys(this);
},
getValues: function () {
return Object.values(this);
},
toQueryString: function (base) {
return Object.toQueryString(this, base);
},
});
Hash.extend = Object.append;
Hash.alias({ indexOf: "keyOf", contains: "hasValue" });
//1.2compat>
/*
---
name: Browser
description: The Browser Object. Contains Browser initialization, Window and Document, and the Browser Hash.
license: MIT-style license.
requires: [Array, Function, Number, String]
provides: [Browser, Window, Document]
...
*/
(function () {
var document = this.document;
var window = (document.window = this);
var ua = navigator.userAgent.toLowerCase(),
platform = navigator.platform.toLowerCase(),
UA = ua.match(
/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/,
) || [null, "unknown", 0],
mode = UA[1] == "ie" && document.documentMode;
var Browser = (this.Browser = {
extend: Function.prototype.extend,
name: UA[1] == "version" ? UA[3] : UA[1],
version: mode || parseFloat(UA[1] == "opera" && UA[4] ? UA[4] : UA[2]),
Platform: {
name: ua.match(/ip(?:ad|od|hone)/)
? "ios"
: (ua.match(/(?:webos|android)/) ||
platform.match(/mac|win|linux/) || ["other"])[0],
},
Features: {
xpath: !!document.evaluate,
air: !!window.runtime,
query: !!document.querySelector,
json: !!window.JSON,
},
Plugins: {},
});
Browser[Browser.name] = true;
Browser[Browser.name + parseInt(Browser.version, 10)] = true;
Browser.Platform[Browser.Platform.name] = true;
// Request
Browser.Request = (function () {
var XMLHTTP = function () {
return new XMLHttpRequest();
};
var MSXML2 = function () {
return new ActiveXObject("MSXML2.XMLHTTP");
};
var MSXML = function () {
return new ActiveXObject("Microsoft.XMLHTTP");
};
return Function.attempt(
function () {
XMLHTTP();
return XMLHTTP;
},
function () {
MSXML2();
return MSXML2;
},
function () {
MSXML();
return MSXML;
},
);
})();
Browser.Features.xhr = !!Browser.Request;
// Flash detection
var version = (
Function.attempt(
function () {
return navigator.plugins["Shockwave Flash"].description;
},
function () {
return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable(
"$version",
);
},
) || "0 r0"
).match(/\d+/g);
Browser.Plugins.Flash = {
version: Number(version[0] || "0." + version[1]) || 0,
build: Number(version[2]) || 0,
};
// String scripts
Browser.exec = function (text) {
if (!text) return text;
if (window.execScript) {
window.execScript(text);
} else {
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.text = text;
document.head.appendChild(script);
document.head.removeChild(script);
}
return text;
};
String.implement("stripScripts", function (exec) {
var scripts = "";
var text = this.replace(
/