forerunnerdb
Version:
A NoSQL document store database for browsers and Node.js.
1,784 lines (1,535 loc) • 375 kB
JavaScript
/*!
* Astrobench - 0.1.2
* Library for JavaScript benchmarks based on Benchmark.js
*
* https://github.com/kupriyanenko/astrobench
*
* Copyright Alexey Kupriyanenko <a.kupriyanenko@gmail.com>
* Released under the MIT license.
*/
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
/*!
* jBone v1.0.16 - 2014-05-07 - Library for DOM manipulation
*
* https://github.com/kupriyanenko/jbone
*
* Copyright 2014 Alexey Kupriyanenko
* Released under the MIT license.
*/
(function (win) {
var
// cache previous versions
_$ = win.$,
_jBone = win.jBone,
// Quick match a standalone tag
rquickSingleTag = /^<(\w+)\s*\/?>$/,
// A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash
rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
// Alias for function
slice = [].slice,
splice = [].splice,
keys = Object.keys,
// Alias for global variables
doc = document,
isString = function(el) {
return typeof el === "string";
},
isObject = function(el) {
return el instanceof Object;
},
isFunction = function(el) {
var getType = {};
return el && getType.toString.call(el) === "[object Function]";
},
isArray = function(el) {
return Array.isArray(el);
},
jBone = function(element, data) {
return new fn.init(element, data);
},
fn;
// set previous values and return the instance upon calling the no-conflict mode
jBone.noConflict = function() {
win.$ = _$;
win.jBone = _jBone;
return jBone;
};
fn = jBone.fn = jBone.prototype = {
init: function(element, data) {
var elements, tag, wraper, fragment;
if (!element) {
return this;
}
if (isString(element)) {
// Create single DOM element
if (tag = rquickSingleTag.exec(element)) {
this[0] = doc.createElement(tag[1]);
this.length = 1;
if (isObject(data)) {
this.attr(data);
}
return this;
}
// Create DOM collection
if ((tag = rquickExpr.exec(element)) && tag[1]) {
fragment = doc.createDocumentFragment();
wraper = doc.createElement("div");
wraper.innerHTML = element;
while (wraper.lastChild) {
fragment.appendChild(wraper.firstChild);
}
elements = slice.call(fragment.childNodes);
return jBone.merge(this, elements);
}
// Find DOM elements with querySelectorAll
if (jBone.isElement(data)) {
return jBone(data).find(element);
}
try {
elements = doc.querySelectorAll(element);
return jBone.merge(this, elements);
} catch (e) {
return this;
}
}
// Wrap DOMElement
if (element.nodeType) {
this[0] = element;
this.length = 1;
return this;
}
// Run function
if (isFunction(element)) {
return element();
}
// Return jBone element as is
if (element instanceof jBone) {
return element;
}
// Return element wrapped by jBone
return jBone.makeArray(element, this);
},
pop: [].pop,
push: [].push,
reverse: [].reverse,
shift: [].shift,
sort: [].sort,
splice: [].splice,
slice: [].slice,
indexOf: [].indexOf,
forEach: [].forEach,
unshift: [].unshift,
concat: [].concat,
join: [].join,
every: [].every,
some: [].some,
filter: [].filter,
map: [].map,
reduce: [].reduce,
reduceRight: [].reduceRight,
length: 0
};
fn.constructor = jBone;
fn.init.prototype = fn;
jBone.setId = function(el) {
var jid = el.jid;
if (el === win) {
jid = "window";
} else if (el.jid === undefined) {
el.jid = jid = ++jBone._cache.jid;
}
if (!jBone._cache.events[jid]) {
jBone._cache.events[jid] = {};
}
};
jBone.getData = function(el) {
el = el instanceof jBone ? el[0] : el;
var jid = el === win ? "window" : el.jid;
return {
jid: jid,
events: jBone._cache.events[jid]
};
};
jBone.isElement = function(el) {
return el && el instanceof jBone || el instanceof HTMLElement || isString(el);
};
jBone._cache = {
events: {},
jid: 0
};
function isArraylike(obj) {
var length = obj.length,
type = typeof obj;
if (isFunction(type) || obj === win) {
return false;
}
if (obj.nodeType === 1 && length) {
return true;
}
return isArray(type) || length === 0 ||
typeof length === "number" && length > 0 && (length - 1) in obj;
}
jBone.merge = function(first, second) {
var l = second.length,
i = first.length,
j = 0;
while (j < l) {
first[i++] = second[j++];
}
first.length = i;
return first;
};
jBone.contains = function(container, contained) {
var result;
container.reverse().some(function(el) {
if (el.contains(contained)) {
return result = el;
}
});
return result;
};
jBone.extend = function(target) {
var k, kl, i, tg;
splice.call(arguments, 1).forEach(function(object) {
if (!object) {
return;
}
k = keys(object);
kl = k.length;
i = 0;
tg = target; //caching target for perf improvement
for (; i < kl; i++) {
tg[k[i]] = object[k[i]];
}
});
return target;
};
jBone.makeArray = function(arr, results) {
var ret = results || [];
if (arr !== null) {
if (isArraylike(arr)) {
jBone.merge(ret, isString(arr) ? [arr] : arr);
} else {
ret.push(arr);
}
}
return ret;
};
function BoneEvent(e, data) {
var key, setter;
this.originalEvent = e;
setter = function(key, e) {
if (key === "preventDefault") {
this[key] = function() {
this.defaultPrevented = true;
return e[key]();
};
} else if (isFunction(e[key])) {
this[key] = function() {
return e[key]();
};
} else {
this[key] = e[key];
}
};
for (key in e) {
if (e[key] || typeof e[key] === "function") {
setter.call(this, key, e);
}
}
jBone.extend(this, data);
}
jBone.Event = function(event, data) {
var namespace, eventType;
if (event.type && !data) {
data = event;
event = event.type;
}
namespace = event.split(".").splice(1).join(".");
eventType = event.split(".")[0];
event = doc.createEvent("Event");
event.initEvent(eventType, true, true);
return jBone.extend(event, {
namespace: namespace,
isDefaultPrevented: function() {
return event.defaultPrevented;
}
}, data);
};
fn.on = function(event) {
var args = arguments,
length = this.length,
i = 0,
callback, target, namespace, fn, events, eventType, expectedTarget, addListener;
if (args.length === 2) {
callback = args[1];
} else {
target = args[1];
callback = args[2];
}
addListener = function(el) {
jBone.setId(el);
events = jBone.getData(el).events;
event.split(" ").forEach(function(event) {
eventType = event.split(".")[0];
namespace = event.split(".").splice(1).join(".");
events[eventType] = events[eventType] || [];
fn = function(e) {
if (e.namespace && e.namespace !== namespace) {
return;
}
expectedTarget = null;
if (!target) {
callback.call(el, e);
} else if (~jBone(el).find(target).indexOf(e.target) || (expectedTarget = jBone.contains(jBone(el).find(target), e.target))) {
expectedTarget = expectedTarget || e.target;
e = new BoneEvent(e, {
currentTarget: expectedTarget
});
callback.call(expectedTarget, e);
}
};
events[eventType].push({
namespace: namespace,
fn: fn,
originfn: callback
});
el.addEventListener && el.addEventListener(eventType, fn, false);
});
};
for (; i < length; i++) {
addListener(this[i]);
}
return this;
};
fn.one = function(event) {
var args = arguments,
i = 0,
length = this.length,
callback, target, addListener;
if (args.length === 2) {
callback = args[1];
} else {
target = args[1], callback = args[2];
}
addListener = function(el) {
event.split(" ").forEach(function(event) {
var fn = function(e) {
jBone(el).off(event, fn);
callback.call(el, e);
};
if (!target) {
jBone(el).on(event, fn);
} else {
jBone(el).on(event, target, fn);
}
});
};
for (; i < length; i++) {
addListener(this[i]);
}
return this;
};
fn.trigger = function(event) {
var events = [],
i = 0,
length = this.length,
dispatchEvents;
if (!event) {
return this;
}
if (isString(event)) {
events = event.split(" ").map(function(event) {
return jBone.Event(event);
});
} else {
event = event instanceof Event ? event : jBone.Event(event);
events = [event];
}
dispatchEvents = function(el) {
events.forEach(function(event) {
if (!event.type) {
return;
}
el.dispatchEvent && el.dispatchEvent(event);
});
};
for (; i < length; i++) {
dispatchEvents(this[i]);
}
return this;
};
fn.off = function(event, fn) {
var i = 0,
length = this.length,
removeListener = function(events, eventType, index, el, e) {
var callback;
// get callback
if ((fn && e.originfn === fn) || !fn) {
callback = e.fn;
}
if (events[eventType][index].fn === callback) {
el.removeEventListener(eventType, callback);
// remove handler from cache
jBone._cache.events[jBone.getData(el).jid][eventType].splice(index, 1);
}
},
events, namespace, removeListeners, eventType;
removeListeners = function(el) {
var l, eventsByType, e;
events = jBone.getData(el).events;
if (!events) {
return;
}
// remove all events
if (!event && events) {
return keys(events).forEach(function(eventType) {
eventsByType = events[eventType];
l = eventsByType.length;
while(l--) {
removeListener(events, eventType, l, el, eventsByType[l]);
}
});
}
event.split(" ").forEach(function(event) {
eventType = event.split(".")[0];
namespace = event.split(".").splice(1).join(".");
// remove named events
if (events[eventType]) {
eventsByType = events[eventType];
l = eventsByType.length;
while(l--) {
e = eventsByType[l];
if (!namespace || (namespace && e.namespace === namespace)) {
removeListener(events, eventType, l, el, e);
}
}
}
// remove all namespaced events
else if (namespace) {
keys(events).forEach(function(eventType) {
eventsByType = events[eventType];
l = eventsByType.length;
while(l--) {
e = eventsByType[l];
if (e.namespace.split(".")[0] === namespace.split(".")[0]) {
removeListener(events, eventType, l, el, e);
}
}
});
}
});
};
for (; i < length; i++) {
removeListeners(this[i]);
}
return this;
};
fn.find = function(selector) {
var results = [],
i = 0,
length = this.length,
finder = function(el) {
if (isFunction(el.querySelectorAll)) {
[].forEach.call(el.querySelectorAll(selector), function(found) {
results.push(found);
});
}
};
for (; i < length; i++) {
finder(this[i]);
}
return jBone(results);
};
fn.get = function(index) {
return this[index];
};
fn.eq = function(index) {
return jBone(this[index]);
};
fn.parent = function() {
var results = [],
parent,
i = 0,
length = this.length;
for (; i < length; i++) {
if (!~results.indexOf(parent = this[i].parentElement) && parent) {
results.push(parent);
}
}
return jBone(results);
};
fn.toArray = function() {
return slice.call(this);
};
fn.is = function() {
var args = arguments;
return this.some(function(el) {
return el.tagName.toLowerCase() === args[0];
});
};
fn.has = function() {
var args = arguments;
return this.some(function(el) {
return el.querySelectorAll(args[0]).length;
});
};
fn.attr = function(key, value) {
var args = arguments,
i = 0,
length = this.length,
setter;
if (isString(key) && args.length === 1) {
return this[0] && this[0].getAttribute(key);
}
if (args.length === 2) {
setter = function(el) {
el.setAttribute(key, value);
};
} else if (isObject(key)) {
setter = function(el) {
keys(key).forEach(function(name) {
el.setAttribute(name, key[name]);
});
};
}
for (; i < length; i++) {
setter(this[i]);
}
return this;
};
fn.val = function(value) {
var i = 0,
length = this.length;
if (arguments.length === 0) {
return this[0] && this[0].value;
}
for (; i < length; i++) {
this[i].value = value;
}
return this;
};
fn.css = function(key, value) {
var args = arguments,
i = 0,
length = this.length,
setter;
// Get attribute
if (isString(key) && args.length === 1) {
return this[0] && win.getComputedStyle(this[0])[key];
}
// Set attributes
if (args.length === 2) {
setter = function(el) {
el.style[key] = value;
};
} else if (isObject(key)) {
setter = function(el) {
keys(key).forEach(function(name) {
el.style[name] = key[name];
});
};
}
for (; i < length; i++) {
setter(this[i]);
}
return this;
};
fn.data = function(key, value) {
var args = arguments, data = {},
i = 0,
length = this.length,
setter,
setValue = function(el, key, value) {
if (isObject(value)) {
el.jdata = el.jdata || {};
el.jdata[key] = value;
} else {
el.dataset[key] = value;
}
},
getValue = function(value) {
if (value === "true") {
return true;
} else if (value === "false") {
return false;
} else {
return value;
}
};
// Get all data
if (args.length === 0) {
this[0].jdata && (data = this[0].jdata);
keys(this[0].dataset).forEach(function(key) {
data[key] = getValue(this[0].dataset[key]);
}, this);
return data;
}
// Get data by name
if (args.length === 1 && isString(key)) {
return this[0] && getValue(this[0].dataset[key] || this[0].jdata && this[0].jdata[key]);
}
// Set data
if (args.length === 1 && isObject(key)) {
setter = function(el) {
keys(key).forEach(function(name) {
setValue(el, name, key[name]);
});
};
} else if (args.length === 2) {
setter = function(el) {
setValue(el, key, value);
};
}
for (; i < length; i++) {
setter(this[i]);
}
return this;
};
fn.html = function(value) {
var args = arguments,
el;
// add HTML into elements
if (args.length === 1 && value !== undefined) {
return this.empty().append(value);
}
// get HTML from element
else if (args.length === 0 && (el = this[0])) {
return el.innerHTML;
}
return this;
};
fn.append = function(appended) {
var i = 0,
length = this.length,
setter;
// create jBone object and then append
if (isString(appended) && rquickExpr.exec(appended)) {
appended = jBone(appended);
}
// create text node for inserting
else if (!isObject(appended)) {
appended = document.createTextNode(appended);
}
// just append NodeElement
if (appended instanceof Node) {
setter = function(el) {
el.appendChild(appended);
};
}
// wrap object by jBone, and then append
else {
appended = appended instanceof jBone ? appended : jBone(appended);
setter = function(el, i) {
appended.forEach(function(node) {
if (i) {
el.appendChild(node.cloneNode());
} else {
el.appendChild(node);
}
});
};
}
for (; i < length; i++) {
setter(this[i], i);
}
return this;
};
fn.appendTo = function(to) {
jBone(to).append(this);
return this;
};
fn.empty = function() {
var i = 0,
length = this.length,
el;
for (; i < length; i++) {
el = this[i];
while (el.lastChild) {
el.removeChild(el.lastChild);
}
}
return this;
};
fn.remove = function() {
var i = 0,
length = this.length,
el;
// remove all listners
this.off();
for (; i < length; i++) {
el = this[i];
// remove data and nodes
delete el.jdata;
el.parentNode && el.parentNode.removeChild(el);
}
return this;
};
if (typeof module === "object" && module && typeof module.exports === "object") {
// Expose jBone as module.exports in loaders that implement the Node
// module pattern (including browserify). Do not create the global, since
// the user will be storing it themselves locally, and globals are frowned
// upon in the Node module world.
module.exports = jBone;
}
// Register as a AMD module
else if (typeof define === "function" && define.amd) {
define(function() {
return jBone;
});
win.jBone = win.$ = jBone;
} else if (typeof win === "object" && typeof win.document === "object") {
win.jBone = win.$ = jBone;
}
}(window));
},{}],2:[function(require,module,exports){
(function (global){
/**
* @license
* Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
* Build: `lodash modern -o ./dist/lodash.js`
* Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
* Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
* Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
* Available under MIT license <http://lodash.com/license>
*/
;(function() {
/** Used as a safe reference for `undefined` in pre ES5 environments */
var undefined;
/** Used to pool arrays and objects used internally */
var arrayPool = [],
objectPool = [];
/** Used to generate unique IDs */
var idCounter = 0;
/** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
var keyPrefix = +new Date + '';
/** Used as the size when optimizations are enabled for large arrays */
var largeArraySize = 75;
/** Used as the max size of the `arrayPool` and `objectPool` */
var maxPoolSize = 40;
/** Used to detect and test whitespace */
var whitespace = (
// whitespace
' \t\x0B\f\xA0\ufeff' +
// line terminators
'\n\r\u2028\u2029' +
// unicode category "Zs" space separators
'\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
);
/** Used to match empty string literals in compiled template source */
var reEmptyStringLeading = /\b__p \+= '';/g,
reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
/**
* Used to match ES6 template delimiters
* http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
*/
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
/** Used to match regexp flags from their coerced string values */
var reFlags = /\w*$/;
/** Used to detected named functions */
var reFuncName = /^\s*function[ \n\r\t]+\w/;
/** Used to match "interpolate" template delimiters */
var reInterpolate = /<%=([\s\S]+?)%>/g;
/** Used to match leading whitespace and zeros to be removed */
var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
/** Used to ensure capturing order of template delimiters */
var reNoMatch = /($^)/;
/** Used to detect functions containing a `this` reference */
var reThis = /\bthis\b/;
/** Used to match unescaped characters in compiled string literals */
var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
/** Used to assign default `context` object properties */
var contextProps = [
'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
'parseInt', 'setTimeout'
];
/** Used to make template sourceURLs easier to identify */
var templateCounter = 0;
/** `Object#toString` result shortcuts */
var argsClass = '[object Arguments]',
arrayClass = '[object Array]',
boolClass = '[object Boolean]',
dateClass = '[object Date]',
funcClass = '[object Function]',
numberClass = '[object Number]',
objectClass = '[object Object]',
regexpClass = '[object RegExp]',
stringClass = '[object String]';
/** Used to identify object classifications that `_.clone` supports */
var cloneableClasses = {};
cloneableClasses[funcClass] = false;
cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
cloneableClasses[boolClass] = cloneableClasses[dateClass] =
cloneableClasses[numberClass] = cloneableClasses[objectClass] =
cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
/** Used as an internal `_.debounce` options object */
var debounceOptions = {
'leading': false,
'maxWait': 0,
'trailing': false
};
/** Used as the property descriptor for `__bindData__` */
var descriptor = {
'configurable': false,
'enumerable': false,
'value': null,
'writable': false
};
/** Used to determine if values are of the language type Object */
var objectTypes = {
'boolean': false,
'function': true,
'object': true,
'number': false,
'string': false,
'undefined': false
};
/** Used to escape characters for inclusion in compiled string literals */
var stringEscapes = {
'\\': '\\',
"'": "'",
'\n': 'n',
'\r': 'r',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
/** Used as a reference to the global object */
var root = (objectTypes[typeof window] && window) || this;
/** Detect free variable `exports` */
var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
/** Detect free variable `module` */
var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
/** Detect the popular CommonJS extension `module.exports` */
var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
/** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
var freeGlobal = objectTypes[typeof global] && global;
if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
root = freeGlobal;
}
/*--------------------------------------------------------------------------*/
/**
* The base implementation of `_.indexOf` without support for binary searches
* or `fromIndex` constraints.
*
* @private
* @param {Array} array The array to search.
* @param {*} value The value to search for.
* @param {number} [fromIndex=0] The index to search from.
* @returns {number} Returns the index of the matched value or `-1`.
*/
function baseIndexOf(array, value, fromIndex) {
var index = (fromIndex || 0) - 1,
length = array ? array.length : 0;
while (++index < length) {
if (array[index] === value) {
return index;
}
}
return -1;
}
/**
* An implementation of `_.contains` for cache objects that mimics the return
* signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
*
* @private
* @param {Object} cache The cache object to inspect.
* @param {*} value The value to search for.
* @returns {number} Returns `0` if `value` is found, else `-1`.
*/
function cacheIndexOf(cache, value) {
var type = typeof value;
cache = cache.cache;
if (type == 'boolean' || value == null) {
return cache[value] ? 0 : -1;
}
if (type != 'number' && type != 'string') {
type = 'object';
}
var key = type == 'number' ? value : keyPrefix + value;
cache = (cache = cache[type]) && cache[key];
return type == 'object'
? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
: (cache ? 0 : -1);
}
/**
* Adds a given value to the corresponding cache object.
*
* @private
* @param {*} value The value to add to the cache.
*/
function cachePush(value) {
var cache = this.cache,
type = typeof value;
if (type == 'boolean' || value == null) {
cache[value] = true;
} else {
if (type != 'number' && type != 'string') {
type = 'object';
}
var key = type == 'number' ? value : keyPrefix + value,
typeCache = cache[type] || (cache[type] = {});
if (type == 'object') {
(typeCache[key] || (typeCache[key] = [])).push(value);
} else {
typeCache[key] = true;
}
}
}
/**
* Used by `_.max` and `_.min` as the default callback when a given
* collection is a string value.
*
* @private
* @param {string} value The character to inspect.
* @returns {number} Returns the code unit of given character.
*/
function charAtCallback(value) {
return value.charCodeAt(0);
}
/**
* Used by `sortBy` to compare transformed `collection` elements, stable sorting
* them in ascending order.
*
* @private
* @param {Object} a The object to compare to `b`.
* @param {Object} b The object to compare to `a`.
* @returns {number} Returns the sort order indicator of `1` or `-1`.
*/
function compareAscending(a, b) {
var ac = a.criteria,
bc = b.criteria,
index = -1,
length = ac.length;
while (++index < length) {
var value = ac[index],
other = bc[index];
if (value !== other) {
if (value > other || typeof value == 'undefined') {
return 1;
}
if (value < other || typeof other == 'undefined') {
return -1;
}
}
}
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
// that causes it, under certain circumstances, to return the same value for
// `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
//
// This also ensures a stable sort in V8 and other engines.
// See http://code.google.com/p/v8/issues/detail?id=90
return a.index - b.index;
}
/**
* Creates a cache object to optimize linear searches of large arrays.
*
* @private
* @param {Array} [array=[]] The array to search.
* @returns {null|Object} Returns the cache object or `null` if caching should not be used.
*/
function createCache(array) {
var index = -1,
length = array.length,
first = array[0],
mid = array[(length / 2) | 0],
last = array[length - 1];
if (first && typeof first == 'object' &&
mid && typeof mid == 'object' && last && typeof last == 'object') {
return false;
}
var cache = getObject();
cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
var result = getObject();
result.array = array;
result.cache = cache;
result.push = cachePush;
while (++index < length) {
result.push(array[index]);
}
return result;
}
/**
* Used by `template` to escape characters for inclusion in compiled
* string literals.
*
* @private
* @param {string} match The matched character to escape.
* @returns {string} Returns the escaped character.
*/
function escapeStringChar(match) {
return '\\' + stringEscapes[match];
}
/**
* Gets an array from the array pool or creates a new one if the pool is empty.
*
* @private
* @returns {Array} The array from the pool.
*/
function getArray() {
return arrayPool.pop() || [];
}
/**
* Gets an object from the object pool or creates a new one if the pool is empty.
*
* @private
* @returns {Object} The object from the pool.
*/
function getObject() {
return objectPool.pop() || {
'array': null,
'cache': null,
'criteria': null,
'false': false,
'index': 0,
'null': false,
'number': null,
'object': null,
'push': null,
'string': null,
'true': false,
'undefined': false,
'value': null
};
}
/**
* Releases the given array back to the array pool.
*
* @private
* @param {Array} [array] The array to release.
*/
function releaseArray(array) {
array.length = 0;
if (arrayPool.length < maxPoolSize) {
arrayPool.push(array);
}
}
/**
* Releases the given object back to the object pool.
*
* @private
* @param {Object} [object] The object to release.
*/
function releaseObject(object) {
var cache = object.cache;
if (cache) {
releaseObject(cache);
}
object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
if (objectPool.length < maxPoolSize) {
objectPool.push(object);
}
}
/**
* Slices the `collection` from the `start` index up to, but not including,
* the `end` index.
*
* Note: This function is used instead of `Array#slice` to support node lists
* in IE < 9 and to ensure dense arrays are returned.
*
* @private
* @param {Array|Object|string} collection The collection to slice.
* @param {number} start The start index.
* @param {number} end The end index.
* @returns {Array} Returns the new array.
*/
function slice(array, start, end) {
start || (start = 0);
if (typeof end == 'undefined') {
end = array ? array.length : 0;
}
var index = -1,
length = end - start || 0,
result = Array(length < 0 ? 0 : length);
while (++index < length) {
result[index] = array[start + index];
}
return result;
}
/*--------------------------------------------------------------------------*/
/**
* Create a new `lodash` function using the given context object.
*
* @static
* @memberOf _
* @category Utilities
* @param {Object} [context=root] The context object.
* @returns {Function} Returns the `lodash` function.
*/
function runInContext(context) {
// Avoid issues with some ES3 environments that attempt to use values, named
// after built-in constructors like `Object`, for the creation of literals.
// ES5 clears this up by stating that literals must use built-in constructors.
// See http://es5.github.io/#x11.1.5.
context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
/** Native constructor references */
var Array = context.Array,
Boolean = context.Boolean,
Date = context.Date,
Function = context.Function,
Math = context.Math,
Number = context.Number,
Object = context.Object,
RegExp = context.RegExp,
String = context.String,
TypeError = context.TypeError;
/**
* Used for `Array` method references.
*
* Normally `Array.prototype` would suffice, however, using an array literal
* avoids issues in Narwhal.
*/
var arrayRef = [];
/** Used for native method references */
var objectProto = Object.prototype;
/** Used to restore the original `_` reference in `noConflict` */
var oldDash = context._;
/** Used to resolve the internal [[Class]] of values */
var toString = objectProto.toString;
/** Used to detect if a method is native */
var reNative = RegExp('^' +
String(toString)
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/toString| for [^\]]+/g, '.*?') + '$'
);
/** Native method shortcuts */
var ceil = Math.ceil,
clearTimeout = context.clearTimeout,
floor = Math.floor,
fnToString = Function.prototype.toString,
getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
hasOwnProperty = objectProto.hasOwnProperty,
push = arrayRef.push,
setTimeout = context.setTimeout,
splice = arrayRef.splice,
unshift = arrayRef.unshift;
/** Used to set meta data on functions */
var defineProperty = (function() {
// IE 8 only accepts DOM elements
try {
var o = {},
func = isNative(func = Object.defineProperty) && func,
result = func(o, o, o) && func;
} catch(e) { }
return result;
}());
/* Native method shortcuts for methods with the same name as other `lodash` methods */
var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
nativeIsFinite = context.isFinite,
nativeIsNaN = context.isNaN,
nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
nativeMax = Math.max,
nativeMin = Math.min,
nativeParseInt = context.parseInt,
nativeRandom = Math.random;
/** Used to lookup a built-in constructor by [[Class]] */
var ctorByClass = {};
ctorByClass[arrayClass] = Array;
ctorByClass[boolClass] = Boolean;
ctorByClass[dateClass] = Date;
ctorByClass[funcClass] = Function;
ctorByClass[objectClass] = Object;
ctorByClass[numberClass] = Number;
ctorByClass[regexpClass] = RegExp;
ctorByClass[stringClass] = String;
/*--------------------------------------------------------------------------*/
/**
* Creates a `lodash` object which wraps the given value to enable intuitive
* method chaining.
*
* In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
* `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
* and `unshift`
*
* Chaining is supported in custom builds as long as the `value` method is
* implicitly or explicitly included in the build.
*
* The chainable wrapper functions are:
* `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
* `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
* `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
* `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
* `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
* `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
* `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
* `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
* `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
* `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
* and `zip`
*
* The non-chainable wrapper functions are:
* `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
* `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
* `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
* `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
* `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
* `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
* `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
* `template`, `unescape`, `uniqueId`, and `value`
*
* The wrapper functions `first` and `last` return wrapped values when `n` is
* provided, otherwise they return unwrapped values.
*
* Explicit chaining can be enabled by using the `_.chain` method.
*
* @name _
* @constructor
* @category Chaining
* @param {*} value The value to wrap in a `lodash` instance.
* @returns {Object} Returns a `lodash` instance.
* @example
*
* var wrapped = _([1, 2, 3]);
*
* // returns an unwrapped value
* wrapped.reduce(function(sum, num) {
* return sum + num;
* });
* // => 6
*
* // returns a wrapped value
* var squares = wrapped.map(function(num) {
* return num * num;
* });
*
* _.isArray(squares);
* // => false
*
* _.isArray(squares.value());
* // => true
*/
function lodash(value) {
// don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
? value
: new lodashWrapper(value);
}
/**
* A fast path for creating `lodash` wrapper objects.
*
* @private
* @param {*} value The value to wrap in a `lodash` instance.
* @param {boolean} chainAll A flag to enable chaining for all methods
* @returns {Object} Returns a `lodash` instance.
*/
function lodashWrapper(value, chainAll) {
this.__chain__ = !!chainAll;
this.__wrapped__ = value;
}
// ensure `new lodashWrapper` is an instance of `lodash`
lodashWrapper.prototype = lodash.prototype;
/**
* An object used to flag environments features.
*
* @static
* @memberOf _
* @type Object
*/
var support = lodash.support = {};
/**
* Detect if functions can be decompiled by `Function#toString`
* (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
*
* @memberOf _.support
* @type boolean
*/
support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
/**
* Detect if `Function#name` is supported (all but IE).
*
* @memberOf _.support
* @type boolean
*/
support.funcNames = typeof Function.name == 'string';
/**
* By default, the template delimiters used by Lo-Dash are similar to those in
* embedded Ruby (ERB). Change the following template settings to use alternative
* delimiters.
*
* @static
* @memberOf _
* @type Object
*/
lodash.templateSettings = {
/**
* Used to detect `data` property values to be HTML-escaped.
*
* @memberOf _.templateSettings
* @type RegExp
*/
'escape': /<%-([\s\S]+?)%>/g,
/**
* Used to detect code to be evaluated.
*
* @memberOf _.templateSettings
* @type RegExp
*/
'evaluate': /<%([\s\S]+?)%>/g,
/**
* Used to detect `data` property values to inject.
*
* @memberOf _.templateSettings
* @type RegExp
*/
'interpolate': reInterpolate,
/**
* Used to reference the data object in the template text.
*
* @memberOf _.templateSettings
* @type string
*/
'variable': '',
/**
* Used to import variables into the compiled template.
*
* @memberOf _.templateSettings
* @type Object
*/
'imports': {
/**
* A reference to the `lodash` function.
*
* @memberOf _.templateSettings.imports
* @type Function
*/
'_': lodash
}
};
/*--------------------------------------------------------------------------*/
/**
* The base implementation of `_.bind` that creates the bound function and
* sets its meta data.
*
* @private
* @param {Array} bindData The bind data array.
* @returns {Function} Returns the new bound function.
*/
function baseBind(bindData) {
var func = bindData[0],
partialArgs = bindData[2],
thisArg = bindData[4];
function bound() {
// `Function#bind` spec
// http://es5.github.io/#x15.3.4.5
if (partialArgs) {
// avoid `arguments` object deoptimizations by using `slice` instead
// of `Array.prototype.slice.call` and not assigning `arguments` to a
// variable as a ternary expression
var args = slice(partialArgs);
push.apply(args, arguments);
}
// mimic the constructor's `return` behavior
// http://es5.github.io/#x13.2.2
if (this instanceof bound) {
// ensure `new bound` is an instance of `func`
var thisBinding = baseCreate(func.prototype),
result = func.apply(thisBinding, args || arguments);
return isObject(result) ? result : thisBinding;
}
return func.apply(thisArg, args || arguments);
}
setBindData(bound, bindData);
return bound;
}
/**
* The base implementation of `_.clone` without argument juggling or support
* for `thisArg` binding.
*
* @private
* @param {*} value The value to clone.
* @param {boolean} [isDeep=false] Specify a deep clone.
* @param {Function} [callback] The function to customize cloning values.
* @param {Array} [stackA=[]] Tracks traversed source objects.
* @param {Array} [stackB=[]] Associates clones with source counterparts.
* @returns {*} Returns the cloned value.
*/
function baseClone(value, isDeep, callback, stackA, stackB) {
if (callback) {
var result = callback(value);
if (typeof result != 'undefined') {
return result;
}
}
// inspect [[Class]]
var isObj = isObject(value);
if (isObj) {
var className = toString.call(value);
if (!cloneableClasses[className]) {
return value;
}
var ctor = ctorByClass[className];
switch (className) {
case boolClass:
case dateClass:
return new ctor(+value);
case numberClass:
case stringClass:
return new ctor(value);
case regexpClass:
result = ctor(value.source, reFlags.exec(value));
result.lastIndex = value.lastIndex;
return result;
}
} else {
return value;
}
var isArr = isArray(value);
if (isDeep) {
// check for circular references and return corresponding clone
var initedStack = !stackA;
stackA || (stackA = getArray());
stackB || (stackB = getArray());
var length = stackA.length;
while (length--) {
if (stackA[length] == value) {
return stackB[length];
}
}
result = isArr ? ctor(value.length) : {};
}
else {
result = isArr ? slice(value) : assign({}, value);
}
// add array properties assigned by `RegExp#exec`
if (isArr) {
if (hasOwnProperty.call(value, 'index')) {
result.index = value.index;
}
if (hasOwnProperty.call(value, 'input')) {
result.input = value.input;
}
}
// exit for shallow clone
if (!isDeep) {
return result;
}
// add the source value to the stack of traversed objects
// and associate it with its clone
stackA.push(value);
stackB.push(result);
// recursively populate clone (susceptible to call stack limits)
(isArr ? forEach : forOwn)(value, function(objValue, key) {
result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
});
if (initedStack) {
releaseArray(stackA);
releaseArray(stackB);
}
return result;
}
/**
* The base implementation of `_.create` without support for assigning
* properties to the created object.
*
* @private
* @param {Object} prototype The object to inherit from.
* @returns {Object} Returns the new object.
*/
function baseCreate(prototype, properties) {
return isObject(prototype) ? nativeCreate(prototype) : {};
}
// fallback for browsers without `Object.create`
if (!nativeCreate) {
baseCreate = (function() {
function Object() {}
return function(prototype) {
if (isObject(prototype)) {
Object.prototype = prototype;
var result = new Object;
Object.prototype = null;
}
return result || context.Object();
};
}());
}
/**
* The base implementation of `_.createCallback` without support for creating
* "_.pluck" or "_.where" style callbacks.
*
* @private
* @param {*} [func=identity] The value to convert to a callback.
* @param {*} [thisArg] The `this` binding of the created callback.
* @param {number} [argCount] The number of arguments the callback accepts.
* @returns {Function} Returns a callback function.
*/
function baseCreateCallback(func, thisArg, argCount) {
if (typeof func != 'function') {
return identity;
}
// exit early for no `thisArg` or already bound by `Function#bind`
if (typeof thisArg == 'undefined' || !('prototype' in func)) {
return func;
}
var bindData = func.__bindData__;
if (typeof bindData == 'undefined') {
if (support.funcNames) {
bindData = !func.name;
}
bindData = bindData || !support.funcDecomp;
if (!bindData) {
var source = fnToString.call(func);
if (!support.funcNames) {
bindData = !reFuncName.test(source);
}
if (!bindData) {
// checks if `func` references the `this` keyword and stores the result
bindData = reThis.test(source);
setBindData(func, bindData);
}
}
}
// exit early if there are no `this` references or `func` is bound
if (bindData === false || (bindData !== true && bindData[1] & 1)) {
return func;
}
switch (argCount) {
case 1: return function(value) {
return func.call(thisArg, value);
};
case 2: return function(a, b) {
return func.call(thisArg, a, b);
};
case 3: return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
case 4: return function(accumulator, value, index, collection) {
return func.call(thisArg, accumulator, value, index, collection);
};
}
return bind(func, thisArg);
}
/**
* The base implementation of `createWrapper` that creates the wrapper and
* sets its meta data.
*
* @private
* @param {Array} bindData The bind data array.
* @returns {Function} Returns the new function.
*/
function baseCreateWrapper(bindData) {
var func = bindData[0],
bitmask = bindData[1],
partialArgs = bindData[2],
partialRightArgs = bindData[3],
thisArg = bindData[4],
arity = bindData[5];
var isBind = bitmask & 1,
isBindKey = bitmask & 2,
isCurry = bitmask & 4,
isCurryBound = bitmask & 8,
key = func;
function bound() {
var thisBinding = isBind ? thisArg : this;
if (partialArgs) {
var args = slice(partialArgs);
push.apply(args, arguments);
}
if (partialRightArgs || isCurry) {
args || (args = slice(arguments));
if (partialRightArgs) {
push.apply(args, partialRightArgs);
}