var identity = function (x) { return x; }; var isArray = function (value) { return $.isArray(value); }; var isObject = function (value) { return !isArray(value) && (value instanceof Object); }; var isNumber = function (value) { return value instanceof Number; }; var isFunction = function (value) { return value instanceof Function; }; var indexOf = function (object, value) { return $.inArray(value, object); }; var inArray = function (array, value) { return indexOf(array, value) !== -1; }; var foreach = function (collection, callback) { for(var i in collection) { if(collection.hasOwnProperty(i)) { callback(collection[i], i, collection); } } }; var last = function (array) { return array[array.length - 1]; }; var argumentsToArray = function (args) { return Array.prototype.slice.call(args); }; var extend = function () { var extended = {}; foreach(argumentsToArray(arguments), function (o) { foreach(o, function (val, key) { extended[key] = val; }); }); return extended; }; var mapToArray = function (collection, callback) { var mapped = []; foreach(collection, function (value, key, coll) { mapped.push(callback(value, key, coll)); }); return mapped; }; var mapToObject = function (collection, callback, keyCallback) { var mapped = {}; foreach(collection, function (value, key, coll) { key = keyCallback ? keyCallback(key, value) : key; mapped[key] = callback(value, key, coll); }); return mapped; }; var map = function (collection, callback, keyCallback) { return isArray(collection) ? mapToArray(collection, callback) : mapToObject(collection, callback, keyCallback); }; var pluck = function (arrayOfObjects, key) { return map(arrayOfObjects, function (val) { return val[key]; }); }; var filter = function (collection, callback) { var filtered; if(isArray(collection)) { filtered = []; foreach(collection, function (val, key, coll) { if(callback(val, key, coll)) { filtered.push(val); } }); } else { filtered = {}; foreach(collection, function (val, key, coll) { if(callback(val, key, coll)) { filtered[key] = val; } }); } return filtered; }; var call = function (collection, functionName, args) { return map(collection, function (object, name) { return object[functionName].apply(object, args || []); }); }; //execute callback immediately and at most one time on the minimumInterval, //ignore block attempts var throttle = function (minimumInterval, callback) { var timeout = null; return function () { var that = this, args = arguments; if(timeout === null) { timeout = setTimeout(function () { timeout = null; }, minimumInterval); callback.apply(that, args); } }; }; var mixinPubSub = function (object) { object = object || {}; var topics = {}; object.publish = function (topic, data) { foreach(topics[topic], function (callback) { callback(data); }); }; object.subscribe = function (topic, callback) { topics[topic] = topics[topic] || []; topics[topic].push(callback); }; object.unsubscribe = function (callback) { foreach(topics, function (subscribers) { var index = indexOf(subscribers, callback); if(index !== -1) { subscribers.splice(index, 1); } }); }; return object; };