mirror of
https://github.com/netzmacht/contao-leaflet-libraries.git
synced 2025-11-28 11:04:07 +01:00
1795 lines
57 KiB
JavaScript
1795 lines
57 KiB
JavaScript
|
|
/**
|
||
|
|
* @license
|
||
|
|
* Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
|
||
|
|
* Build: `lodash exports="node" include="clone,merge,isEmpty,isArray,compact,each" -d`
|
||
|
|
* 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 to pool arrays and objects used internally */
|
||
|
|
var arrayPool = [];
|
||
|
|
|
||
|
|
/** Used internally to indicate various things */
|
||
|
|
var indicatorObject = {};
|
||
|
|
|
||
|
|
/** Used as the max size of the `arrayPool` and `objectPool` */
|
||
|
|
var maxPoolSize = 40;
|
||
|
|
|
||
|
|
/** 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 detect functions containing a `this` reference */
|
||
|
|
var reThis = /\bthis\b/;
|
||
|
|
|
||
|
|
/** Used to fix the JScript [[DontEnum]] bug */
|
||
|
|
var shadowedProps = [
|
||
|
|
'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
|
||
|
|
'toLocaleString', 'toString', 'valueOf'
|
||
|
|
];
|
||
|
|
|
||
|
|
/** `Object#toString` result shortcuts */
|
||
|
|
var argsClass = '[object Arguments]',
|
||
|
|
arrayClass = '[object Array]',
|
||
|
|
boolClass = '[object Boolean]',
|
||
|
|
dateClass = '[object Date]',
|
||
|
|
errorClass = '[object Error]',
|
||
|
|
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 the property descriptor for `__bindData__` */
|
||
|
|
var descriptor = {
|
||
|
|
'configurable': false,
|
||
|
|
'enumerable': false,
|
||
|
|
'value': null,
|
||
|
|
'writable': false
|
||
|
|
};
|
||
|
|
|
||
|
|
/** Used as the data object for `iteratorTemplate` */
|
||
|
|
var iteratorData = {
|
||
|
|
'args': '',
|
||
|
|
'array': null,
|
||
|
|
'bottom': '',
|
||
|
|
'firstArg': '',
|
||
|
|
'init': '',
|
||
|
|
'keys': null,
|
||
|
|
'loop': '',
|
||
|
|
'shadowedProps': null,
|
||
|
|
'support': null,
|
||
|
|
'top': '',
|
||
|
|
'useHas': 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 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;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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() || [];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Checks if `value` is a DOM node in IE < 9.
|
||
|
|
*
|
||
|
|
* @private
|
||
|
|
* @param {*} value The value to check.
|
||
|
|
* @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`.
|
||
|
|
*/
|
||
|
|
function isNode(value) {
|
||
|
|
// IE < 9 presents DOM nodes as `Object` objects except they have `toString`
|
||
|
|
// methods that are `typeof` "string" and still can coerce nodes to strings
|
||
|
|
return typeof value.toString != 'function' && typeof (value + '') == 'string';
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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 errorProto = Error.prototype,
|
||
|
|
objectProto = Object.prototype,
|
||
|
|
stringProto = String.prototype;
|
||
|
|
|
||
|
|
/** 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 fnToString = Function.prototype.toString,
|
||
|
|
getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
|
||
|
|
hasOwnProperty = objectProto.hasOwnProperty,
|
||
|
|
push = arrayRef.push,
|
||
|
|
propertyIsEnumerable = objectProto.propertyIsEnumerable,
|
||
|
|
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,
|
||
|
|
nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys;
|
||
|
|
|
||
|
|
/** 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;
|
||
|
|
|
||
|
|
/** Used to avoid iterating non-enumerable properties in IE < 9 */
|
||
|
|
var nonEnumProps = {};
|
||
|
|
nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
|
||
|
|
nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
|
||
|
|
nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
|
||
|
|
nonEnumProps[objectClass] = { 'constructor': true };
|
||
|
|
|
||
|
|
(function() {
|
||
|
|
var length = shadowedProps.length;
|
||
|
|
while (length--) {
|
||
|
|
var key = shadowedProps[length];
|
||
|
|
for (var className in nonEnumProps) {
|
||
|
|
if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) {
|
||
|
|
nonEnumProps[className][key] = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}());
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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() {
|
||
|
|
// no operation performed
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* An object used to flag environments features.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @type Object
|
||
|
|
*/
|
||
|
|
var support = lodash.support = {};
|
||
|
|
|
||
|
|
(function() {
|
||
|
|
var ctor = function() { this.x = 1; },
|
||
|
|
object = { '0': 1, 'length': 1 },
|
||
|
|
props = [];
|
||
|
|
|
||
|
|
ctor.prototype = { 'valueOf': 1, 'y': 1 };
|
||
|
|
for (var key in new ctor) { props.push(key); }
|
||
|
|
for (key in arguments) { }
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
support.argsClass = toString.call(arguments) == argsClass;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect if `name` or `message` properties of `Error.prototype` are
|
||
|
|
* enumerable by default. (IE < 9, Safari < 5.1)
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect if `prototype` properties are enumerable by default.
|
||
|
|
*
|
||
|
|
* Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
|
||
|
|
* (if the prototype or a property on the prototype has been set)
|
||
|
|
* incorrectly sets a function's `prototype` property [[Enumerable]]
|
||
|
|
* value to `true`.
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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(root.WinRTError) && reThis.test(function() { return this; });
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect if `Function#name` is supported (all but IE).
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
support.funcNames = typeof Function.name == 'string';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect if `arguments` object indexes are non-enumerable
|
||
|
|
* (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
support.nonEnumArgs = key != 0;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect if properties shadowing those on `Object.prototype` are non-enumerable.
|
||
|
|
*
|
||
|
|
* In IE < 9 an objects own properties, shadowing non-enumerable ones, are
|
||
|
|
* made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
support.nonEnumShadows = !/valueOf/.test(props);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect if own properties are iterated after inherited properties (all but IE < 9).
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
support.ownLast = props[0] != 'x';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
|
||
|
|
*
|
||
|
|
* Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
|
||
|
|
* and `splice()` functions that fail to remove the last element, `value[0]`,
|
||
|
|
* of array-like objects even though the `length` property is set to `0`.
|
||
|
|
* The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
|
||
|
|
* is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect lack of support for accessing string characters by index.
|
||
|
|
*
|
||
|
|
* IE < 8 can't access characters by index and IE 8 can only access
|
||
|
|
* characters by index on string literals.
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
|
||
|
|
* and that the JS engine errors when attempting to coerce an object to
|
||
|
|
* a string without a `toString` function.
|
||
|
|
*
|
||
|
|
* @memberOf _.support
|
||
|
|
* @type boolean
|
||
|
|
*/
|
||
|
|
try {
|
||
|
|
support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
|
||
|
|
} catch(e) {
|
||
|
|
support.nodeClass = true;
|
||
|
|
}
|
||
|
|
}(1));
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The template used to create iterator functions.
|
||
|
|
*
|
||
|
|
* @private
|
||
|
|
* @param {Object} data The data object used to populate the text.
|
||
|
|
* @returns {string} Returns the interpolated text.
|
||
|
|
*/
|
||
|
|
var iteratorTemplate = function(obj) {
|
||
|
|
|
||
|
|
var __p = 'var index, iterable = ' +
|
||
|
|
(obj.firstArg) +
|
||
|
|
', result = ' +
|
||
|
|
(obj.init) +
|
||
|
|
';\nif (!iterable) return result;\n' +
|
||
|
|
(obj.top) +
|
||
|
|
';';
|
||
|
|
if (obj.array) {
|
||
|
|
__p += '\nvar length = iterable.length; index = -1;\nif (' +
|
||
|
|
(obj.array) +
|
||
|
|
') { ';
|
||
|
|
if (support.unindexedChars) {
|
||
|
|
__p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } ';
|
||
|
|
}
|
||
|
|
__p += '\n while (++index < length) {\n ' +
|
||
|
|
(obj.loop) +
|
||
|
|
';\n }\n}\nelse { ';
|
||
|
|
} else if (support.nonEnumArgs) {
|
||
|
|
__p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' +
|
||
|
|
(obj.loop) +
|
||
|
|
';\n }\n } else { ';
|
||
|
|
}
|
||
|
|
|
||
|
|
if (support.enumPrototypes) {
|
||
|
|
__p += '\n var skipProto = typeof iterable == \'function\';\n ';
|
||
|
|
}
|
||
|
|
|
||
|
|
if (support.enumErrorProps) {
|
||
|
|
__p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n ';
|
||
|
|
}
|
||
|
|
|
||
|
|
var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); }
|
||
|
|
|
||
|
|
if (obj.useHas && obj.keys) {
|
||
|
|
__p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n';
|
||
|
|
if (conditions.length) {
|
||
|
|
__p += ' if (' +
|
||
|
|
(conditions.join(' && ')) +
|
||
|
|
') {\n ';
|
||
|
|
}
|
||
|
|
__p +=
|
||
|
|
(obj.loop) +
|
||
|
|
'; ';
|
||
|
|
if (conditions.length) {
|
||
|
|
__p += '\n }';
|
||
|
|
}
|
||
|
|
__p += '\n } ';
|
||
|
|
} else {
|
||
|
|
__p += '\n for (index in iterable) {\n';
|
||
|
|
if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) {
|
||
|
|
__p += ' if (' +
|
||
|
|
(conditions.join(' && ')) +
|
||
|
|
') {\n ';
|
||
|
|
}
|
||
|
|
__p +=
|
||
|
|
(obj.loop) +
|
||
|
|
'; ';
|
||
|
|
if (conditions.length) {
|
||
|
|
__p += '\n }';
|
||
|
|
}
|
||
|
|
__p += '\n } ';
|
||
|
|
if (support.nonEnumShadows) {
|
||
|
|
__p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n ';
|
||
|
|
for (k = 0; k < 7; k++) {
|
||
|
|
__p += '\n index = \'' +
|
||
|
|
(obj.shadowedProps[k]) +
|
||
|
|
'\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
|
||
|
|
if (!obj.useHas) {
|
||
|
|
__p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
|
||
|
|
}
|
||
|
|
__p += ') {\n ' +
|
||
|
|
(obj.loop) +
|
||
|
|
';\n } ';
|
||
|
|
}
|
||
|
|
__p += '\n } ';
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if (obj.array || support.nonEnumArgs) {
|
||
|
|
__p += '\n}';
|
||
|
|
}
|
||
|
|
__p +=
|
||
|
|
(obj.bottom) +
|
||
|
|
';\nreturn result';
|
||
|
|
|
||
|
|
return __p
|
||
|
|
};
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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] || (!support.nodeClass && isNode(value))) {
|
||
|
|
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 ? baseEach : 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 || root.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);
|
||
|
|
}
|
||
|
|
if (isCurry && args.length < arity) {
|
||
|
|
bitmask |= 16 & ~32;
|
||
|
|
return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
args || (args = arguments);
|
||
|
|
if (isBindKey) {
|
||
|
|
func = thisBinding[key];
|
||
|
|
}
|
||
|
|
if (this instanceof bound) {
|
||
|
|
thisBinding = baseCreate(func.prototype);
|
||
|
|
var result = func.apply(thisBinding, args);
|
||
|
|
return isObject(result) ? result : thisBinding;
|
||
|
|
}
|
||
|
|
return func.apply(thisBinding, args);
|
||
|
|
}
|
||
|
|
setBindData(bound, bindData);
|
||
|
|
return bound;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The base implementation of `_.merge` without argument juggling or support
|
||
|
|
* for `thisArg` binding.
|
||
|
|
*
|
||
|
|
* @private
|
||
|
|
* @param {Object} object The destination object.
|
||
|
|
* @param {Object} source The source object.
|
||
|
|
* @param {Function} [callback] The function to customize merging properties.
|
||
|
|
* @param {Array} [stackA=[]] Tracks traversed source objects.
|
||
|
|
* @param {Array} [stackB=[]] Associates values with source counterparts.
|
||
|
|
*/
|
||
|
|
function baseMerge(object, source, callback, stackA, stackB) {
|
||
|
|
(isArray(source) ? forEach : forOwn)(source, function(source, key) {
|
||
|
|
var found,
|
||
|
|
isArr,
|
||
|
|
result = source,
|
||
|
|
value = object[key];
|
||
|
|
|
||
|
|
if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
|
||
|
|
// avoid merging previously merged cyclic sources
|
||
|
|
var stackLength = stackA.length;
|
||
|
|
while (stackLength--) {
|
||
|
|
if ((found = stackA[stackLength] == source)) {
|
||
|
|
value = stackB[stackLength];
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (!found) {
|
||
|
|
var isShallow;
|
||
|
|
if (callback) {
|
||
|
|
result = callback(value, source);
|
||
|
|
if ((isShallow = typeof result != 'undefined')) {
|
||
|
|
value = result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (!isShallow) {
|
||
|
|
value = isArr
|
||
|
|
? (isArray(value) ? value : [])
|
||
|
|
: (isPlainObject(value) ? value : {});
|
||
|
|
}
|
||
|
|
// add `source` and associated `value` to the stack of traversed objects
|
||
|
|
stackA.push(source);
|
||
|
|
stackB.push(value);
|
||
|
|
|
||
|
|
// recursively merge objects and arrays (susceptible to call stack limits)
|
||
|
|
if (!isShallow) {
|
||
|
|
baseMerge(value, source, callback, stackA, stackB);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (callback) {
|
||
|
|
result = callback(value, source);
|
||
|
|
if (typeof result == 'undefined') {
|
||
|
|
result = source;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (typeof result != 'undefined') {
|
||
|
|
value = result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
object[key] = value;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a function that, when called, either curries or invokes `func`
|
||
|
|
* with an optional `this` binding and partially applied arguments.
|
||
|
|
*
|
||
|
|
* @private
|
||
|
|
* @param {Function|string} func The function or method name to reference.
|
||
|
|
* @param {number} bitmask The bitmask of method flags to compose.
|
||
|
|
* The bitmask may be composed of the following flags:
|
||
|
|
* 1 - `_.bind`
|
||
|
|
* 2 - `_.bindKey`
|
||
|
|
* 4 - `_.curry`
|
||
|
|
* 8 - `_.curry` (bound)
|
||
|
|
* 16 - `_.partial`
|
||
|
|
* 32 - `_.partialRight`
|
||
|
|
* @param {Array} [partialArgs] An array of arguments to prepend to those
|
||
|
|
* provided to the new function.
|
||
|
|
* @param {Array} [partialRightArgs] An array of arguments to append to those
|
||
|
|
* provided to the new function.
|
||
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
||
|
|
* @param {number} [arity] The arity of `func`.
|
||
|
|
* @returns {Function} Returns the new function.
|
||
|
|
*/
|
||
|
|
function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
|
||
|
|
var isBind = bitmask & 1,
|
||
|
|
isBindKey = bitmask & 2,
|
||
|
|
isCurry = bitmask & 4,
|
||
|
|
isCurryBound = bitmask & 8,
|
||
|
|
isPartial = bitmask & 16,
|
||
|
|
isPartialRight = bitmask & 32;
|
||
|
|
|
||
|
|
if (!isBindKey && !isFunction(func)) {
|
||
|
|
throw new TypeError;
|
||
|
|
}
|
||
|
|
if (isPartial && !partialArgs.length) {
|
||
|
|
bitmask &= ~16;
|
||
|
|
isPartial = partialArgs = false;
|
||
|
|
}
|
||
|
|
if (isPartialRight && !partialRightArgs.length) {
|
||
|
|
bitmask &= ~32;
|
||
|
|
isPartialRight = partialRightArgs = false;
|
||
|
|
}
|
||
|
|
var bindData = func && func.__bindData__;
|
||
|
|
if (bindData && bindData !== true) {
|
||
|
|
// clone `bindData`
|
||
|
|
bindData = slice(bindData);
|
||
|
|
if (bindData[2]) {
|
||
|
|
bindData[2] = slice(bindData[2]);
|
||
|
|
}
|
||
|
|
if (bindData[3]) {
|
||
|
|
bindData[3] = slice(bindData[3]);
|
||
|
|
}
|
||
|
|
// set `thisBinding` is not previously bound
|
||
|
|
if (isBind && !(bindData[1] & 1)) {
|
||
|
|
bindData[4] = thisArg;
|
||
|
|
}
|
||
|
|
// set if previously bound but not currently (subsequent curried functions)
|
||
|
|
if (!isBind && bindData[1] & 1) {
|
||
|
|
bitmask |= 8;
|
||
|
|
}
|
||
|
|
// set curried arity if not yet set
|
||
|
|
if (isCurry && !(bindData[1] & 4)) {
|
||
|
|
bindData[5] = arity;
|
||
|
|
}
|
||
|
|
// append partial left arguments
|
||
|
|
if (isPartial) {
|
||
|
|
push.apply(bindData[2] || (bindData[2] = []), partialArgs);
|
||
|
|
}
|
||
|
|
// append partial right arguments
|
||
|
|
if (isPartialRight) {
|
||
|
|
unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
|
||
|
|
}
|
||
|
|
// merge flags
|
||
|
|
bindData[1] |= bitmask;
|
||
|
|
return createWrapper.apply(null, bindData);
|
||
|
|
}
|
||
|
|
// fast path for `_.bind`
|
||
|
|
var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
|
||
|
|
return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates compiled iteration functions.
|
||
|
|
*
|
||
|
|
* @private
|
||
|
|
* @param {...Object} [options] The compile options object(s).
|
||
|
|
* @param {string} [options.array] Code to determine if the iterable is an array or array-like.
|
||
|
|
* @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
|
||
|
|
* @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration.
|
||
|
|
* @param {string} [options.args] A comma separated string of iteration function arguments.
|
||
|
|
* @param {string} [options.top] Code to execute before the iteration branches.
|
||
|
|
* @param {string} [options.loop] Code to execute in the object loop.
|
||
|
|
* @param {string} [options.bottom] Code to execute after the iteration branches.
|
||
|
|
* @returns {Function} Returns the compiled function.
|
||
|
|
*/
|
||
|
|
function createIterator() {
|
||
|
|
// data properties
|
||
|
|
iteratorData.shadowedProps = shadowedProps;
|
||
|
|
|
||
|
|
// iterator options
|
||
|
|
iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = '';
|
||
|
|
iteratorData.init = 'iterable';
|
||
|
|
iteratorData.useHas = true;
|
||
|
|
|
||
|
|
// merge options into a template data object
|
||
|
|
for (var object, index = 0; object = arguments[index]; index++) {
|
||
|
|
for (var key in object) {
|
||
|
|
iteratorData[key] = object[key];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var args = iteratorData.args;
|
||
|
|
iteratorData.firstArg = /^[^,]+/.exec(args)[0];
|
||
|
|
|
||
|
|
// create the function factory
|
||
|
|
var factory = Function(
|
||
|
|
'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' +
|
||
|
|
'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' +
|
||
|
|
'objectTypes, nonEnumProps, stringClass, stringProto, toString',
|
||
|
|
'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}'
|
||
|
|
);
|
||
|
|
|
||
|
|
// return the compiled function
|
||
|
|
return factory(
|
||
|
|
baseCreateCallback, errorClass, errorProto, hasOwnProperty,
|
||
|
|
indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto,
|
||
|
|
objectTypes, nonEnumProps, stringClass, stringProto, toString
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Checks if `value` is a native function.
|
||
|
|
*
|
||
|
|
* @private
|
||
|
|
* @param {*} value The value to check.
|
||
|
|
* @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
|
||
|
|
*/
|
||
|
|
function isNative(value) {
|
||
|
|
return typeof value == 'function' && reNative.test(value);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Sets `this` binding data on a given function.
|
||
|
|
*
|
||
|
|
* @private
|
||
|
|
* @param {Function} func The function to set data on.
|
||
|
|
* @param {Array} value The data array to set.
|
||
|
|
*/
|
||
|
|
var setBindData = !defineProperty ? noop : function(func, value) {
|
||
|
|
descriptor.value = value;
|
||
|
|
defineProperty(func, '__bindData__', descriptor);
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A fallback implementation of `isPlainObject` which checks if a given value
|
||
|
|
* is an object created by the `Object` constructor, assuming objects created
|
||
|
|
* by the `Object` constructor have no inherited enumerable properties and that
|
||
|
|
* there are no `Object.prototype` extensions.
|
||
|
|
*
|
||
|
|
* @private
|
||
|
|
* @param {*} value The value to check.
|
||
|
|
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
||
|
|
*/
|
||
|
|
function shimIsPlainObject(value) {
|
||
|
|
var ctor,
|
||
|
|
result;
|
||
|
|
|
||
|
|
// avoid non Object objects, `arguments` objects, and DOM elements
|
||
|
|
if (!(value && toString.call(value) == objectClass) ||
|
||
|
|
(ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) ||
|
||
|
|
(!support.argsClass && isArguments(value)) ||
|
||
|
|
(!support.nodeClass && isNode(value))) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
// IE < 9 iterates inherited properties before own properties. If the first
|
||
|
|
// iterated property is an object's own property then there are no inherited
|
||
|
|
// enumerable properties.
|
||
|
|
if (support.ownLast) {
|
||
|
|
forIn(value, function(value, key, object) {
|
||
|
|
result = hasOwnProperty.call(object, key);
|
||
|
|
return false;
|
||
|
|
});
|
||
|
|
return result !== false;
|
||
|
|
}
|
||
|
|
// In most environments an object's own properties are iterated before
|
||
|
|
// its inherited properties. If the last iterated property is an object's
|
||
|
|
// own property then there are no inherited enumerable properties.
|
||
|
|
forIn(value, function(value, key) {
|
||
|
|
result = key;
|
||
|
|
});
|
||
|
|
return typeof result == 'undefined' || hasOwnProperty.call(value, result);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Checks if `value` is an `arguments` object.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Objects
|
||
|
|
* @param {*} value The value to check.
|
||
|
|
* @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* (function() { return _.isArguments(arguments); })(1, 2, 3);
|
||
|
|
* // => true
|
||
|
|
*
|
||
|
|
* _.isArguments([1, 2, 3]);
|
||
|
|
* // => false
|
||
|
|
*/
|
||
|
|
function isArguments(value) {
|
||
|
|
return value && typeof value == 'object' && typeof value.length == 'number' &&
|
||
|
|
toString.call(value) == argsClass || false;
|
||
|
|
}
|
||
|
|
// fallback for browsers that can't detect `arguments` objects by [[Class]]
|
||
|
|
if (!support.argsClass) {
|
||
|
|
isArguments = function(value) {
|
||
|
|
return value && typeof value == 'object' && typeof value.length == 'number' &&
|
||
|
|
hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Checks if `value` is an array.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @type Function
|
||
|
|
* @category Objects
|
||
|
|
* @param {*} value The value to check.
|
||
|
|
* @returns {boolean} Returns `true` if the `value` is an array, else `false`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* (function() { return _.isArray(arguments); })();
|
||
|
|
* // => false
|
||
|
|
*
|
||
|
|
* _.isArray([1, 2, 3]);
|
||
|
|
* // => true
|
||
|
|
*/
|
||
|
|
var isArray = nativeIsArray || function(value) {
|
||
|
|
return value && typeof value == 'object' && typeof value.length == 'number' &&
|
||
|
|
toString.call(value) == arrayClass || false;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A fallback implementation of `Object.keys` which produces an array of the
|
||
|
|
* given object's own enumerable property names.
|
||
|
|
*
|
||
|
|
* @private
|
||
|
|
* @type Function
|
||
|
|
* @param {Object} object The object to inspect.
|
||
|
|
* @returns {Array} Returns an array of property names.
|
||
|
|
*/
|
||
|
|
var shimKeys = createIterator({
|
||
|
|
'args': 'object',
|
||
|
|
'init': '[]',
|
||
|
|
'top': 'if (!(objectTypes[typeof object])) return result',
|
||
|
|
'loop': 'result.push(index)'
|
||
|
|
});
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates an array composed of the own enumerable property names of an object.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Objects
|
||
|
|
* @param {Object} object The object to inspect.
|
||
|
|
* @returns {Array} Returns an array of property names.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* _.keys({ 'one': 1, 'two': 2, 'three': 3 });
|
||
|
|
* // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
|
||
|
|
*/
|
||
|
|
var keys = !nativeKeys ? shimKeys : function(object) {
|
||
|
|
if (!isObject(object)) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
if ((support.enumPrototypes && typeof object == 'function') ||
|
||
|
|
(support.nonEnumArgs && object.length && isArguments(object))) {
|
||
|
|
return shimKeys(object);
|
||
|
|
}
|
||
|
|
return nativeKeys(object);
|
||
|
|
};
|
||
|
|
|
||
|
|
/** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
|
||
|
|
var eachIteratorOptions = {
|
||
|
|
'args': 'collection, callback, thisArg',
|
||
|
|
'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)",
|
||
|
|
'array': "typeof length == 'number'",
|
||
|
|
'keys': keys,
|
||
|
|
'loop': 'if (callback(iterable[index], index, collection) === false) return result'
|
||
|
|
};
|
||
|
|
|
||
|
|
/** Reusable iterator options for `assign` and `defaults` */
|
||
|
|
var defaultsIteratorOptions = {
|
||
|
|
'args': 'object, source, guard',
|
||
|
|
'top':
|
||
|
|
'var args = arguments,\n' +
|
||
|
|
' argsIndex = 0,\n' +
|
||
|
|
" argsLength = typeof guard == 'number' ? 2 : args.length;\n" +
|
||
|
|
'while (++argsIndex < argsLength) {\n' +
|
||
|
|
' iterable = args[argsIndex];\n' +
|
||
|
|
' if (iterable && objectTypes[typeof iterable]) {',
|
||
|
|
'keys': keys,
|
||
|
|
'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
|
||
|
|
'bottom': ' }\n}'
|
||
|
|
};
|
||
|
|
|
||
|
|
/** Reusable iterator options for `forIn` and `forOwn` */
|
||
|
|
var forOwnIteratorOptions = {
|
||
|
|
'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
|
||
|
|
'array': false
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A function compiled to iterate `arguments` objects, arrays, objects, and
|
||
|
|
* strings consistenly across environments, executing the callback for each
|
||
|
|
* element in the collection. The callback is bound to `thisArg` and invoked
|
||
|
|
* with three arguments; (value, index|key, collection). Callbacks may exit
|
||
|
|
* iteration early by explicitly returning `false`.
|
||
|
|
*
|
||
|
|
* @private
|
||
|
|
* @type Function
|
||
|
|
* @param {Array|Object|string} collection The collection to iterate over.
|
||
|
|
* @param {Function} [callback=identity] The function called per iteration.
|
||
|
|
* @param {*} [thisArg] The `this` binding of `callback`.
|
||
|
|
* @returns {Array|Object|string} Returns `collection`.
|
||
|
|
*/
|
||
|
|
var baseEach = createIterator(eachIteratorOptions);
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Assigns own enumerable properties of source object(s) to the destination
|
||
|
|
* object. Subsequent sources will overwrite property assignments of previous
|
||
|
|
* sources. If a callback is provided it will be executed to produce the
|
||
|
|
* assigned values. The callback is bound to `thisArg` and invoked with two
|
||
|
|
* arguments; (objectValue, sourceValue).
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @type Function
|
||
|
|
* @alias extend
|
||
|
|
* @category Objects
|
||
|
|
* @param {Object} object The destination object.
|
||
|
|
* @param {...Object} [source] The source objects.
|
||
|
|
* @param {Function} [callback] The function to customize assigning values.
|
||
|
|
* @param {*} [thisArg] The `this` binding of `callback`.
|
||
|
|
* @returns {Object} Returns the destination object.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
|
||
|
|
* // => { 'name': 'fred', 'employer': 'slate' }
|
||
|
|
*
|
||
|
|
* var defaults = _.partialRight(_.assign, function(a, b) {
|
||
|
|
* return typeof a == 'undefined' ? b : a;
|
||
|
|
* });
|
||
|
|
*
|
||
|
|
* var object = { 'name': 'barney' };
|
||
|
|
* defaults(object, { 'name': 'fred', 'employer': 'slate' });
|
||
|
|
* // => { 'name': 'barney', 'employer': 'slate' }
|
||
|
|
*/
|
||
|
|
var assign = createIterator(defaultsIteratorOptions, {
|
||
|
|
'top':
|
||
|
|
defaultsIteratorOptions.top.replace(';',
|
||
|
|
';\n' +
|
||
|
|
"if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" +
|
||
|
|
' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' +
|
||
|
|
"} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" +
|
||
|
|
' callback = args[--argsLength];\n' +
|
||
|
|
'}'
|
||
|
|
),
|
||
|
|
'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
|
||
|
|
});
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a clone of `value`. If `isDeep` is `true` nested objects will also
|
||
|
|
* be cloned, otherwise they will be assigned by reference. If a callback
|
||
|
|
* is provided it will be executed to produce the cloned values. If the
|
||
|
|
* callback returns `undefined` cloning will be handled by the method instead.
|
||
|
|
* The callback is bound to `thisArg` and invoked with one argument; (value).
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Objects
|
||
|
|
* @param {*} value The value to clone.
|
||
|
|
* @param {boolean} [isDeep=false] Specify a deep clone.
|
||
|
|
* @param {Function} [callback] The function to customize cloning values.
|
||
|
|
* @param {*} [thisArg] The `this` binding of `callback`.
|
||
|
|
* @returns {*} Returns the cloned value.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* var characters = [
|
||
|
|
* { 'name': 'barney', 'age': 36 },
|
||
|
|
* { 'name': 'fred', 'age': 40 }
|
||
|
|
* ];
|
||
|
|
*
|
||
|
|
* var shallow = _.clone(characters);
|
||
|
|
* shallow[0] === characters[0];
|
||
|
|
* // => true
|
||
|
|
*
|
||
|
|
* var deep = _.clone(characters, true);
|
||
|
|
* deep[0] === characters[0];
|
||
|
|
* // => false
|
||
|
|
*
|
||
|
|
* _.mixin({
|
||
|
|
* 'clone': _.partialRight(_.clone, function(value) {
|
||
|
|
* return _.isElement(value) ? value.cloneNode(false) : undefined;
|
||
|
|
* })
|
||
|
|
* });
|
||
|
|
*
|
||
|
|
* var clone = _.clone(document.body);
|
||
|
|
* clone.childNodes.length;
|
||
|
|
* // => 0
|
||
|
|
*/
|
||
|
|
function clone(value, isDeep, callback, thisArg) {
|
||
|
|
// allows working with "Collections" methods without using their `index`
|
||
|
|
// and `collection` arguments for `isDeep` and `callback`
|
||
|
|
if (typeof isDeep != 'boolean' && isDeep != null) {
|
||
|
|
thisArg = callback;
|
||
|
|
callback = isDeep;
|
||
|
|
isDeep = false;
|
||
|
|
}
|
||
|
|
return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Iterates over own and inherited enumerable properties of an object,
|
||
|
|
* executing the callback for each property. The callback is bound to `thisArg`
|
||
|
|
* and invoked with three arguments; (value, key, object). Callbacks may exit
|
||
|
|
* iteration early by explicitly returning `false`.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @type Function
|
||
|
|
* @category Objects
|
||
|
|
* @param {Object} object The object to iterate over.
|
||
|
|
* @param {Function} [callback=identity] The function called per iteration.
|
||
|
|
* @param {*} [thisArg] The `this` binding of `callback`.
|
||
|
|
* @returns {Object} Returns `object`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* function Shape() {
|
||
|
|
* this.x = 0;
|
||
|
|
* this.y = 0;
|
||
|
|
* }
|
||
|
|
*
|
||
|
|
* Shape.prototype.move = function(x, y) {
|
||
|
|
* this.x += x;
|
||
|
|
* this.y += y;
|
||
|
|
* };
|
||
|
|
*
|
||
|
|
* _.forIn(new Shape, function(value, key) {
|
||
|
|
* console.log(key);
|
||
|
|
* });
|
||
|
|
* // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
|
||
|
|
*/
|
||
|
|
var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
|
||
|
|
'useHas': false
|
||
|
|
});
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Iterates over own enumerable properties of an object, executing the callback
|
||
|
|
* for each property. The callback is bound to `thisArg` and invoked with three
|
||
|
|
* arguments; (value, key, object). Callbacks may exit iteration early by
|
||
|
|
* explicitly returning `false`.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @type Function
|
||
|
|
* @category Objects
|
||
|
|
* @param {Object} object The object to iterate over.
|
||
|
|
* @param {Function} [callback=identity] The function called per iteration.
|
||
|
|
* @param {*} [thisArg] The `this` binding of `callback`.
|
||
|
|
* @returns {Object} Returns `object`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
|
||
|
|
* console.log(key);
|
||
|
|
* });
|
||
|
|
* // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
|
||
|
|
*/
|
||
|
|
var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
|
||
|
|
* length of `0` and objects with no own enumerable properties are considered
|
||
|
|
* "empty".
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Objects
|
||
|
|
* @param {Array|Object|string} value The value to inspect.
|
||
|
|
* @returns {boolean} Returns `true` if the `value` is empty, else `false`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* _.isEmpty([1, 2, 3]);
|
||
|
|
* // => false
|
||
|
|
*
|
||
|
|
* _.isEmpty({});
|
||
|
|
* // => true
|
||
|
|
*
|
||
|
|
* _.isEmpty('');
|
||
|
|
* // => true
|
||
|
|
*/
|
||
|
|
function isEmpty(value) {
|
||
|
|
var result = true;
|
||
|
|
if (!value) {
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
var className = toString.call(value),
|
||
|
|
length = value.length;
|
||
|
|
|
||
|
|
if ((className == arrayClass || className == stringClass ||
|
||
|
|
(support.argsClass ? className == argsClass : isArguments(value))) ||
|
||
|
|
(className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
|
||
|
|
return !length;
|
||
|
|
}
|
||
|
|
forOwn(value, function() {
|
||
|
|
return (result = false);
|
||
|
|
});
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Checks if `value` is a function.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Objects
|
||
|
|
* @param {*} value The value to check.
|
||
|
|
* @returns {boolean} Returns `true` if the `value` is a function, else `false`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* _.isFunction(_);
|
||
|
|
* // => true
|
||
|
|
*/
|
||
|
|
function isFunction(value) {
|
||
|
|
return typeof value == 'function';
|
||
|
|
}
|
||
|
|
// fallback for older versions of Chrome and Safari
|
||
|
|
if (isFunction(/x/)) {
|
||
|
|
isFunction = function(value) {
|
||
|
|
return typeof value == 'function' && toString.call(value) == funcClass;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Checks if `value` is the language type of Object.
|
||
|
|
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Objects
|
||
|
|
* @param {*} value The value to check.
|
||
|
|
* @returns {boolean} Returns `true` if the `value` is an object, else `false`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* _.isObject({});
|
||
|
|
* // => true
|
||
|
|
*
|
||
|
|
* _.isObject([1, 2, 3]);
|
||
|
|
* // => true
|
||
|
|
*
|
||
|
|
* _.isObject(1);
|
||
|
|
* // => false
|
||
|
|
*/
|
||
|
|
function isObject(value) {
|
||
|
|
// check if the value is the ECMAScript language type of Object
|
||
|
|
// http://es5.github.io/#x8
|
||
|
|
// and avoid a V8 bug
|
||
|
|
// http://code.google.com/p/v8/issues/detail?id=2291
|
||
|
|
return !!(value && objectTypes[typeof value]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Checks if `value` is an object created by the `Object` constructor.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Objects
|
||
|
|
* @param {*} value The value to check.
|
||
|
|
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* function Shape() {
|
||
|
|
* this.x = 0;
|
||
|
|
* this.y = 0;
|
||
|
|
* }
|
||
|
|
*
|
||
|
|
* _.isPlainObject(new Shape);
|
||
|
|
* // => false
|
||
|
|
*
|
||
|
|
* _.isPlainObject([1, 2, 3]);
|
||
|
|
* // => false
|
||
|
|
*
|
||
|
|
* _.isPlainObject({ 'x': 0, 'y': 0 });
|
||
|
|
* // => true
|
||
|
|
*/
|
||
|
|
var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
|
||
|
|
if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
var valueOf = value.valueOf,
|
||
|
|
objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
|
||
|
|
|
||
|
|
return objProto
|
||
|
|
? (value == objProto || getPrototypeOf(value) == objProto)
|
||
|
|
: shimIsPlainObject(value);
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Checks if `value` is a string.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Objects
|
||
|
|
* @param {*} value The value to check.
|
||
|
|
* @returns {boolean} Returns `true` if the `value` is a string, else `false`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* _.isString('fred');
|
||
|
|
* // => true
|
||
|
|
*/
|
||
|
|
function isString(value) {
|
||
|
|
return typeof value == 'string' ||
|
||
|
|
value && typeof value == 'object' && toString.call(value) == stringClass || false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Recursively merges own enumerable properties of the source object(s), that
|
||
|
|
* don't resolve to `undefined` into the destination object. Subsequent sources
|
||
|
|
* will overwrite property assignments of previous sources. If a callback is
|
||
|
|
* provided it will be executed to produce the merged values of the destination
|
||
|
|
* and source properties. If the callback returns `undefined` merging will
|
||
|
|
* be handled by the method instead. The callback is bound to `thisArg` and
|
||
|
|
* invoked with two arguments; (objectValue, sourceValue).
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Objects
|
||
|
|
* @param {Object} object The destination object.
|
||
|
|
* @param {...Object} [source] The source objects.
|
||
|
|
* @param {Function} [callback] The function to customize merging properties.
|
||
|
|
* @param {*} [thisArg] The `this` binding of `callback`.
|
||
|
|
* @returns {Object} Returns the destination object.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* var names = {
|
||
|
|
* 'characters': [
|
||
|
|
* { 'name': 'barney' },
|
||
|
|
* { 'name': 'fred' }
|
||
|
|
* ]
|
||
|
|
* };
|
||
|
|
*
|
||
|
|
* var ages = {
|
||
|
|
* 'characters': [
|
||
|
|
* { 'age': 36 },
|
||
|
|
* { 'age': 40 }
|
||
|
|
* ]
|
||
|
|
* };
|
||
|
|
*
|
||
|
|
* _.merge(names, ages);
|
||
|
|
* // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
|
||
|
|
*
|
||
|
|
* var food = {
|
||
|
|
* 'fruits': ['apple'],
|
||
|
|
* 'vegetables': ['beet']
|
||
|
|
* };
|
||
|
|
*
|
||
|
|
* var otherFood = {
|
||
|
|
* 'fruits': ['banana'],
|
||
|
|
* 'vegetables': ['carrot']
|
||
|
|
* };
|
||
|
|
*
|
||
|
|
* _.merge(food, otherFood, function(a, b) {
|
||
|
|
* return _.isArray(a) ? a.concat(b) : undefined;
|
||
|
|
* });
|
||
|
|
* // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
|
||
|
|
*/
|
||
|
|
function merge(object) {
|
||
|
|
var args = arguments,
|
||
|
|
length = 2;
|
||
|
|
|
||
|
|
if (!isObject(object)) {
|
||
|
|
return object;
|
||
|
|
}
|
||
|
|
// allows working with `_.reduce` and `_.reduceRight` without using
|
||
|
|
// their `index` and `collection` arguments
|
||
|
|
if (typeof args[2] != 'number') {
|
||
|
|
length = args.length;
|
||
|
|
}
|
||
|
|
if (length > 3 && typeof args[length - 2] == 'function') {
|
||
|
|
var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
|
||
|
|
} else if (length > 2 && typeof args[length - 1] == 'function') {
|
||
|
|
callback = args[--length];
|
||
|
|
}
|
||
|
|
var sources = slice(arguments, 1, length),
|
||
|
|
index = -1,
|
||
|
|
stackA = getArray(),
|
||
|
|
stackB = getArray();
|
||
|
|
|
||
|
|
while (++index < length) {
|
||
|
|
baseMerge(object, sources[index], callback, stackA, stackB);
|
||
|
|
}
|
||
|
|
releaseArray(stackA);
|
||
|
|
releaseArray(stackB);
|
||
|
|
return object;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Iterates over elements of a collection, executing the callback for each
|
||
|
|
* element. The callback is bound to `thisArg` and invoked with three arguments;
|
||
|
|
* (value, index|key, collection). Callbacks may exit iteration early by
|
||
|
|
* explicitly returning `false`.
|
||
|
|
*
|
||
|
|
* Note: As with other "Collections" methods, objects with a `length` property
|
||
|
|
* are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
|
||
|
|
* may be used for object iteration.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @alias each
|
||
|
|
* @category Collections
|
||
|
|
* @param {Array|Object|string} collection The collection to iterate over.
|
||
|
|
* @param {Function} [callback=identity] The function called per iteration.
|
||
|
|
* @param {*} [thisArg] The `this` binding of `callback`.
|
||
|
|
* @returns {Array|Object|string} Returns `collection`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
|
||
|
|
* // => logs each number and returns '1,2,3'
|
||
|
|
*
|
||
|
|
* _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
|
||
|
|
* // => logs each number and returns the object (property order is not guaranteed across environments)
|
||
|
|
*/
|
||
|
|
function forEach(collection, callback, thisArg) {
|
||
|
|
if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
|
||
|
|
var index = -1,
|
||
|
|
length = collection.length;
|
||
|
|
|
||
|
|
while (++index < length) {
|
||
|
|
if (callback(collection[index], index, collection) === false) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
baseEach(collection, callback, thisArg);
|
||
|
|
}
|
||
|
|
return collection;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates an array with all falsey values removed. The values `false`, `null`,
|
||
|
|
* `0`, `""`, `undefined`, and `NaN` are all falsey.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Arrays
|
||
|
|
* @param {Array} array The array to compact.
|
||
|
|
* @returns {Array} Returns a new array of filtered values.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* _.compact([0, 1, false, 2, '', 3]);
|
||
|
|
* // => [1, 2, 3]
|
||
|
|
*/
|
||
|
|
function compact(array) {
|
||
|
|
var index = -1,
|
||
|
|
length = array ? array.length : 0,
|
||
|
|
result = [];
|
||
|
|
|
||
|
|
while (++index < length) {
|
||
|
|
var value = array[index];
|
||
|
|
if (value) {
|
||
|
|
result.push(value);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Creates a function that, when called, invokes `func` with the `this`
|
||
|
|
* binding of `thisArg` and prepends any additional `bind` arguments to those
|
||
|
|
* provided to the bound function.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Functions
|
||
|
|
* @param {Function} func The function to bind.
|
||
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
||
|
|
* @param {...*} [arg] Arguments to be partially applied.
|
||
|
|
* @returns {Function} Returns the new bound function.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* var func = function(greeting) {
|
||
|
|
* return greeting + ' ' + this.name;
|
||
|
|
* };
|
||
|
|
*
|
||
|
|
* func = _.bind(func, { 'name': 'fred' }, 'hi');
|
||
|
|
* func();
|
||
|
|
* // => 'hi fred'
|
||
|
|
*/
|
||
|
|
function bind(func, thisArg) {
|
||
|
|
return arguments.length > 2
|
||
|
|
? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
|
||
|
|
: createWrapper(func, 1, null, null, thisArg);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This method returns the first argument provided to it.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Utilities
|
||
|
|
* @param {*} value Any value.
|
||
|
|
* @returns {*} Returns `value`.
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* var object = { 'name': 'fred' };
|
||
|
|
* _.identity(object) === object;
|
||
|
|
* // => true
|
||
|
|
*/
|
||
|
|
function identity(value) {
|
||
|
|
return value;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A no-operation function.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @category Utilities
|
||
|
|
* @example
|
||
|
|
*
|
||
|
|
* var object = { 'name': 'fred' };
|
||
|
|
* _.noop(object) === undefined;
|
||
|
|
* // => true
|
||
|
|
*/
|
||
|
|
function noop() {
|
||
|
|
// no operation performed
|
||
|
|
}
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
lodash.assign = assign;
|
||
|
|
lodash.bind = bind;
|
||
|
|
lodash.compact = compact;
|
||
|
|
lodash.forEach = forEach;
|
||
|
|
lodash.forIn = forIn;
|
||
|
|
lodash.forOwn = forOwn;
|
||
|
|
lodash.keys = keys;
|
||
|
|
lodash.merge = merge;
|
||
|
|
|
||
|
|
lodash.each = forEach;
|
||
|
|
lodash.extend = assign;
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
// add functions that return unwrapped values when chaining
|
||
|
|
lodash.clone = clone;
|
||
|
|
lodash.identity = identity;
|
||
|
|
lodash.isArguments = isArguments;
|
||
|
|
lodash.isArray = isArray;
|
||
|
|
lodash.isEmpty = isEmpty;
|
||
|
|
lodash.isFunction = isFunction;
|
||
|
|
lodash.isObject = isObject;
|
||
|
|
lodash.isPlainObject = isPlainObject;
|
||
|
|
lodash.isString = isString;
|
||
|
|
lodash.noop = noop;
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The semantic version number.
|
||
|
|
*
|
||
|
|
* @static
|
||
|
|
* @memberOf _
|
||
|
|
* @type string
|
||
|
|
*/
|
||
|
|
lodash.VERSION = '2.4.1';
|
||
|
|
|
||
|
|
/*--------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
if (freeExports && freeModule) {
|
||
|
|
// in Node.js or RingoJS
|
||
|
|
if (moduleExports) {
|
||
|
|
(freeModule.exports = lodash)._ = lodash;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}.call(this));
|