Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit

  • Loading branch information...
commit c25a232eeaa64594d7a6762ab4ef6645423e6181 0 parents
@arlolra authored
9 lib/routes.js
@@ -0,0 +1,9 @@
+module.exports = function (app) {
+
+ app.get('/', function (req, res) {
+
+ res.send('hey')
+
+ })
+
+}
18 package.json
@@ -0,0 +1,18 @@
+{
+ "author" : "Arlo Breault <arlolra@gmail.com>"
+ , "name" : "herder"
+ , "version" : "0.0.1"
+ , "homepage" : "http://thoughtherder.com"
+ , "repository" : {
+ "type" : "git"
+ , "url" : "git@github.com:arlolra/herder.git"
+ }
+ , "main" : "server.js"
+ , "engines" : {
+ "node" : "0.4.x"
+ }
+ , "dependencies" : {
+ "express" : "2.4.x"
+ , "redis" : "0.6.x"
+ }
+}
3,012 public/js/ender.js
@@ -0,0 +1,3012 @@
+/*!
+ * =============================================================
+ * Ender: open module JavaScript framework (https://ender.no.de)
+ * Build: ender build underscore reqwest bean bonzo domready qwery jeesh keymaster
+ * =============================================================
+ */
+
+/*!
+ * Ender: open module JavaScript framework (client-lib)
+ * copyright Dustin Diaz & Jacob Thornton 2011 (@ded @fat)
+ * http://ender.no.de
+ * License MIT
+ */
+!function (context) {
+
+ // a global object for node.js module compatiblity
+ // ============================================
+
+ context['global'] = context
+
+ // Implements simple module system
+ // losely based on CommonJS Modules spec v1.1.1
+ // ============================================
+
+ var modules = {}
+ , old = context.$
+
+ function require (identifier) {
+ var module = modules[identifier] || window[identifier]
+ if (!module) throw new Error("Requested module '" + identifier + "' has not been defined.")
+ return module
+ }
+
+ function provide (name, what) {
+ return (modules[name] = what)
+ }
+
+ context['provide'] = provide
+ context['require'] = require
+
+ // Implements Ender's $ global access object
+ // =========================================
+
+ function aug(o, o2) {
+ for (var k in o2) k != 'noConflict' && k != '_VERSION' && (o[k] = o2[k])
+ return o
+ }
+
+ function boosh(s, r, els) {
+ // string || node || nodelist || window
+ if (ender._select && (typeof s == 'string' || s.nodeName || s.length && 'item' in s || s == window)) {
+ els = ender._select(s, r)
+ els.selector = s
+ } else els = isFinite(s.length) ? s : [s]
+ return aug(els, boosh)
+ }
+
+ function ender(s, r) {
+ return boosh(s, r)
+ }
+
+ aug(ender, {
+ _VERSION: '0.3.4'
+ , fn: context.$ && context.$.fn || {} // for easy compat to jQuery plugins
+ , ender: function (o, chain) {
+ aug(chain ? boosh : ender, o)
+ }
+ , _select: function (s, r) {
+ return (r || document).querySelectorAll(s)
+ }
+ })
+
+ aug(boosh, {
+ forEach: function (fn, scope, i) {
+ // opt out of native forEach so we can intentionally call our own scope
+ // defaulting to the current item and be able to return self
+ for (i = 0, l = this.length; i < l; ++i) i in this && fn.call(scope || this[i], this[i], i, this)
+ // return self for chaining
+ return this
+ },
+ $: ender // handy reference to self
+ })
+
+ ender.noConflict = function () {
+ context.$ = old
+ return this
+ }
+
+ if (typeof module !== 'undefined' && module.exports) module.exports = ender
+ // use subscript notation as extern for Closure compilation
+ context['ender'] = context['$'] = context['ender'] || ender
+
+}(this);
+
+!function () {
+
+ var module = { exports: {} }, exports = module.exports;
+
+ // Underscore.js 1.1.7
+ // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
+ // Underscore is freely distributable under the MIT license.
+ // Portions of Underscore are inspired or borrowed from Prototype,
+ // Oliver Steele's Functional, and John Resig's Micro-Templating.
+ // For all details and documentation:
+ // http://documentcloud.github.com/underscore
+
+ (function() {
+
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `global` on the server.
+ var root = this;
+
+ // Save the previous value of the `_` variable.
+ var previousUnderscore = root._;
+
+ // Establish the object that gets returned to break out of a loop iteration.
+ var breaker = {};
+
+ // Save bytes in the minified (but not gzipped) version:
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+ // Create quick reference variables for speed access to core prototypes.
+ var slice = ArrayProto.slice,
+ unshift = ArrayProto.unshift,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
+
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
+ var
+ nativeForEach = ArrayProto.forEach,
+ nativeMap = ArrayProto.map,
+ nativeReduce = ArrayProto.reduce,
+ nativeReduceRight = ArrayProto.reduceRight,
+ nativeFilter = ArrayProto.filter,
+ nativeEvery = ArrayProto.every,
+ nativeSome = ArrayProto.some,
+ nativeIndexOf = ArrayProto.indexOf,
+ nativeLastIndexOf = ArrayProto.lastIndexOf,
+ nativeIsArray = Array.isArray,
+ nativeKeys = Object.keys,
+ nativeBind = FuncProto.bind;
+
+ // Create a safe reference to the Underscore object for use below.
+ var _ = function(obj) { return new wrapper(obj); };
+
+ // Export the Underscore object for **CommonJS**, with backwards-compatibility
+ // for the old `require()` API. If we're not in CommonJS, add `_` to the
+ // global object.
+ if (typeof module !== 'undefined' && module.exports) {
+ module.exports = _;
+ _._ = _;
+ } else {
+ // Exported as a string, for Closure Compiler "advanced" mode.
+ root['_'] = _;
+ }
+
+ // Current version.
+ _.VERSION = '1.1.7';
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles objects with the built-in `forEach`, arrays, and raw objects.
+ // Delegates to **ECMAScript 5**'s native `forEach` if available.
+ var each = _.each = _.forEach = function(obj, iterator, context) {
+ if (obj == null) return;
+ if (nativeForEach && obj.forEach === nativeForEach) {
+ obj.forEach(iterator, context);
+ } else if (obj.length === +obj.length) {
+ for (var i = 0, l = obj.length; i < l; i++) {
+ if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
+ }
+ } else {
+ for (var key in obj) {
+ if (hasOwnProperty.call(obj, key)) {
+ if (iterator.call(context, obj[key], key, obj) === breaker) return;
+ }
+ }
+ }
+ };
+
+ // Return the results of applying the iterator to each element.
+ // Delegates to **ECMAScript 5**'s native `map` if available.
+ _.map = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
+ each(obj, function(value, index, list) {
+ results[results.length] = iterator.call(context, value, index, list);
+ });
+ return results;
+ };
+
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
+ _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
+ var initial = memo !== void 0;
+ if (obj == null) obj = [];
+ if (nativeReduce && obj.reduce === nativeReduce) {
+ if (context) iterator = _.bind(iterator, context);
+ return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
+ }
+ each(obj, function(value, index, list) {
+ if (!initial) {
+ memo = value;
+ initial = true;
+ } else {
+ memo = iterator.call(context, memo, value, index, list);
+ }
+ });
+ if (!initial) throw new TypeError("Reduce of empty array with no initial value");
+ return memo;
+ };
+
+ // The right-associative version of reduce, also known as `foldr`.
+ // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
+ _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
+ if (obj == null) obj = [];
+ if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
+ if (context) iterator = _.bind(iterator, context);
+ return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
+ }
+ var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
+ return _.reduce(reversed, iterator, memo, context);
+ };
+
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, iterator, context) {
+ var result;
+ any(obj, function(value, index, list) {
+ if (iterator.call(context, value, index, list)) {
+ result = value;
+ return true;
+ }
+ });
+ return result;
+ };
+
+ // Return all the elements that pass a truth test.
+ // Delegates to **ECMAScript 5**'s native `filter` if available.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
+ each(obj, function(value, index, list) {
+ if (iterator.call(context, value, index, list)) results[results.length] = value;
+ });
+ return results;
+ };
+
+ // Return all the elements for which a truth test fails.
+ _.reject = function(obj, iterator, context) {
+ var results = [];
+ if (obj == null) return results;
+ each(obj, function(value, index, list) {
+ if (!iterator.call(context, value, index, list)) results[results.length] = value;
+ });
+ return results;
+ };
+
+ // Determine whether all of the elements match a truth test.
+ // Delegates to **ECMAScript 5**'s native `every` if available.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, iterator, context) {
+ var result = true;
+ if (obj == null) return result;
+ if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
+ each(obj, function(value, index, list) {
+ if (!(result = result && iterator.call(context, value, index, list))) return breaker;
+ });
+ return result;
+ };
+
+ // Determine if at least one element in the object matches a truth test.
+ // Delegates to **ECMAScript 5**'s native `some` if available.
+ // Aliased as `any`.
+ var any = _.some = _.any = function(obj, iterator, context) {
+ iterator = iterator || _.identity;
+ var result = false;
+ if (obj == null) return result;
+ if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
+ each(obj, function(value, index, list) {
+ if (result |= iterator.call(context, value, index, list)) return breaker;
+ });
+ return !!result;
+ };
+
+ // Determine if a given value is included in the array or object using `===`.
+ // Aliased as `contains`.
+ _.include = _.contains = function(obj, target) {
+ var found = false;
+ if (obj == null) return found;
+ if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
+ any(obj, function(value) {
+ if (found = value === target) return true;
+ });
+ return found;
+ };
+
+ // Invoke a method (with arguments) on every item in a collection.
+ _.invoke = function(obj, method) {
+ var args = slice.call(arguments, 2);
+ return _.map(obj, function(value) {
+ return (method.call ? method || value : value[method]).apply(value, args);
+ });
+ };
+
+ // Convenience version of a common use case of `map`: fetching a property.
+ _.pluck = function(obj, key) {
+ return _.map(obj, function(value){ return value[key]; });
+ };
+
+ // Return the maximum element or (element-based computation).
+ _.max = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
+ var result = {computed : -Infinity};
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ computed >= result.computed && (result = {value : value, computed : computed});
+ });
+ return result.value;
+ };
+
+ // Return the minimum element (or element-based computation).
+ _.min = function(obj, iterator, context) {
+ if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
+ var result = {computed : Infinity};
+ each(obj, function(value, index, list) {
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
+ computed < result.computed && (result = {value : value, computed : computed});
+ });
+ return result.value;
+ };
+
+ // Sort the object's values by a criterion produced by an iterator.
+ _.sortBy = function(obj, iterator, context) {
+ return _.pluck(_.map(obj, function(value, index, list) {
+ return {
+ value : value,
+ criteria : iterator.call(context, value, index, list)
+ };
+ }).sort(function(left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }), 'value');
+ };
+
+ // Groups the object's values by a criterion produced by an iterator
+ _.groupBy = function(obj, iterator) {
+ var result = {};
+ each(obj, function(value, index) {
+ var key = iterator(value, index);
+ (result[key] || (result[key] = [])).push(value);
+ });
+ return result;
+ };
+
+ // Use a comparator function to figure out at what index an object should
+ // be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iterator) {
+ iterator || (iterator = _.identity);
+ var low = 0, high = array.length;
+ while (low < high) {
+ var mid = (low + high) >> 1;
+ iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
+ }
+ return low;
+ };
+
+ // Safely convert anything iterable into a real, live array.
+ _.toArray = function(iterable) {
+ if (!iterable) return [];
+ if (iterable.toArray) return iterable.toArray();
+ if (_.isArray(iterable)) return slice.call(iterable);
+ if (_.isArguments(iterable)) return slice.call(iterable);
+ return _.values(iterable);
+ };
+
+ // Return the number of elements in an object.
+ _.size = function(obj) {
+ return _.toArray(obj).length;
+ };
+
+ // Array Functions
+ // ---------------
+
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head`. The **guard** check allows it to work
+ // with `_.map`.
+ _.first = _.head = function(array, n, guard) {
+ return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
+ };
+
+ // Returns everything but the first entry of the array. Aliased as `tail`.
+ // Especially useful on the arguments object. Passing an **index** will return
+ // the rest of the values in the array from that index onward. The **guard**
+ // check allows it to work with `_.map`.
+ _.rest = _.tail = function(array, index, guard) {
+ return slice.call(array, (index == null) || guard ? 1 : index);
+ };
+
+ // Get the last element of an array.
+ _.last = function(array) {
+ return array[array.length - 1];
+ };
+
+ // Trim out all falsy values from an array.
+ _.compact = function(array) {
+ return _.filter(array, function(value){ return !!value; });
+ };
+
+ // Return a completely flattened version of an array.
+ _.flatten = function(array) {
+ return _.reduce(array, function(memo, value) {
+ if (_.isArray(value)) return memo.concat(_.flatten(value));
+ memo[memo.length] = value;
+ return memo;
+ }, []);
+ };
+
+ // Return a version of the array that does not contain the specified value(s).
+ _.without = function(array) {
+ return _.difference(array, slice.call(arguments, 1));
+ };
+
+ // Produce a duplicate-free version of the array. If the array has already
+ // been sorted, you have the option of using a faster algorithm.
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted) {
+ return _.reduce(array, function(memo, el, i) {
+ if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
+ return memo;
+ }, []);
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(_.flatten(arguments));
+ };
+
+ // Produce an array that contains every item shared between all the
+ // passed-in arrays. (Aliased as "intersect" for back-compat.)
+ _.intersection = _.intersect = function(array) {
+ var rest = slice.call(arguments, 1);
+ return _.filter(_.uniq(array), function(item) {
+ return _.every(rest, function(other) {
+ return _.indexOf(other, item) >= 0;
+ });
+ });
+ };
+
+ // Take the difference between one array and another.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array, other) {
+ return _.filter(array, function(value){ return !_.include(other, value); });
+ };
+
+ // Zip together multiple lists into a single array -- elements that share
+ // an index go together.
+ _.zip = function() {
+ var args = slice.call(arguments);
+ var length = _.max(_.pluck(args, 'length'));
+ var results = new Array(length);
+ for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
+ return results;
+ };
+
+ // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
+ // we need this function. Return the position of the first occurrence of an
+ // item in an array, or -1 if the item is not included in the array.
+ // Delegates to **ECMAScript 5**'s native `indexOf` if available.
+ // If the array is large and already in sort order, pass `true`
+ // for **isSorted** to use binary search.
+ _.indexOf = function(array, item, isSorted) {
+ if (array == null) return -1;
+ var i, l;
+ if (isSorted) {
+ i = _.sortedIndex(array, item);
+ return array[i] === item ? i : -1;
+ }
+ if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
+ for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
+ return -1;
+ };
+
+
+ // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
+ _.lastIndexOf = function(array, item) {
+ if (array == null) return -1;
+ if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
+ var i = array.length;
+ while (i--) if (array[i] === item) return i;
+ return -1;
+ };
+
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
+ _.range = function(start, stop, step) {
+ if (arguments.length <= 1) {
+ stop = start || 0;
+ start = 0;
+ }
+ step = arguments[2] || 1;
+
+ var len = Math.max(Math.ceil((stop - start) / step), 0);
+ var idx = 0;
+ var range = new Array(len);
+
+ while(idx < len) {
+ range[idx++] = start;
+ start += step;
+ }
+
+ return range;
+ };
+
+ // Function (ahem) Functions
+ // ------------------
+
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Binding with arguments is also known as `curry`.
+ // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
+ // We check for `func.bind` first, to fail fast when `func` is undefined.
+ _.bind = function(func, obj) {
+ if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ var args = slice.call(arguments, 2);
+ return function() {
+ return func.apply(obj, args.concat(slice.call(arguments)));
+ };
+ };
+
+ // Bind all of an object's methods to that object. Useful for ensuring that
+ // all callbacks defined on an object belong to it.
+ _.bindAll = function(obj) {
+ var funcs = slice.call(arguments, 1);
+ if (funcs.length == 0) funcs = _.functions(obj);
+ each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
+ return obj;
+ };
+
+ // Memoize an expensive function by storing its results.
+ _.memoize = function(func, hasher) {
+ var memo = {};
+ hasher || (hasher = _.identity);
+ return function() {
+ var key = hasher.apply(this, arguments);
+ return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
+ };
+ };
+
+ // Delays a function for the given number of milliseconds, and then calls
+ // it with the arguments supplied.
+ _.delay = function(func, wait) {
+ var args = slice.call(arguments, 2);
+ return setTimeout(function(){ return func.apply(func, args); }, wait);
+ };
+
+ // Defers a function, scheduling it to run after the current call stack has
+ // cleared.
+ _.defer = function(func) {
+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+ };
+
+ // Internal function used to implement `_.throttle` and `_.debounce`.
+ var limit = function(func, wait, debounce) {
+ var timeout;
+ return function() {
+ var context = this, args = arguments;
+ var throttler = function() {
+ timeout = null;
+ func.apply(context, args);
+ };
+ if (debounce) clearTimeout(timeout);
+ if (debounce || !timeout) timeout = setTimeout(throttler, wait);
+ };
+ };
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time.
+ _.throttle = function(func, wait) {
+ return limit(func, wait, false);
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds.
+ _.debounce = function(func, wait) {
+ return limit(func, wait, true);
+ };
+
+ // Returns a function that will be executed at most one time, no matter how
+ // often you call it. Useful for lazy initialization.
+ _.once = function(func) {
+ var ran = false, memo;
+ return function() {
+ if (ran) return memo;
+ ran = true;
+ return memo = func.apply(this, arguments);
+ };
+ };
+
+ // Returns the first function passed as an argument to the second,
+ // allowing you to adjust arguments, run code before and after, and
+ // conditionally execute the original function.
+ _.wrap = function(func, wrapper) {
+ return function() {
+ var args = [func].concat(slice.call(arguments));
+ return wrapper.apply(this, args);
+ };
+ };
+
+ // Returns a function that is the composition of a list of functions, each
+ // consuming the return value of the function that follows.
+ _.compose = function() {
+ var funcs = slice.call(arguments);
+ return function() {
+ var args = slice.call(arguments);
+ for (var i = funcs.length - 1; i >= 0; i--) {
+ args = [funcs[i].apply(this, args)];
+ }
+ return args[0];
+ };
+ };
+
+ // Returns a function that will only be executed after being called N times.
+ _.after = function(times, func) {
+ return function() {
+ if (--times < 1) { return func.apply(this, arguments); }
+ };
+ };
+
+
+ // Object Functions
+ // ----------------
+
+ // Retrieve the names of an object's properties.
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
+ _.keys = nativeKeys || function(obj) {
+ if (obj !== Object(obj)) throw new TypeError('Invalid object');
+ var keys = [];
+ for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
+ return keys;
+ };
+
+ // Retrieve the values of an object's properties.
+ _.values = function(obj) {
+ return _.map(obj, _.identity);
+ };
+
+ // Return a sorted list of the function names available on the object.
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
+ };
+
+ // Extend a given object with all the properties in passed-in object(s).
+ _.extend = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ for (var prop in source) {
+ if (source[prop] !== void 0) obj[prop] = source[prop];
+ }
+ });
+ return obj;
+ };
+
+ // Fill in a given object with default properties.
+ _.defaults = function(obj) {
+ each(slice.call(arguments, 1), function(source) {
+ for (var prop in source) {
+ if (obj[prop] == null) obj[prop] = source[prop];
+ }
+ });
+ return obj;
+ };
+
+ // Create a (shallow-cloned) duplicate of an object.
+ _.clone = function(obj) {
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+ };
+
+ // Invokes interceptor with the obj, and then returns obj.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
+ _.tap = function(obj, interceptor) {
+ interceptor(obj);
+ return obj;
+ };
+
+ // Perform a deep comparison to check if two objects are equal.
+ _.isEqual = function(a, b) {
+ // Check object identity.
+ if (a === b) return true;
+ // Different types?
+ var atype = typeof(a), btype = typeof(b);
+ if (atype != btype) return false;
+ // Basic equality test (watch out for coercions).
+ if (a == b) return true;
+ // One is falsy and the other truthy.
+ if ((!a && b) || (a && !b)) return false;
+ // Unwrap any wrapped objects.
+ if (a._chain) a = a._wrapped;
+ if (b._chain) b = b._wrapped;
+ // One of them implements an isEqual()?
+ if (a.isEqual) return a.isEqual(b);
+ if (b.isEqual) return b.isEqual(a);
+ // Check dates' integer values.
+ if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
+ // Both are NaN?
+ if (_.isNaN(a) && _.isNaN(b)) return false;
+ // Compare regular expressions.
+ if (_.isRegExp(a) && _.isRegExp(b))
+ return a.source === b.source &&
+ a.global === b.global &&
+ a.ignoreCase === b.ignoreCase &&
+ a.multiline === b.multiline;
+ // If a is not an object by this point, we can't handle it.
+ if (atype !== 'object') return false;
+ // Check for different array lengths before comparing contents.
+ if (a.length && (a.length !== b.length)) return false;
+ // Nothing else worked, deep compare the contents.
+ var aKeys = _.keys(a), bKeys = _.keys(b);
+ // Different object sizes?
+ if (aKeys.length != bKeys.length) return false;
+ // Recursive comparison of contents.
+ for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
+ return true;
+ };
+
+ // Is a given array or object empty?
+ _.isEmpty = function(obj) {
+ if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
+ for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
+ return true;
+ };
+
+ // Is a given value a DOM element?
+ _.isElement = function(obj) {
+ return !!(obj && obj.nodeType == 1);
+ };
+
+ // Is a given value an array?
+ // Delegates to ECMA5's native Array.isArray
+ _.isArray = nativeIsArray || function(obj) {
+ return toString.call(obj) === '[object Array]';
+ };
+
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ return obj === Object(obj);
+ };
+
+ // Is a given variable an arguments object?
+ _.isArguments = function(obj) {
+ return !!(obj && hasOwnProperty.call(obj, 'callee'));
+ };
+
+ // Is a given value a function?
+ _.isFunction = function(obj) {
+ return !!(obj && obj.constructor && obj.call && obj.apply);
+ };
+
+ // Is a given value a string?
+ _.isString = function(obj) {
+ return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
+ };
+
+ // Is a given value a number?
+ _.isNumber = function(obj) {
+ return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
+ };
+
+ // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
+ // that does not equal itself.
+ _.isNaN = function(obj) {
+ return obj !== obj;
+ };
+
+ // Is a given value a boolean?
+ _.isBoolean = function(obj) {
+ return obj === true || obj === false;
+ };
+
+ // Is a given value a date?
+ _.isDate = function(obj) {
+ return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
+ };
+
+ // Is the given value a regular expression?
+ _.isRegExp = function(obj) {
+ return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
+ };
+
+ // Is a given value equal to null?
+ _.isNull = function(obj) {
+ return obj === null;
+ };
+
+ // Is a given variable undefined?
+ _.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ // Utility Functions
+ // -----------------
+
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+ // previous owner. Returns a reference to the Underscore object.
+ _.noConflict = function() {
+ root._ = previousUnderscore;
+ return this;
+ };
+
+ // Keep the identity function around for default iterators.
+ _.identity = function(value) {
+ return value;
+ };
+
+ // Run a function **n** times.
+ _.times = function (n, iterator, context) {
+ for (var i = 0; i < n; i++) iterator.call(context, i);
+ };
+
+ // Add your own custom functions to the Underscore object, ensuring that
+ // they're correctly added to the OOP wrapper as well.
+ _.mixin = function(obj) {
+ each(_.functions(obj), function(name){
+ addToWrapper(name, _[name] = obj[name]);
+ });
+ };
+
+ // Generate a unique integer id (unique within the entire client session).
+ // Useful for temporary DOM ids.
+ var idCounter = 0;
+ _.uniqueId = function(prefix) {
+ var id = idCounter++;
+ return prefix ? prefix + id : id;
+ };
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g
+ };
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ _.template = function(str, data) {
+ var c = _.templateSettings;
+ var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
+ 'with(obj||{}){__p.push(\'' +
+ str.replace(/\\/g, '\\\\')
+ .replace(/'/g, "\\'")
+ .replace(c.interpolate, function(match, code) {
+ return "'," + code.replace(/\\'/g, "'") + ",'";
+ })
+ .replace(c.evaluate || null, function(match, code) {
+ return "');" + code.replace(/\\'/g, "'")
+ .replace(/[\r\n\t]/g, ' ') + "__p.push('";
+ })
+ .replace(/\r/g, '\\r')
+ .replace(/\n/g, '\\n')
+ .replace(/\t/g, '\\t')
+ + "');}return __p.join('');";
+ var func = new Function('obj', tmpl);
+ return data ? func(data) : func;
+ };
+
+ // The OOP Wrapper
+ // ---------------
+
+ // If Underscore is called as a function, it returns a wrapped object that
+ // can be used OO-style. This wrapper holds altered versions of all the
+ // underscore functions. Wrapped objects may be chained.
+ var wrapper = function(obj) { this._wrapped = obj; };
+
+ // Expose `wrapper.prototype` as `_.prototype`
+ _.prototype = wrapper.prototype;
+
+ // Helper function to continue chaining intermediate results.
+ var result = function(obj, chain) {
+ return chain ? _(obj).chain() : obj;
+ };
+
+ // A method to easily add functions to the OOP wrapper.
+ var addToWrapper = function(name, func) {
+ wrapper.prototype[name] = function() {
+ var args = slice.call(arguments);
+ unshift.call(args, this._wrapped);
+ return result(func.apply(_, args), this._chain);
+ };
+ };
+
+ // Add all of the Underscore functions to the wrapper object.
+ _.mixin(_);
+
+ // Add all mutator Array functions to the wrapper.
+ each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+ var method = ArrayProto[name];
+ wrapper.prototype[name] = function() {
+ method.apply(this._wrapped, arguments);
+ return result(this._wrapped, this._chain);
+ };
+ });
+
+ // Add all accessor Array functions to the wrapper.
+ each(['concat', 'join', 'slice'], function(name) {
+ var method = ArrayProto[name];
+ wrapper.prototype[name] = function() {
+ return result(method.apply(this._wrapped, arguments), this._chain);
+ };
+ });
+
+ // Start chaining a wrapped Underscore object.
+ wrapper.prototype.chain = function() {
+ this._chain = true;
+ return this;
+ };
+
+ // Extracts the result from a wrapped and chained object.
+ wrapper.prototype.value = function() {
+ return this._wrapped;
+ };
+
+ })();
+
+
+ provide("underscore", module.exports);
+
+ $.ender(module.exports);
+
+}();
+
+!function () {
+
+ var module = { exports: {} }, exports = module.exports;
+
+ /*!
+ * Reqwest! A general purpose XHR connection manager
+ * (c) Dustin Diaz 2011
+ * https://github.com/ded/reqwest
+ * license MIT
+ */
+ !function (name, definition) {
+ if (typeof define == 'function') define(definition)
+ else if (typeof module != 'undefined') module.exports = definition()
+ else this[name] = definition()
+ }('reqwest', function () {
+
+ var context = this
+ , win = window
+ , doc = document
+ , old = context.reqwest
+ , twoHundo = /^20\d$/
+ , byTag = 'getElementsByTagName'
+ , readyState = 'readyState'
+ , contentType = 'Content-Type'
+ , head = doc[byTag]('head')[0]
+ , uniqid = 0
+ , lastValue // data stored by the most recent JSONP callback
+ , xhr = ('XMLHttpRequest' in win) ?
+ function () {
+ return new XMLHttpRequest()
+ } :
+ function () {
+ return new ActiveXObject('Microsoft.XMLHTTP')
+ }
+
+ function handleReadyState(o, success, error) {
+ return function () {
+ if (o && o[readyState] == 4) {
+ if (twoHundo.test(o.status)) {
+ success(o)
+ } else {
+ error(o)
+ }
+ }
+ }
+ }
+
+ function setHeaders(http, o) {
+ var headers = o.headers || {}
+ headers.Accept = headers.Accept || 'text/javascript, text/html, application/xml, text/xml, */*'
+
+ // breaks cross-origin requests with legacy browsers
+ if (!o.crossOrigin) {
+ headers['X-Requested-With'] = headers['X-Requested-With'] || 'XMLHttpRequest'
+ }
+ headers[contentType] = headers[contentType] || 'application/x-www-form-urlencoded'
+ for (var h in headers) {
+ headers.hasOwnProperty(h) && http.setRequestHeader(h, headers[h], false)
+ }
+ }
+
+ function getCallbackName(o) {
+ var callbackVar = o.jsonpCallback || "callback"
+ if (o.url.slice(-(callbackVar.length + 2)) == (callbackVar + "=?")) {
+ // Generate a guaranteed unique callback name
+ var callbackName = "reqwest_" + uniqid++
+
+ // Replace the ? in the URL with the generated name
+ o.url = o.url.substr(0, o.url.length - 1) + callbackName
+ return callbackName
+ } else {
+ // Find the supplied callback name
+ var regex = new RegExp(callbackVar + "=([\\w]+)")
+ return o.url.match(regex)[1]
+ }
+ }
+
+ // Store the data returned by the most recent callback
+ function generalCallback(data) {
+ lastValue = data
+ }
+
+ function getRequest(o, fn, err) {
+ if (o.type == 'jsonp') {
+ var script = doc.createElement('script')
+ , loaded = 0
+
+ // Add the global callback
+ win[getCallbackName(o)] = generalCallback
+
+ // Setup our script element
+ script.type = 'text/javascript'
+ script.src = o.url
+ script.async = true
+
+ script.onload = script.onreadystatechange = function () {
+ if ((script[readyState] && script[readyState] !== "complete" && script[readyState] !== "loaded") || loaded) {
+ return false
+ }
+ script.onload = script.onreadystatechange = null
+ // Call the user callback with the last value stored
+ // and clean up values and scripts.
+ o.success && o.success(lastValue)
+ lastValue = undefined
+ head.removeChild(script)
+ loaded = 1
+ }
+
+ // Add the script to the DOM head
+ head.appendChild(script)
+ } else {
+ var http = xhr()
+ http.open(o.method || 'GET', typeof o == 'string' ? o : o.url, true)
+ setHeaders(http, o)
+ http.onreadystatechange = handleReadyState(http, fn, err)
+ o.before && o.before(http)
+ http.send(o.data || null)
+ return http
+ }
+ }
+
+ function Reqwest(o, fn) {
+ this.o = o
+ this.fn = fn
+ init.apply(this, arguments)
+ }
+
+ function setType(url) {
+ if (/\.json$/.test(url)) {
+ return 'json'
+ }
+ if (/\.jsonp$/.test(url)) {
+ return 'jsonp'
+ }
+ if (/\.js$/.test(url)) {
+ return 'js'
+ }
+ if (/\.html?$/.test(url)) {
+ return 'html'
+ }
+ if (/\.xml$/.test(url)) {
+ return 'xml'
+ }
+ return 'js'
+ }
+
+ function init(o, fn) {
+ this.url = typeof o == 'string' ? o : o.url
+ this.timeout = null
+ var type = o.type || setType(this.url)
+ , self = this
+ fn = fn || function () {}
+
+ if (o.timeout) {
+ this.timeout = setTimeout(function () {
+ self.abort()
+ }, o.timeout)
+ }
+
+ function complete(resp) {
+ o.timeout && clearTimeout(self.timeout)
+ self.timeout = null
+ o.complete && o.complete(resp)
+ }
+
+ function success(resp) {
+ var r = resp.responseText
+ if (r) {
+ switch (type) {
+ case 'json':
+ resp = win.JSON ? win.JSON.parse(r) : eval('(' + r + ')')
+ break;
+ case 'js':
+ resp = eval(r)
+ break;
+ case 'html':
+ resp = r
+ break;
+ }
+ }
+
+ fn(resp)
+ o.success && o.success(resp)
+ complete(resp)
+ }
+
+ function error(resp) {
+ o.error && o.error(resp)
+ complete(resp)
+ }
+
+ this.request = getRequest(o, success, error)
+ }
+
+ Reqwest.prototype = {
+ abort: function () {
+ this.request.abort()
+ }
+
+ , retry: function () {
+ init.call(this, this.o, this.fn)
+ }
+ }
+
+ function reqwest(o, fn) {
+ return new Reqwest(o, fn)
+ }
+
+ function enc(v) {
+ return encodeURIComponent(v)
+ }
+
+ function serial(el) {
+ var n = el.name
+ // don't serialize elements that are disabled or without a name
+ if (el.disabled || !n) {
+ return ''
+ }
+ n = enc(n)
+ switch (el.tagName.toLowerCase()) {
+ case 'input':
+ switch (el.type) {
+ // silly wabbit
+ case 'reset':
+ case 'button':
+ case 'image':
+ case 'file':
+ return ''
+ case 'checkbox':
+ case 'radio':
+ return el.checked ? n + '=' + (el.value ? enc(el.value) : true) + '&' : ''
+ default: // text hidden password submit
+ return n + '=' + (el.value ? enc(el.value) : '') + '&'
+ }
+ break;
+ case 'textarea':
+ return n + '=' + enc(el.value) + '&'
+ case 'select':
+ // @todo refactor beyond basic single selected value case
+ return n + '=' + enc(el.options[el.selectedIndex].value) + '&'
+ }
+ return ''
+ }
+
+ reqwest.serialize = function (form) {
+ var fields = [form[byTag]('input')
+ , form[byTag]('select')
+ , form[byTag]('textarea')]
+ , serialized = [], i, j
+
+ for (i = 0, l = fields.length; i < l; ++i) {
+ for (j = 0, l2 = fields[i].length; j < l2; ++j) serialized.push(serial(fields[i][j]))
+ }
+ return serialized.join('').replace(/&$/, '')
+ }
+
+ reqwest.serializeArray = function (f) {
+ for (var pairs = this.serialize(f).split('&'), i = 0, l = pairs.length, r = [], o; i < l; i++) {
+ pairs[i] && (o = pairs[i].split('=')) && r.push({name: o[0], value: o[1]})
+ }
+ return r
+ }
+
+ reqwest.noConflict = function () {
+ context.reqwest = old
+ return this
+ }
+
+ return reqwest
+ })
+
+ provide("reqwest", module.exports);
+
+ var r = require('reqwest')
+ ender.ender({
+ ajax: r
+ })
+ ender.ender({
+ serialize: function () {
+ return r.serialize(this[0])
+ }
+ , serializeArray: function() {
+ return r.serializeArray(this[0])
+ }
+ }, true)
+
+}();
+
+!function () {
+
+ var module = { exports: {} }, exports = module.exports;
+
+ // keymaster.js
+ // (c) 2011 Thomas Fuchs
+ // keymaster.js may be freely distributed under the MIT license.
+
+ ;(function(global){
+ var k,
+ _handlers = {},
+ _mods = { 16: false, 18: false, 17: false, 91: false },
+ _scope = 'all',
+ // modifier keys
+ _MODIFIERS = {
+ '': 16, shift: 16,
+ '': 18, alt: 18, option: 18,
+ '': 17, ctrl: 17, control: 17,
+ '': 91, command: 91
+ },
+ // special keys
+ _MAP = {
+ backspace: 8, tab: 9, clear: 12,
+ enter: 13, 'return': 13,
+ esc: 27, escape: 27, space: 32,
+ left: 37, up: 38,
+ right: 39, down: 40,
+ del: 46, 'delete': 46,
+ home: 36, end: 35,
+ pageup: 33, pagedown: 34,
+ ',': 188, '.': 190, '/': 191,
+ '`': 192, '-': 189, '=': 187,
+ ';': 186, '\'': 222,
+ '[': 219, ']': 221, '\\': 220
+ };
+
+ for(k=1;k<20;k++) _MODIFIERS['f'+k] = 111+k;
+
+ // IE doesn't support Array#indexOf, so have a simple replacement
+ function index(array, item){
+ var i = array.length;
+ while(i--) if(array[i]===item) return i;
+ return -1;
+ }
+
+ // handle keydown event
+ function dispatch(event){
+ var key, tagName, handler, k, i, modifiersMatch;
+ tagName = (event.target || event.srcElement).tagName;
+ key = event.keyCode;
+
+ // if a modifier key, set the key.<modifierkeyname> property to true and return
+ if(key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko
+ if(key in _mods) {
+ _mods[key] = true;
+ // 'assignKey' from inside this closure is exported to window.key
+ for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = true;
+ return;
+ }
+
+ // ignore keypressed in any elements that support keyboard data input
+ if (tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA') return;
+
+ // abort if no potentially matching shortcuts found
+ if (!(key in _handlers)) return;
+
+ // for each potential shortcut
+ for (i = 0; i < _handlers[key].length; i++) {
+ handler = _handlers[key][i];
+
+ // see if it's in the current scope
+ if(handler.scope == _scope || handler.scope == 'all'){
+ // check if modifiers match if any
+ modifiersMatch = handler.mods.length > 0;
+ for(k in _mods)
+ if((!_mods[k] && index(handler.mods, +k) > -1) ||
+ (_mods[k] && index(handler.mods, +k) == -1)) modifiersMatch = false;
+ // call the handler and stop the event if neccessary
+ if((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch){
+ if(handler.method(event, handler)===false){
+ if(event.preventDefault) event.preventDefault();
+ else event.returnValue = false;
+ if(event.stopPropagation) event.stopPropagation();
+ if(event.cancelBubble) event.cancelBubble = true;
+ }
+ }
+ }
+ }
+ };
+
+ // unset modifier keys on keyup
+ function clearModifier(event){
+ var key = event.keyCode, k;
+ if(key == 93 || key == 224) key = 91;
+ if(key in _mods) {
+ _mods[key] = false;
+ for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = false;
+ }
+ };
+
+ // parse and assign shortcut
+ function assignKey(key, scope, method){
+ var keys, mods, i, mi;
+ if (method === undefined) {
+ method = scope;
+ scope = 'all';
+ }
+ key = key.replace(/\s/g,'');
+ keys = key.split(',');
+
+ if((keys[keys.length-1])=='')
+ keys[keys.length-2] += ',';
+ // for each shortcut
+ for (i = 0; i < keys.length; i++) {
+ // set modifier keys if any
+ mods = [];
+ key = keys[i].split('+');
+ if(key.length > 1){
+ mods = key.slice(0,key.length-1);
+ for (mi = 0; mi < mods.length; mi++)
+ mods[mi] = _MODIFIERS[mods[mi]];
+ key = [key[key.length-1]];
+ }
+ // convert to keycode and...
+ key = key[0]
+ key = _MAP[key] || key.toUpperCase().charCodeAt(0);
+ // ...store handler
+ if (!(key in _handlers)) _handlers[key] = [];
+ _handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods });
+ }
+ };
+
+ // initialize key.<modifier> to false
+ for(k in _MODIFIERS) assignKey[k] = false;
+
+ // set current scope (default 'all')
+ function setScope(scope){ _scope = scope || 'all' };
+
+ // cross-browser events
+ function addEvent(object, event, method) {
+ if (object.addEventListener)
+ object.addEventListener(event, method, false);
+ else if(object.attachEvent)
+ object.attachEvent('on'+event, function(){ method(window.event) });
+ };
+
+ // set the handlers globally on document
+ addEvent(document, 'keydown', dispatch);
+ addEvent(document, 'keyup', clearModifier);
+
+ // set window.key and window.key.setScope
+ global.key = assignKey;
+ global.key.setScope = setScope;
+
+ if(typeof module !== 'undefined') module.exports = key;
+
+ })(this);
+
+
+ provide("keymaster", module.exports);
+
+ !function ($) {
+ $.ender({
+ key: require('keymaster')
+ })
+ }(ender)
+
+}();
+
+!function () {
+
+ var module = { exports: {} }, exports = module.exports;
+
+ /*!
+ * bean.js - copyright Jacob Thornton 2011
+ * https://github.com/fat/bean
+ * MIT License
+ * special thanks to:
+ * dean edwards: http://dean.edwards.name/
+ * dperini: https://github.com/dperini/nwevents
+ * the entire mootools team: github.com/mootools/mootools-core
+ */
+ !function (context) {
+ var __uid = 1,
+ registry = {},
+ collected = {},
+ overOut = /over|out/,
+ namespace = /[^\.]*(?=\..*)\.|.*/,
+ stripName = /\..*/,
+ addEvent = 'addEventListener',
+ attachEvent = 'attachEvent',
+ removeEvent = 'removeEventListener',
+ detachEvent = 'detachEvent',
+ doc = context.document || {},
+ root = doc.documentElement || {},
+ W3C_MODEL = root[addEvent],
+ eventSupport = W3C_MODEL ? addEvent : attachEvent,
+
+ isDescendant = function (parent, child) {
+ var node = child.parentNode;
+ while (node !== null) {
+ if (node == parent) {
+ return true;
+ }
+ node = node.parentNode;
+ }
+ },
+
+ retrieveUid = function (obj, uid) {
+ return (obj.__uid = uid && (uid + '::' + __uid++) || obj.__uid || __uid++);
+ },
+
+ retrieveEvents = function (element) {
+ var uid = retrieveUid(element);
+ return (registry[uid] = registry[uid] || {});
+ },
+
+ listener = W3C_MODEL ? function (element, type, fn, add) {
+ element[add ? addEvent : removeEvent](type, fn, false);
+ } : function (element, type, fn, add, custom) {
+ custom && add && (element['_on' + custom] = element['_on' + custom] || 0);
+ element[add ? attachEvent : detachEvent]('on' + type, fn);
+ },
+
+ nativeHandler = function (element, fn, args) {
+ return function (event) {
+ event = fixEvent(event || ((this.ownerDocument || this.document || this).parentWindow || context).event);
+ return fn.apply(element, [event].concat(args));
+ };
+ },
+
+ customHandler = function (element, fn, type, condition, args) {
+ return function (e) {
+ if (condition ? condition.apply(this, arguments) : W3C_MODEL ? true : e && e.propertyName == '_on' + type || !e) {
+ fn.apply(element, Array.prototype.slice.call(arguments, e ? 0 : 1).concat(args));
+ }
+ };
+ },
+
+ addListener = function (element, orgType, fn, args) {
+ var type = orgType.replace(stripName, ''),
+ events = retrieveEvents(element),
+ handlers = events[type] || (events[type] = {}),
+ originalFn = fn,
+ uid = retrieveUid(fn, orgType.replace(namespace, ''));
+ if (handlers[uid]) {
+ return element;
+ }
+ var custom = customEvents[type];
+ if (custom) {
+ fn = custom.condition ? customHandler(element, fn, type, custom.condition) : fn;
+ type = custom.base || type;
+ }
+ var isNative = nativeEvents[type];
+ fn = isNative ? nativeHandler(element, fn, args) : customHandler(element, fn, type, false, args);
+ isNative = W3C_MODEL || isNative;
+ if (type == 'unload') {
+ var org = fn;
+ fn = function () {
+ removeListener(element, type, fn) && org();
+ };
+ }
+ element[eventSupport] && listener(element, isNative ? type : 'propertychange', fn, true, !isNative && type);
+ handlers[uid] = fn;
+ fn.__uid = uid;
+ fn.__originalFn = originalFn;
+ return type == 'unload' ? element : (collected[retrieveUid(element)] = element);
+ },
+
+ removeListener = function (element, orgType, handler) {
+ var uid, names, uids, i, events = retrieveEvents(element), type = orgType.replace(stripName, '');
+ if (!events || !events[type]) {
+ return element;
+ }
+ names = orgType.replace(namespace, '');
+ uids = names ? names.split('.') : [handler.__uid];
+
+ function destroyHandler(uid) {
+ handler = events[type][uid];
+ if (!handler) {
+ return;
+ }
+ delete events[type][uid];
+ if (element[eventSupport]) {
+ type = customEvents[type] ? customEvents[type].base : type;
+ var isNative = W3C_MODEL || nativeEvents[type];
+ listener(element, isNative ? type : 'propertychange', handler, false, !isNative && type);
+ }
+ }
+
+ destroyHandler(names); //get combos
+ for (i = uids.length; i--; destroyHandler(uids[i])) {} //get singles
+
+ return element;
+ },
+
+ del = function (selector, fn, $) {
+ return function (e) {
+ var array = typeof selector == 'string' ? $(selector, this) : selector;
+ for (var target = e.target; target && target != this; target = target.parentNode) {
+ for (var i = array.length; i--;) {
+ if (array[i] == target) {
+ return fn.apply(target, arguments);
+ }
+ }
+ }
+ };
+ },
+
+ add = function (element, events, fn, delfn, $) {
+ if (typeof events == 'object' && !fn) {
+ for (var type in events) {
+ events.hasOwnProperty(type) && add(element, type, events[type]);
+ }
+ } else {
+ var isDel = typeof fn == 'string', types = (isDel ? fn : events).split(' ');
+ fn = isDel ? del(events, delfn, $) : fn;
+ for (var i = types.length; i--;) {
+ addListener(element, types[i], fn, Array.prototype.slice.call(arguments, isDel ? 4 : 3));
+ }
+ }
+ return element;
+ },
+
+ remove = function (element, orgEvents, fn) {
+ var k, m, type, events, i,
+ isString = typeof(orgEvents) == 'string',
+ names = isString && orgEvents.replace(namespace, ''),
+ names = names && names.split('.'),
+ rm = removeListener,
+ attached = retrieveEvents(element);
+ if (isString && /\s/.test(orgEvents)) {
+ orgEvents = orgEvents.split(' ');
+ i = orgEvents.length - 1;
+ while (remove(element, orgEvents[i]) && i--) {}
+ return element;
+ }
+ events = isString ? orgEvents.replace(stripName, '') : orgEvents;
+ if (!attached || names || (isString && !attached[events])) {
+ for (k in attached) {
+ if (attached.hasOwnProperty(k)) {
+ for (i in attached[k]) {
+ for (m = names.length; m--;) {
+ attached[k].hasOwnProperty(i) && new RegExp('^' + names[m] + '::\\d*(\\..*)?$').test(i) && rm(element, [k, i].join('.'));
+ }
+ }
+ }
+ }
+ return element;
+ }
+ if (typeof fn == 'function') {
+ rm(element, events, fn);
+ } else if (names) {
+ rm(element, orgEvents);
+ } else {
+ rm = events ? rm : remove;
+ type = isString && events;
+ events = events ? (fn || attached[events] || events) : attached;
+ for (k in events) {
+ if (events.hasOwnProperty(k)) {
+ rm(element, type || k, events[k]);
+ delete events[k]; // remove unused leaf keys
+ }
+ }
+ }
+ return element;
+ },
+
+ fire = function (element, type, args) {
+ var evt, k, i, m, types = type.split(' ');
+ for (i = types.length; i--;) {
+ type = types[i].replace(stripName, '');
+ var isNative = nativeEvents[type],
+ isNamespace = types[i].replace(namespace, ''),
+ handlers = retrieveEvents(element)[type];
+ if (isNamespace) {
+ isNamespace = isNamespace.split('.');
+ for (k = isNamespace.length; k--;) {
+ for (m in handlers) {
+ handlers.hasOwnProperty(m) && new RegExp('^' + isNamespace[k] + '::\\d*(\\..*)?$').test(m) && handlers[m].apply(element, [false].concat(args));
+ }
+ }
+ } else if (!args && element[eventSupport]) {
+ fireListener(isNative, type, element);
+ } else {
+ for (k in handlers) {
+ handlers.hasOwnProperty(k) && handlers[k].apply(element, [false].concat(args));
+ }
+ }
+ }
+ return element;
+ },
+
+ fireListener = W3C_MODEL ? function (isNative, type, element) {
+ evt = document.createEvent(isNative ? "HTMLEvents" : "UIEvents");
+ evt[isNative ? 'initEvent' : 'initUIEvent'](type, true, true, context, 1);
+ element.dispatchEvent(evt);
+ } : function (isNative, type, element) {
+ isNative ? element.fireEvent('on' + type, document.createEventObject()) : element['_on' + type]++;
+ },
+
+ clone = function (element, from, type) {
+ var events = retrieveEvents(from), obj, k;
+ var uid = retrieveUid(element);
+ obj = type ? events[type] : events;
+ for (k in obj) {
+ obj.hasOwnProperty(k) && (type ? add : clone)(element, type || from, type ? obj[k].__originalFn : k);
+ }
+ return element;
+ },
+
+ fixEvent = function (e) {
+ var result = {};
+ if (!e) {
+ return result;
+ }
+ var type = e.type, target = e.target || e.srcElement;
+ result.preventDefault = fixEvent.preventDefault(e);
+ result.stopPropagation = fixEvent.stopPropagation(e);
+ result.target = target && target.nodeType == 3 ? target.parentNode : target;
+ if (~type.indexOf('key')) {
+ result.keyCode = e.which || e.keyCode;
+ } else if ((/click|mouse|menu/i).test(type)) {
+ result.rightClick = e.which == 3 || e.button == 2;
+ result.pos = { x: 0, y: 0 };
+ if (e.pageX || e.pageY) {
+ result.clientX = e.pageX;
+ result.clientY = e.pageY;
+ } else if (e.clientX || e.clientY) {
+ result.clientX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
+ result.clientY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
+ }
+ overOut.test(type) && (result.relatedTarget = e.relatedTarget || e[(type == 'mouseover' ? 'from' : 'to') + 'Element']);
+ }
+ for (var k in e) {
+ if (!(k in result)) {
+ result[k] = e[k];
+ }
+ }
+ return result;
+ };
+
+ fixEvent.preventDefault = function (e) {
+ return function () {
+ if (e.preventDefault) {
+ e.preventDefault();
+ }
+ else {
+ e.returnValue = false;
+ }
+ };
+ };
+
+ fixEvent.stopPropagation = function (e) {
+ return function () {
+ if (e.stopPropagation) {
+ e.stopPropagation();
+ } else {
+ e.cancelBubble = true;
+ }
+ };
+ };
+
+ var nativeEvents = { click: 1, dblclick: 1, mouseup: 1, mousedown: 1, contextmenu: 1, //mouse buttons
+ mousewheel: 1, DOMMouseScroll: 1, //mouse wheel
+ mouseover: 1, mouseout: 1, mousemove: 1, selectstart: 1, selectend: 1, //mouse movement
+ keydown: 1, keypress: 1, keyup: 1, //keyboard
+ orientationchange: 1, // mobile
+ touchstart: 1, touchmove: 1, touchend: 1, touchcancel: 1, // touch
+ gesturestart: 1, gesturechange: 1, gestureend: 1, // gesture
+ focus: 1, blur: 1, change: 1, reset: 1, select: 1, submit: 1, //form elements
+ load: 1, unload: 1, beforeunload: 1, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window
+ error: 1, abort: 1, scroll: 1 }; //misc
+
+ function check(event) {
+ var related = event.relatedTarget;
+ if (!related) {
+ return related === null;
+ }
+ return (related != this && related.prefix != 'xul' && !/document/.test(this.toString()) && !isDescendant(this, related));
+ }
+
+ var customEvents = {
+ mouseenter: { base: 'mouseover', condition: check },
+ mouseleave: { base: 'mouseout', condition: check },
+ mousewheel: { base: /Firefox/.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel' }
+ };
+
+ var bean = { add: add, remove: remove, clone: clone, fire: fire };
+
+ var clean = function (el) {
+ var uid = remove(el).__uid;
+ if (uid) {
+ delete collected[uid];
+ delete registry[uid];
+ }
+ };
+
+ if (context[attachEvent]) {
+ add(context, 'unload', function () {
+ for (var k in collected) {
+ collected.hasOwnProperty(k) && clean(collected[k]);
+ }
+ context.CollectGarbage && CollectGarbage();
+ });
+ }
+
+ var oldBean = context.bean;
+ bean.noConflict = function () {
+ context.bean = oldBean;
+ return this;
+ };
+
+ (typeof module !== 'undefined' && module.exports) ?
+ (module.exports = bean) :
+ (context['bean'] = bean);
+
+ }(this);
+
+ provide("bean", module.exports);
+
+ !function ($) {
+ var b = require('bean'),
+ integrate = function (method, type, method2) {
+ var _args = type ? [type] : [];
+ return function () {
+ for (var args, i = 0, l = this.length; i < l; i++) {
+ args = [this[i]].concat(_args, Array.prototype.slice.call(arguments, 0));
+ args.length == 4 && args.push($);
+ !arguments.length && method == 'add' && type && (method = 'fire');
+ b[method].apply(this, args);
+ }
+ return this;
+ };
+ };
+
+ var add = integrate('add'),
+ remove = integrate('remove'),
+ fire = integrate('fire');
+
+ var methods = {
+
+ on: add,
+ addListener: add,
+ bind: add,
+ listen: add,
+ delegate: add,
+
+ unbind: remove,
+ unlisten: remove,
+ removeListener: remove,
+ undelegate: remove,
+
+ emit: fire,
+ trigger: fire,
+
+ cloneEvents: integrate('clone'),
+
+ hover: function (enter, leave, i) { // i for internal
+ for (i = this.length; i--;) {
+ b.add.call(this, this[i], 'mouseenter', enter);
+ b.add.call(this, this[i], 'mouseleave', leave);
+ }
+ return this;
+ }
+ };
+
+ var i, shortcuts = [
+ 'blur', 'change', 'click', 'dblclick', 'error', 'focus', 'focusin',
+ 'focusout', 'keydown', 'keypress', 'keyup', 'load', 'mousedown',
+ 'mouseenter', 'mouseleave', 'mouseout', 'mouseover', 'mouseup', 'mousemove',
+ 'resize', 'scroll', 'select', 'submit', 'unload'
+ ];
+
+ for (i = shortcuts.length; i--;) {
+ methods[shortcuts[i]] = integrate('add', shortcuts[i]);
+ }
+
+ $.ender(methods, true);
+ }(ender);
+
+}();
+
+!function () {
+
+ var module = { exports: {} }, exports = module.exports;
+
+ /*!
+ * Bonzo: DOM Utility (c) Dustin Diaz 2011
+ * https://github.com/ded/bonzo
+ * License MIT
+ */
+ !function (name, definition){
+ if (typeof define == 'function') define(definition)
+ else if (typeof module != 'undefined') module.exports = definition()
+ else this[name] = definition()
+ }('bonzo', function() {
+ var context = this
+ , win = window
+ , doc = win.document
+ , html = doc.documentElement
+ , parentNode = 'parentNode'
+ , query = null
+ , specialAttributes = /^checked|value|selected$/
+ , specialTags = /select|fieldset|table|tbody|tfoot|td|tr|colgroup/i
+ , table = 'table'
+ , tagMap = { thead: table, tbody: table, tfoot: table, tr: 'tbody', th: 'tr', td: 'tr', fieldset: 'form', option: 'select' }
+ , stateAttributes = /^checked|selected$/
+ , ie = /msie/i.test(navigator.userAgent)
+ , uidList = []
+ , uuids = 0
+ , digit = /^-?[\d\.]+$/
+ , px = 'px'
+ // commonly used methods
+ , setAttribute = 'setAttribute'
+ , getAttribute = 'getAttribute'
+ , trimReplace = /(^\s*|\s*$)/g
+ , unitless = { lineHeight: 1, zoom: 1, zIndex: 1, opacity: 1 }
+ , transform = function () {
+ var props = ['webkitTransform', 'MozTransform', 'OTransform', 'msTransform', 'Transform'], i
+ for (i = 0; i < props.length; i++) {
+ if (props[i] in doc.createElement('a').style) {
+ return props[i]
+ }
+ }
+ }()
+ , trim = String.prototype.trim ?
+ function (s) {
+ return s.trim()
+ } :
+ function (s) {
+ return s.replace(trimReplace, '')
+ }
+
+ function classReg(c) {
+ return new RegExp("(^|\\s+)" + c + "(\\s+|$)")
+ }
+
+ function each(ar, fn, scope) {
+ for (var i = 0, l = ar.length; i < l; i++) fn.call(scope || ar[i], ar[i], i, ar)
+ return ar
+ }
+
+ function camelize(s) {
+ return s.replace(/-(.)/g, function (m, m1) {
+ return m1.toUpperCase()
+ })
+ }
+
+ function is(node) {
+ return node && node.nodeName && node.nodeType == 1
+ }
+
+ function some(ar, fn, scope, i) {
+ for (i = 0, j = ar.length; i < j; ++i) {
+ if (fn.call(scope, ar[i], i, ar)) {
+ return true
+ }
+ }
+ return false
+ }
+
+ var getStyle = doc.defaultView && doc.defaultView.getComputedStyle ?
+ function (el, property) {
+ property = property == 'transform' ? transform : property
+ property = property == 'transform-origin' ? transform + "Origin" : property
+ var value = null
+ if (property == 'float') {
+ property = 'cssFloat'
+ }
+ var computed = doc.defaultView.getComputedStyle(el, '')
+ computed && (value = computed[camelize(property)])
+ return el.style[property] || value
+ } : (ie && html.currentStyle) ?
+
+ function (el, property) {
+ property = camelize(property)
+ property = property == 'float' ? 'styleFloat' : property
+
+ if (property == 'opacity') {
+ var val = 100
+ try {
+ val = el.filters['DXImageTransform.Microsoft.Alpha'].opacity
+ } catch (e1) {
+ try {
+ val = el.filters('alpha').opacity
+ } catch (e2) {}
+ }
+ return val / 100
+ }
+ var value = el.currentStyle ? el.currentStyle[property] : null
+ return el.style[property] || value
+ } :
+
+ function (el, property) {
+ return el.style[camelize(property)]
+ }
+
+ function insert(target, host, fn) {
+ var i = 0, self = host || this, r = []
+ , nodes = query && typeof target == 'string' && target.charAt(0) != '<' ? function (n) {
+ return (n = query(target)) && (n.selected = 1) && n
+ }() : target
+ each(normalize(nodes), function (t) {
+ each(self, function (el) {
+ var n = !el[parentNode] || (el[parentNode] && !el[parentNode][parentNode]) ?
+ function () {
+ var c = el.cloneNode(true)
+ self.$ && self.cloneEvents && self.$(c).cloneEvents(el)
+ return c;
+ }() :
+ el
+ fn(t, n)
+ r[i] = n
+ i++
+ });
+ }, this)
+ each(r, function (e, i) {
+ self[i] = e
+ })
+ self.length = i
+ return self
+ }
+
+ function xy(el, x, y) {
+ var $el = bonzo(el)
+ , style = $el.css('position')
+ , offset = $el.offset()
+ , rel = 'relative'
+ , isRel = style == rel
+ , delta = [parseInt($el.css('left'), 10), parseInt($el.css('top'), 10)]
+
+ if (style == 'static') {
+ $el.css('position', rel)
+ style = rel
+ }
+
+ isNaN(delta[0]) && (delta[0] = isRel ? 0 : el.offsetLeft)
+ isNaN(delta[1]) && (delta[1] = isRel ? 0 : el.offsetTop)
+
+ x != null && (el.style.left = x - offset.left + delta[0] + px)
+ y != null && (el.style.top = y - offset.top + delta[1] + px)
+
+ }
+
+ function hasClass(el, c) {
+ return classReg(c).test(el.className)
+ }
+ function addClass(el, c) {
+ el.className = trim(el.className + ' ' + c)
+ }
+ function removeClass(el, c) {
+ el.className = trim(el.className.replace(classReg(c), ' '))
+ }
+
+ function Bonzo(elements) {
+ this.length = 0
+ if (elements) {
+ elements = typeof elements !== 'string' &&
+ !elements.nodeType &&
+ typeof elements.length !== 'undefined' ?
+ elements :
+ [elements]
+ this.length = elements.length
+ for (var i = 0; i < elements.length; i++) {
+ this[i] = elements[i]
+ }
+ }
+ }
+
+ Bonzo.prototype = {
+
+ get: function (index) {
+ return this[index]
+ }
+
+ , each: function (fn, scope) {
+ return each(this, fn, scope)
+ }
+
+ , map: function (fn, reject) {
+ var m = [], n, i
+ for (i = 0; i < this.length; i++) {
+ n = fn.call(this, this[i], i)
+ reject ? (reject(n) && m.push(n)) : m.push(n)
+ }
+ return m
+ }
+
+ , first: function () {
+ return bonzo(this[0])
+ }
+
+ , last: function () {
+ return bonzo(this[this.length - 1])
+ }
+
+ , html: function (h, text) {
+ var method = text ?
+ html.textContent === null ?
+ 'innerText' :
+ 'textContent' :
+ 'innerHTML', m;
+ function append(el) {
+ while (el.firstChild) el.removeChild(el.firstChild)
+ each(normalize(h), function (node) {
+ el.appendChild(node)
+ })
+ }
+ return typeof h !== 'undefined' ?
+ this.each(function (el) {
+ (m = el.tagName.match(specialTags)) ?
+ append(el, m[0]) :
+ (el[method] = h)
+ }) :
+ this[0] ? this[0][method] : ''
+ }
+
+ , text: function (text) {
+ return this.html(text, 1)
+ }
+
+ , addClass: function (c) {
+ return this.each(function (el) {
+ hasClass(el, c) || addClass(el, c)
+ })
+ }
+
+ , removeClass: function (c) {
+ return this.each(function (el) {
+ hasClass(el, c) && removeClass(el, c)
+ })
+ }
+
+ , hasClass: function (c) {
+ return some(this, function (el) {
+ return hasClass(el, c)
+ })
+ }
+
+ , toggleClass: function (c, condition) {
+ return this.each(function (el) {
+ typeof condition !== 'undefined' ?
+ condition ? addClass(el, c) : removeClass(el, c) :
+ hasClass(el, c) ? removeClass(el, c) : addClass(el, c)
+ })
+ }
+
+ , show: function (type) {
+ return this.each(function (el) {
+ el.style.display = type || ''
+ })
+ }
+
+ , hide: function (elements) {
+ return this.each(function (el) {
+ el.style.display = 'none'
+ })
+ }
+
+ , append: function (node) {
+ return this.each(function (el) {
+ each(normalize(node), function (i) {
+ el.appendChild(i)
+ })
+ })
+ }
+
+ , prepend: function (node) {
+ return this.each(function (el) {
+ var first = el.firstChild
+ each(normalize(node), function (i) {
+ el.insertBefore(i, first)
+ })
+ })
+ }
+
+ , appendTo: function (target, host) {
+ return insert.call(this, target, host, function (t, el) {
+ t.appendChild(el)
+ })
+ }
+
+ , prependTo: function (target, host) {
+ return insert.call(this, target, host, function (t, el) {
+ t.insertBefore(el, t.firstChild)
+ })
+ }
+
+ , next: function () {
+ return this.related('nextSibling')
+ }
+
+ , previous: function () {
+ return this.related('previousSibling')
+ }
+
+ , related: function (method) {
+ return this.map(
+ function (el) {
+ el = el[method]
+ while (el && el.nodeType !== 1) {
+ el = el[method]
+ }
+ return el || 0
+ },
+ function (el) {
+ return el
+ }
+ )
+ }
+
+ , before: function (node) {
+ return this.each(function (el) {
+ each(bonzo.create(node), function (i) {
+ el[parentNode].insertBefore(i, el)
+ })
+ })
+ }
+
+ , after: function (node) {
+ return this.each(function (el) {
+ each(bonzo.create(node), function (i) {
+ el[parentNode].insertBefore(i, el.nextSibling)
+ })
+ })
+ }
+
+ , insertBefore: function (target, host) {
+ return insert.call(this, target, host, function (t, el) {
+ t[parentNode].insertBefore(el, t)
+ })
+ }
+
+ , insertAfter: function (target, host) {
+ return insert.call(this, target, host, function (t, el) {
+ var sibling = t.nextSibling
+ if (sibling) {
+ t[parentNode].insertBefore(el, sibling);
+ }
+ else {
+ t[parentNode].appendChild(el)
+ }
+ })
+ }
+
+ , css: function (o, v, p) {
+ // is this a request for just getting a style?
+ if (v === undefined && typeof o == 'string') {
+ // repurpose 'v'
+ v = this[0];
+ if (!v) {
+ return null
+ }
+ if (v == doc || v == win) {
+ p = (v == doc) ? bonzo.doc() : bonzo.viewport()
+ return o == 'width' ? p.width : o == 'height' ? p.height : ''
+ }
+ return getStyle(v, o)
+ }
+ var iter = o
+ if (typeof o == 'string') {
+ iter = {}
+ iter[o] = v
+ }
+
+ if (ie && iter.opacity) {
+ // oh this 'ol gamut
+ iter.filter = 'alpha(opacity=' + (iter.opacity * 100) + ')'
+ // give it layout
+ iter.zoom = o.zoom || 1;
+ delete iter.opacity;
+ }
+
+ if (v = iter['float']) {
+ // float is a reserved style word. w3 uses cssFloat, ie uses styleFloat
+ ie ? (iter.styleFloat = v) : (iter.cssFloat = v);
+ delete iter['float'];
+ }
+
+ function fn(el, p, v) {
+ for (var k in iter) {
+ if (iter.hasOwnProperty(k)) {
+ v = iter[k];
+ // change "5" to "5px" - unless you're line-height, which is allowed
+ (p = camelize(k)) && digit.test(v) && !(p in unitless) && (v += px)
+ p = p == 'transform' ? transform : p
+ p = p == 'transformOrigin' ? transform + 'Origin' : p
+ el.style[p] = v
+ }
+ }
+ }
+ return this.each(fn)
+ }
+
+ , offset: function (x, y) {
+ if (typeof x == 'number' || typeof y == 'number') {
+ return this.each(function (el) {
+ xy(el, x, y)
+ })
+ }
+ var el = this[0]
+ , width = el.offsetWidth
+ , height = el.offsetHeight
+ , top = el.offsetTop
+ , left = el.offsetLeft
+ while (el = el.offsetParent) {
+ top = top + el.offsetTop
+ left = left + el.offsetLeft
+ }
+
+ return {
+ top: top
+ , left: left
+ , height: height
+ , width: width
+ }
+ }
+
+ , attr: function (k, v) {
+ var el = this[0]
+ if (typeof k != 'string' && !(k instanceof String)) {
+ for (var n in k) {
+ k.hasOwnProperty(n) && this.attr(n, k[n])
+ }
+ return this
+ }
+ return typeof v == 'undefined' ?
+ specialAttributes.test(k) ?
+ stateAttributes.test(k) && typeof el[k] == 'string' ?
+ true : el[k] : el[getAttribute](k) :
+ this.each(function (el) {
+ specialAttributes.test(k) ? (el[k] = v) : el[setAttribute](k, v)
+ })
+ }
+
+ , val: function (s) {
+ return (typeof s == 'string') ? this.attr('value', s) : this[0].value
+ }
+
+ , removeAttr: function (k) {
+ return this.each(function (el) {
+ stateAttributes.test(k) ? (el[k] = false) : el.removeAttribute(k)
+ })
+ }
+
+ , data: function (k, v) {
+ var el = this[0]
+ if (typeof v === 'undefined') {
+ el[getAttribute]('data-node-uid') || el[setAttribute]('data-node-uid', ++uuids)
+ var uid = el[getAttribute]('data-node-uid')
+ uidList[uid] || (uidList[uid] = {})
+ return uidList[uid][k]
+ } else {
+ return this.each(function (el) {
+ el[getAttribute]('data-node-uid') || el[setAttribute]('data-node-uid', ++uuids)
+ var uid = el[getAttribute]('data-node-uid')
+ , o = uidList[uid] || (uidList[uid] = {})
+ o[k] = v
+ })
+ }
+ }
+
+ , remove: function () {
+ return this.each(function (el) {
+ el[parentNode] && el[parentNode].removeChild(el)
+ })
+ }
+
+ , empty: function () {
+ return this.each(function (el) {
+ while (el.firstChild) {
+ el.removeChild(el.firstChild)
+ }
+ })
+ }
+
+ , detach: function () {
+ return this.map(function (el) {
+ return el[parentNode].removeChild(el)
+ })
+ }
+
+ , scrollTop: function (y) {
+ return scroll.call(this, null, y, 'y')
+ }
+
+ , scrollLeft: function (x) {
+ return scroll.call(this, x, null, 'x')
+ }
+
+ , toggle: function(callback) {
+ this.each(function (el) {
+ el.style.display = (el.offsetWidth || el.offsetHeight) ? 'none' : 'block'
+ })
+ callback && callback()
+ return this
+ }
+ }
+
+ function normalize(node) {
+ return typeof node == 'string' ? bonzo.create(nod