]> code.delx.au - gnu-emacs-elpa/blob - benchmark/fixtures/lodash-2.4.1.js
Trivial cleanup.
[gnu-emacs-elpa] / benchmark / fixtures / lodash-2.4.1.js
1 /**
2 * @license
3 * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
4 * Build: `lodash modern -o ./dist/lodash.js`
5 * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
6 * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
7 * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8 * Available under MIT license <http://lodash.com/license>
9 */
10 ;(function() {
11
12 /** Used as a safe reference for `undefined` in pre ES5 environments */
13 var undefined;
14
15 /** Used to pool arrays and objects used internally */
16 var arrayPool = [],
17 objectPool = [];
18
19 /** Used to generate unique IDs */
20 var idCounter = 0;
21
22 /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
23 var keyPrefix = +new Date + '';
24
25 /** Used as the size when optimizations are enabled for large arrays */
26 var largeArraySize = 75;
27
28 /** Used as the max size of the `arrayPool` and `objectPool` */
29 var maxPoolSize = 40;
30
31 /** Used to detect and test whitespace */
32 var whitespace = (
33 // whitespace
34 ' \t\x0B\f\xA0\ufeff' +
35
36 // line terminators
37 '\n\r\u2028\u2029' +
38
39 // unicode category "Zs" space separators
40 '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
41 );
42
43 /** Used to match empty string literals in compiled template source */
44 var reEmptyStringLeading = /\b__p \+= '';/g,
45 reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
46 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
47
48 /**
49 * Used to match ES6 template delimiters
50 * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
51 */
52 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
53
54 /** Used to match regexp flags from their coerced string values */
55 var reFlags = /\w*$/;
56
57 /** Used to detected named functions */
58 var reFuncName = /^\s*function[ \n\r\t]+\w/;
59
60 /** Used to match "interpolate" template delimiters */
61 var reInterpolate = /<%=([\s\S]+?)%>/g;
62
63 /** Used to match leading whitespace and zeros to be removed */
64 var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
65
66 /** Used to ensure capturing order of template delimiters */
67 var reNoMatch = /($^)/;
68
69 /** Used to detect functions containing a `this` reference */
70 var reThis = /\bthis\b/;
71
72 /** Used to match unescaped characters in compiled string literals */
73 var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
74
75 /** Used to assign default `context` object properties */
76 var contextProps = [
77 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
78 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
79 'parseInt', 'setTimeout'
80 ];
81
82 /** Used to make template sourceURLs easier to identify */
83 var templateCounter = 0;
84
85 /** `Object#toString` result shortcuts */
86 var argsClass = '[object Arguments]',
87 arrayClass = '[object Array]',
88 boolClass = '[object Boolean]',
89 dateClass = '[object Date]',
90 funcClass = '[object Function]',
91 numberClass = '[object Number]',
92 objectClass = '[object Object]',
93 regexpClass = '[object RegExp]',
94 stringClass = '[object String]';
95
96 /** Used to identify object classifications that `_.clone` supports */
97 var cloneableClasses = {};
98 cloneableClasses[funcClass] = false;
99 cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
100 cloneableClasses[boolClass] = cloneableClasses[dateClass] =
101 cloneableClasses[numberClass] = cloneableClasses[objectClass] =
102 cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
103
104 /** Used as an internal `_.debounce` options object */
105 var debounceOptions = {
106 'leading': false,
107 'maxWait': 0,
108 'trailing': false
109 };
110
111 /** Used as the property descriptor for `__bindData__` */
112 var descriptor = {
113 'configurable': false,
114 'enumerable': false,
115 'value': null,
116 'writable': false
117 };
118
119 /** Used to determine if values are of the language type Object */
120 var objectTypes = {
121 'boolean': false,
122 'function': true,
123 'object': true,
124 'number': false,
125 'string': false,
126 'undefined': false
127 };
128
129 /** Used to escape characters for inclusion in compiled string literals */
130 var stringEscapes = {
131 '\\': '\\',
132 "'": "'",
133 '\n': 'n',
134 '\r': 'r',
135 '\t': 't',
136 '\u2028': 'u2028',
137 '\u2029': 'u2029'
138 };
139
140 /** Used as a reference to the global object */
141 var root = (objectTypes[typeof window] && window) || this;
142
143 /** Detect free variable `exports` */
144 var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
145
146 /** Detect free variable `module` */
147 var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
148
149 /** Detect the popular CommonJS extension `module.exports` */
150 var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
151
152 /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
153 var freeGlobal = objectTypes[typeof global] && global;
154 if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
155 root = freeGlobal;
156 }
157
158 /*--------------------------------------------------------------------------*/
159
160 /**
161 * The base implementation of `_.indexOf` without support for binary searches
162 * or `fromIndex` constraints.
163 *
164 * @private
165 * @param {Array} array The array to search.
166 * @param {*} value The value to search for.
167 * @param {number} [fromIndex=0] The index to search from.
168 * @returns {number} Returns the index of the matched value or `-1`.
169 */
170 function baseIndexOf(array, value, fromIndex) {
171 var index = (fromIndex || 0) - 1,
172 length = array ? array.length : 0;
173
174 while (++index < length) {
175 if (array[index] === value) {
176 return index;
177 }
178 }
179 return -1;
180 }
181
182 /**
183 * An implementation of `_.contains` for cache objects that mimics the return
184 * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
185 *
186 * @private
187 * @param {Object} cache The cache object to inspect.
188 * @param {*} value The value to search for.
189 * @returns {number} Returns `0` if `value` is found, else `-1`.
190 */
191 function cacheIndexOf(cache, value) {
192 var type = typeof value;
193 cache = cache.cache;
194
195 if (type == 'boolean' || value == null) {
196 return cache[value] ? 0 : -1;
197 }
198 if (type != 'number' && type != 'string') {
199 type = 'object';
200 }
201 var key = type == 'number' ? value : keyPrefix + value;
202 cache = (cache = cache[type]) && cache[key];
203
204 return type == 'object'
205 ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
206 : (cache ? 0 : -1);
207 }
208
209 /**
210 * Adds a given value to the corresponding cache object.
211 *
212 * @private
213 * @param {*} value The value to add to the cache.
214 */
215 function cachePush(value) {
216 var cache = this.cache,
217 type = typeof value;
218
219 if (type == 'boolean' || value == null) {
220 cache[value] = true;
221 } else {
222 if (type != 'number' && type != 'string') {
223 type = 'object';
224 }
225 var key = type == 'number' ? value : keyPrefix + value,
226 typeCache = cache[type] || (cache[type] = {});
227
228 if (type == 'object') {
229 (typeCache[key] || (typeCache[key] = [])).push(value);
230 } else {
231 typeCache[key] = true;
232 }
233 }
234 }
235
236 /**
237 * Used by `_.max` and `_.min` as the default callback when a given
238 * collection is a string value.
239 *
240 * @private
241 * @param {string} value The character to inspect.
242 * @returns {number} Returns the code unit of given character.
243 */
244 function charAtCallback(value) {
245 return value.charCodeAt(0);
246 }
247
248 /**
249 * Used by `sortBy` to compare transformed `collection` elements, stable sorting
250 * them in ascending order.
251 *
252 * @private
253 * @param {Object} a The object to compare to `b`.
254 * @param {Object} b The object to compare to `a`.
255 * @returns {number} Returns the sort order indicator of `1` or `-1`.
256 */
257 function compareAscending(a, b) {
258 var ac = a.criteria,
259 bc = b.criteria,
260 index = -1,
261 length = ac.length;
262
263 while (++index < length) {
264 var value = ac[index],
265 other = bc[index];
266
267 if (value !== other) {
268 if (value > other || typeof value == 'undefined') {
269 return 1;
270 }
271 if (value < other || typeof other == 'undefined') {
272 return -1;
273 }
274 }
275 }
276 // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
277 // that causes it, under certain circumstances, to return the same value for
278 // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
279 //
280 // This also ensures a stable sort in V8 and other engines.
281 // See http://code.google.com/p/v8/issues/detail?id=90
282 return a.index - b.index;
283 }
284
285 /**
286 * Creates a cache object to optimize linear searches of large arrays.
287 *
288 * @private
289 * @param {Array} [array=[]] The array to search.
290 * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
291 */
292 function createCache(array) {
293 var index = -1,
294 length = array.length,
295 first = array[0],
296 mid = array[(length / 2) | 0],
297 last = array[length - 1];
298
299 if (first && typeof first == 'object' &&
300 mid && typeof mid == 'object' && last && typeof last == 'object') {
301 return false;
302 }
303 var cache = getObject();
304 cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
305
306 var result = getObject();
307 result.array = array;
308 result.cache = cache;
309 result.push = cachePush;
310
311 while (++index < length) {
312 result.push(array[index]);
313 }
314 return result;
315 }
316
317 /**
318 * Used by `template` to escape characters for inclusion in compiled
319 * string literals.
320 *
321 * @private
322 * @param {string} match The matched character to escape.
323 * @returns {string} Returns the escaped character.
324 */
325 function escapeStringChar(match) {
326 return '\\' + stringEscapes[match];
327 }
328
329 /**
330 * Gets an array from the array pool or creates a new one if the pool is empty.
331 *
332 * @private
333 * @returns {Array} The array from the pool.
334 */
335 function getArray() {
336 return arrayPool.pop() || [];
337 }
338
339 /**
340 * Gets an object from the object pool or creates a new one if the pool is empty.
341 *
342 * @private
343 * @returns {Object} The object from the pool.
344 */
345 function getObject() {
346 return objectPool.pop() || {
347 'array': null,
348 'cache': null,
349 'criteria': null,
350 'false': false,
351 'index': 0,
352 'null': false,
353 'number': null,
354 'object': null,
355 'push': null,
356 'string': null,
357 'true': false,
358 'undefined': false,
359 'value': null
360 };
361 }
362
363 /**
364 * Releases the given array back to the array pool.
365 *
366 * @private
367 * @param {Array} [array] The array to release.
368 */
369 function releaseArray(array) {
370 array.length = 0;
371 if (arrayPool.length < maxPoolSize) {
372 arrayPool.push(array);
373 }
374 }
375
376 /**
377 * Releases the given object back to the object pool.
378 *
379 * @private
380 * @param {Object} [object] The object to release.
381 */
382 function releaseObject(object) {
383 var cache = object.cache;
384 if (cache) {
385 releaseObject(cache);
386 }
387 object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
388 if (objectPool.length < maxPoolSize) {
389 objectPool.push(object);
390 }
391 }
392
393 /**
394 * Slices the `collection` from the `start` index up to, but not including,
395 * the `end` index.
396 *
397 * Note: This function is used instead of `Array#slice` to support node lists
398 * in IE < 9 and to ensure dense arrays are returned.
399 *
400 * @private
401 * @param {Array|Object|string} collection The collection to slice.
402 * @param {number} start The start index.
403 * @param {number} end The end index.
404 * @returns {Array} Returns the new array.
405 */
406 function slice(array, start, end) {
407 start || (start = 0);
408 if (typeof end == 'undefined') {
409 end = array ? array.length : 0;
410 }
411 var index = -1,
412 length = end - start || 0,
413 result = Array(length < 0 ? 0 : length);
414
415 while (++index < length) {
416 result[index] = array[start + index];
417 }
418 return result;
419 }
420
421 /*--------------------------------------------------------------------------*/
422
423 /**
424 * Create a new `lodash` function using the given context object.
425 *
426 * @static
427 * @memberOf _
428 * @category Utilities
429 * @param {Object} [context=root] The context object.
430 * @returns {Function} Returns the `lodash` function.
431 */
432 function runInContext(context) {
433 // Avoid issues with some ES3 environments that attempt to use values, named
434 // after built-in constructors like `Object`, for the creation of literals.
435 // ES5 clears this up by stating that literals must use built-in constructors.
436 // See http://es5.github.io/#x11.1.5.
437 context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
438
439 /** Native constructor references */
440 var Array = context.Array,
441 Boolean = context.Boolean,
442 Date = context.Date,
443 Function = context.Function,
444 Math = context.Math,
445 Number = context.Number,
446 Object = context.Object,
447 RegExp = context.RegExp,
448 String = context.String,
449 TypeError = context.TypeError;
450
451 /**
452 * Used for `Array` method references.
453 *
454 * Normally `Array.prototype` would suffice, however, using an array literal
455 * avoids issues in Narwhal.
456 */
457 var arrayRef = [];
458
459 /** Used for native method references */
460 var objectProto = Object.prototype;
461
462 /** Used to restore the original `_` reference in `noConflict` */
463 var oldDash = context._;
464
465 /** Used to resolve the internal [[Class]] of values */
466 var toString = objectProto.toString;
467
468 /** Used to detect if a method is native */
469 var reNative = RegExp('^' +
470 String(toString)
471 .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
472 .replace(/toString| for [^\]]+/g, '.*?') + '$'
473 );
474
475 /** Native method shortcuts */
476 var ceil = Math.ceil,
477 clearTimeout = context.clearTimeout,
478 floor = Math.floor,
479 fnToString = Function.prototype.toString,
480 getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
481 hasOwnProperty = objectProto.hasOwnProperty,
482 push = arrayRef.push,
483 setTimeout = context.setTimeout,
484 splice = arrayRef.splice,
485 unshift = arrayRef.unshift;
486
487 /** Used to set meta data on functions */
488 var defineProperty = (function() {
489 // IE 8 only accepts DOM elements
490 try {
491 var o = {},
492 func = isNative(func = Object.defineProperty) && func,
493 result = func(o, o, o) && func;
494 } catch(e) { }
495 return result;
496 }());
497
498 /* Native method shortcuts for methods with the same name as other `lodash` methods */
499 var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
500 nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
501 nativeIsFinite = context.isFinite,
502 nativeIsNaN = context.isNaN,
503 nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
504 nativeMax = Math.max,
505 nativeMin = Math.min,
506 nativeParseInt = context.parseInt,
507 nativeRandom = Math.random;
508
509 /** Used to lookup a built-in constructor by [[Class]] */
510 var ctorByClass = {};
511 ctorByClass[arrayClass] = Array;
512 ctorByClass[boolClass] = Boolean;
513 ctorByClass[dateClass] = Date;
514 ctorByClass[funcClass] = Function;
515 ctorByClass[objectClass] = Object;
516 ctorByClass[numberClass] = Number;
517 ctorByClass[regexpClass] = RegExp;
518 ctorByClass[stringClass] = String;
519
520 /*--------------------------------------------------------------------------*/
521
522 /**
523 * Creates a `lodash` object which wraps the given value to enable intuitive
524 * method chaining.
525 *
526 * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
527 * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
528 * and `unshift`
529 *
530 * Chaining is supported in custom builds as long as the `value` method is
531 * implicitly or explicitly included in the build.
532 *
533 * The chainable wrapper functions are:
534 * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
535 * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
536 * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
537 * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
538 * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
539 * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
540 * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
541 * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
542 * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
543 * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
544 * and `zip`
545 *
546 * The non-chainable wrapper functions are:
547 * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
548 * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
549 * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
550 * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
551 * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
552 * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
553 * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
554 * `template`, `unescape`, `uniqueId`, and `value`
555 *
556 * The wrapper functions `first` and `last` return wrapped values when `n` is
557 * provided, otherwise they return unwrapped values.
558 *
559 * Explicit chaining can be enabled by using the `_.chain` method.
560 *
561 * @name _
562 * @constructor
563 * @category Chaining
564 * @param {*} value The value to wrap in a `lodash` instance.
565 * @returns {Object} Returns a `lodash` instance.
566 * @example
567 *
568 * var wrapped = _([1, 2, 3]);
569 *
570 * // returns an unwrapped value
571 * wrapped.reduce(function(sum, num) {
572 * return sum + num;
573 * });
574 * // => 6
575 *
576 * // returns a wrapped value
577 * var squares = wrapped.map(function(num) {
578 * return num * num;
579 * });
580 *
581 * _.isArray(squares);
582 * // => false
583 *
584 * _.isArray(squares.value());
585 * // => true
586 */
587 function lodash(value) {
588 // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
589 return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
590 ? value
591 : new lodashWrapper(value);
592 }
593
594 /**
595 * A fast path for creating `lodash` wrapper objects.
596 *
597 * @private
598 * @param {*} value The value to wrap in a `lodash` instance.
599 * @param {boolean} chainAll A flag to enable chaining for all methods
600 * @returns {Object} Returns a `lodash` instance.
601 */
602 function lodashWrapper(value, chainAll) {
603 this.__chain__ = !!chainAll;
604 this.__wrapped__ = value;
605 }
606 // ensure `new lodashWrapper` is an instance of `lodash`
607 lodashWrapper.prototype = lodash.prototype;
608
609 /**
610 * An object used to flag environments features.
611 *
612 * @static
613 * @memberOf _
614 * @type Object
615 */
616 var support = lodash.support = {};
617
618 /**
619 * Detect if functions can be decompiled by `Function#toString`
620 * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
621 *
622 * @memberOf _.support
623 * @type boolean
624 */
625 support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
626
627 /**
628 * Detect if `Function#name` is supported (all but IE).
629 *
630 * @memberOf _.support
631 * @type boolean
632 */
633 support.funcNames = typeof Function.name == 'string';
634
635 /**
636 * By default, the template delimiters used by Lo-Dash are similar to those in
637 * embedded Ruby (ERB). Change the following template settings to use alternative
638 * delimiters.
639 *
640 * @static
641 * @memberOf _
642 * @type Object
643 */
644 lodash.templateSettings = {
645
646 /**
647 * Used to detect `data` property values to be HTML-escaped.
648 *
649 * @memberOf _.templateSettings
650 * @type RegExp
651 */
652 'escape': /<%-([\s\S]+?)%>/g,
653
654 /**
655 * Used to detect code to be evaluated.
656 *
657 * @memberOf _.templateSettings
658 * @type RegExp
659 */
660 'evaluate': /<%([\s\S]+?)%>/g,
661
662 /**
663 * Used to detect `data` property values to inject.
664 *
665 * @memberOf _.templateSettings
666 * @type RegExp
667 */
668 'interpolate': reInterpolate,
669
670 /**
671 * Used to reference the data object in the template text.
672 *
673 * @memberOf _.templateSettings
674 * @type string
675 */
676 'variable': '',
677
678 /**
679 * Used to import variables into the compiled template.
680 *
681 * @memberOf _.templateSettings
682 * @type Object
683 */
684 'imports': {
685
686 /**
687 * A reference to the `lodash` function.
688 *
689 * @memberOf _.templateSettings.imports
690 * @type Function
691 */
692 '_': lodash
693 }
694 };
695
696 /*--------------------------------------------------------------------------*/
697
698 /**
699 * The base implementation of `_.bind` that creates the bound function and
700 * sets its meta data.
701 *
702 * @private
703 * @param {Array} bindData The bind data array.
704 * @returns {Function} Returns the new bound function.
705 */
706 function baseBind(bindData) {
707 var func = bindData[0],
708 partialArgs = bindData[2],
709 thisArg = bindData[4];
710
711 function bound() {
712 // `Function#bind` spec
713 // http://es5.github.io/#x15.3.4.5
714 if (partialArgs) {
715 // avoid `arguments` object deoptimizations by using `slice` instead
716 // of `Array.prototype.slice.call` and not assigning `arguments` to a
717 // variable as a ternary expression
718 var args = slice(partialArgs);
719 push.apply(args, arguments);
720 }
721 // mimic the constructor's `return` behavior
722 // http://es5.github.io/#x13.2.2
723 if (this instanceof bound) {
724 // ensure `new bound` is an instance of `func`
725 var thisBinding = baseCreate(func.prototype),
726 result = func.apply(thisBinding, args || arguments);
727 return isObject(result) ? result : thisBinding;
728 }
729 return func.apply(thisArg, args || arguments);
730 }
731 setBindData(bound, bindData);
732 return bound;
733 }
734
735 /**
736 * The base implementation of `_.clone` without argument juggling or support
737 * for `thisArg` binding.
738 *
739 * @private
740 * @param {*} value The value to clone.
741 * @param {boolean} [isDeep=false] Specify a deep clone.
742 * @param {Function} [callback] The function to customize cloning values.
743 * @param {Array} [stackA=[]] Tracks traversed source objects.
744 * @param {Array} [stackB=[]] Associates clones with source counterparts.
745 * @returns {*} Returns the cloned value.
746 */
747 function baseClone(value, isDeep, callback, stackA, stackB) {
748 if (callback) {
749 var result = callback(value);
750 if (typeof result != 'undefined') {
751 return result;
752 }
753 }
754 // inspect [[Class]]
755 var isObj = isObject(value);
756 if (isObj) {
757 var className = toString.call(value);
758 if (!cloneableClasses[className]) {
759 return value;
760 }
761 var ctor = ctorByClass[className];
762 switch (className) {
763 case boolClass:
764 case dateClass:
765 return new ctor(+value);
766
767 case numberClass:
768 case stringClass:
769 return new ctor(value);
770
771 case regexpClass:
772 result = ctor(value.source, reFlags.exec(value));
773 result.lastIndex = value.lastIndex;
774 return result;
775 }
776 } else {
777 return value;
778 }
779 var isArr = isArray(value);
780 if (isDeep) {
781 // check for circular references and return corresponding clone
782 var initedStack = !stackA;
783 stackA || (stackA = getArray());
784 stackB || (stackB = getArray());
785
786 var length = stackA.length;
787 while (length--) {
788 if (stackA[length] == value) {
789 return stackB[length];
790 }
791 }
792 result = isArr ? ctor(value.length) : {};
793 }
794 else {
795 result = isArr ? slice(value) : assign({}, value);
796 }
797 // add array properties assigned by `RegExp#exec`
798 if (isArr) {
799 if (hasOwnProperty.call(value, 'index')) {
800 result.index = value.index;
801 }
802 if (hasOwnProperty.call(value, 'input')) {
803 result.input = value.input;
804 }
805 }
806 // exit for shallow clone
807 if (!isDeep) {
808 return result;
809 }
810 // add the source value to the stack of traversed objects
811 // and associate it with its clone
812 stackA.push(value);
813 stackB.push(result);
814
815 // recursively populate clone (susceptible to call stack limits)
816 (isArr ? forEach : forOwn)(value, function(objValue, key) {
817 result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
818 });
819
820 if (initedStack) {
821 releaseArray(stackA);
822 releaseArray(stackB);
823 }
824 return result;
825 }
826
827 /**
828 * The base implementation of `_.create` without support for assigning
829 * properties to the created object.
830 *
831 * @private
832 * @param {Object} prototype The object to inherit from.
833 * @returns {Object} Returns the new object.
834 */
835 function baseCreate(prototype, properties) {
836 return isObject(prototype) ? nativeCreate(prototype) : {};
837 }
838 // fallback for browsers without `Object.create`
839 if (!nativeCreate) {
840 baseCreate = (function() {
841 function Object() {}
842 return function(prototype) {
843 if (isObject(prototype)) {
844 Object.prototype = prototype;
845 var result = new Object;
846 Object.prototype = null;
847 }
848 return result || context.Object();
849 };
850 }());
851 }
852
853 /**
854 * The base implementation of `_.createCallback` without support for creating
855 * "_.pluck" or "_.where" style callbacks.
856 *
857 * @private
858 * @param {*} [func=identity] The value to convert to a callback.
859 * @param {*} [thisArg] The `this` binding of the created callback.
860 * @param {number} [argCount] The number of arguments the callback accepts.
861 * @returns {Function} Returns a callback function.
862 */
863 function baseCreateCallback(func, thisArg, argCount) {
864 if (typeof func != 'function') {
865 return identity;
866 }
867 // exit early for no `thisArg` or already bound by `Function#bind`
868 if (typeof thisArg == 'undefined' || !('prototype' in func)) {
869 return func;
870 }
871 var bindData = func.__bindData__;
872 if (typeof bindData == 'undefined') {
873 if (support.funcNames) {
874 bindData = !func.name;
875 }
876 bindData = bindData || !support.funcDecomp;
877 if (!bindData) {
878 var source = fnToString.call(func);
879 if (!support.funcNames) {
880 bindData = !reFuncName.test(source);
881 }
882 if (!bindData) {
883 // checks if `func` references the `this` keyword and stores the result
884 bindData = reThis.test(source);
885 setBindData(func, bindData);
886 }
887 }
888 }
889 // exit early if there are no `this` references or `func` is bound
890 if (bindData === false || (bindData !== true && bindData[1] & 1)) {
891 return func;
892 }
893 switch (argCount) {
894 case 1: return function(value) {
895 return func.call(thisArg, value);
896 };
897 case 2: return function(a, b) {
898 return func.call(thisArg, a, b);
899 };
900 case 3: return function(value, index, collection) {
901 return func.call(thisArg, value, index, collection);
902 };
903 case 4: return function(accumulator, value, index, collection) {
904 return func.call(thisArg, accumulator, value, index, collection);
905 };
906 }
907 return bind(func, thisArg);
908 }
909
910 /**
911 * The base implementation of `createWrapper` that creates the wrapper and
912 * sets its meta data.
913 *
914 * @private
915 * @param {Array} bindData The bind data array.
916 * @returns {Function} Returns the new function.
917 */
918 function baseCreateWrapper(bindData) {
919 var func = bindData[0],
920 bitmask = bindData[1],
921 partialArgs = bindData[2],
922 partialRightArgs = bindData[3],
923 thisArg = bindData[4],
924 arity = bindData[5];
925
926 var isBind = bitmask & 1,
927 isBindKey = bitmask & 2,
928 isCurry = bitmask & 4,
929 isCurryBound = bitmask & 8,
930 key = func;
931
932 function bound() {
933 var thisBinding = isBind ? thisArg : this;
934 if (partialArgs) {
935 var args = slice(partialArgs);
936 push.apply(args, arguments);
937 }
938 if (partialRightArgs || isCurry) {
939 args || (args = slice(arguments));
940 if (partialRightArgs) {
941 push.apply(args, partialRightArgs);
942 }
943 if (isCurry && args.length < arity) {
944 bitmask |= 16 & ~32;
945 return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
946 }
947 }
948 args || (args = arguments);
949 if (isBindKey) {
950 func = thisBinding[key];
951 }
952 if (this instanceof bound) {
953 thisBinding = baseCreate(func.prototype);
954 var result = func.apply(thisBinding, args);
955 return isObject(result) ? result : thisBinding;
956 }
957 return func.apply(thisBinding, args);
958 }
959 setBindData(bound, bindData);
960 return bound;
961 }
962
963 /**
964 * The base implementation of `_.difference` that accepts a single array
965 * of values to exclude.
966 *
967 * @private
968 * @param {Array} array The array to process.
969 * @param {Array} [values] The array of values to exclude.
970 * @returns {Array} Returns a new array of filtered values.
971 */
972 function baseDifference(array, values) {
973 var index = -1,
974 indexOf = getIndexOf(),
975 length = array ? array.length : 0,
976 isLarge = length >= largeArraySize && indexOf === baseIndexOf,
977 result = [];
978
979 if (isLarge) {
980 var cache = createCache(values);
981 if (cache) {
982 indexOf = cacheIndexOf;
983 values = cache;
984 } else {
985 isLarge = false;
986 }
987 }
988 while (++index < length) {
989 var value = array[index];
990 if (indexOf(values, value) < 0) {
991 result.push(value);
992 }
993 }
994 if (isLarge) {
995 releaseObject(values);
996 }
997 return result;
998 }
999
1000 /**
1001 * The base implementation of `_.flatten` without support for callback
1002 * shorthands or `thisArg` binding.
1003 *
1004 * @private
1005 * @param {Array} array The array to flatten.
1006 * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
1007 * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
1008 * @param {number} [fromIndex=0] The index to start from.
1009 * @returns {Array} Returns a new flattened array.
1010 */
1011 function baseFlatten(array, isShallow, isStrict, fromIndex) {
1012 var index = (fromIndex || 0) - 1,
1013 length = array ? array.length : 0,
1014 result = [];
1015
1016 while (++index < length) {
1017 var value = array[index];
1018
1019 if (value && typeof value == 'object' && typeof value.length == 'number'
1020 && (isArray(value) || isArguments(value))) {
1021 // recursively flatten arrays (susceptible to call stack limits)
1022 if (!isShallow) {
1023 value = baseFlatten(value, isShallow, isStrict);
1024 }
1025 var valIndex = -1,
1026 valLength = value.length,
1027 resIndex = result.length;
1028
1029 result.length += valLength;
1030 while (++valIndex < valLength) {
1031 result[resIndex++] = value[valIndex];
1032 }
1033 } else if (!isStrict) {
1034 result.push(value);
1035 }
1036 }
1037 return result;
1038 }
1039
1040 /**
1041 * The base implementation of `_.isEqual`, without support for `thisArg` binding,
1042 * that allows partial "_.where" style comparisons.
1043 *
1044 * @private
1045 * @param {*} a The value to compare.
1046 * @param {*} b The other value to compare.
1047 * @param {Function} [callback] The function to customize comparing values.
1048 * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
1049 * @param {Array} [stackA=[]] Tracks traversed `a` objects.
1050 * @param {Array} [stackB=[]] Tracks traversed `b` objects.
1051 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
1052 */
1053 function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
1054 // used to indicate that when comparing objects, `a` has at least the properties of `b`
1055 if (callback) {
1056 var result = callback(a, b);
1057 if (typeof result != 'undefined') {
1058 return !!result;
1059 }
1060 }
1061 // exit early for identical values
1062 if (a === b) {
1063 // treat `+0` vs. `-0` as not equal
1064 return a !== 0 || (1 / a == 1 / b);
1065 }
1066 var type = typeof a,
1067 otherType = typeof b;
1068
1069 // exit early for unlike primitive values
1070 if (a === a &&
1071 !(a && objectTypes[type]) &&
1072 !(b && objectTypes[otherType])) {
1073 return false;
1074 }
1075 // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
1076 // http://es5.github.io/#x15.3.4.4
1077 if (a == null || b == null) {
1078 return a === b;
1079 }
1080 // compare [[Class]] names
1081 var className = toString.call(a),
1082 otherClass = toString.call(b);
1083
1084 if (className == argsClass) {
1085 className = objectClass;
1086 }
1087 if (otherClass == argsClass) {
1088 otherClass = objectClass;
1089 }
1090 if (className != otherClass) {
1091 return false;
1092 }
1093 switch (className) {
1094 case boolClass:
1095 case dateClass:
1096 // coerce dates and booleans to numbers, dates to milliseconds and booleans
1097 // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
1098 return +a == +b;
1099
1100 case numberClass:
1101 // treat `NaN` vs. `NaN` as equal
1102 return (a != +a)
1103 ? b != +b
1104 // but treat `+0` vs. `-0` as not equal
1105 : (a == 0 ? (1 / a == 1 / b) : a == +b);
1106
1107 case regexpClass:
1108 case stringClass:
1109 // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
1110 // treat string primitives and their corresponding object instances as equal
1111 return a == String(b);
1112 }
1113 var isArr = className == arrayClass;
1114 if (!isArr) {
1115 // unwrap any `lodash` wrapped values
1116 var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
1117 bWrapped = hasOwnProperty.call(b, '__wrapped__');
1118
1119 if (aWrapped || bWrapped) {
1120 return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
1121 }
1122 // exit for functions and DOM nodes
1123 if (className != objectClass) {
1124 return false;
1125 }
1126 // in older versions of Opera, `arguments` objects have `Array` constructors
1127 var ctorA = a.constructor,
1128 ctorB = b.constructor;
1129
1130 // non `Object` object instances with different constructors are not equal
1131 if (ctorA != ctorB &&
1132 !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
1133 ('constructor' in a && 'constructor' in b)
1134 ) {
1135 return false;
1136 }
1137 }
1138 // assume cyclic structures are equal
1139 // the algorithm for detecting cyclic structures is adapted from ES 5.1
1140 // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
1141 var initedStack = !stackA;
1142 stackA || (stackA = getArray());
1143 stackB || (stackB = getArray());
1144
1145 var length = stackA.length;
1146 while (length--) {
1147 if (stackA[length] == a) {
1148 return stackB[length] == b;
1149 }
1150 }
1151 var size = 0;
1152 result = true;
1153
1154 // add `a` and `b` to the stack of traversed objects
1155 stackA.push(a);
1156 stackB.push(b);
1157
1158 // recursively compare objects and arrays (susceptible to call stack limits)
1159 if (isArr) {
1160 // compare lengths to determine if a deep comparison is necessary
1161 length = a.length;
1162 size = b.length;
1163 result = size == length;
1164
1165 if (result || isWhere) {
1166 // deep compare the contents, ignoring non-numeric properties
1167 while (size--) {
1168 var index = length,
1169 value = b[size];
1170
1171 if (isWhere) {
1172 while (index--) {
1173 if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
1174 break;
1175 }
1176 }
1177 } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
1178 break;
1179 }
1180 }
1181 }
1182 }
1183 else {
1184 // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
1185 // which, in this case, is more costly
1186 forIn(b, function(value, key, b) {
1187 if (hasOwnProperty.call(b, key)) {
1188 // count the number of properties.
1189 size++;
1190 // deep compare each property value.
1191 return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
1192 }
1193 });
1194
1195 if (result && !isWhere) {
1196 // ensure both objects have the same number of properties
1197 forIn(a, function(value, key, a) {
1198 if (hasOwnProperty.call(a, key)) {
1199 // `size` will be `-1` if `a` has more properties than `b`
1200 return (result = --size > -1);
1201 }
1202 });
1203 }
1204 }
1205 stackA.pop();
1206 stackB.pop();
1207
1208 if (initedStack) {
1209 releaseArray(stackA);
1210 releaseArray(stackB);
1211 }
1212 return result;
1213 }
1214
1215 /**
1216 * The base implementation of `_.merge` without argument juggling or support
1217 * for `thisArg` binding.
1218 *
1219 * @private
1220 * @param {Object} object The destination object.
1221 * @param {Object} source The source object.
1222 * @param {Function} [callback] The function to customize merging properties.
1223 * @param {Array} [stackA=[]] Tracks traversed source objects.
1224 * @param {Array} [stackB=[]] Associates values with source counterparts.
1225 */
1226 function baseMerge(object, source, callback, stackA, stackB) {
1227 (isArray(source) ? forEach : forOwn)(source, function(source, key) {
1228 var found,
1229 isArr,
1230 result = source,
1231 value = object[key];
1232
1233 if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
1234 // avoid merging previously merged cyclic sources
1235 var stackLength = stackA.length;
1236 while (stackLength--) {
1237 if ((found = stackA[stackLength] == source)) {
1238 value = stackB[stackLength];
1239 break;
1240 }
1241 }
1242 if (!found) {
1243 var isShallow;
1244 if (callback) {
1245 result = callback(value, source);
1246 if ((isShallow = typeof result != 'undefined')) {
1247 value = result;
1248 }
1249 }
1250 if (!isShallow) {
1251 value = isArr
1252 ? (isArray(value) ? value : [])
1253 : (isPlainObject(value) ? value : {});
1254 }
1255 // add `source` and associated `value` to the stack of traversed objects
1256 stackA.push(source);
1257 stackB.push(value);
1258
1259 // recursively merge objects and arrays (susceptible to call stack limits)
1260 if (!isShallow) {
1261 baseMerge(value, source, callback, stackA, stackB);
1262 }
1263 }
1264 }
1265 else {
1266 if (callback) {
1267 result = callback(value, source);
1268 if (typeof result == 'undefined') {
1269 result = source;
1270 }
1271 }
1272 if (typeof result != 'undefined') {
1273 value = result;
1274 }
1275 }
1276 object[key] = value;
1277 });
1278 }
1279
1280 /**
1281 * The base implementation of `_.random` without argument juggling or support
1282 * for returning floating-point numbers.
1283 *
1284 * @private
1285 * @param {number} min The minimum possible value.
1286 * @param {number} max The maximum possible value.
1287 * @returns {number} Returns a random number.
1288 */
1289 function baseRandom(min, max) {
1290 return min + floor(nativeRandom() * (max - min + 1));
1291 }
1292
1293 /**
1294 * The base implementation of `_.uniq` without support for callback shorthands
1295 * or `thisArg` binding.
1296 *
1297 * @private
1298 * @param {Array} array The array to process.
1299 * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
1300 * @param {Function} [callback] The function called per iteration.
1301 * @returns {Array} Returns a duplicate-value-free array.
1302 */
1303 function baseUniq(array, isSorted, callback) {
1304 var index = -1,
1305 indexOf = getIndexOf(),
1306 length = array ? array.length : 0,
1307 result = [];
1308
1309 var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
1310 seen = (callback || isLarge) ? getArray() : result;
1311
1312 if (isLarge) {
1313 var cache = createCache(seen);
1314 indexOf = cacheIndexOf;
1315 seen = cache;
1316 }
1317 while (++index < length) {
1318 var value = array[index],
1319 computed = callback ? callback(value, index, array) : value;
1320
1321 if (isSorted
1322 ? !index || seen[seen.length - 1] !== computed
1323 : indexOf(seen, computed) < 0
1324 ) {
1325 if (callback || isLarge) {
1326 seen.push(computed);
1327 }
1328 result.push(value);
1329 }
1330 }
1331 if (isLarge) {
1332 releaseArray(seen.array);
1333 releaseObject(seen);
1334 } else if (callback) {
1335 releaseArray(seen);
1336 }
1337 return result;
1338 }
1339
1340 /**
1341 * Creates a function that aggregates a collection, creating an object composed
1342 * of keys generated from the results of running each element of the collection
1343 * through a callback. The given `setter` function sets the keys and values
1344 * of the composed object.
1345 *
1346 * @private
1347 * @param {Function} setter The setter function.
1348 * @returns {Function} Returns the new aggregator function.
1349 */
1350 function createAggregator(setter) {
1351 return function(collection, callback, thisArg) {
1352 var result = {};
1353 callback = lodash.createCallback(callback, thisArg, 3);
1354
1355 var index = -1,
1356 length = collection ? collection.length : 0;
1357
1358 if (typeof length == 'number') {
1359 while (++index < length) {
1360 var value = collection[index];
1361 setter(result, value, callback(value, index, collection), collection);
1362 }
1363 } else {
1364 forOwn(collection, function(value, key, collection) {
1365 setter(result, value, callback(value, key, collection), collection);
1366 });
1367 }
1368 return result;
1369 };
1370 }
1371
1372 /**
1373 * Creates a function that, when called, either curries or invokes `func`
1374 * with an optional `this` binding and partially applied arguments.
1375 *
1376 * @private
1377 * @param {Function|string} func The function or method name to reference.
1378 * @param {number} bitmask The bitmask of method flags to compose.
1379 * The bitmask may be composed of the following flags:
1380 * 1 - `_.bind`
1381 * 2 - `_.bindKey`
1382 * 4 - `_.curry`
1383 * 8 - `_.curry` (bound)
1384 * 16 - `_.partial`
1385 * 32 - `_.partialRight`
1386 * @param {Array} [partialArgs] An array of arguments to prepend to those
1387 * provided to the new function.
1388 * @param {Array} [partialRightArgs] An array of arguments to append to those
1389 * provided to the new function.
1390 * @param {*} [thisArg] The `this` binding of `func`.
1391 * @param {number} [arity] The arity of `func`.
1392 * @returns {Function} Returns the new function.
1393 */
1394 function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
1395 var isBind = bitmask & 1,
1396 isBindKey = bitmask & 2,
1397 isCurry = bitmask & 4,
1398 isCurryBound = bitmask & 8,
1399 isPartial = bitmask & 16,
1400 isPartialRight = bitmask & 32;
1401
1402 if (!isBindKey && !isFunction(func)) {
1403 throw new TypeError;
1404 }
1405 if (isPartial && !partialArgs.length) {
1406 bitmask &= ~16;
1407 isPartial = partialArgs = false;
1408 }
1409 if (isPartialRight && !partialRightArgs.length) {
1410 bitmask &= ~32;
1411 isPartialRight = partialRightArgs = false;
1412 }
1413 var bindData = func && func.__bindData__;
1414 if (bindData && bindData !== true) {
1415 // clone `bindData`
1416 bindData = slice(bindData);
1417 if (bindData[2]) {
1418 bindData[2] = slice(bindData[2]);
1419 }
1420 if (bindData[3]) {
1421 bindData[3] = slice(bindData[3]);
1422 }
1423 // set `thisBinding` is not previously bound
1424 if (isBind && !(bindData[1] & 1)) {
1425 bindData[4] = thisArg;
1426 }
1427 // set if previously bound but not currently (subsequent curried functions)
1428 if (!isBind && bindData[1] & 1) {
1429 bitmask |= 8;
1430 }
1431 // set curried arity if not yet set
1432 if (isCurry && !(bindData[1] & 4)) {
1433 bindData[5] = arity;
1434 }
1435 // append partial left arguments
1436 if (isPartial) {
1437 push.apply(bindData[2] || (bindData[2] = []), partialArgs);
1438 }
1439 // append partial right arguments
1440 if (isPartialRight) {
1441 unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
1442 }
1443 // merge flags
1444 bindData[1] |= bitmask;
1445 return createWrapper.apply(null, bindData);
1446 }
1447 // fast path for `_.bind`
1448 var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper;
1449 return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]);
1450 }
1451
1452 /**
1453 * Used by `escape` to convert characters to HTML entities.
1454 *
1455 * @private
1456 * @param {string} match The matched character to escape.
1457 * @returns {string} Returns the escaped character.
1458 */
1459 function escapeHtmlChar(match) {
1460 return htmlEscapes[match];
1461 }
1462
1463 /**
1464 * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
1465 * customized, this method returns the custom method, otherwise it returns
1466 * the `baseIndexOf` function.
1467 *
1468 * @private
1469 * @returns {Function} Returns the "indexOf" function.
1470 */
1471 function getIndexOf() {
1472 var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
1473 return result;
1474 }
1475
1476 /**
1477 * Checks if `value` is a native function.
1478 *
1479 * @private
1480 * @param {*} value The value to check.
1481 * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
1482 */
1483 function isNative(value) {
1484 return typeof value == 'function' && reNative.test(value);
1485 }
1486
1487 /**
1488 * Sets `this` binding data on a given function.
1489 *
1490 * @private
1491 * @param {Function} func The function to set data on.
1492 * @param {Array} value The data array to set.
1493 */
1494 var setBindData = !defineProperty ? noop : function(func, value) {
1495 descriptor.value = value;
1496 defineProperty(func, '__bindData__', descriptor);
1497 };
1498
1499 /**
1500 * A fallback implementation of `isPlainObject` which checks if a given value
1501 * is an object created by the `Object` constructor, assuming objects created
1502 * by the `Object` constructor have no inherited enumerable properties and that
1503 * there are no `Object.prototype` extensions.
1504 *
1505 * @private
1506 * @param {*} value The value to check.
1507 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
1508 */
1509 function shimIsPlainObject(value) {
1510 var ctor,
1511 result;
1512
1513 // avoid non Object objects, `arguments` objects, and DOM elements
1514 if (!(value && toString.call(value) == objectClass) ||
1515 (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) {
1516 return false;
1517 }
1518 // In most environments an object's own properties are iterated before
1519 // its inherited properties. If the last iterated property is an object's
1520 // own property then there are no inherited enumerable properties.
1521 forIn(value, function(value, key) {
1522 result = key;
1523 });
1524 return typeof result == 'undefined' || hasOwnProperty.call(value, result);
1525 }
1526
1527 /**
1528 * Used by `unescape` to convert HTML entities to characters.
1529 *
1530 * @private
1531 * @param {string} match The matched character to unescape.
1532 * @returns {string} Returns the unescaped character.
1533 */
1534 function unescapeHtmlChar(match) {
1535 return htmlUnescapes[match];
1536 }
1537
1538 /*--------------------------------------------------------------------------*/
1539
1540 /**
1541 * Checks if `value` is an `arguments` object.
1542 *
1543 * @static
1544 * @memberOf _
1545 * @category Objects
1546 * @param {*} value The value to check.
1547 * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
1548 * @example
1549 *
1550 * (function() { return _.isArguments(arguments); })(1, 2, 3);
1551 * // => true
1552 *
1553 * _.isArguments([1, 2, 3]);
1554 * // => false
1555 */
1556 function isArguments(value) {
1557 return value && typeof value == 'object' && typeof value.length == 'number' &&
1558 toString.call(value) == argsClass || false;
1559 }
1560
1561 /**
1562 * Checks if `value` is an array.
1563 *
1564 * @static
1565 * @memberOf _
1566 * @type Function
1567 * @category Objects
1568 * @param {*} value The value to check.
1569 * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
1570 * @example
1571 *
1572 * (function() { return _.isArray(arguments); })();
1573 * // => false
1574 *
1575 * _.isArray([1, 2, 3]);
1576 * // => true
1577 */
1578 var isArray = nativeIsArray || function(value) {
1579 return value && typeof value == 'object' && typeof value.length == 'number' &&
1580 toString.call(value) == arrayClass || false;
1581 };
1582
1583 /**
1584 * A fallback implementation of `Object.keys` which produces an array of the
1585 * given object's own enumerable property names.
1586 *
1587 * @private
1588 * @type Function
1589 * @param {Object} object The object to inspect.
1590 * @returns {Array} Returns an array of property names.
1591 */
1592 var shimKeys = function(object) {
1593 var index, iterable = object, result = [];
1594 if (!iterable) return result;
1595 if (!(objectTypes[typeof object])) return result;
1596 for (index in iterable) {
1597 if (hasOwnProperty.call(iterable, index)) {
1598 result.push(index);
1599 }
1600 }
1601 return result
1602 };
1603
1604 /**
1605 * Creates an array composed of the own enumerable property names of an object.
1606 *
1607 * @static
1608 * @memberOf _
1609 * @category Objects
1610 * @param {Object} object The object to inspect.
1611 * @returns {Array} Returns an array of property names.
1612 * @example
1613 *
1614 * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
1615 * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
1616 */
1617 var keys = !nativeKeys ? shimKeys : function(object) {
1618 if (!isObject(object)) {
1619 return [];
1620 }
1621 return nativeKeys(object);
1622 };
1623
1624 /**
1625 * Used to convert characters to HTML entities:
1626 *
1627 * Though the `>` character is escaped for symmetry, characters like `>` and `/`
1628 * don't require escaping in HTML and have no special meaning unless they're part
1629 * of a tag or an unquoted attribute value.
1630 * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
1631 */
1632 var htmlEscapes = {
1633 '&': '&amp;',
1634 '<': '&lt;',
1635 '>': '&gt;',
1636 '"': '&quot;',
1637 "'": '&#39;'
1638 };
1639
1640 /** Used to convert HTML entities to characters */
1641 var htmlUnescapes = invert(htmlEscapes);
1642
1643 /** Used to match HTML entities and HTML characters */
1644 var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
1645 reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
1646
1647 /*--------------------------------------------------------------------------*/
1648
1649 /**
1650 * Assigns own enumerable properties of source object(s) to the destination
1651 * object. Subsequent sources will overwrite property assignments of previous
1652 * sources. If a callback is provided it will be executed to produce the
1653 * assigned values. The callback is bound to `thisArg` and invoked with two
1654 * arguments; (objectValue, sourceValue).
1655 *
1656 * @static
1657 * @memberOf _
1658 * @type Function
1659 * @alias extend
1660 * @category Objects
1661 * @param {Object} object The destination object.
1662 * @param {...Object} [source] The source objects.
1663 * @param {Function} [callback] The function to customize assigning values.
1664 * @param {*} [thisArg] The `this` binding of `callback`.
1665 * @returns {Object} Returns the destination object.
1666 * @example
1667 *
1668 * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
1669 * // => { 'name': 'fred', 'employer': 'slate' }
1670 *
1671 * var defaults = _.partialRight(_.assign, function(a, b) {
1672 * return typeof a == 'undefined' ? b : a;
1673 * });
1674 *
1675 * var object = { 'name': 'barney' };
1676 * defaults(object, { 'name': 'fred', 'employer': 'slate' });
1677 * // => { 'name': 'barney', 'employer': 'slate' }
1678 */
1679 var assign = function(object, source, guard) {
1680 var index, iterable = object, result = iterable;
1681 if (!iterable) return result;
1682 var args = arguments,
1683 argsIndex = 0,
1684 argsLength = typeof guard == 'number' ? 2 : args.length;
1685 if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
1686 var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);
1687 } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
1688 callback = args[--argsLength];
1689 }
1690 while (++argsIndex < argsLength) {
1691 iterable = args[argsIndex];
1692 if (iterable && objectTypes[typeof iterable]) {
1693 var ownIndex = -1,
1694 ownProps = objectTypes[typeof iterable] && keys(iterable),
1695 length = ownProps ? ownProps.length : 0;
1696
1697 while (++ownIndex < length) {
1698 index = ownProps[ownIndex];
1699 result[index] = callback ? callback(result[index], iterable[index]) : iterable[index];
1700 }
1701 }
1702 }
1703 return result
1704 };
1705
1706 /**
1707 * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
1708 * be cloned, otherwise they will be assigned by reference. If a callback
1709 * is provided it will be executed to produce the cloned values. If the
1710 * callback returns `undefined` cloning will be handled by the method instead.
1711 * The callback is bound to `thisArg` and invoked with one argument; (value).
1712 *
1713 * @static
1714 * @memberOf _
1715 * @category Objects
1716 * @param {*} value The value to clone.
1717 * @param {boolean} [isDeep=false] Specify a deep clone.
1718 * @param {Function} [callback] The function to customize cloning values.
1719 * @param {*} [thisArg] The `this` binding of `callback`.
1720 * @returns {*} Returns the cloned value.
1721 * @example
1722 *
1723 * var characters = [
1724 * { 'name': 'barney', 'age': 36 },
1725 * { 'name': 'fred', 'age': 40 }
1726 * ];
1727 *
1728 * var shallow = _.clone(characters);
1729 * shallow[0] === characters[0];
1730 * // => true
1731 *
1732 * var deep = _.clone(characters, true);
1733 * deep[0] === characters[0];
1734 * // => false
1735 *
1736 * _.mixin({
1737 * 'clone': _.partialRight(_.clone, function(value) {
1738 * return _.isElement(value) ? value.cloneNode(false) : undefined;
1739 * })
1740 * });
1741 *
1742 * var clone = _.clone(document.body);
1743 * clone.childNodes.length;
1744 * // => 0
1745 */
1746 function clone(value, isDeep, callback, thisArg) {
1747 // allows working with "Collections" methods without using their `index`
1748 // and `collection` arguments for `isDeep` and `callback`
1749 if (typeof isDeep != 'boolean' && isDeep != null) {
1750 thisArg = callback;
1751 callback = isDeep;
1752 isDeep = false;
1753 }
1754 return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
1755 }
1756
1757 /**
1758 * Creates a deep clone of `value`. If a callback is provided it will be
1759 * executed to produce the cloned values. If the callback returns `undefined`
1760 * cloning will be handled by the method instead. The callback is bound to
1761 * `thisArg` and invoked with one argument; (value).
1762 *
1763 * Note: This method is loosely based on the structured clone algorithm. Functions
1764 * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
1765 * objects created by constructors other than `Object` are cloned to plain `Object` objects.
1766 * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
1767 *
1768 * @static
1769 * @memberOf _
1770 * @category Objects
1771 * @param {*} value The value to deep clone.
1772 * @param {Function} [callback] The function to customize cloning values.
1773 * @param {*} [thisArg] The `this` binding of `callback`.
1774 * @returns {*} Returns the deep cloned value.
1775 * @example
1776 *
1777 * var characters = [
1778 * { 'name': 'barney', 'age': 36 },
1779 * { 'name': 'fred', 'age': 40 }
1780 * ];
1781 *
1782 * var deep = _.cloneDeep(characters);
1783 * deep[0] === characters[0];
1784 * // => false
1785 *
1786 * var view = {
1787 * 'label': 'docs',
1788 * 'node': element
1789 * };
1790 *
1791 * var clone = _.cloneDeep(view, function(value) {
1792 * return _.isElement(value) ? value.cloneNode(true) : undefined;
1793 * });
1794 *
1795 * clone.node == view.node;
1796 * // => false
1797 */
1798 function cloneDeep(value, callback, thisArg) {
1799 return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
1800 }
1801
1802 /**
1803 * Creates an object that inherits from the given `prototype` object. If a
1804 * `properties` object is provided its own enumerable properties are assigned
1805 * to the created object.
1806 *
1807 * @static
1808 * @memberOf _
1809 * @category Objects
1810 * @param {Object} prototype The object to inherit from.
1811 * @param {Object} [properties] The properties to assign to the object.
1812 * @returns {Object} Returns the new object.
1813 * @example
1814 *
1815 * function Shape() {
1816 * this.x = 0;
1817 * this.y = 0;
1818 * }
1819 *
1820 * function Circle() {
1821 * Shape.call(this);
1822 * }
1823 *
1824 * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
1825 *
1826 * var circle = new Circle;
1827 * circle instanceof Circle;
1828 * // => true
1829 *
1830 * circle instanceof Shape;
1831 * // => true
1832 */
1833 function create(prototype, properties) {
1834 var result = baseCreate(prototype);
1835 return properties ? assign(result, properties) : result;
1836 }
1837
1838 /**
1839 * Assigns own enumerable properties of source object(s) to the destination
1840 * object for all destination properties that resolve to `undefined`. Once a
1841 * property is set, additional defaults of the same property will be ignored.
1842 *
1843 * @static
1844 * @memberOf _
1845 * @type Function
1846 * @category Objects
1847 * @param {Object} object The destination object.
1848 * @param {...Object} [source] The source objects.
1849 * @param- {Object} [guard] Allows working with `_.reduce` without using its
1850 * `key` and `object` arguments as sources.
1851 * @returns {Object} Returns the destination object.
1852 * @example
1853 *
1854 * var object = { 'name': 'barney' };
1855 * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
1856 * // => { 'name': 'barney', 'employer': 'slate' }
1857 */
1858 var defaults = function(object, source, guard) {
1859 var index, iterable = object, result = iterable;
1860 if (!iterable) return result;
1861 var args = arguments,
1862 argsIndex = 0,
1863 argsLength = typeof guard == 'number' ? 2 : args.length;
1864 while (++argsIndex < argsLength) {
1865 iterable = args[argsIndex];
1866 if (iterable && objectTypes[typeof iterable]) {
1867 var ownIndex = -1,
1868 ownProps = objectTypes[typeof iterable] && keys(iterable),
1869 length = ownProps ? ownProps.length : 0;
1870
1871 while (++ownIndex < length) {
1872 index = ownProps[ownIndex];
1873 if (typeof result[index] == 'undefined') result[index] = iterable[index];
1874 }
1875 }
1876 }
1877 return result
1878 };
1879
1880 /**
1881 * This method is like `_.findIndex` except that it returns the key of the
1882 * first element that passes the callback check, instead of the element itself.
1883 *
1884 * If a property name is provided for `callback` the created "_.pluck" style
1885 * callback will return the property value of the given element.
1886 *
1887 * If an object is provided for `callback` the created "_.where" style callback
1888 * will return `true` for elements that have the properties of the given object,
1889 * else `false`.
1890 *
1891 * @static
1892 * @memberOf _
1893 * @category Objects
1894 * @param {Object} object The object to search.
1895 * @param {Function|Object|string} [callback=identity] The function called per
1896 * iteration. If a property name or object is provided it will be used to
1897 * create a "_.pluck" or "_.where" style callback, respectively.
1898 * @param {*} [thisArg] The `this` binding of `callback`.
1899 * @returns {string|undefined} Returns the key of the found element, else `undefined`.
1900 * @example
1901 *
1902 * var characters = {
1903 * 'barney': { 'age': 36, 'blocked': false },
1904 * 'fred': { 'age': 40, 'blocked': true },
1905 * 'pebbles': { 'age': 1, 'blocked': false }
1906 * };
1907 *
1908 * _.findKey(characters, function(chr) {
1909 * return chr.age < 40;
1910 * });
1911 * // => 'barney' (property order is not guaranteed across environments)
1912 *
1913 * // using "_.where" callback shorthand
1914 * _.findKey(characters, { 'age': 1 });
1915 * // => 'pebbles'
1916 *
1917 * // using "_.pluck" callback shorthand
1918 * _.findKey(characters, 'blocked');
1919 * // => 'fred'
1920 */
1921 function findKey(object, callback, thisArg) {
1922 var result;
1923 callback = lodash.createCallback(callback, thisArg, 3);
1924 forOwn(object, function(value, key, object) {
1925 if (callback(value, key, object)) {
1926 result = key;
1927 return false;
1928 }
1929 });
1930 return result;
1931 }
1932
1933 /**
1934 * This method is like `_.findKey` except that it iterates over elements
1935 * of a `collection` in the opposite order.
1936 *
1937 * If a property name is provided for `callback` the created "_.pluck" style
1938 * callback will return the property value of the given element.
1939 *
1940 * If an object is provided for `callback` the created "_.where" style callback
1941 * will return `true` for elements that have the properties of the given object,
1942 * else `false`.
1943 *
1944 * @static
1945 * @memberOf _
1946 * @category Objects
1947 * @param {Object} object The object to search.
1948 * @param {Function|Object|string} [callback=identity] The function called per
1949 * iteration. If a property name or object is provided it will be used to
1950 * create a "_.pluck" or "_.where" style callback, respectively.
1951 * @param {*} [thisArg] The `this` binding of `callback`.
1952 * @returns {string|undefined} Returns the key of the found element, else `undefined`.
1953 * @example
1954 *
1955 * var characters = {
1956 * 'barney': { 'age': 36, 'blocked': true },
1957 * 'fred': { 'age': 40, 'blocked': false },
1958 * 'pebbles': { 'age': 1, 'blocked': true }
1959 * };
1960 *
1961 * _.findLastKey(characters, function(chr) {
1962 * return chr.age < 40;
1963 * });
1964 * // => returns `pebbles`, assuming `_.findKey` returns `barney`
1965 *
1966 * // using "_.where" callback shorthand
1967 * _.findLastKey(characters, { 'age': 40 });
1968 * // => 'fred'
1969 *
1970 * // using "_.pluck" callback shorthand
1971 * _.findLastKey(characters, 'blocked');
1972 * // => 'pebbles'
1973 */
1974 function findLastKey(object, callback, thisArg) {
1975 var result;
1976 callback = lodash.createCallback(callback, thisArg, 3);
1977 forOwnRight(object, function(value, key, object) {
1978 if (callback(value, key, object)) {
1979 result = key;
1980 return false;
1981 }
1982 });
1983 return result;
1984 }
1985
1986 /**
1987 * Iterates over own and inherited enumerable properties of an object,
1988 * executing the callback for each property. The callback is bound to `thisArg`
1989 * and invoked with three arguments; (value, key, object). Callbacks may exit
1990 * iteration early by explicitly returning `false`.
1991 *
1992 * @static
1993 * @memberOf _
1994 * @type Function
1995 * @category Objects
1996 * @param {Object} object The object to iterate over.
1997 * @param {Function} [callback=identity] The function called per iteration.
1998 * @param {*} [thisArg] The `this` binding of `callback`.
1999 * @returns {Object} Returns `object`.
2000 * @example
2001 *
2002 * function Shape() {
2003 * this.x = 0;
2004 * this.y = 0;
2005 * }
2006 *
2007 * Shape.prototype.move = function(x, y) {
2008 * this.x += x;
2009 * this.y += y;
2010 * };
2011 *
2012 * _.forIn(new Shape, function(value, key) {
2013 * console.log(key);
2014 * });
2015 * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
2016 */
2017 var forIn = function(collection, callback, thisArg) {
2018 var index, iterable = collection, result = iterable;
2019 if (!iterable) return result;
2020 if (!objectTypes[typeof iterable]) return result;
2021 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
2022 for (index in iterable) {
2023 if (callback(iterable[index], index, collection) === false) return result;
2024 }
2025 return result
2026 };
2027
2028 /**
2029 * This method is like `_.forIn` except that it iterates over elements
2030 * of a `collection` in the opposite order.
2031 *
2032 * @static
2033 * @memberOf _
2034 * @category Objects
2035 * @param {Object} object The object to iterate over.
2036 * @param {Function} [callback=identity] The function called per iteration.
2037 * @param {*} [thisArg] The `this` binding of `callback`.
2038 * @returns {Object} Returns `object`.
2039 * @example
2040 *
2041 * function Shape() {
2042 * this.x = 0;
2043 * this.y = 0;
2044 * }
2045 *
2046 * Shape.prototype.move = function(x, y) {
2047 * this.x += x;
2048 * this.y += y;
2049 * };
2050 *
2051 * _.forInRight(new Shape, function(value, key) {
2052 * console.log(key);
2053 * });
2054 * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
2055 */
2056 function forInRight(object, callback, thisArg) {
2057 var pairs = [];
2058
2059 forIn(object, function(value, key) {
2060 pairs.push(key, value);
2061 });
2062
2063 var length = pairs.length;
2064 callback = baseCreateCallback(callback, thisArg, 3);
2065 while (length--) {
2066 if (callback(pairs[length--], pairs[length], object) === false) {
2067 break;
2068 }
2069 }
2070 return object;
2071 }
2072
2073 /**
2074 * Iterates over own enumerable properties of an object, executing the callback
2075 * for each property. The callback is bound to `thisArg` and invoked with three
2076 * arguments; (value, key, object). Callbacks may exit iteration early by
2077 * explicitly returning `false`.
2078 *
2079 * @static
2080 * @memberOf _
2081 * @type Function
2082 * @category Objects
2083 * @param {Object} object The object to iterate over.
2084 * @param {Function} [callback=identity] The function called per iteration.
2085 * @param {*} [thisArg] The `this` binding of `callback`.
2086 * @returns {Object} Returns `object`.
2087 * @example
2088 *
2089 * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
2090 * console.log(key);
2091 * });
2092 * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
2093 */
2094 var forOwn = function(collection, callback, thisArg) {
2095 var index, iterable = collection, result = iterable;
2096 if (!iterable) return result;
2097 if (!objectTypes[typeof iterable]) return result;
2098 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
2099 var ownIndex = -1,
2100 ownProps = objectTypes[typeof iterable] && keys(iterable),
2101 length = ownProps ? ownProps.length : 0;
2102
2103 while (++ownIndex < length) {
2104 index = ownProps[ownIndex];
2105 if (callback(iterable[index], index, collection) === false) return result;
2106 }
2107 return result
2108 };
2109
2110 /**
2111 * This method is like `_.forOwn` except that it iterates over elements
2112 * of a `collection` in the opposite order.
2113 *
2114 * @static
2115 * @memberOf _
2116 * @category Objects
2117 * @param {Object} object The object to iterate over.
2118 * @param {Function} [callback=identity] The function called per iteration.
2119 * @param {*} [thisArg] The `this` binding of `callback`.
2120 * @returns {Object} Returns `object`.
2121 * @example
2122 *
2123 * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
2124 * console.log(key);
2125 * });
2126 * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
2127 */
2128 function forOwnRight(object, callback, thisArg) {
2129 var props = keys(object),
2130 length = props.length;
2131
2132 callback = baseCreateCallback(callback, thisArg, 3);
2133 while (length--) {
2134 var key = props[length];
2135 if (callback(object[key], key, object) === false) {
2136 break;
2137 }
2138 }
2139 return object;
2140 }
2141
2142 /**
2143 * Creates a sorted array of property names of all enumerable properties,
2144 * own and inherited, of `object` that have function values.
2145 *
2146 * @static
2147 * @memberOf _
2148 * @alias methods
2149 * @category Objects
2150 * @param {Object} object The object to inspect.
2151 * @returns {Array} Returns an array of property names that have function values.
2152 * @example
2153 *
2154 * _.functions(_);
2155 * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
2156 */
2157 function functions(object) {
2158 var result = [];
2159 forIn(object, function(value, key) {
2160 if (isFunction(value)) {
2161 result.push(key);
2162 }
2163 });
2164 return result.sort();
2165 }
2166
2167 /**
2168 * Checks if the specified property name exists as a direct property of `object`,
2169 * instead of an inherited property.
2170 *
2171 * @static
2172 * @memberOf _
2173 * @category Objects
2174 * @param {Object} object The object to inspect.
2175 * @param {string} key The name of the property to check.
2176 * @returns {boolean} Returns `true` if key is a direct property, else `false`.
2177 * @example
2178 *
2179 * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
2180 * // => true
2181 */
2182 function has(object, key) {
2183 return object ? hasOwnProperty.call(object, key) : false;
2184 }
2185
2186 /**
2187 * Creates an object composed of the inverted keys and values of the given object.
2188 *
2189 * @static
2190 * @memberOf _
2191 * @category Objects
2192 * @param {Object} object The object to invert.
2193 * @returns {Object} Returns the created inverted object.
2194 * @example
2195 *
2196 * _.invert({ 'first': 'fred', 'second': 'barney' });
2197 * // => { 'fred': 'first', 'barney': 'second' }
2198 */
2199 function invert(object) {
2200 var index = -1,
2201 props = keys(object),
2202 length = props.length,
2203 result = {};
2204
2205 while (++index < length) {
2206 var key = props[index];
2207 result[object[key]] = key;
2208 }
2209 return result;
2210 }
2211
2212 /**
2213 * Checks if `value` is a boolean value.
2214 *
2215 * @static
2216 * @memberOf _
2217 * @category Objects
2218 * @param {*} value The value to check.
2219 * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
2220 * @example
2221 *
2222 * _.isBoolean(null);
2223 * // => false
2224 */
2225 function isBoolean(value) {
2226 return value === true || value === false ||
2227 value && typeof value == 'object' && toString.call(value) == boolClass || false;
2228 }
2229
2230 /**
2231 * Checks if `value` is a date.
2232 *
2233 * @static
2234 * @memberOf _
2235 * @category Objects
2236 * @param {*} value The value to check.
2237 * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
2238 * @example
2239 *
2240 * _.isDate(new Date);
2241 * // => true
2242 */
2243 function isDate(value) {
2244 return value && typeof value == 'object' && toString.call(value) == dateClass || false;
2245 }
2246
2247 /**
2248 * Checks if `value` is a DOM element.
2249 *
2250 * @static
2251 * @memberOf _
2252 * @category Objects
2253 * @param {*} value The value to check.
2254 * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
2255 * @example
2256 *
2257 * _.isElement(document.body);
2258 * // => true
2259 */
2260 function isElement(value) {
2261 return value && value.nodeType === 1 || false;
2262 }
2263
2264 /**
2265 * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
2266 * length of `0` and objects with no own enumerable properties are considered
2267 * "empty".
2268 *
2269 * @static
2270 * @memberOf _
2271 * @category Objects
2272 * @param {Array|Object|string} value The value to inspect.
2273 * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
2274 * @example
2275 *
2276 * _.isEmpty([1, 2, 3]);
2277 * // => false
2278 *
2279 * _.isEmpty({});
2280 * // => true
2281 *
2282 * _.isEmpty('');
2283 * // => true
2284 */
2285 function isEmpty(value) {
2286 var result = true;
2287 if (!value) {
2288 return result;
2289 }
2290 var className = toString.call(value),
2291 length = value.length;
2292
2293 if ((className == arrayClass || className == stringClass || className == argsClass ) ||
2294 (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
2295 return !length;
2296 }
2297 forOwn(value, function() {
2298 return (result = false);
2299 });
2300 return result;
2301 }
2302
2303 /**
2304 * Performs a deep comparison between two values to determine if they are
2305 * equivalent to each other. If a callback is provided it will be executed
2306 * to compare values. If the callback returns `undefined` comparisons will
2307 * be handled by the method instead. The callback is bound to `thisArg` and
2308 * invoked with two arguments; (a, b).
2309 *
2310 * @static
2311 * @memberOf _
2312 * @category Objects
2313 * @param {*} a The value to compare.
2314 * @param {*} b The other value to compare.
2315 * @param {Function} [callback] The function to customize comparing values.
2316 * @param {*} [thisArg] The `this` binding of `callback`.
2317 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2318 * @example
2319 *
2320 * var object = { 'name': 'fred' };
2321 * var copy = { 'name': 'fred' };
2322 *
2323 * object == copy;
2324 * // => false
2325 *
2326 * _.isEqual(object, copy);
2327 * // => true
2328 *
2329 * var words = ['hello', 'goodbye'];
2330 * var otherWords = ['hi', 'goodbye'];
2331 *
2332 * _.isEqual(words, otherWords, function(a, b) {
2333 * var reGreet = /^(?:hello|hi)$/i,
2334 * aGreet = _.isString(a) && reGreet.test(a),
2335 * bGreet = _.isString(b) && reGreet.test(b);
2336 *
2337 * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
2338 * });
2339 * // => true
2340 */
2341 function isEqual(a, b, callback, thisArg) {
2342 return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
2343 }
2344
2345 /**
2346 * Checks if `value` is, or can be coerced to, a finite number.
2347 *
2348 * Note: This is not the same as native `isFinite` which will return true for
2349 * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
2350 *
2351 * @static
2352 * @memberOf _
2353 * @category Objects
2354 * @param {*} value The value to check.
2355 * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
2356 * @example
2357 *
2358 * _.isFinite(-101);
2359 * // => true
2360 *
2361 * _.isFinite('10');
2362 * // => true
2363 *
2364 * _.isFinite(true);
2365 * // => false
2366 *
2367 * _.isFinite('');
2368 * // => false
2369 *
2370 * _.isFinite(Infinity);
2371 * // => false
2372 */
2373 function isFinite(value) {
2374 return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
2375 }
2376
2377 /**
2378 * Checks if `value` is a function.
2379 *
2380 * @static
2381 * @memberOf _
2382 * @category Objects
2383 * @param {*} value The value to check.
2384 * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
2385 * @example
2386 *
2387 * _.isFunction(_);
2388 * // => true
2389 */
2390 function isFunction(value) {
2391 return typeof value == 'function';
2392 }
2393
2394 /**
2395 * Checks if `value` is the language type of Object.
2396 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
2397 *
2398 * @static
2399 * @memberOf _
2400 * @category Objects
2401 * @param {*} value The value to check.
2402 * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
2403 * @example
2404 *
2405 * _.isObject({});
2406 * // => true
2407 *
2408 * _.isObject([1, 2, 3]);
2409 * // => true
2410 *
2411 * _.isObject(1);
2412 * // => false
2413 */
2414 function isObject(value) {
2415 // check if the value is the ECMAScript language type of Object
2416 // http://es5.github.io/#x8
2417 // and avoid a V8 bug
2418 // http://code.google.com/p/v8/issues/detail?id=2291
2419 return !!(value && objectTypes[typeof value]);
2420 }
2421
2422 /**
2423 * Checks if `value` is `NaN`.
2424 *
2425 * Note: This is not the same as native `isNaN` which will return `true` for
2426 * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
2427 *
2428 * @static
2429 * @memberOf _
2430 * @category Objects
2431 * @param {*} value The value to check.
2432 * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
2433 * @example
2434 *
2435 * _.isNaN(NaN);
2436 * // => true
2437 *
2438 * _.isNaN(new Number(NaN));
2439 * // => true
2440 *
2441 * isNaN(undefined);
2442 * // => true
2443 *
2444 * _.isNaN(undefined);
2445 * // => false
2446 */
2447 function isNaN(value) {
2448 // `NaN` as a primitive is the only value that is not equal to itself
2449 // (perform the [[Class]] check first to avoid errors with some host objects in IE)
2450 return isNumber(value) && value != +value;
2451 }
2452
2453 /**
2454 * Checks if `value` is `null`.
2455 *
2456 * @static
2457 * @memberOf _
2458 * @category Objects
2459 * @param {*} value The value to check.
2460 * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
2461 * @example
2462 *
2463 * _.isNull(null);
2464 * // => true
2465 *
2466 * _.isNull(undefined);
2467 * // => false
2468 */
2469 function isNull(value) {
2470 return value === null;
2471 }
2472
2473 /**
2474 * Checks if `value` is a number.
2475 *
2476 * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
2477 *
2478 * @static
2479 * @memberOf _
2480 * @category Objects
2481 * @param {*} value The value to check.
2482 * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
2483 * @example
2484 *
2485 * _.isNumber(8.4 * 5);
2486 * // => true
2487 */
2488 function isNumber(value) {
2489 return typeof value == 'number' ||
2490 value && typeof value == 'object' && toString.call(value) == numberClass || false;
2491 }
2492
2493 /**
2494 * Checks if `value` is an object created by the `Object` constructor.
2495 *
2496 * @static
2497 * @memberOf _
2498 * @category Objects
2499 * @param {*} value The value to check.
2500 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
2501 * @example
2502 *
2503 * function Shape() {
2504 * this.x = 0;
2505 * this.y = 0;
2506 * }
2507 *
2508 * _.isPlainObject(new Shape);
2509 * // => false
2510 *
2511 * _.isPlainObject([1, 2, 3]);
2512 * // => false
2513 *
2514 * _.isPlainObject({ 'x': 0, 'y': 0 });
2515 * // => true
2516 */
2517 var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
2518 if (!(value && toString.call(value) == objectClass)) {
2519 return false;
2520 }
2521 var valueOf = value.valueOf,
2522 objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
2523
2524 return objProto
2525 ? (value == objProto || getPrototypeOf(value) == objProto)
2526 : shimIsPlainObject(value);
2527 };
2528
2529 /**
2530 * Checks if `value` is a regular expression.
2531 *
2532 * @static
2533 * @memberOf _
2534 * @category Objects
2535 * @param {*} value The value to check.
2536 * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
2537 * @example
2538 *
2539 * _.isRegExp(/fred/);
2540 * // => true
2541 */
2542 function isRegExp(value) {
2543 return value && typeof value == 'object' && toString.call(value) == regexpClass || false;
2544 }
2545
2546 /**
2547 * Checks if `value` is a string.
2548 *
2549 * @static
2550 * @memberOf _
2551 * @category Objects
2552 * @param {*} value The value to check.
2553 * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
2554 * @example
2555 *
2556 * _.isString('fred');
2557 * // => true
2558 */
2559 function isString(value) {
2560 return typeof value == 'string' ||
2561 value && typeof value == 'object' && toString.call(value) == stringClass || false;
2562 }
2563
2564 /**
2565 * Checks if `value` is `undefined`.
2566 *
2567 * @static
2568 * @memberOf _
2569 * @category Objects
2570 * @param {*} value The value to check.
2571 * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
2572 * @example
2573 *
2574 * _.isUndefined(void 0);
2575 * // => true
2576 */
2577 function isUndefined(value) {
2578 return typeof value == 'undefined';
2579 }
2580
2581 /**
2582 * Creates an object with the same keys as `object` and values generated by
2583 * running each own enumerable property of `object` through the callback.
2584 * The callback is bound to `thisArg` and invoked with three arguments;
2585 * (value, key, object).
2586 *
2587 * If a property name is provided for `callback` the created "_.pluck" style
2588 * callback will return the property value of the given element.
2589 *
2590 * If an object is provided for `callback` the created "_.where" style callback
2591 * will return `true` for elements that have the properties of the given object,
2592 * else `false`.
2593 *
2594 * @static
2595 * @memberOf _
2596 * @category Objects
2597 * @param {Object} object The object to iterate over.
2598 * @param {Function|Object|string} [callback=identity] The function called
2599 * per iteration. If a property name or object is provided it will be used
2600 * to create a "_.pluck" or "_.where" style callback, respectively.
2601 * @param {*} [thisArg] The `this` binding of `callback`.
2602 * @returns {Array} Returns a new object with values of the results of each `callback` execution.
2603 * @example
2604 *
2605 * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
2606 * // => { 'a': 3, 'b': 6, 'c': 9 }
2607 *
2608 * var characters = {
2609 * 'fred': { 'name': 'fred', 'age': 40 },
2610 * 'pebbles': { 'name': 'pebbles', 'age': 1 }
2611 * };
2612 *
2613 * // using "_.pluck" callback shorthand
2614 * _.mapValues(characters, 'age');
2615 * // => { 'fred': 40, 'pebbles': 1 }
2616 */
2617 function mapValues(object, callback, thisArg) {
2618 var result = {};
2619 callback = lodash.createCallback(callback, thisArg, 3);
2620
2621 forOwn(object, function(value, key, object) {
2622 result[key] = callback(value, key, object);
2623 });
2624 return result;
2625 }
2626
2627 /**
2628 * Recursively merges own enumerable properties of the source object(s), that
2629 * don't resolve to `undefined` into the destination object. Subsequent sources
2630 * will overwrite property assignments of previous sources. If a callback is
2631 * provided it will be executed to produce the merged values of the destination
2632 * and source properties. If the callback returns `undefined` merging will
2633 * be handled by the method instead. The callback is bound to `thisArg` and
2634 * invoked with two arguments; (objectValue, sourceValue).
2635 *
2636 * @static
2637 * @memberOf _
2638 * @category Objects
2639 * @param {Object} object The destination object.
2640 * @param {...Object} [source] The source objects.
2641 * @param {Function} [callback] The function to customize merging properties.
2642 * @param {*} [thisArg] The `this` binding of `callback`.
2643 * @returns {Object} Returns the destination object.
2644 * @example
2645 *
2646 * var names = {
2647 * 'characters': [
2648 * { 'name': 'barney' },
2649 * { 'name': 'fred' }
2650 * ]
2651 * };
2652 *
2653 * var ages = {
2654 * 'characters': [
2655 * { 'age': 36 },
2656 * { 'age': 40 }
2657 * ]
2658 * };
2659 *
2660 * _.merge(names, ages);
2661 * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
2662 *
2663 * var food = {
2664 * 'fruits': ['apple'],
2665 * 'vegetables': ['beet']
2666 * };
2667 *
2668 * var otherFood = {
2669 * 'fruits': ['banana'],
2670 * 'vegetables': ['carrot']
2671 * };
2672 *
2673 * _.merge(food, otherFood, function(a, b) {
2674 * return _.isArray(a) ? a.concat(b) : undefined;
2675 * });
2676 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
2677 */
2678 function merge(object) {
2679 var args = arguments,
2680 length = 2;
2681
2682 if (!isObject(object)) {
2683 return object;
2684 }
2685 // allows working with `_.reduce` and `_.reduceRight` without using
2686 // their `index` and `collection` arguments
2687 if (typeof args[2] != 'number') {
2688 length = args.length;
2689 }
2690 if (length > 3 && typeof args[length - 2] == 'function') {
2691 var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
2692 } else if (length > 2 && typeof args[length - 1] == 'function') {
2693 callback = args[--length];
2694 }
2695 var sources = slice(arguments, 1, length),
2696 index = -1,
2697 stackA = getArray(),
2698 stackB = getArray();
2699
2700 while (++index < length) {
2701 baseMerge(object, sources[index], callback, stackA, stackB);
2702 }
2703 releaseArray(stackA);
2704 releaseArray(stackB);
2705 return object;
2706 }
2707
2708 /**
2709 * Creates a shallow clone of `object` excluding the specified properties.
2710 * Property names may be specified as individual arguments or as arrays of
2711 * property names. If a callback is provided it will be executed for each
2712 * property of `object` omitting the properties the callback returns truey
2713 * for. The callback is bound to `thisArg` and invoked with three arguments;
2714 * (value, key, object).
2715 *
2716 * @static
2717 * @memberOf _
2718 * @category Objects
2719 * @param {Object} object The source object.
2720 * @param {Function|...string|string[]} [callback] The properties to omit or the
2721 * function called per iteration.
2722 * @param {*} [thisArg] The `this` binding of `callback`.
2723 * @returns {Object} Returns an object without the omitted properties.
2724 * @example
2725 *
2726 * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
2727 * // => { 'name': 'fred' }
2728 *
2729 * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
2730 * return typeof value == 'number';
2731 * });
2732 * // => { 'name': 'fred' }
2733 */
2734 function omit(object, callback, thisArg) {
2735 var result = {};
2736 if (typeof callback != 'function') {
2737 var props = [];
2738 forIn(object, function(value, key) {
2739 props.push(key);
2740 });
2741 props = baseDifference(props, baseFlatten(arguments, true, false, 1));
2742
2743 var index = -1,
2744 length = props.length;
2745
2746 while (++index < length) {
2747 var key = props[index];
2748 result[key] = object[key];
2749 }
2750 } else {
2751 callback = lodash.createCallback(callback, thisArg, 3);
2752 forIn(object, function(value, key, object) {
2753 if (!callback(value, key, object)) {
2754 result[key] = value;
2755 }
2756 });
2757 }
2758 return result;
2759 }
2760
2761 /**
2762 * Creates a two dimensional array of an object's key-value pairs,
2763 * i.e. `[[key1, value1], [key2, value2]]`.
2764 *
2765 * @static
2766 * @memberOf _
2767 * @category Objects
2768 * @param {Object} object The object to inspect.
2769 * @returns {Array} Returns new array of key-value pairs.
2770 * @example
2771 *
2772 * _.pairs({ 'barney': 36, 'fred': 40 });
2773 * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
2774 */
2775 function pairs(object) {
2776 var index = -1,
2777 props = keys(object),
2778 length = props.length,
2779 result = Array(length);
2780
2781 while (++index < length) {
2782 var key = props[index];
2783 result[index] = [key, object[key]];
2784 }
2785 return result;
2786 }
2787
2788 /**
2789 * Creates a shallow clone of `object` composed of the specified properties.
2790 * Property names may be specified as individual arguments or as arrays of
2791 * property names. If a callback is provided it will be executed for each
2792 * property of `object` picking the properties the callback returns truey
2793 * for. The callback is bound to `thisArg` and invoked with three arguments;
2794 * (value, key, object).
2795 *
2796 * @static
2797 * @memberOf _
2798 * @category Objects
2799 * @param {Object} object The source object.
2800 * @param {Function|...string|string[]} [callback] The function called per
2801 * iteration or property names to pick, specified as individual property
2802 * names or arrays of property names.
2803 * @param {*} [thisArg] The `this` binding of `callback`.
2804 * @returns {Object} Returns an object composed of the picked properties.
2805 * @example
2806 *
2807 * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
2808 * // => { 'name': 'fred' }
2809 *
2810 * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
2811 * return key.charAt(0) != '_';
2812 * });
2813 * // => { 'name': 'fred' }
2814 */
2815 function pick(object, callback, thisArg) {
2816 var result = {};
2817 if (typeof callback != 'function') {
2818 var index = -1,
2819 props = baseFlatten(arguments, true, false, 1),
2820 length = isObject(object) ? props.length : 0;
2821
2822 while (++index < length) {
2823 var key = props[index];
2824 if (key in object) {
2825 result[key] = object[key];
2826 }
2827 }
2828 } else {
2829 callback = lodash.createCallback(callback, thisArg, 3);
2830 forIn(object, function(value, key, object) {
2831 if (callback(value, key, object)) {
2832 result[key] = value;
2833 }
2834 });
2835 }
2836 return result;
2837 }
2838
2839 /**
2840 * An alternative to `_.reduce` this method transforms `object` to a new
2841 * `accumulator` object which is the result of running each of its own
2842 * enumerable properties through a callback, with each callback execution
2843 * potentially mutating the `accumulator` object. The callback is bound to
2844 * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
2845 * Callbacks may exit iteration early by explicitly returning `false`.
2846 *
2847 * @static
2848 * @memberOf _
2849 * @category Objects
2850 * @param {Array|Object} object The object to iterate over.
2851 * @param {Function} [callback=identity] The function called per iteration.
2852 * @param {*} [accumulator] The custom accumulator value.
2853 * @param {*} [thisArg] The `this` binding of `callback`.
2854 * @returns {*} Returns the accumulated value.
2855 * @example
2856 *
2857 * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
2858 * num *= num;
2859 * if (num % 2) {
2860 * return result.push(num) < 3;
2861 * }
2862 * });
2863 * // => [1, 9, 25]
2864 *
2865 * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
2866 * result[key] = num * 3;
2867 * });
2868 * // => { 'a': 3, 'b': 6, 'c': 9 }
2869 */
2870 function transform(object, callback, accumulator, thisArg) {
2871 var isArr = isArray(object);
2872 if (accumulator == null) {
2873 if (isArr) {
2874 accumulator = [];
2875 } else {
2876 var ctor = object && object.constructor,
2877 proto = ctor && ctor.prototype;
2878
2879 accumulator = baseCreate(proto);
2880 }
2881 }
2882 if (callback) {
2883 callback = lodash.createCallback(callback, thisArg, 4);
2884 (isArr ? forEach : forOwn)(object, function(value, index, object) {
2885 return callback(accumulator, value, index, object);
2886 });
2887 }
2888 return accumulator;
2889 }
2890
2891 /**
2892 * Creates an array composed of the own enumerable property values of `object`.
2893 *
2894 * @static
2895 * @memberOf _
2896 * @category Objects
2897 * @param {Object} object The object to inspect.
2898 * @returns {Array} Returns an array of property values.
2899 * @example
2900 *
2901 * _.values({ 'one': 1, 'two': 2, 'three': 3 });
2902 * // => [1, 2, 3] (property order is not guaranteed across environments)
2903 */
2904 function values(object) {
2905 var index = -1,
2906 props = keys(object),
2907 length = props.length,
2908 result = Array(length);
2909
2910 while (++index < length) {
2911 result[index] = object[props[index]];
2912 }
2913 return result;
2914 }
2915
2916 /*--------------------------------------------------------------------------*/
2917
2918 /**
2919 * Creates an array of elements from the specified indexes, or keys, of the
2920 * `collection`. Indexes may be specified as individual arguments or as arrays
2921 * of indexes.
2922 *
2923 * @static
2924 * @memberOf _
2925 * @category Collections
2926 * @param {Array|Object|string} collection The collection to iterate over.
2927 * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
2928 * to retrieve, specified as individual indexes or arrays of indexes.
2929 * @returns {Array} Returns a new array of elements corresponding to the
2930 * provided indexes.
2931 * @example
2932 *
2933 * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
2934 * // => ['a', 'c', 'e']
2935 *
2936 * _.at(['fred', 'barney', 'pebbles'], 0, 2);
2937 * // => ['fred', 'pebbles']
2938 */
2939 function at(collection) {
2940 var args = arguments,
2941 index = -1,
2942 props = baseFlatten(args, true, false, 1),
2943 length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
2944 result = Array(length);
2945
2946 while(++index < length) {
2947 result[index] = collection[props[index]];
2948 }
2949 return result;
2950 }
2951
2952 /**
2953 * Checks if a given value is present in a collection using strict equality
2954 * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
2955 * offset from the end of the collection.
2956 *
2957 * @static
2958 * @memberOf _
2959 * @alias include
2960 * @category Collections
2961 * @param {Array|Object|string} collection The collection to iterate over.
2962 * @param {*} target The value to check for.
2963 * @param {number} [fromIndex=0] The index to search from.
2964 * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
2965 * @example
2966 *
2967 * _.contains([1, 2, 3], 1);
2968 * // => true
2969 *
2970 * _.contains([1, 2, 3], 1, 2);
2971 * // => false
2972 *
2973 * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
2974 * // => true
2975 *
2976 * _.contains('pebbles', 'eb');
2977 * // => true
2978 */
2979 function contains(collection, target, fromIndex) {
2980 var index = -1,
2981 indexOf = getIndexOf(),
2982 length = collection ? collection.length : 0,
2983 result = false;
2984
2985 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
2986 if (isArray(collection)) {
2987 result = indexOf(collection, target, fromIndex) > -1;
2988 } else if (typeof length == 'number') {
2989 result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
2990 } else {
2991 forOwn(collection, function(value) {
2992 if (++index >= fromIndex) {
2993 return !(result = value === target);
2994 }
2995 });
2996 }
2997 return result;
2998 }
2999
3000 /**
3001 * Creates an object composed of keys generated from the results of running
3002 * each element of `collection` through the callback. The corresponding value
3003 * of each key is the number of times the key was returned by the callback.
3004 * The callback is bound to `thisArg` and invoked with three arguments;
3005 * (value, index|key, collection).
3006 *
3007 * If a property name is provided for `callback` the created "_.pluck" style
3008 * callback will return the property value of the given element.
3009 *
3010 * If an object is provided for `callback` the created "_.where" style callback
3011 * will return `true` for elements that have the properties of the given object,
3012 * else `false`.
3013 *
3014 * @static
3015 * @memberOf _
3016 * @category Collections
3017 * @param {Array|Object|string} collection The collection to iterate over.
3018 * @param {Function|Object|string} [callback=identity] The function called
3019 * per iteration. If a property name or object is provided it will be used
3020 * to create a "_.pluck" or "_.where" style callback, respectively.
3021 * @param {*} [thisArg] The `this` binding of `callback`.
3022 * @returns {Object} Returns the composed aggregate object.
3023 * @example
3024 *
3025 * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
3026 * // => { '4': 1, '6': 2 }
3027 *
3028 * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
3029 * // => { '4': 1, '6': 2 }
3030 *
3031 * _.countBy(['one', 'two', 'three'], 'length');
3032 * // => { '3': 2, '5': 1 }
3033 */
3034 var countBy = createAggregator(function(result, value, key) {
3035 (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
3036 });
3037
3038 /**
3039 * Checks if the given callback returns truey value for **all** elements of
3040 * a collection. The callback is bound to `thisArg` and invoked with three
3041 * arguments; (value, index|key, collection).
3042 *
3043 * If a property name is provided for `callback` the created "_.pluck" style
3044 * callback will return the property value of the given element.
3045 *
3046 * If an object is provided for `callback` the created "_.where" style callback
3047 * will return `true` for elements that have the properties of the given object,
3048 * else `false`.
3049 *
3050 * @static
3051 * @memberOf _
3052 * @alias all
3053 * @category Collections
3054 * @param {Array|Object|string} collection The collection to iterate over.
3055 * @param {Function|Object|string} [callback=identity] The function called
3056 * per iteration. If a property name or object is provided it will be used
3057 * to create a "_.pluck" or "_.where" style callback, respectively.
3058 * @param {*} [thisArg] The `this` binding of `callback`.
3059 * @returns {boolean} Returns `true` if all elements passed the callback check,
3060 * else `false`.
3061 * @example
3062 *
3063 * _.every([true, 1, null, 'yes']);
3064 * // => false
3065 *
3066 * var characters = [
3067 * { 'name': 'barney', 'age': 36 },
3068 * { 'name': 'fred', 'age': 40 }
3069 * ];
3070 *
3071 * // using "_.pluck" callback shorthand
3072 * _.every(characters, 'age');
3073 * // => true
3074 *
3075 * // using "_.where" callback shorthand
3076 * _.every(characters, { 'age': 36 });
3077 * // => false
3078 */
3079 function every(collection, callback, thisArg) {
3080 var result = true;
3081 callback = lodash.createCallback(callback, thisArg, 3);
3082
3083 var index = -1,
3084 length = collection ? collection.length : 0;
3085
3086 if (typeof length == 'number') {
3087 while (++index < length) {
3088 if (!(result = !!callback(collection[index], index, collection))) {
3089 break;
3090 }
3091 }
3092 } else {
3093 forOwn(collection, function(value, index, collection) {
3094 return (result = !!callback(value, index, collection));
3095 });
3096 }
3097 return result;
3098 }
3099
3100 /**
3101 * Iterates over elements of a collection, returning an array of all elements
3102 * the callback returns truey for. The callback is bound to `thisArg` and
3103 * invoked with three arguments; (value, index|key, collection).
3104 *
3105 * If a property name is provided for `callback` the created "_.pluck" style
3106 * callback will return the property value of the given element.
3107 *
3108 * If an object is provided for `callback` the created "_.where" style callback
3109 * will return `true` for elements that have the properties of the given object,
3110 * else `false`.
3111 *
3112 * @static
3113 * @memberOf _
3114 * @alias select
3115 * @category Collections
3116 * @param {Array|Object|string} collection The collection to iterate over.
3117 * @param {Function|Object|string} [callback=identity] The function called
3118 * per iteration. If a property name or object is provided it will be used
3119 * to create a "_.pluck" or "_.where" style callback, respectively.
3120 * @param {*} [thisArg] The `this` binding of `callback`.
3121 * @returns {Array} Returns a new array of elements that passed the callback check.
3122 * @example
3123 *
3124 * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
3125 * // => [2, 4, 6]
3126 *
3127 * var characters = [
3128 * { 'name': 'barney', 'age': 36, 'blocked': false },
3129 * { 'name': 'fred', 'age': 40, 'blocked': true }
3130 * ];
3131 *
3132 * // using "_.pluck" callback shorthand
3133 * _.filter(characters, 'blocked');
3134 * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
3135 *
3136 * // using "_.where" callback shorthand
3137 * _.filter(characters, { 'age': 36 });
3138 * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
3139 */
3140 function filter(collection, callback, thisArg) {
3141 var result = [];
3142 callback = lodash.createCallback(callback, thisArg, 3);
3143
3144 var index = -1,
3145 length = collection ? collection.length : 0;
3146
3147 if (typeof length == 'number') {
3148 while (++index < length) {
3149 var value = collection[index];
3150 if (callback(value, index, collection)) {
3151 result.push(value);
3152 }
3153 }
3154 } else {
3155 forOwn(collection, function(value, index, collection) {
3156 if (callback(value, index, collection)) {
3157 result.push(value);
3158 }
3159 });
3160 }
3161 return result;
3162 }
3163
3164 /**
3165 * Iterates over elements of a collection, returning the first element that
3166 * the callback returns truey for. The callback is bound to `thisArg` and
3167 * invoked with three arguments; (value, index|key, collection).
3168 *
3169 * If a property name is provided for `callback` the created "_.pluck" style
3170 * callback will return the property value of the given element.
3171 *
3172 * If an object is provided for `callback` the created "_.where" style callback
3173 * will return `true` for elements that have the properties of the given object,
3174 * else `false`.
3175 *
3176 * @static
3177 * @memberOf _
3178 * @alias detect, findWhere
3179 * @category Collections
3180 * @param {Array|Object|string} collection The collection to iterate over.
3181 * @param {Function|Object|string} [callback=identity] The function called
3182 * per iteration. If a property name or object is provided it will be used
3183 * to create a "_.pluck" or "_.where" style callback, respectively.
3184 * @param {*} [thisArg] The `this` binding of `callback`.
3185 * @returns {*} Returns the found element, else `undefined`.
3186 * @example
3187 *
3188 * var characters = [
3189 * { 'name': 'barney', 'age': 36, 'blocked': false },
3190 * { 'name': 'fred', 'age': 40, 'blocked': true },
3191 * { 'name': 'pebbles', 'age': 1, 'blocked': false }
3192 * ];
3193 *
3194 * _.find(characters, function(chr) {
3195 * return chr.age < 40;
3196 * });
3197 * // => { 'name': 'barney', 'age': 36, 'blocked': false }
3198 *
3199 * // using "_.where" callback shorthand
3200 * _.find(characters, { 'age': 1 });
3201 * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
3202 *
3203 * // using "_.pluck" callback shorthand
3204 * _.find(characters, 'blocked');
3205 * // => { 'name': 'fred', 'age': 40, 'blocked': true }
3206 */
3207 function find(collection, callback, thisArg) {
3208 callback = lodash.createCallback(callback, thisArg, 3);
3209
3210 var index = -1,
3211 length = collection ? collection.length : 0;
3212
3213 if (typeof length == 'number') {
3214 while (++index < length) {
3215 var value = collection[index];
3216 if (callback(value, index, collection)) {
3217 return value;
3218 }
3219 }
3220 } else {
3221 var result;
3222 forOwn(collection, function(value, index, collection) {
3223 if (callback(value, index, collection)) {
3224 result = value;
3225 return false;
3226 }
3227 });
3228 return result;
3229 }
3230 }
3231
3232 /**
3233 * This method is like `_.find` except that it iterates over elements
3234 * of a `collection` from right to left.
3235 *
3236 * @static
3237 * @memberOf _
3238 * @category Collections
3239 * @param {Array|Object|string} collection The collection to iterate over.
3240 * @param {Function|Object|string} [callback=identity] The function called
3241 * per iteration. If a property name or object is provided it will be used
3242 * to create a "_.pluck" or "_.where" style callback, respectively.
3243 * @param {*} [thisArg] The `this` binding of `callback`.
3244 * @returns {*} Returns the found element, else `undefined`.
3245 * @example
3246 *
3247 * _.findLast([1, 2, 3, 4], function(num) {
3248 * return num % 2 == 1;
3249 * });
3250 * // => 3
3251 */
3252 function findLast(collection, callback, thisArg) {
3253 var result;
3254 callback = lodash.createCallback(callback, thisArg, 3);
3255 forEachRight(collection, function(value, index, collection) {
3256 if (callback(value, index, collection)) {
3257 result = value;
3258 return false;
3259 }
3260 });
3261 return result;
3262 }
3263
3264 /**
3265 * Iterates over elements of a collection, executing the callback for each
3266 * element. The callback is bound to `thisArg` and invoked with three arguments;
3267 * (value, index|key, collection). Callbacks may exit iteration early by
3268 * explicitly returning `false`.
3269 *
3270 * Note: As with other "Collections" methods, objects with a `length` property
3271 * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
3272 * may be used for object iteration.
3273 *
3274 * @static
3275 * @memberOf _
3276 * @alias each
3277 * @category Collections
3278 * @param {Array|Object|string} collection The collection to iterate over.
3279 * @param {Function} [callback=identity] The function called per iteration.
3280 * @param {*} [thisArg] The `this` binding of `callback`.
3281 * @returns {Array|Object|string} Returns `collection`.
3282 * @example
3283 *
3284 * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
3285 * // => logs each number and returns '1,2,3'
3286 *
3287 * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
3288 * // => logs each number and returns the object (property order is not guaranteed across environments)
3289 */
3290 function forEach(collection, callback, thisArg) {
3291 var index = -1,
3292 length = collection ? collection.length : 0;
3293
3294 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
3295 if (typeof length == 'number') {
3296 while (++index < length) {
3297 if (callback(collection[index], index, collection) === false) {
3298 break;
3299 }
3300 }
3301 } else {
3302 forOwn(collection, callback);
3303 }
3304 return collection;
3305 }
3306
3307 /**
3308 * This method is like `_.forEach` except that it iterates over elements
3309 * of a `collection` from right to left.
3310 *
3311 * @static
3312 * @memberOf _
3313 * @alias eachRight
3314 * @category Collections
3315 * @param {Array|Object|string} collection The collection to iterate over.
3316 * @param {Function} [callback=identity] The function called per iteration.
3317 * @param {*} [thisArg] The `this` binding of `callback`.
3318 * @returns {Array|Object|string} Returns `collection`.
3319 * @example
3320 *
3321 * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
3322 * // => logs each number from right to left and returns '3,2,1'
3323 */
3324 function forEachRight(collection, callback, thisArg) {
3325 var length = collection ? collection.length : 0;
3326 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
3327 if (typeof length == 'number') {
3328 while (length--) {
3329 if (callback(collection[length], length, collection) === false) {
3330 break;
3331 }
3332 }
3333 } else {
3334 var props = keys(collection);
3335 length = props.length;
3336 forOwn(collection, function(value, key, collection) {
3337 key = props ? props[--length] : --length;
3338 return callback(collection[key], key, collection);
3339 });
3340 }
3341 return collection;
3342 }
3343
3344 /**
3345 * Creates an object composed of keys generated from the results of running
3346 * each element of a collection through the callback. The corresponding value
3347 * of each key is an array of the elements responsible for generating the key.
3348 * The callback is bound to `thisArg` and invoked with three arguments;
3349 * (value, index|key, collection).
3350 *
3351 * If a property name is provided for `callback` the created "_.pluck" style
3352 * callback will return the property value of the given element.
3353 *
3354 * If an object is provided for `callback` the created "_.where" style callback
3355 * will return `true` for elements that have the properties of the given object,
3356 * else `false`
3357 *
3358 * @static
3359 * @memberOf _
3360 * @category Collections
3361 * @param {Array|Object|string} collection The collection to iterate over.
3362 * @param {Function|Object|string} [callback=identity] The function called
3363 * per iteration. If a property name or object is provided it will be used
3364 * to create a "_.pluck" or "_.where" style callback, respectively.
3365 * @param {*} [thisArg] The `this` binding of `callback`.
3366 * @returns {Object} Returns the composed aggregate object.
3367 * @example
3368 *
3369 * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
3370 * // => { '4': [4.2], '6': [6.1, 6.4] }
3371 *
3372 * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
3373 * // => { '4': [4.2], '6': [6.1, 6.4] }
3374 *
3375 * // using "_.pluck" callback shorthand
3376 * _.groupBy(['one', 'two', 'three'], 'length');
3377 * // => { '3': ['one', 'two'], '5': ['three'] }
3378 */
3379 var groupBy = createAggregator(function(result, value, key) {
3380 (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
3381 });
3382
3383 /**
3384 * Creates an object composed of keys generated from the results of running
3385 * each element of the collection through the given callback. The corresponding
3386 * value of each key is the last element responsible for generating the key.
3387 * The callback is bound to `thisArg` and invoked with three arguments;
3388 * (value, index|key, collection).
3389 *
3390 * If a property name is provided for `callback` the created "_.pluck" style
3391 * callback will return the property value of the given element.
3392 *
3393 * If an object is provided for `callback` the created "_.where" style callback
3394 * will return `true` for elements that have the properties of the given object,
3395 * else `false`.
3396 *
3397 * @static
3398 * @memberOf _
3399 * @category Collections
3400 * @param {Array|Object|string} collection The collection to iterate over.
3401 * @param {Function|Object|string} [callback=identity] The function called
3402 * per iteration. If a property name or object is provided it will be used
3403 * to create a "_.pluck" or "_.where" style callback, respectively.
3404 * @param {*} [thisArg] The `this` binding of `callback`.
3405 * @returns {Object} Returns the composed aggregate object.
3406 * @example
3407 *
3408 * var keys = [
3409 * { 'dir': 'left', 'code': 97 },
3410 * { 'dir': 'right', 'code': 100 }
3411 * ];
3412 *
3413 * _.indexBy(keys, 'dir');
3414 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
3415 *
3416 * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
3417 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
3418 *
3419 * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
3420 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
3421 */
3422 var indexBy = createAggregator(function(result, value, key) {
3423 result[key] = value;
3424 });
3425
3426 /**
3427 * Invokes the method named by `methodName` on each element in the `collection`
3428 * returning an array of the results of each invoked method. Additional arguments
3429 * will be provided to each invoked method. If `methodName` is a function it
3430 * will be invoked for, and `this` bound to, each element in the `collection`.
3431 *
3432 * @static
3433 * @memberOf _
3434 * @category Collections
3435 * @param {Array|Object|string} collection The collection to iterate over.
3436 * @param {Function|string} methodName The name of the method to invoke or
3437 * the function invoked per iteration.
3438 * @param {...*} [arg] Arguments to invoke the method with.
3439 * @returns {Array} Returns a new array of the results of each invoked method.
3440 * @example
3441 *
3442 * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
3443 * // => [[1, 5, 7], [1, 2, 3]]
3444 *
3445 * _.invoke([123, 456], String.prototype.split, '');
3446 * // => [['1', '2', '3'], ['4', '5', '6']]
3447 */
3448 function invoke(collection, methodName) {
3449 var args = slice(arguments, 2),
3450 index = -1,
3451 isFunc = typeof methodName == 'function',
3452 length = collection ? collection.length : 0,
3453 result = Array(typeof length == 'number' ? length : 0);
3454
3455 forEach(collection, function(value) {
3456 result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
3457 });
3458 return result;
3459 }
3460
3461 /**
3462 * Creates an array of values by running each element in the collection
3463 * through the callback. The callback is bound to `thisArg` and invoked with
3464 * three arguments; (value, index|key, collection).
3465 *
3466 * If a property name is provided for `callback` the created "_.pluck" style
3467 * callback will return the property value of the given element.
3468 *
3469 * If an object is provided for `callback` the created "_.where" style callback
3470 * will return `true` for elements that have the properties of the given object,
3471 * else `false`.
3472 *
3473 * @static
3474 * @memberOf _
3475 * @alias collect
3476 * @category Collections
3477 * @param {Array|Object|string} collection The collection to iterate over.
3478 * @param {Function|Object|string} [callback=identity] The function called
3479 * per iteration. If a property name or object is provided it will be used
3480 * to create a "_.pluck" or "_.where" style callback, respectively.
3481 * @param {*} [thisArg] The `this` binding of `callback`.
3482 * @returns {Array} Returns a new array of the results of each `callback` execution.
3483 * @example
3484 *
3485 * _.map([1, 2, 3], function(num) { return num * 3; });
3486 * // => [3, 6, 9]
3487 *
3488 * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
3489 * // => [3, 6, 9] (property order is not guaranteed across environments)
3490 *
3491 * var characters = [
3492 * { 'name': 'barney', 'age': 36 },
3493 * { 'name': 'fred', 'age': 40 }
3494 * ];
3495 *
3496 * // using "_.pluck" callback shorthand
3497 * _.map(characters, 'name');
3498 * // => ['barney', 'fred']
3499 */
3500 function map(collection, callback, thisArg) {
3501 var index = -1,
3502 length = collection ? collection.length : 0;
3503
3504 callback = lodash.createCallback(callback, thisArg, 3);
3505 if (typeof length == 'number') {
3506 var result = Array(length);
3507 while (++index < length) {
3508 result[index] = callback(collection[index], index, collection);
3509 }
3510 } else {
3511 result = [];
3512 forOwn(collection, function(value, key, collection) {
3513 result[++index] = callback(value, key, collection);
3514 });
3515 }
3516 return result;
3517 }
3518
3519 /**
3520 * Retrieves the maximum value of a collection. If the collection is empty or
3521 * falsey `-Infinity` is returned. If a callback is provided it will be executed
3522 * for each value in the collection to generate the criterion by which the value
3523 * is ranked. The callback is bound to `thisArg` and invoked with three
3524 * arguments; (value, index, collection).
3525 *
3526 * If a property name is provided for `callback` the created "_.pluck" style
3527 * callback will return the property value of the given element.
3528 *
3529 * If an object is provided for `callback` the created "_.where" style callback
3530 * will return `true` for elements that have the properties of the given object,
3531 * else `false`.
3532 *
3533 * @static
3534 * @memberOf _
3535 * @category Collections
3536 * @param {Array|Object|string} collection The collection to iterate over.
3537 * @param {Function|Object|string} [callback=identity] The function called
3538 * per iteration. If a property name or object is provided it will be used
3539 * to create a "_.pluck" or "_.where" style callback, respectively.
3540 * @param {*} [thisArg] The `this` binding of `callback`.
3541 * @returns {*} Returns the maximum value.
3542 * @example
3543 *
3544 * _.max([4, 2, 8, 6]);
3545 * // => 8
3546 *
3547 * var characters = [
3548 * { 'name': 'barney', 'age': 36 },
3549 * { 'name': 'fred', 'age': 40 }
3550 * ];
3551 *
3552 * _.max(characters, function(chr) { return chr.age; });
3553 * // => { 'name': 'fred', 'age': 40 };
3554 *
3555 * // using "_.pluck" callback shorthand
3556 * _.max(characters, 'age');
3557 * // => { 'name': 'fred', 'age': 40 };
3558 */
3559 function max(collection, callback, thisArg) {
3560 var computed = -Infinity,
3561 result = computed;
3562
3563 // allows working with functions like `_.map` without using
3564 // their `index` argument as a callback
3565 if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
3566 callback = null;
3567 }
3568 if (callback == null && isArray(collection)) {
3569 var index = -1,
3570 length = collection.length;
3571
3572 while (++index < length) {
3573 var value = collection[index];
3574 if (value > result) {
3575 result = value;
3576 }
3577 }
3578 } else {
3579 callback = (callback == null && isString(collection))
3580 ? charAtCallback
3581 : lodash.createCallback(callback, thisArg, 3);
3582
3583 forEach(collection, function(value, index, collection) {
3584 var current = callback(value, index, collection);
3585 if (current > computed) {
3586 computed = current;
3587 result = value;
3588 }
3589 });
3590 }
3591 return result;
3592 }
3593
3594 /**
3595 * Retrieves the minimum value of a collection. If the collection is empty or
3596 * falsey `Infinity` is returned. If a callback is provided it will be executed
3597 * for each value in the collection to generate the criterion by which the value
3598 * is ranked. The callback is bound to `thisArg` and invoked with three
3599 * arguments; (value, index, collection).
3600 *
3601 * If a property name is provided for `callback` the created "_.pluck" style
3602 * callback will return the property value of the given element.
3603 *
3604 * If an object is provided for `callback` the created "_.where" style callback
3605 * will return `true` for elements that have the properties of the given object,
3606 * else `false`.
3607 *
3608 * @static
3609 * @memberOf _
3610 * @category Collections
3611 * @param {Array|Object|string} collection The collection to iterate over.
3612 * @param {Function|Object|string} [callback=identity] The function called
3613 * per iteration. If a property name or object is provided it will be used
3614 * to create a "_.pluck" or "_.where" style callback, respectively.
3615 * @param {*} [thisArg] The `this` binding of `callback`.
3616 * @returns {*} Returns the minimum value.
3617 * @example
3618 *
3619 * _.min([4, 2, 8, 6]);
3620 * // => 2
3621 *
3622 * var characters = [
3623 * { 'name': 'barney', 'age': 36 },
3624 * { 'name': 'fred', 'age': 40 }
3625 * ];
3626 *
3627 * _.min(characters, function(chr) { return chr.age; });
3628 * // => { 'name': 'barney', 'age': 36 };
3629 *
3630 * // using "_.pluck" callback shorthand
3631 * _.min(characters, 'age');
3632 * // => { 'name': 'barney', 'age': 36 };
3633 */
3634 function min(collection, callback, thisArg) {
3635 var computed = Infinity,
3636 result = computed;
3637
3638 // allows working with functions like `_.map` without using
3639 // their `index` argument as a callback
3640 if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) {
3641 callback = null;
3642 }
3643 if (callback == null && isArray(collection)) {
3644 var index = -1,
3645 length = collection.length;
3646
3647 while (++index < length) {
3648 var value = collection[index];
3649 if (value < result) {
3650 result = value;
3651 }
3652 }
3653 } else {
3654 callback = (callback == null && isString(collection))
3655 ? charAtCallback
3656 : lodash.createCallback(callback, thisArg, 3);
3657
3658 forEach(collection, function(value, index, collection) {
3659 var current = callback(value, index, collection);
3660 if (current < computed) {
3661 computed = current;
3662 result = value;
3663 }
3664 });
3665 }
3666 return result;
3667 }
3668
3669 /**
3670 * Retrieves the value of a specified property from all elements in the collection.
3671 *
3672 * @static
3673 * @memberOf _
3674 * @type Function
3675 * @category Collections
3676 * @param {Array|Object|string} collection The collection to iterate over.
3677 * @param {string} property The name of the property to pluck.
3678 * @returns {Array} Returns a new array of property values.
3679 * @example
3680 *
3681 * var characters = [
3682 * { 'name': 'barney', 'age': 36 },
3683 * { 'name': 'fred', 'age': 40 }
3684 * ];
3685 *
3686 * _.pluck(characters, 'name');
3687 * // => ['barney', 'fred']
3688 */
3689 var pluck = map;
3690
3691 /**
3692 * Reduces a collection to a value which is the accumulated result of running
3693 * each element in the collection through the callback, where each successive
3694 * callback execution consumes the return value of the previous execution. If
3695 * `accumulator` is not provided the first element of the collection will be
3696 * used as the initial `accumulator` value. The callback is bound to `thisArg`
3697 * and invoked with four arguments; (accumulator, value, index|key, collection).
3698 *
3699 * @static
3700 * @memberOf _
3701 * @alias foldl, inject
3702 * @category Collections
3703 * @param {Array|Object|string} collection The collection to iterate over.
3704 * @param {Function} [callback=identity] The function called per iteration.
3705 * @param {*} [accumulator] Initial value of the accumulator.
3706 * @param {*} [thisArg] The `this` binding of `callback`.
3707 * @returns {*} Returns the accumulated value.
3708 * @example
3709 *
3710 * var sum = _.reduce([1, 2, 3], function(sum, num) {
3711 * return sum + num;
3712 * });
3713 * // => 6
3714 *
3715 * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
3716 * result[key] = num * 3;
3717 * return result;
3718 * }, {});
3719 * // => { 'a': 3, 'b': 6, 'c': 9 }
3720 */
3721 function reduce(collection, callback, accumulator, thisArg) {
3722 if (!collection) return accumulator;
3723 var noaccum = arguments.length < 3;
3724 callback = lodash.createCallback(callback, thisArg, 4);
3725
3726 var index = -1,
3727 length = collection.length;
3728
3729 if (typeof length == 'number') {
3730 if (noaccum) {
3731 accumulator = collection[++index];
3732 }
3733 while (++index < length) {
3734 accumulator = callback(accumulator, collection[index], index, collection);
3735 }
3736 } else {
3737 forOwn(collection, function(value, index, collection) {
3738 accumulator = noaccum
3739 ? (noaccum = false, value)
3740 : callback(accumulator, value, index, collection)
3741 });
3742 }
3743 return accumulator;
3744 }
3745
3746 /**
3747 * This method is like `_.reduce` except that it iterates over elements
3748 * of a `collection` from right to left.
3749 *
3750 * @static
3751 * @memberOf _
3752 * @alias foldr
3753 * @category Collections
3754 * @param {Array|Object|string} collection The collection to iterate over.
3755 * @param {Function} [callback=identity] The function called per iteration.
3756 * @param {*} [accumulator] Initial value of the accumulator.
3757 * @param {*} [thisArg] The `this` binding of `callback`.
3758 * @returns {*} Returns the accumulated value.
3759 * @example
3760 *
3761 * var list = [[0, 1], [2, 3], [4, 5]];
3762 * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
3763 * // => [4, 5, 2, 3, 0, 1]
3764 */
3765 function reduceRight(collection, callback, accumulator, thisArg) {
3766 var noaccum = arguments.length < 3;
3767 callback = lodash.createCallback(callback, thisArg, 4);
3768 forEachRight(collection, function(value, index, collection) {
3769 accumulator = noaccum
3770 ? (noaccum = false, value)
3771 : callback(accumulator, value, index, collection);
3772 });
3773 return accumulator;
3774 }
3775
3776 /**
3777 * The opposite of `_.filter` this method returns the elements of a
3778 * collection that the callback does **not** return truey for.
3779 *
3780 * If a property name is provided for `callback` the created "_.pluck" style
3781 * callback will return the property value of the given element.
3782 *
3783 * If an object is provided for `callback` the created "_.where" style callback
3784 * will return `true` for elements that have the properties of the given object,
3785 * else `false`.
3786 *
3787 * @static
3788 * @memberOf _
3789 * @category Collections
3790 * @param {Array|Object|string} collection The collection to iterate over.
3791 * @param {Function|Object|string} [callback=identity] The function called
3792 * per iteration. If a property name or object is provided it will be used
3793 * to create a "_.pluck" or "_.where" style callback, respectively.
3794 * @param {*} [thisArg] The `this` binding of `callback`.
3795 * @returns {Array} Returns a new array of elements that failed the callback check.
3796 * @example
3797 *
3798 * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
3799 * // => [1, 3, 5]
3800 *
3801 * var characters = [
3802 * { 'name': 'barney', 'age': 36, 'blocked': false },
3803 * { 'name': 'fred', 'age': 40, 'blocked': true }
3804 * ];
3805 *
3806 * // using "_.pluck" callback shorthand
3807 * _.reject(characters, 'blocked');
3808 * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
3809 *
3810 * // using "_.where" callback shorthand
3811 * _.reject(characters, { 'age': 36 });
3812 * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
3813 */
3814 function reject(collection, callback, thisArg) {
3815 callback = lodash.createCallback(callback, thisArg, 3);
3816 return filter(collection, function(value, index, collection) {
3817 return !callback(value, index, collection);
3818 });
3819 }
3820
3821 /**
3822 * Retrieves a random element or `n` random elements from a collection.
3823 *
3824 * @static
3825 * @memberOf _
3826 * @category Collections
3827 * @param {Array|Object|string} collection The collection to sample.
3828 * @param {number} [n] The number of elements to sample.
3829 * @param- {Object} [guard] Allows working with functions like `_.map`
3830 * without using their `index` arguments as `n`.
3831 * @returns {Array} Returns the random sample(s) of `collection`.
3832 * @example
3833 *
3834 * _.sample([1, 2, 3, 4]);
3835 * // => 2
3836 *
3837 * _.sample([1, 2, 3, 4], 2);
3838 * // => [3, 1]
3839 */
3840 function sample(collection, n, guard) {
3841 if (collection && typeof collection.length != 'number') {
3842 collection = values(collection);
3843 }
3844 if (n == null || guard) {
3845 return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
3846 }
3847 var result = shuffle(collection);
3848 result.length = nativeMin(nativeMax(0, n), result.length);
3849 return result;
3850 }
3851
3852 /**
3853 * Creates an array of shuffled values, using a version of the Fisher-Yates
3854 * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
3855 *
3856 * @static
3857 * @memberOf _
3858 * @category Collections
3859 * @param {Array|Object|string} collection The collection to shuffle.
3860 * @returns {Array} Returns a new shuffled collection.
3861 * @example
3862 *
3863 * _.shuffle([1, 2, 3, 4, 5, 6]);
3864 * // => [4, 1, 6, 3, 5, 2]
3865 */
3866 function shuffle(collection) {
3867 var index = -1,
3868 length = collection ? collection.length : 0,
3869 result = Array(typeof length == 'number' ? length : 0);
3870
3871 forEach(collection, function(value) {
3872 var rand = baseRandom(0, ++index);
3873 result[index] = result[rand];
3874 result[rand] = value;
3875 });
3876 return result;
3877 }
3878
3879 /**
3880 * Gets the size of the `collection` by returning `collection.length` for arrays
3881 * and array-like objects or the number of own enumerable properties for objects.
3882 *
3883 * @static
3884 * @memberOf _
3885 * @category Collections
3886 * @param {Array|Object|string} collection The collection to inspect.
3887 * @returns {number} Returns `collection.length` or number of own enumerable properties.
3888 * @example
3889 *
3890 * _.size([1, 2]);
3891 * // => 2
3892 *
3893 * _.size({ 'one': 1, 'two': 2, 'three': 3 });
3894 * // => 3
3895 *
3896 * _.size('pebbles');
3897 * // => 7
3898 */
3899 function size(collection) {
3900 var length = collection ? collection.length : 0;
3901 return typeof length == 'number' ? length : keys(collection).length;
3902 }
3903
3904 /**
3905 * Checks if the callback returns a truey value for **any** element of a
3906 * collection. The function returns as soon as it finds a passing value and
3907 * does not iterate over the entire collection. The callback is bound to
3908 * `thisArg` and invoked with three arguments; (value, index|key, collection).
3909 *
3910 * If a property name is provided for `callback` the created "_.pluck" style
3911 * callback will return the property value of the given element.
3912 *
3913 * If an object is provided for `callback` the created "_.where" style callback
3914 * will return `true` for elements that have the properties of the given object,
3915 * else `false`.
3916 *
3917 * @static
3918 * @memberOf _
3919 * @alias any
3920 * @category Collections
3921 * @param {Array|Object|string} collection The collection to iterate over.
3922 * @param {Function|Object|string} [callback=identity] The function called
3923 * per iteration. If a property name or object is provided it will be used
3924 * to create a "_.pluck" or "_.where" style callback, respectively.
3925 * @param {*} [thisArg] The `this` binding of `callback`.
3926 * @returns {boolean} Returns `true` if any element passed the callback check,
3927 * else `false`.
3928 * @example
3929 *
3930 * _.some([null, 0, 'yes', false], Boolean);
3931 * // => true
3932 *
3933 * var characters = [
3934 * { 'name': 'barney', 'age': 36, 'blocked': false },
3935 * { 'name': 'fred', 'age': 40, 'blocked': true }
3936 * ];
3937 *
3938 * // using "_.pluck" callback shorthand
3939 * _.some(characters, 'blocked');
3940 * // => true
3941 *
3942 * // using "_.where" callback shorthand
3943 * _.some(characters, { 'age': 1 });
3944 * // => false
3945 */
3946 function some(collection, callback, thisArg) {
3947 var result;
3948 callback = lodash.createCallback(callback, thisArg, 3);
3949
3950 var index = -1,
3951 length = collection ? collection.length : 0;
3952
3953 if (typeof length == 'number') {
3954 while (++index < length) {
3955 if ((result = callback(collection[index], index, collection))) {
3956 break;
3957 }
3958 }
3959 } else {
3960 forOwn(collection, function(value, index, collection) {
3961 return !(result = callback(value, index, collection));
3962 });
3963 }
3964 return !!result;
3965 }
3966
3967 /**
3968 * Creates an array of elements, sorted in ascending order by the results of
3969 * running each element in a collection through the callback. This method
3970 * performs a stable sort, that is, it will preserve the original sort order
3971 * of equal elements. The callback is bound to `thisArg` and invoked with
3972 * three arguments; (value, index|key, collection).
3973 *
3974 * If a property name is provided for `callback` the created "_.pluck" style
3975 * callback will return the property value of the given element.
3976 *
3977 * If an array of property names is provided for `callback` the collection
3978 * will be sorted by each property value.
3979 *
3980 * If an object is provided for `callback` the created "_.where" style callback
3981 * will return `true` for elements that have the properties of the given object,
3982 * else `false`.
3983 *
3984 * @static
3985 * @memberOf _
3986 * @category Collections
3987 * @param {Array|Object|string} collection The collection to iterate over.
3988 * @param {Array|Function|Object|string} [callback=identity] The function called
3989 * per iteration. If a property name or object is provided it will be used
3990 * to create a "_.pluck" or "_.where" style callback, respectively.
3991 * @param {*} [thisArg] The `this` binding of `callback`.
3992 * @returns {Array} Returns a new array of sorted elements.
3993 * @example
3994 *
3995 * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
3996 * // => [3, 1, 2]
3997 *
3998 * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
3999 * // => [3, 1, 2]
4000 *
4001 * var characters = [
4002 * { 'name': 'barney', 'age': 36 },
4003 * { 'name': 'fred', 'age': 40 },
4004 * { 'name': 'barney', 'age': 26 },
4005 * { 'name': 'fred', 'age': 30 }
4006 * ];
4007 *
4008 * // using "_.pluck" callback shorthand
4009 * _.map(_.sortBy(characters, 'age'), _.values);
4010 * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
4011 *
4012 * // sorting by multiple properties
4013 * _.map(_.sortBy(characters, ['name', 'age']), _.values);
4014 * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
4015 */
4016 function sortBy(collection, callback, thisArg) {
4017 var index = -1,
4018 isArr = isArray(callback),
4019 length = collection ? collection.length : 0,
4020 result = Array(typeof length == 'number' ? length : 0);
4021
4022 if (!isArr) {
4023 callback = lodash.createCallback(callback, thisArg, 3);
4024 }
4025 forEach(collection, function(value, key, collection) {
4026 var object = result[++index] = getObject();
4027 if (isArr) {
4028 object.criteria = map(callback, function(key) { return value[key]; });
4029 } else {
4030 (object.criteria = getArray())[0] = callback(value, key, collection);
4031 }
4032 object.index = index;
4033 object.value = value;
4034 });
4035
4036 length = result.length;
4037 result.sort(compareAscending);
4038 while (length--) {
4039 var object = result[length];
4040 result[length] = object.value;
4041 if (!isArr) {
4042 releaseArray(object.criteria);
4043 }
4044 releaseObject(object);
4045 }
4046 return result;
4047 }
4048
4049 /**
4050 * Converts the `collection` to an array.
4051 *
4052 * @static
4053 * @memberOf _
4054 * @category Collections
4055 * @param {Array|Object|string} collection The collection to convert.
4056 * @returns {Array} Returns the new converted array.
4057 * @example
4058 *
4059 * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
4060 * // => [2, 3, 4]
4061 */
4062 function toArray(collection) {
4063 if (collection && typeof collection.length == 'number') {
4064 return slice(collection);
4065 }
4066 return values(collection);
4067 }
4068
4069 /**
4070 * Performs a deep comparison of each element in a `collection` to the given
4071 * `properties` object, returning an array of all elements that have equivalent
4072 * property values.
4073 *
4074 * @static
4075 * @memberOf _
4076 * @type Function
4077 * @category Collections
4078 * @param {Array|Object|string} collection The collection to iterate over.
4079 * @param {Object} props The object of property values to filter by.
4080 * @returns {Array} Returns a new array of elements that have the given properties.
4081 * @example
4082 *
4083 * var characters = [
4084 * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
4085 * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
4086 * ];
4087 *
4088 * _.where(characters, { 'age': 36 });
4089 * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
4090 *
4091 * _.where(characters, { 'pets': ['dino'] });
4092 * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
4093 */
4094 var where = filter;
4095
4096 /*--------------------------------------------------------------------------*/
4097
4098 /**
4099 * Creates an array with all falsey values removed. The values `false`, `null`,
4100 * `0`, `""`, `undefined`, and `NaN` are all falsey.
4101 *
4102 * @static
4103 * @memberOf _
4104 * @category Arrays
4105 * @param {Array} array The array to compact.
4106 * @returns {Array} Returns a new array of filtered values.
4107 * @example
4108 *
4109 * _.compact([0, 1, false, 2, '', 3]);
4110 * // => [1, 2, 3]
4111 */
4112 function compact(array) {
4113 var index = -1,
4114 length = array ? array.length : 0,
4115 result = [];
4116
4117 while (++index < length) {
4118 var value = array[index];
4119 if (value) {
4120 result.push(value);
4121 }
4122 }
4123 return result;
4124 }
4125
4126 /**
4127 * Creates an array excluding all values of the provided arrays using strict
4128 * equality for comparisons, i.e. `===`.
4129 *
4130 * @static
4131 * @memberOf _
4132 * @category Arrays
4133 * @param {Array} array The array to process.
4134 * @param {...Array} [values] The arrays of values to exclude.
4135 * @returns {Array} Returns a new array of filtered values.
4136 * @example
4137 *
4138 * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
4139 * // => [1, 3, 4]
4140 */
4141 function difference(array) {
4142 return baseDifference(array, baseFlatten(arguments, true, true, 1));
4143 }
4144
4145 /**
4146 * This method is like `_.find` except that it returns the index of the first
4147 * element that passes the callback check, instead of the element itself.
4148 *
4149 * If a property name is provided for `callback` the created "_.pluck" style
4150 * callback will return the property value of the given element.
4151 *
4152 * If an object is provided for `callback` the created "_.where" style callback
4153 * will return `true` for elements that have the properties of the given object,
4154 * else `false`.
4155 *
4156 * @static
4157 * @memberOf _
4158 * @category Arrays
4159 * @param {Array} array The array to search.
4160 * @param {Function|Object|string} [callback=identity] The function called
4161 * per iteration. If a property name or object is provided it will be used
4162 * to create a "_.pluck" or "_.where" style callback, respectively.
4163 * @param {*} [thisArg] The `this` binding of `callback`.
4164 * @returns {number} Returns the index of the found element, else `-1`.
4165 * @example
4166 *
4167 * var characters = [
4168 * { 'name': 'barney', 'age': 36, 'blocked': false },
4169 * { 'name': 'fred', 'age': 40, 'blocked': true },
4170 * { 'name': 'pebbles', 'age': 1, 'blocked': false }
4171 * ];
4172 *
4173 * _.findIndex(characters, function(chr) {
4174 * return chr.age < 20;
4175 * });
4176 * // => 2
4177 *
4178 * // using "_.where" callback shorthand
4179 * _.findIndex(characters, { 'age': 36 });
4180 * // => 0
4181 *
4182 * // using "_.pluck" callback shorthand
4183 * _.findIndex(characters, 'blocked');
4184 * // => 1
4185 */
4186 function findIndex(array, callback, thisArg) {
4187 var index = -1,
4188 length = array ? array.length : 0;
4189
4190 callback = lodash.createCallback(callback, thisArg, 3);
4191 while (++index < length) {
4192 if (callback(array[index], index, array)) {
4193 return index;
4194 }
4195 }
4196 return -1;
4197 }
4198
4199 /**
4200 * This method is like `_.findIndex` except that it iterates over elements
4201 * of a `collection` from right to left.
4202 *
4203 * If a property name is provided for `callback` the created "_.pluck" style
4204 * callback will return the property value of the given element.
4205 *
4206 * If an object is provided for `callback` the created "_.where" style callback
4207 * will return `true` for elements that have the properties of the given object,
4208 * else `false`.
4209 *
4210 * @static
4211 * @memberOf _
4212 * @category Arrays
4213 * @param {Array} array The array to search.
4214 * @param {Function|Object|string} [callback=identity] The function called
4215 * per iteration. If a property name or object is provided it will be used
4216 * to create a "_.pluck" or "_.where" style callback, respectively.
4217 * @param {*} [thisArg] The `this` binding of `callback`.
4218 * @returns {number} Returns the index of the found element, else `-1`.
4219 * @example
4220 *
4221 * var characters = [
4222 * { 'name': 'barney', 'age': 36, 'blocked': true },
4223 * { 'name': 'fred', 'age': 40, 'blocked': false },
4224 * { 'name': 'pebbles', 'age': 1, 'blocked': true }
4225 * ];
4226 *
4227 * _.findLastIndex(characters, function(chr) {
4228 * return chr.age > 30;
4229 * });
4230 * // => 1
4231 *
4232 * // using "_.where" callback shorthand
4233 * _.findLastIndex(characters, { 'age': 36 });
4234 * // => 0
4235 *
4236 * // using "_.pluck" callback shorthand
4237 * _.findLastIndex(characters, 'blocked');
4238 * // => 2
4239 */
4240 function findLastIndex(array, callback, thisArg) {
4241 var length = array ? array.length : 0;
4242 callback = lodash.createCallback(callback, thisArg, 3);
4243 while (length--) {
4244 if (callback(array[length], length, array)) {
4245 return length;
4246 }
4247 }
4248 return -1;
4249 }
4250
4251 /**
4252 * Gets the first element or first `n` elements of an array. If a callback
4253 * is provided elements at the beginning of the array are returned as long
4254 * as the callback returns truey. The callback is bound to `thisArg` and
4255 * invoked with three arguments; (value, index, array).
4256 *
4257 * If a property name is provided for `callback` the created "_.pluck" style
4258 * callback will return the property value of the given element.
4259 *
4260 * If an object is provided for `callback` the created "_.where" style callback
4261 * will return `true` for elements that have the properties of the given object,
4262 * else `false`.
4263 *
4264 * @static
4265 * @memberOf _
4266 * @alias head, take
4267 * @category Arrays
4268 * @param {Array} array The array to query.
4269 * @param {Function|Object|number|string} [callback] The function called
4270 * per element or the number of elements to return. If a property name or
4271 * object is provided it will be used to create a "_.pluck" or "_.where"
4272 * style callback, respectively.
4273 * @param {*} [thisArg] The `this` binding of `callback`.
4274 * @returns {*} Returns the first element(s) of `array`.
4275 * @example
4276 *
4277 * _.first([1, 2, 3]);
4278 * // => 1
4279 *
4280 * _.first([1, 2, 3], 2);
4281 * // => [1, 2]
4282 *
4283 * _.first([1, 2, 3], function(num) {
4284 * return num < 3;
4285 * });
4286 * // => [1, 2]
4287 *
4288 * var characters = [
4289 * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
4290 * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
4291 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
4292 * ];
4293 *
4294 * // using "_.pluck" callback shorthand
4295 * _.first(characters, 'blocked');
4296 * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
4297 *
4298 * // using "_.where" callback shorthand
4299 * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
4300 * // => ['barney', 'fred']
4301 */
4302 function first(array, callback, thisArg) {
4303 var n = 0,
4304 length = array ? array.length : 0;
4305
4306 if (typeof callback != 'number' && callback != null) {
4307 var index = -1;
4308 callback = lodash.createCallback(callback, thisArg, 3);
4309 while (++index < length && callback(array[index], index, array)) {
4310 n++;
4311 }
4312 } else {
4313 n = callback;
4314 if (n == null || thisArg) {
4315 return array ? array[0] : undefined;
4316 }
4317 }
4318 return slice(array, 0, nativeMin(nativeMax(0, n), length));
4319 }
4320
4321 /**
4322 * Flattens a nested array (the nesting can be to any depth). If `isShallow`
4323 * is truey, the array will only be flattened a single level. If a callback
4324 * is provided each element of the array is passed through the callback before
4325 * flattening. The callback is bound to `thisArg` and invoked with three
4326 * arguments; (value, index, array).
4327 *
4328 * If a property name is provided for `callback` the created "_.pluck" style
4329 * callback will return the property value of the given element.
4330 *
4331 * If an object is provided for `callback` the created "_.where" style callback
4332 * will return `true` for elements that have the properties of the given object,
4333 * else `false`.
4334 *
4335 * @static
4336 * @memberOf _
4337 * @category Arrays
4338 * @param {Array} array The array to flatten.
4339 * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
4340 * @param {Function|Object|string} [callback=identity] The function called
4341 * per iteration. If a property name or object is provided it will be used
4342 * to create a "_.pluck" or "_.where" style callback, respectively.
4343 * @param {*} [thisArg] The `this` binding of `callback`.
4344 * @returns {Array} Returns a new flattened array.
4345 * @example
4346 *
4347 * _.flatten([1, [2], [3, [[4]]]]);
4348 * // => [1, 2, 3, 4];
4349 *
4350 * _.flatten([1, [2], [3, [[4]]]], true);
4351 * // => [1, 2, 3, [[4]]];
4352 *
4353 * var characters = [
4354 * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
4355 * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
4356 * ];
4357 *
4358 * // using "_.pluck" callback shorthand
4359 * _.flatten(characters, 'pets');
4360 * // => ['hoppy', 'baby puss', 'dino']
4361 */
4362 function flatten(array, isShallow, callback, thisArg) {
4363 // juggle arguments
4364 if (typeof isShallow != 'boolean' && isShallow != null) {
4365 thisArg = callback;
4366 callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow;
4367 isShallow = false;
4368 }
4369 if (callback != null) {
4370 array = map(array, callback, thisArg);
4371 }
4372 return baseFlatten(array, isShallow);
4373 }
4374
4375 /**
4376 * Gets the index at which the first occurrence of `value` is found using
4377 * strict equality for comparisons, i.e. `===`. If the array is already sorted
4378 * providing `true` for `fromIndex` will run a faster binary search.
4379 *
4380 * @static
4381 * @memberOf _
4382 * @category Arrays
4383 * @param {Array} array The array to search.
4384 * @param {*} value The value to search for.
4385 * @param {boolean|number} [fromIndex=0] The index to search from or `true`
4386 * to perform a binary search on a sorted array.
4387 * @returns {number} Returns the index of the matched value or `-1`.
4388 * @example
4389 *
4390 * _.indexOf([1, 2, 3, 1, 2, 3], 2);
4391 * // => 1
4392 *
4393 * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
4394 * // => 4
4395 *
4396 * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
4397 * // => 2
4398 */
4399 function indexOf(array, value, fromIndex) {
4400 if (typeof fromIndex == 'number') {
4401 var length = array ? array.length : 0;
4402 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
4403 } else if (fromIndex) {
4404 var index = sortedIndex(array, value);
4405 return array[index] === value ? index : -1;
4406 }
4407 return baseIndexOf(array, value, fromIndex);
4408 }
4409
4410 /**
4411 * Gets all but the last element or last `n` elements of an array. If a
4412 * callback is provided elements at the end of the array are excluded from
4413 * the result as long as the callback returns truey. The callback is bound
4414 * to `thisArg` and invoked with three arguments; (value, index, array).
4415 *
4416 * If a property name is provided for `callback` the created "_.pluck" style
4417 * callback will return the property value of the given element.
4418 *
4419 * If an object is provided for `callback` the created "_.where" style callback
4420 * will return `true` for elements that have the properties of the given object,
4421 * else `false`.
4422 *
4423 * @static
4424 * @memberOf _
4425 * @category Arrays
4426 * @param {Array} array The array to query.
4427 * @param {Function|Object|number|string} [callback=1] The function called
4428 * per element or the number of elements to exclude. If a property name or
4429 * object is provided it will be used to create a "_.pluck" or "_.where"
4430 * style callback, respectively.
4431 * @param {*} [thisArg] The `this` binding of `callback`.
4432 * @returns {Array} Returns a slice of `array`.
4433 * @example
4434 *
4435 * _.initial([1, 2, 3]);
4436 * // => [1, 2]
4437 *
4438 * _.initial([1, 2, 3], 2);
4439 * // => [1]
4440 *
4441 * _.initial([1, 2, 3], function(num) {
4442 * return num > 1;
4443 * });
4444 * // => [1]
4445 *
4446 * var characters = [
4447 * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
4448 * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
4449 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
4450 * ];
4451 *
4452 * // using "_.pluck" callback shorthand
4453 * _.initial(characters, 'blocked');
4454 * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
4455 *
4456 * // using "_.where" callback shorthand
4457 * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
4458 * // => ['barney', 'fred']
4459 */
4460 function initial(array, callback, thisArg) {
4461 var n = 0,
4462 length = array ? array.length : 0;
4463
4464 if (typeof callback != 'number' && callback != null) {
4465 var index = length;
4466 callback = lodash.createCallback(callback, thisArg, 3);
4467 while (index-- && callback(array[index], index, array)) {
4468 n++;
4469 }
4470 } else {
4471 n = (callback == null || thisArg) ? 1 : callback || n;
4472 }
4473 return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
4474 }
4475
4476 /**
4477 * Creates an array of unique values present in all provided arrays using
4478 * strict equality for comparisons, i.e. `===`.
4479 *
4480 * @static
4481 * @memberOf _
4482 * @category Arrays
4483 * @param {...Array} [array] The arrays to inspect.
4484 * @returns {Array} Returns an array of shared values.
4485 * @example
4486 *
4487 * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
4488 * // => [1, 2]
4489 */
4490 function intersection() {
4491 var args = [],
4492 argsIndex = -1,
4493 argsLength = arguments.length,
4494 caches = getArray(),
4495 indexOf = getIndexOf(),
4496 trustIndexOf = indexOf === baseIndexOf,
4497 seen = getArray();
4498
4499 while (++argsIndex < argsLength) {
4500 var value = arguments[argsIndex];
4501 if (isArray(value) || isArguments(value)) {
4502 args.push(value);
4503 caches.push(trustIndexOf && value.length >= largeArraySize &&
4504 createCache(argsIndex ? args[argsIndex] : seen));
4505 }
4506 }
4507 var array = args[0],
4508 index = -1,
4509 length = array ? array.length : 0,
4510 result = [];
4511
4512 outer:
4513 while (++index < length) {
4514 var cache = caches[0];
4515 value = array[index];
4516
4517 if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
4518 argsIndex = argsLength;
4519 (cache || seen).push(value);
4520 while (--argsIndex) {
4521 cache = caches[argsIndex];
4522 if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
4523 continue outer;
4524 }
4525 }
4526 result.push(value);
4527 }
4528 }
4529 while (argsLength--) {
4530 cache = caches[argsLength];
4531 if (cache) {
4532 releaseObject(cache);
4533 }
4534 }
4535 releaseArray(caches);
4536 releaseArray(seen);
4537 return result;
4538 }
4539
4540 /**
4541 * Gets the last element or last `n` elements of an array. If a callback is
4542 * provided elements at the end of the array are returned as long as the
4543 * callback returns truey. The callback is bound to `thisArg` and invoked
4544 * with three arguments; (value, index, array).
4545 *
4546 * If a property name is provided for `callback` the created "_.pluck" style
4547 * callback will return the property value of the given element.
4548 *
4549 * If an object is provided for `callback` the created "_.where" style callback
4550 * will return `true` for elements that have the properties of the given object,
4551 * else `false`.
4552 *
4553 * @static
4554 * @memberOf _
4555 * @category Arrays
4556 * @param {Array} array The array to query.
4557 * @param {Function|Object|number|string} [callback] The function called
4558 * per element or the number of elements to return. If a property name or
4559 * object is provided it will be used to create a "_.pluck" or "_.where"
4560 * style callback, respectively.
4561 * @param {*} [thisArg] The `this` binding of `callback`.
4562 * @returns {*} Returns the last element(s) of `array`.
4563 * @example
4564 *
4565 * _.last([1, 2, 3]);
4566 * // => 3
4567 *
4568 * _.last([1, 2, 3], 2);
4569 * // => [2, 3]
4570 *
4571 * _.last([1, 2, 3], function(num) {
4572 * return num > 1;
4573 * });
4574 * // => [2, 3]
4575 *
4576 * var characters = [
4577 * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
4578 * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
4579 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
4580 * ];
4581 *
4582 * // using "_.pluck" callback shorthand
4583 * _.pluck(_.last(characters, 'blocked'), 'name');
4584 * // => ['fred', 'pebbles']
4585 *
4586 * // using "_.where" callback shorthand
4587 * _.last(characters, { 'employer': 'na' });
4588 * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
4589 */
4590 function last(array, callback, thisArg) {
4591 var n = 0,
4592 length = array ? array.length : 0;
4593
4594 if (typeof callback != 'number' && callback != null) {
4595 var index = length;
4596 callback = lodash.createCallback(callback, thisArg, 3);
4597 while (index-- && callback(array[index], index, array)) {
4598 n++;
4599 }
4600 } else {
4601 n = callback;
4602 if (n == null || thisArg) {
4603 return array ? array[length - 1] : undefined;
4604 }
4605 }
4606 return slice(array, nativeMax(0, length - n));
4607 }
4608
4609 /**
4610 * Gets the index at which the last occurrence of `value` is found using strict
4611 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
4612 * as the offset from the end of the collection.
4613 *
4614 * If a property name is provided for `callback` the created "_.pluck" style
4615 * callback will return the property value of the given element.
4616 *
4617 * If an object is provided for `callback` the created "_.where" style callback
4618 * will return `true` for elements that have the properties of the given object,
4619 * else `false`.
4620 *
4621 * @static
4622 * @memberOf _
4623 * @category Arrays
4624 * @param {Array} array The array to search.
4625 * @param {*} value The value to search for.
4626 * @param {number} [fromIndex=array.length-1] The index to search from.
4627 * @returns {number} Returns the index of the matched value or `-1`.
4628 * @example
4629 *
4630 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
4631 * // => 4
4632 *
4633 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
4634 * // => 1
4635 */
4636 function lastIndexOf(array, value, fromIndex) {
4637 var index = array ? array.length : 0;
4638 if (typeof fromIndex == 'number') {
4639 index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
4640 }
4641 while (index--) {
4642 if (array[index] === value) {
4643 return index;
4644 }
4645 }
4646 return -1;
4647 }
4648
4649 /**
4650 * Removes all provided values from the given array using strict equality for
4651 * comparisons, i.e. `===`.
4652 *
4653 * @static
4654 * @memberOf _
4655 * @category Arrays
4656 * @param {Array} array The array to modify.
4657 * @param {...*} [value] The values to remove.
4658 * @returns {Array} Returns `array`.
4659 * @example
4660 *
4661 * var array = [1, 2, 3, 1, 2, 3];
4662 * _.pull(array, 2, 3);
4663 * console.log(array);
4664 * // => [1, 1]
4665 */
4666 function pull(array) {
4667 var args = arguments,
4668 argsIndex = 0,
4669 argsLength = args.length,
4670 length = array ? array.length : 0;
4671
4672 while (++argsIndex < argsLength) {
4673 var index = -1,
4674 value = args[argsIndex];
4675 while (++index < length) {
4676 if (array[index] === value) {
4677 splice.call(array, index--, 1);
4678 length--;
4679 }
4680 }
4681 }
4682 return array;
4683 }
4684
4685 /**
4686 * Creates an array of numbers (positive and/or negative) progressing from
4687 * `start` up to but not including `end`. If `start` is less than `stop` a
4688 * zero-length range is created unless a negative `step` is specified.
4689 *
4690 * @static
4691 * @memberOf _
4692 * @category Arrays
4693 * @param {number} [start=0] The start of the range.
4694 * @param {number} end The end of the range.
4695 * @param {number} [step=1] The value to increment or decrement by.
4696 * @returns {Array} Returns a new range array.
4697 * @example
4698 *
4699 * _.range(4);
4700 * // => [0, 1, 2, 3]
4701 *
4702 * _.range(1, 5);
4703 * // => [1, 2, 3, 4]
4704 *
4705 * _.range(0, 20, 5);
4706 * // => [0, 5, 10, 15]
4707 *
4708 * _.range(0, -4, -1);
4709 * // => [0, -1, -2, -3]
4710 *
4711 * _.range(1, 4, 0);
4712 * // => [1, 1, 1]
4713 *
4714 * _.range(0);
4715 * // => []
4716 */
4717 function range(start, end, step) {
4718 start = +start || 0;
4719 step = typeof step == 'number' ? step : (+step || 1);
4720
4721 if (end == null) {
4722 end = start;
4723 start = 0;
4724 }
4725 // use `Array(length)` so engines like Chakra and V8 avoid slower modes
4726 // http://youtu.be/XAqIpGU8ZZk#t=17m25s
4727 var index = -1,
4728 length = nativeMax(0, ceil((end - start) / (step || 1))),
4729 result = Array(length);
4730
4731 while (++index < length) {
4732 result[index] = start;
4733 start += step;
4734 }
4735 return result;
4736 }
4737
4738 /**
4739 * Removes all elements from an array that the callback returns truey for
4740 * and returns an array of removed elements. The callback is bound to `thisArg`
4741 * and invoked with three arguments; (value, index, array).
4742 *
4743 * If a property name is provided for `callback` the created "_.pluck" style
4744 * callback will return the property value of the given element.
4745 *
4746 * If an object is provided for `callback` the created "_.where" style callback
4747 * will return `true` for elements that have the properties of the given object,
4748 * else `false`.
4749 *
4750 * @static
4751 * @memberOf _
4752 * @category Arrays
4753 * @param {Array} array The array to modify.
4754 * @param {Function|Object|string} [callback=identity] The function called
4755 * per iteration. If a property name or object is provided it will be used
4756 * to create a "_.pluck" or "_.where" style callback, respectively.
4757 * @param {*} [thisArg] The `this` binding of `callback`.
4758 * @returns {Array} Returns a new array of removed elements.
4759 * @example
4760 *
4761 * var array = [1, 2, 3, 4, 5, 6];
4762 * var evens = _.remove(array, function(num) { return num % 2 == 0; });
4763 *
4764 * console.log(array);
4765 * // => [1, 3, 5]
4766 *
4767 * console.log(evens);
4768 * // => [2, 4, 6]
4769 */
4770 function remove(array, callback, thisArg) {
4771 var index = -1,
4772 length = array ? array.length : 0,
4773 result = [];
4774
4775 callback = lodash.createCallback(callback, thisArg, 3);
4776 while (++index < length) {
4777 var value = array[index];
4778 if (callback(value, index, array)) {
4779 result.push(value);
4780 splice.call(array, index--, 1);
4781 length--;
4782 }
4783 }
4784 return result;
4785 }
4786
4787 /**
4788 * The opposite of `_.initial` this method gets all but the first element or
4789 * first `n` elements of an array. If a callback function is provided elements
4790 * at the beginning of the array are excluded from the result as long as the
4791 * callback returns truey. The callback is bound to `thisArg` and invoked
4792 * with three arguments; (value, index, array).
4793 *
4794 * If a property name is provided for `callback` the created "_.pluck" style
4795 * callback will return the property value of the given element.
4796 *
4797 * If an object is provided for `callback` the created "_.where" style callback
4798 * will return `true` for elements that have the properties of the given object,
4799 * else `false`.
4800 *
4801 * @static
4802 * @memberOf _
4803 * @alias drop, tail
4804 * @category Arrays
4805 * @param {Array} array The array to query.
4806 * @param {Function|Object|number|string} [callback=1] The function called
4807 * per element or the number of elements to exclude. If a property name or
4808 * object is provided it will be used to create a "_.pluck" or "_.where"
4809 * style callback, respectively.
4810 * @param {*} [thisArg] The `this` binding of `callback`.
4811 * @returns {Array} Returns a slice of `array`.
4812 * @example
4813 *
4814 * _.rest([1, 2, 3]);
4815 * // => [2, 3]
4816 *
4817 * _.rest([1, 2, 3], 2);
4818 * // => [3]
4819 *
4820 * _.rest([1, 2, 3], function(num) {
4821 * return num < 3;
4822 * });
4823 * // => [3]
4824 *
4825 * var characters = [
4826 * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
4827 * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
4828 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
4829 * ];
4830 *
4831 * // using "_.pluck" callback shorthand
4832 * _.pluck(_.rest(characters, 'blocked'), 'name');
4833 * // => ['fred', 'pebbles']
4834 *
4835 * // using "_.where" callback shorthand
4836 * _.rest(characters, { 'employer': 'slate' });
4837 * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
4838 */
4839 function rest(array, callback, thisArg) {
4840 if (typeof callback != 'number' && callback != null) {
4841 var n = 0,
4842 index = -1,
4843 length = array ? array.length : 0;
4844
4845 callback = lodash.createCallback(callback, thisArg, 3);
4846 while (++index < length && callback(array[index], index, array)) {
4847 n++;
4848 }
4849 } else {
4850 n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
4851 }
4852 return slice(array, n);
4853 }
4854
4855 /**
4856 * Uses a binary search to determine the smallest index at which a value
4857 * should be inserted into a given sorted array in order to maintain the sort
4858 * order of the array. If a callback is provided it will be executed for
4859 * `value` and each element of `array` to compute their sort ranking. The
4860 * callback is bound to `thisArg` and invoked with one argument; (value).
4861 *
4862 * If a property name is provided for `callback` the created "_.pluck" style
4863 * callback will return the property value of the given element.
4864 *
4865 * If an object is provided for `callback` the created "_.where" style callback
4866 * will return `true` for elements that have the properties of the given object,
4867 * else `false`.
4868 *
4869 * @static
4870 * @memberOf _
4871 * @category Arrays
4872 * @param {Array} array The array to inspect.
4873 * @param {*} value The value to evaluate.
4874 * @param {Function|Object|string} [callback=identity] The function called
4875 * per iteration. If a property name or object is provided it will be used
4876 * to create a "_.pluck" or "_.where" style callback, respectively.
4877 * @param {*} [thisArg] The `this` binding of `callback`.
4878 * @returns {number} Returns the index at which `value` should be inserted
4879 * into `array`.
4880 * @example
4881 *
4882 * _.sortedIndex([20, 30, 50], 40);
4883 * // => 2
4884 *
4885 * // using "_.pluck" callback shorthand
4886 * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
4887 * // => 2
4888 *
4889 * var dict = {
4890 * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
4891 * };
4892 *
4893 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
4894 * return dict.wordToNumber[word];
4895 * });
4896 * // => 2
4897 *
4898 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
4899 * return this.wordToNumber[word];
4900 * }, dict);
4901 * // => 2
4902 */
4903 function sortedIndex(array, value, callback, thisArg) {
4904 var low = 0,
4905 high = array ? array.length : low;
4906
4907 // explicitly reference `identity` for better inlining in Firefox
4908 callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
4909 value = callback(value);
4910
4911 while (low < high) {
4912 var mid = (low + high) >>> 1;
4913 (callback(array[mid]) < value)
4914 ? low = mid + 1
4915 : high = mid;
4916 }
4917 return low;
4918 }
4919
4920 /**
4921 * Creates an array of unique values, in order, of the provided arrays using
4922 * strict equality for comparisons, i.e. `===`.
4923 *
4924 * @static
4925 * @memberOf _
4926 * @category Arrays
4927 * @param {...Array} [array] The arrays to inspect.
4928 * @returns {Array} Returns an array of combined values.
4929 * @example
4930 *
4931 * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
4932 * // => [1, 2, 3, 5, 4]
4933 */
4934 function union() {
4935 return baseUniq(baseFlatten(arguments, true, true));
4936 }
4937
4938 /**
4939 * Creates a duplicate-value-free version of an array using strict equality
4940 * for comparisons, i.e. `===`. If the array is sorted, providing
4941 * `true` for `isSorted` will use a faster algorithm. If a callback is provided
4942 * each element of `array` is passed through the callback before uniqueness
4943 * is computed. The callback is bound to `thisArg` and invoked with three
4944 * arguments; (value, index, array).
4945 *
4946 * If a property name is provided for `callback` the created "_.pluck" style
4947 * callback will return the property value of the given element.
4948 *
4949 * If an object is provided for `callback` the created "_.where" style callback
4950 * will return `true` for elements that have the properties of the given object,
4951 * else `false`.
4952 *
4953 * @static
4954 * @memberOf _
4955 * @alias unique
4956 * @category Arrays
4957 * @param {Array} array The array to process.
4958 * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
4959 * @param {Function|Object|string} [callback=identity] The function called
4960 * per iteration. If a property name or object is provided it will be used
4961 * to create a "_.pluck" or "_.where" style callback, respectively.
4962 * @param {*} [thisArg] The `this` binding of `callback`.
4963 * @returns {Array} Returns a duplicate-value-free array.
4964 * @example
4965 *
4966 * _.uniq([1, 2, 1, 3, 1]);
4967 * // => [1, 2, 3]
4968 *
4969 * _.uniq([1, 1, 2, 2, 3], true);
4970 * // => [1, 2, 3]
4971 *
4972 * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
4973 * // => ['A', 'b', 'C']
4974 *
4975 * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
4976 * // => [1, 2.5, 3]
4977 *
4978 * // using "_.pluck" callback shorthand
4979 * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
4980 * // => [{ 'x': 1 }, { 'x': 2 }]
4981 */
4982 function uniq(array, isSorted, callback, thisArg) {
4983 // juggle arguments
4984 if (typeof isSorted != 'boolean' && isSorted != null) {
4985 thisArg = callback;
4986 callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted;
4987 isSorted = false;
4988 }
4989 if (callback != null) {
4990 callback = lodash.createCallback(callback, thisArg, 3);
4991 }
4992 return baseUniq(array, isSorted, callback);
4993 }
4994
4995 /**
4996 * Creates an array excluding all provided values using strict equality for
4997 * comparisons, i.e. `===`.
4998 *
4999 * @static
5000 * @memberOf _
5001 * @category Arrays
5002 * @param {Array} array The array to filter.
5003 * @param {...*} [value] The values to exclude.
5004 * @returns {Array} Returns a new array of filtered values.
5005 * @example
5006 *
5007 * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
5008 * // => [2, 3, 4]
5009 */
5010 function without(array) {
5011 return baseDifference(array, slice(arguments, 1));
5012 }
5013
5014 /**
5015 * Creates an array that is the symmetric difference of the provided arrays.
5016 * See http://en.wikipedia.org/wiki/Symmetric_difference.
5017 *
5018 * @static
5019 * @memberOf _
5020 * @category Arrays
5021 * @param {...Array} [array] The arrays to inspect.
5022 * @returns {Array} Returns an array of values.
5023 * @example
5024 *
5025 * _.xor([1, 2, 3], [5, 2, 1, 4]);
5026 * // => [3, 5, 4]
5027 *
5028 * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
5029 * // => [1, 4, 5]
5030 */
5031 function xor() {
5032 var index = -1,
5033 length = arguments.length;
5034
5035 while (++index < length) {
5036 var array = arguments[index];
5037 if (isArray(array) || isArguments(array)) {
5038 var result = result
5039 ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result)))
5040 : array;
5041 }
5042 }
5043 return result || [];
5044 }
5045
5046 /**
5047 * Creates an array of grouped elements, the first of which contains the first
5048 * elements of the given arrays, the second of which contains the second
5049 * elements of the given arrays, and so on.
5050 *
5051 * @static
5052 * @memberOf _
5053 * @alias unzip
5054 * @category Arrays
5055 * @param {...Array} [array] Arrays to process.
5056 * @returns {Array} Returns a new array of grouped elements.
5057 * @example
5058 *
5059 * _.zip(['fred', 'barney'], [30, 40], [true, false]);
5060 * // => [['fred', 30, true], ['barney', 40, false]]
5061 */
5062 function zip() {
5063 var array = arguments.length > 1 ? arguments : arguments[0],
5064 index = -1,
5065 length = array ? max(pluck(array, 'length')) : 0,
5066 result = Array(length < 0 ? 0 : length);
5067
5068 while (++index < length) {
5069 result[index] = pluck(array, index);
5070 }
5071 return result;
5072 }
5073
5074 /**
5075 * Creates an object composed from arrays of `keys` and `values`. Provide
5076 * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
5077 * or two arrays, one of `keys` and one of corresponding `values`.
5078 *
5079 * @static
5080 * @memberOf _
5081 * @alias object
5082 * @category Arrays
5083 * @param {Array} keys The array of keys.
5084 * @param {Array} [values=[]] The array of values.
5085 * @returns {Object} Returns an object composed of the given keys and
5086 * corresponding values.
5087 * @example
5088 *
5089 * _.zipObject(['fred', 'barney'], [30, 40]);
5090 * // => { 'fred': 30, 'barney': 40 }
5091 */
5092 function zipObject(keys, values) {
5093 var index = -1,
5094 length = keys ? keys.length : 0,
5095 result = {};
5096
5097 if (!values && length && !isArray(keys[0])) {
5098 values = [];
5099 }
5100 while (++index < length) {
5101 var key = keys[index];
5102 if (values) {
5103 result[key] = values[index];
5104 } else if (key) {
5105 result[key[0]] = key[1];
5106 }
5107 }
5108 return result;
5109 }
5110
5111 /*--------------------------------------------------------------------------*/
5112
5113 /**
5114 * Creates a function that executes `func`, with the `this` binding and
5115 * arguments of the created function, only after being called `n` times.
5116 *
5117 * @static
5118 * @memberOf _
5119 * @category Functions
5120 * @param {number} n The number of times the function must be called before
5121 * `func` is executed.
5122 * @param {Function} func The function to restrict.
5123 * @returns {Function} Returns the new restricted function.
5124 * @example
5125 *
5126 * var saves = ['profile', 'settings'];
5127 *
5128 * var done = _.after(saves.length, function() {
5129 * console.log('Done saving!');
5130 * });
5131 *
5132 * _.forEach(saves, function(type) {
5133 * asyncSave({ 'type': type, 'complete': done });
5134 * });
5135 * // => logs 'Done saving!', after all saves have completed
5136 */
5137 function after(n, func) {
5138 if (!isFunction(func)) {
5139 throw new TypeError;
5140 }
5141 return function() {
5142 if (--n < 1) {
5143 return func.apply(this, arguments);
5144 }
5145 };
5146 }
5147
5148 /**
5149 * Creates a function that, when called, invokes `func` with the `this`
5150 * binding of `thisArg` and prepends any additional `bind` arguments to those
5151 * provided to the bound function.
5152 *
5153 * @static
5154 * @memberOf _
5155 * @category Functions
5156 * @param {Function} func The function to bind.
5157 * @param {*} [thisArg] The `this` binding of `func`.
5158 * @param {...*} [arg] Arguments to be partially applied.
5159 * @returns {Function} Returns the new bound function.
5160 * @example
5161 *
5162 * var func = function(greeting) {
5163 * return greeting + ' ' + this.name;
5164 * };
5165 *
5166 * func = _.bind(func, { 'name': 'fred' }, 'hi');
5167 * func();
5168 * // => 'hi fred'
5169 */
5170 function bind(func, thisArg) {
5171 return arguments.length > 2
5172 ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
5173 : createWrapper(func, 1, null, null, thisArg);
5174 }
5175
5176 /**
5177 * Binds methods of an object to the object itself, overwriting the existing
5178 * method. Method names may be specified as individual arguments or as arrays
5179 * of method names. If no method names are provided all the function properties
5180 * of `object` will be bound.
5181 *
5182 * @static
5183 * @memberOf _
5184 * @category Functions
5185 * @param {Object} object The object to bind and assign the bound methods to.
5186 * @param {...string} [methodName] The object method names to
5187 * bind, specified as individual method names or arrays of method names.
5188 * @returns {Object} Returns `object`.
5189 * @example
5190 *
5191 * var view = {
5192 * 'label': 'docs',
5193 * 'onClick': function() { console.log('clicked ' + this.label); }
5194 * };
5195 *
5196 * _.bindAll(view);
5197 * jQuery('#docs').on('click', view.onClick);
5198 * // => logs 'clicked docs', when the button is clicked
5199 */
5200 function bindAll(object) {
5201 var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
5202 index = -1,
5203 length = funcs.length;
5204
5205 while (++index < length) {
5206 var key = funcs[index];
5207 object[key] = createWrapper(object[key], 1, null, null, object);
5208 }
5209 return object;
5210 }
5211
5212 /**
5213 * Creates a function that, when called, invokes the method at `object[key]`
5214 * and prepends any additional `bindKey` arguments to those provided to the bound
5215 * function. This method differs from `_.bind` by allowing bound functions to
5216 * reference methods that will be redefined or don't yet exist.
5217 * See http://michaux.ca/articles/lazy-function-definition-pattern.
5218 *
5219 * @static
5220 * @memberOf _
5221 * @category Functions
5222 * @param {Object} object The object the method belongs to.
5223 * @param {string} key The key of the method.
5224 * @param {...*} [arg] Arguments to be partially applied.
5225 * @returns {Function} Returns the new bound function.
5226 * @example
5227 *
5228 * var object = {
5229 * 'name': 'fred',
5230 * 'greet': function(greeting) {
5231 * return greeting + ' ' + this.name;
5232 * }
5233 * };
5234 *
5235 * var func = _.bindKey(object, 'greet', 'hi');
5236 * func();
5237 * // => 'hi fred'
5238 *
5239 * object.greet = function(greeting) {
5240 * return greeting + 'ya ' + this.name + '!';
5241 * };
5242 *
5243 * func();
5244 * // => 'hiya fred!'
5245 */
5246 function bindKey(object, key) {
5247 return arguments.length > 2
5248 ? createWrapper(key, 19, slice(arguments, 2), null, object)
5249 : createWrapper(key, 3, null, null, object);
5250 }
5251
5252 /**
5253 * Creates a function that is the composition of the provided functions,
5254 * where each function consumes the return value of the function that follows.
5255 * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
5256 * Each function is executed with the `this` binding of the composed function.
5257 *
5258 * @static
5259 * @memberOf _
5260 * @category Functions
5261 * @param {...Function} [func] Functions to compose.
5262 * @returns {Function} Returns the new composed function.
5263 * @example
5264 *
5265 * var realNameMap = {
5266 * 'pebbles': 'penelope'
5267 * };
5268 *
5269 * var format = function(name) {
5270 * name = realNameMap[name.toLowerCase()] || name;
5271 * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
5272 * };
5273 *
5274 * var greet = function(formatted) {
5275 * return 'Hiya ' + formatted + '!';
5276 * };
5277 *
5278 * var welcome = _.compose(greet, format);
5279 * welcome('pebbles');
5280 * // => 'Hiya Penelope!'
5281 */
5282 function compose() {
5283 var funcs = arguments,
5284 length = funcs.length;
5285
5286 while (length--) {
5287 if (!isFunction(funcs[length])) {
5288 throw new TypeError;
5289 }
5290 }
5291 return function() {
5292 var args = arguments,
5293 length = funcs.length;
5294
5295 while (length--) {
5296 args = [funcs[length].apply(this, args)];
5297 }
5298 return args[0];
5299 };
5300 }
5301
5302 /**
5303 * Creates a function which accepts one or more arguments of `func` that when
5304 * invoked either executes `func` returning its result, if all `func` arguments
5305 * have been provided, or returns a function that accepts one or more of the
5306 * remaining `func` arguments, and so on. The arity of `func` can be specified
5307 * if `func.length` is not sufficient.
5308 *
5309 * @static
5310 * @memberOf _
5311 * @category Functions
5312 * @param {Function} func The function to curry.
5313 * @param {number} [arity=func.length] The arity of `func`.
5314 * @returns {Function} Returns the new curried function.
5315 * @example
5316 *
5317 * var curried = _.curry(function(a, b, c) {
5318 * console.log(a + b + c);
5319 * });
5320 *
5321 * curried(1)(2)(3);
5322 * // => 6
5323 *
5324 * curried(1, 2)(3);
5325 * // => 6
5326 *
5327 * curried(1, 2, 3);
5328 * // => 6
5329 */
5330 function curry(func, arity) {
5331 arity = typeof arity == 'number' ? arity : (+arity || func.length);
5332 return createWrapper(func, 4, null, null, null, arity);
5333 }
5334
5335 /**
5336 * Creates a function that will delay the execution of `func` until after
5337 * `wait` milliseconds have elapsed since the last time it was invoked.
5338 * Provide an options object to indicate that `func` should be invoked on
5339 * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
5340 * to the debounced function will return the result of the last `func` call.
5341 *
5342 * Note: If `leading` and `trailing` options are `true` `func` will be called
5343 * on the trailing edge of the timeout only if the the debounced function is
5344 * invoked more than once during the `wait` timeout.
5345 *
5346 * @static
5347 * @memberOf _
5348 * @category Functions
5349 * @param {Function} func The function to debounce.
5350 * @param {number} wait The number of milliseconds to delay.
5351 * @param {Object} [options] The options object.
5352 * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
5353 * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
5354 * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
5355 * @returns {Function} Returns the new debounced function.
5356 * @example
5357 *
5358 * // avoid costly calculations while the window size is in flux
5359 * var lazyLayout = _.debounce(calculateLayout, 150);
5360 * jQuery(window).on('resize', lazyLayout);
5361 *
5362 * // execute `sendMail` when the click event is fired, debouncing subsequent calls
5363 * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
5364 * 'leading': true,
5365 * 'trailing': false
5366 * });
5367 *
5368 * // ensure `batchLog` is executed once after 1 second of debounced calls
5369 * var source = new EventSource('/stream');
5370 * source.addEventListener('message', _.debounce(batchLog, 250, {
5371 * 'maxWait': 1000
5372 * }, false);
5373 */
5374 function debounce(func, wait, options) {
5375 var args,
5376 maxTimeoutId,
5377 result,
5378 stamp,
5379 thisArg,
5380 timeoutId,
5381 trailingCall,
5382 lastCalled = 0,
5383 maxWait = false,
5384 trailing = true;
5385
5386 if (!isFunction(func)) {
5387 throw new TypeError;
5388 }
5389 wait = nativeMax(0, wait) || 0;
5390 if (options === true) {
5391 var leading = true;
5392 trailing = false;
5393 } else if (isObject(options)) {
5394 leading = options.leading;
5395 maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
5396 trailing = 'trailing' in options ? options.trailing : trailing;
5397 }
5398 var delayed = function() {
5399 var remaining = wait - (now() - stamp);
5400 if (remaining <= 0) {
5401 if (maxTimeoutId) {
5402 clearTimeout(maxTimeoutId);
5403 }
5404 var isCalled = trailingCall;
5405 maxTimeoutId = timeoutId = trailingCall = undefined;
5406 if (isCalled) {
5407 lastCalled = now();
5408 result = func.apply(thisArg, args);
5409 if (!timeoutId && !maxTimeoutId) {
5410 args = thisArg = null;
5411 }
5412 }
5413 } else {
5414 timeoutId = setTimeout(delayed, remaining);
5415 }
5416 };
5417
5418 var maxDelayed = function() {
5419 if (timeoutId) {
5420 clearTimeout(timeoutId);
5421 }
5422 maxTimeoutId = timeoutId = trailingCall = undefined;
5423 if (trailing || (maxWait !== wait)) {
5424 lastCalled = now();
5425 result = func.apply(thisArg, args);
5426 if (!timeoutId && !maxTimeoutId) {
5427 args = thisArg = null;
5428 }
5429 }
5430 };
5431
5432 return function() {
5433 args = arguments;
5434 stamp = now();
5435 thisArg = this;
5436 trailingCall = trailing && (timeoutId || !leading);
5437
5438 if (maxWait === false) {
5439 var leadingCall = leading && !timeoutId;
5440 } else {
5441 if (!maxTimeoutId && !leading) {
5442 lastCalled = stamp;
5443 }
5444 var remaining = maxWait - (stamp - lastCalled),
5445 isCalled = remaining <= 0;
5446
5447 if (isCalled) {
5448 if (maxTimeoutId) {
5449 maxTimeoutId = clearTimeout(maxTimeoutId);
5450 }
5451 lastCalled = stamp;
5452 result = func.apply(thisArg, args);
5453 }
5454 else if (!maxTimeoutId) {
5455 maxTimeoutId = setTimeout(maxDelayed, remaining);
5456 }
5457 }
5458 if (isCalled && timeoutId) {
5459 timeoutId = clearTimeout(timeoutId);
5460 }
5461 else if (!timeoutId && wait !== maxWait) {
5462 timeoutId = setTimeout(delayed, wait);
5463 }
5464 if (leadingCall) {
5465 isCalled = true;
5466 result = func.apply(thisArg, args);
5467 }
5468 if (isCalled && !timeoutId && !maxTimeoutId) {
5469 args = thisArg = null;
5470 }
5471 return result;
5472 };
5473 }
5474
5475 /**
5476 * Defers executing the `func` function until the current call stack has cleared.
5477 * Additional arguments will be provided to `func` when it is invoked.
5478 *
5479 * @static
5480 * @memberOf _
5481 * @category Functions
5482 * @param {Function} func The function to defer.
5483 * @param {...*} [arg] Arguments to invoke the function with.
5484 * @returns {number} Returns the timer id.
5485 * @example
5486 *
5487 * _.defer(function(text) { console.log(text); }, 'deferred');
5488 * // logs 'deferred' after one or more milliseconds
5489 */
5490 function defer(func) {
5491 if (!isFunction(func)) {
5492 throw new TypeError;
5493 }
5494 var args = slice(arguments, 1);
5495 return setTimeout(function() { func.apply(undefined, args); }, 1);
5496 }
5497
5498 /**
5499 * Executes the `func` function after `wait` milliseconds. Additional arguments
5500 * will be provided to `func` when it is invoked.
5501 *
5502 * @static
5503 * @memberOf _
5504 * @category Functions
5505 * @param {Function} func The function to delay.
5506 * @param {number} wait The number of milliseconds to delay execution.
5507 * @param {...*} [arg] Arguments to invoke the function with.
5508 * @returns {number} Returns the timer id.
5509 * @example
5510 *
5511 * _.delay(function(text) { console.log(text); }, 1000, 'later');
5512 * // => logs 'later' after one second
5513 */
5514 function delay(func, wait) {
5515 if (!isFunction(func)) {
5516 throw new TypeError;
5517 }
5518 var args = slice(arguments, 2);
5519 return setTimeout(function() { func.apply(undefined, args); }, wait);
5520 }
5521
5522 /**
5523 * Creates a function that memoizes the result of `func`. If `resolver` is
5524 * provided it will be used to determine the cache key for storing the result
5525 * based on the arguments provided to the memoized function. By default, the
5526 * first argument provided to the memoized function is used as the cache key.
5527 * The `func` is executed with the `this` binding of the memoized function.
5528 * The result cache is exposed as the `cache` property on the memoized function.
5529 *
5530 * @static
5531 * @memberOf _
5532 * @category Functions
5533 * @param {Function} func The function to have its output memoized.
5534 * @param {Function} [resolver] A function used to resolve the cache key.
5535 * @returns {Function} Returns the new memoizing function.
5536 * @example
5537 *
5538 * var fibonacci = _.memoize(function(n) {
5539 * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
5540 * });
5541 *
5542 * fibonacci(9)
5543 * // => 34
5544 *
5545 * var data = {
5546 * 'fred': { 'name': 'fred', 'age': 40 },
5547 * 'pebbles': { 'name': 'pebbles', 'age': 1 }
5548 * };
5549 *
5550 * // modifying the result cache
5551 * var get = _.memoize(function(name) { return data[name]; }, _.identity);
5552 * get('pebbles');
5553 * // => { 'name': 'pebbles', 'age': 1 }
5554 *
5555 * get.cache.pebbles.name = 'penelope';
5556 * get('pebbles');
5557 * // => { 'name': 'penelope', 'age': 1 }
5558 */
5559 function memoize(func, resolver) {
5560 if (!isFunction(func)) {
5561 throw new TypeError;
5562 }
5563 var memoized = function() {
5564 var cache = memoized.cache,
5565 key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
5566
5567 return hasOwnProperty.call(cache, key)
5568 ? cache[key]
5569 : (cache[key] = func.apply(this, arguments));
5570 }
5571 memoized.cache = {};
5572 return memoized;
5573 }
5574
5575 /**
5576 * Creates a function that is restricted to execute `func` once. Repeat calls to
5577 * the function will return the value of the first call. The `func` is executed
5578 * with the `this` binding of the created function.
5579 *
5580 * @static
5581 * @memberOf _
5582 * @category Functions
5583 * @param {Function} func The function to restrict.
5584 * @returns {Function} Returns the new restricted function.
5585 * @example
5586 *
5587 * var initialize = _.once(createApplication);
5588 * initialize();
5589 * initialize();
5590 * // `initialize` executes `createApplication` once
5591 */
5592 function once(func) {
5593 var ran,
5594 result;
5595
5596 if (!isFunction(func)) {
5597 throw new TypeError;
5598 }
5599 return function() {
5600 if (ran) {
5601 return result;
5602 }
5603 ran = true;
5604 result = func.apply(this, arguments);
5605
5606 // clear the `func` variable so the function may be garbage collected
5607 func = null;
5608 return result;
5609 };
5610 }
5611
5612 /**
5613 * Creates a function that, when called, invokes `func` with any additional
5614 * `partial` arguments prepended to those provided to the new function. This
5615 * method is similar to `_.bind` except it does **not** alter the `this` binding.
5616 *
5617 * @static
5618 * @memberOf _
5619 * @category Functions
5620 * @param {Function} func The function to partially apply arguments to.
5621 * @param {...*} [arg] Arguments to be partially applied.
5622 * @returns {Function} Returns the new partially applied function.
5623 * @example
5624 *
5625 * var greet = function(greeting, name) { return greeting + ' ' + name; };
5626 * var hi = _.partial(greet, 'hi');
5627 * hi('fred');
5628 * // => 'hi fred'
5629 */
5630 function partial(func) {
5631 return createWrapper(func, 16, slice(arguments, 1));
5632 }
5633
5634 /**
5635 * This method is like `_.partial` except that `partial` arguments are
5636 * appended to those provided to the new function.
5637 *
5638 * @static
5639 * @memberOf _
5640 * @category Functions
5641 * @param {Function} func The function to partially apply arguments to.
5642 * @param {...*} [arg] Arguments to be partially applied.
5643 * @returns {Function} Returns the new partially applied function.
5644 * @example
5645 *
5646 * var defaultsDeep = _.partialRight(_.merge, _.defaults);
5647 *
5648 * var options = {
5649 * 'variable': 'data',
5650 * 'imports': { 'jq': $ }
5651 * };
5652 *
5653 * defaultsDeep(options, _.templateSettings);
5654 *
5655 * options.variable
5656 * // => 'data'
5657 *
5658 * options.imports
5659 * // => { '_': _, 'jq': $ }
5660 */
5661 function partialRight(func) {
5662 return createWrapper(func, 32, null, slice(arguments, 1));
5663 }
5664
5665 /**
5666 * Creates a function that, when executed, will only call the `func` function
5667 * at most once per every `wait` milliseconds. Provide an options object to
5668 * indicate that `func` should be invoked on the leading and/or trailing edge
5669 * of the `wait` timeout. Subsequent calls to the throttled function will
5670 * return the result of the last `func` call.
5671 *
5672 * Note: If `leading` and `trailing` options are `true` `func` will be called
5673 * on the trailing edge of the timeout only if the the throttled function is
5674 * invoked more than once during the `wait` timeout.
5675 *
5676 * @static
5677 * @memberOf _
5678 * @category Functions
5679 * @param {Function} func The function to throttle.
5680 * @param {number} wait The number of milliseconds to throttle executions to.
5681 * @param {Object} [options] The options object.
5682 * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
5683 * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
5684 * @returns {Function} Returns the new throttled function.
5685 * @example
5686 *
5687 * // avoid excessively updating the position while scrolling
5688 * var throttled = _.throttle(updatePosition, 100);
5689 * jQuery(window).on('scroll', throttled);
5690 *
5691 * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
5692 * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
5693 * 'trailing': false
5694 * }));
5695 */
5696 function throttle(func, wait, options) {
5697 var leading = true,
5698 trailing = true;
5699
5700 if (!isFunction(func)) {
5701 throw new TypeError;
5702 }
5703 if (options === false) {
5704 leading = false;
5705 } else if (isObject(options)) {
5706 leading = 'leading' in options ? options.leading : leading;
5707 trailing = 'trailing' in options ? options.trailing : trailing;
5708 }
5709 debounceOptions.leading = leading;
5710 debounceOptions.maxWait = wait;
5711 debounceOptions.trailing = trailing;
5712
5713 return debounce(func, wait, debounceOptions);
5714 }
5715
5716 /**
5717 * Creates a function that provides `value` to the wrapper function as its
5718 * first argument. Additional arguments provided to the function are appended
5719 * to those provided to the wrapper function. The wrapper is executed with
5720 * the `this` binding of the created function.
5721 *
5722 * @static
5723 * @memberOf _
5724 * @category Functions
5725 * @param {*} value The value to wrap.
5726 * @param {Function} wrapper The wrapper function.
5727 * @returns {Function} Returns the new function.
5728 * @example
5729 *
5730 * var p = _.wrap(_.escape, function(func, text) {
5731 * return '<p>' + func(text) + '</p>';
5732 * });
5733 *
5734 * p('Fred, Wilma, & Pebbles');
5735 * // => '<p>Fred, Wilma, &amp; Pebbles</p>'
5736 */
5737 function wrap(value, wrapper) {
5738 return createWrapper(wrapper, 16, [value]);
5739 }
5740
5741 /*--------------------------------------------------------------------------*/
5742
5743 /**
5744 * Creates a function that returns `value`.
5745 *
5746 * @static
5747 * @memberOf _
5748 * @category Utilities
5749 * @param {*} value The value to return from the new function.
5750 * @returns {Function} Returns the new function.
5751 * @example
5752 *
5753 * var object = { 'name': 'fred' };
5754 * var getter = _.constant(object);
5755 * getter() === object;
5756 * // => true
5757 */
5758 function constant(value) {
5759 return function() {
5760 return value;
5761 };
5762 }
5763
5764 /**
5765 * Produces a callback bound to an optional `thisArg`. If `func` is a property
5766 * name the created callback will return the property value for a given element.
5767 * If `func` is an object the created callback will return `true` for elements
5768 * that contain the equivalent object properties, otherwise it will return `false`.
5769 *
5770 * @static
5771 * @memberOf _
5772 * @category Utilities
5773 * @param {*} [func=identity] The value to convert to a callback.
5774 * @param {*} [thisArg] The `this` binding of the created callback.
5775 * @param {number} [argCount] The number of arguments the callback accepts.
5776 * @returns {Function} Returns a callback function.
5777 * @example
5778 *
5779 * var characters = [
5780 * { 'name': 'barney', 'age': 36 },
5781 * { 'name': 'fred', 'age': 40 }
5782 * ];
5783 *
5784 * // wrap to create custom callback shorthands
5785 * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
5786 * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
5787 * return !match ? func(callback, thisArg) : function(object) {
5788 * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
5789 * };
5790 * });
5791 *
5792 * _.filter(characters, 'age__gt38');
5793 * // => [{ 'name': 'fred', 'age': 40 }]
5794 */
5795 function createCallback(func, thisArg, argCount) {
5796 var type = typeof func;
5797 if (func == null || type == 'function') {
5798 return baseCreateCallback(func, thisArg, argCount);
5799 }
5800 // handle "_.pluck" style callback shorthands
5801 if (type != 'object') {
5802 return property(func);
5803 }
5804 var props = keys(func),
5805 key = props[0],
5806 a = func[key];
5807
5808 // handle "_.where" style callback shorthands
5809 if (props.length == 1 && a === a && !isObject(a)) {
5810 // fast path the common case of providing an object with a single
5811 // property containing a primitive value
5812 return function(object) {
5813 var b = object[key];
5814 return a === b && (a !== 0 || (1 / a == 1 / b));
5815 };
5816 }
5817 return function(object) {
5818 var length = props.length,
5819 result = false;
5820
5821 while (length--) {
5822 if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
5823 break;
5824 }
5825 }
5826 return result;
5827 };
5828 }
5829
5830 /**
5831 * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
5832 * corresponding HTML entities.
5833 *
5834 * @static
5835 * @memberOf _
5836 * @category Utilities
5837 * @param {string} string The string to escape.
5838 * @returns {string} Returns the escaped string.
5839 * @example
5840 *
5841 * _.escape('Fred, Wilma, & Pebbles');
5842 * // => 'Fred, Wilma, &amp; Pebbles'
5843 */
5844 function escape(string) {
5845 return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
5846 }
5847
5848 /**
5849 * This method returns the first argument provided to it.
5850 *
5851 * @static
5852 * @memberOf _
5853 * @category Utilities
5854 * @param {*} value Any value.
5855 * @returns {*} Returns `value`.
5856 * @example
5857 *
5858 * var object = { 'name': 'fred' };
5859 * _.identity(object) === object;
5860 * // => true
5861 */
5862 function identity(value) {
5863 return value;
5864 }
5865
5866 /**
5867 * Adds function properties of a source object to the destination object.
5868 * If `object` is a function methods will be added to its prototype as well.
5869 *
5870 * @static
5871 * @memberOf _
5872 * @category Utilities
5873 * @param {Function|Object} [object=lodash] object The destination object.
5874 * @param {Object} source The object of functions to add.
5875 * @param {Object} [options] The options object.
5876 * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
5877 * @example
5878 *
5879 * function capitalize(string) {
5880 * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
5881 * }
5882 *
5883 * _.mixin({ 'capitalize': capitalize });
5884 * _.capitalize('fred');
5885 * // => 'Fred'
5886 *
5887 * _('fred').capitalize().value();
5888 * // => 'Fred'
5889 *
5890 * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
5891 * _('fred').capitalize();
5892 * // => 'Fred'
5893 */
5894 function mixin(object, source, options) {
5895 var chain = true,
5896 methodNames = source && functions(source);
5897
5898 if (!source || (!options && !methodNames.length)) {
5899 if (options == null) {
5900 options = source;
5901 }
5902 ctor = lodashWrapper;
5903 source = object;
5904 object = lodash;
5905 methodNames = functions(source);
5906 }
5907 if (options === false) {
5908 chain = false;
5909 } else if (isObject(options) && 'chain' in options) {
5910 chain = options.chain;
5911 }
5912 var ctor = object,
5913 isFunc = isFunction(ctor);
5914
5915 forEach(methodNames, function(methodName) {
5916 var func = object[methodName] = source[methodName];
5917 if (isFunc) {
5918 ctor.prototype[methodName] = function() {
5919 var chainAll = this.__chain__,
5920 value = this.__wrapped__,
5921 args = [value];
5922
5923 push.apply(args, arguments);
5924 var result = func.apply(object, args);
5925 if (chain || chainAll) {
5926 if (value === result && isObject(result)) {
5927 return this;
5928 }
5929 result = new ctor(result);
5930 result.__chain__ = chainAll;
5931 }
5932 return result;
5933 };
5934 }
5935 });
5936 }
5937
5938 /**
5939 * Reverts the '_' variable to its previous value and returns a reference to
5940 * the `lodash` function.
5941 *
5942 * @static
5943 * @memberOf _
5944 * @category Utilities
5945 * @returns {Function} Returns the `lodash` function.
5946 * @example
5947 *
5948 * var lodash = _.noConflict();
5949 */
5950 function noConflict() {
5951 context._ = oldDash;
5952 return this;
5953 }
5954
5955 /**
5956 * A no-operation function.
5957 *
5958 * @static
5959 * @memberOf _
5960 * @category Utilities
5961 * @example
5962 *
5963 * var object = { 'name': 'fred' };
5964 * _.noop(object) === undefined;
5965 * // => true
5966 */
5967 function noop() {
5968 // no operation performed
5969 }
5970
5971 /**
5972 * Gets the number of milliseconds that have elapsed since the Unix epoch
5973 * (1 January 1970 00:00:00 UTC).
5974 *
5975 * @static
5976 * @memberOf _
5977 * @category Utilities
5978 * @example
5979 *
5980 * var stamp = _.now();
5981 * _.defer(function() { console.log(_.now() - stamp); });
5982 * // => logs the number of milliseconds it took for the deferred function to be called
5983 */
5984 var now = isNative(now = Date.now) && now || function() {
5985 return new Date().getTime();
5986 };
5987
5988 /**
5989 * Converts the given value into an integer of the specified radix.
5990 * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
5991 * `value` is a hexadecimal, in which case a `radix` of `16` is used.
5992 *
5993 * Note: This method avoids differences in native ES3 and ES5 `parseInt`
5994 * implementations. See http://es5.github.io/#E.
5995 *
5996 * @static
5997 * @memberOf _
5998 * @category Utilities
5999 * @param {string} value The value to parse.
6000 * @param {number} [radix] The radix used to interpret the value to parse.
6001 * @returns {number} Returns the new integer value.
6002 * @example
6003 *
6004 * _.parseInt('08');
6005 * // => 8
6006 */
6007 var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
6008 // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt`
6009 return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
6010 };
6011
6012 /**
6013 * Creates a "_.pluck" style function, which returns the `key` value of a
6014 * given object.
6015 *
6016 * @static
6017 * @memberOf _
6018 * @category Utilities
6019 * @param {string} key The name of the property to retrieve.
6020 * @returns {Function} Returns the new function.
6021 * @example
6022 *
6023 * var characters = [
6024 * { 'name': 'fred', 'age': 40 },
6025 * { 'name': 'barney', 'age': 36 }
6026 * ];
6027 *
6028 * var getName = _.property('name');
6029 *
6030 * _.map(characters, getName);
6031 * // => ['barney', 'fred']
6032 *
6033 * _.sortBy(characters, getName);
6034 * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }]
6035 */
6036 function property(key) {
6037 return function(object) {
6038 return object[key];
6039 };
6040 }
6041
6042 /**
6043 * Produces a random number between `min` and `max` (inclusive). If only one
6044 * argument is provided a number between `0` and the given number will be
6045 * returned. If `floating` is truey or either `min` or `max` are floats a
6046 * floating-point number will be returned instead of an integer.
6047 *
6048 * @static
6049 * @memberOf _
6050 * @category Utilities
6051 * @param {number} [min=0] The minimum possible value.
6052 * @param {number} [max=1] The maximum possible value.
6053 * @param {boolean} [floating=false] Specify returning a floating-point number.
6054 * @returns {number} Returns a random number.
6055 * @example
6056 *
6057 * _.random(0, 5);
6058 * // => an integer between 0 and 5
6059 *
6060 * _.random(5);
6061 * // => also an integer between 0 and 5
6062 *
6063 * _.random(5, true);
6064 * // => a floating-point number between 0 and 5
6065 *
6066 * _.random(1.2, 5.2);
6067 * // => a floating-point number between 1.2 and 5.2
6068 */
6069 function random(min, max, floating) {
6070 var noMin = min == null,
6071 noMax = max == null;
6072
6073 if (floating == null) {
6074 if (typeof min == 'boolean' && noMax) {
6075 floating = min;
6076 min = 1;
6077 }
6078 else if (!noMax && typeof max == 'boolean') {
6079 floating = max;
6080 noMax = true;
6081 }
6082 }
6083 if (noMin && noMax) {
6084 max = 1;
6085 }
6086 min = +min || 0;
6087 if (noMax) {
6088 max = min;
6089 min = 0;
6090 } else {
6091 max = +max || 0;
6092 }
6093 if (floating || min % 1 || max % 1) {
6094 var rand = nativeRandom();
6095 return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
6096 }
6097 return baseRandom(min, max);
6098 }
6099
6100 /**
6101 * Resolves the value of property `key` on `object`. If `key` is a function
6102 * it will be invoked with the `this` binding of `object` and its result returned,
6103 * else the property value is returned. If `object` is falsey then `undefined`
6104 * is returned.
6105 *
6106 * @static
6107 * @memberOf _
6108 * @category Utilities
6109 * @param {Object} object The object to inspect.
6110 * @param {string} key The name of the property to resolve.
6111 * @returns {*} Returns the resolved value.
6112 * @example
6113 *
6114 * var object = {
6115 * 'cheese': 'crumpets',
6116 * 'stuff': function() {
6117 * return 'nonsense';
6118 * }
6119 * };
6120 *
6121 * _.result(object, 'cheese');
6122 * // => 'crumpets'
6123 *
6124 * _.result(object, 'stuff');
6125 * // => 'nonsense'
6126 */
6127 function result(object, key) {
6128 if (object) {
6129 var value = object[key];
6130 return isFunction(value) ? object[key]() : value;
6131 }
6132 }
6133
6134 /**
6135 * A micro-templating method that handles arbitrary delimiters, preserves
6136 * whitespace, and correctly escapes quotes within interpolated code.
6137 *
6138 * Note: In the development build, `_.template` utilizes sourceURLs for easier
6139 * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
6140 *
6141 * For more information on precompiling templates see:
6142 * http://lodash.com/custom-builds
6143 *
6144 * For more information on Chrome extension sandboxes see:
6145 * http://developer.chrome.com/stable/extensions/sandboxingEval.html
6146 *
6147 * @static
6148 * @memberOf _
6149 * @category Utilities
6150 * @param {string} text The template text.
6151 * @param {Object} data The data object used to populate the text.
6152 * @param {Object} [options] The options object.
6153 * @param {RegExp} [options.escape] The "escape" delimiter.
6154 * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
6155 * @param {Object} [options.imports] An object to import into the template as local variables.
6156 * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
6157 * @param {string} [sourceURL] The sourceURL of the template's compiled source.
6158 * @param {string} [variable] The data object variable name.
6159 * @returns {Function|string} Returns a compiled function when no `data` object
6160 * is given, else it returns the interpolated text.
6161 * @example
6162 *
6163 * // using the "interpolate" delimiter to create a compiled template
6164 * var compiled = _.template('hello <%= name %>');
6165 * compiled({ 'name': 'fred' });
6166 * // => 'hello fred'
6167 *
6168 * // using the "escape" delimiter to escape HTML in data property values
6169 * _.template('<b><%- value %></b>', { 'value': '<script>' });
6170 * // => '<b>&lt;script&gt;</b>'
6171 *
6172 * // using the "evaluate" delimiter to generate HTML
6173 * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
6174 * _.template(list, { 'people': ['fred', 'barney'] });
6175 * // => '<li>fred</li><li>barney</li>'
6176 *
6177 * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
6178 * _.template('hello ${ name }', { 'name': 'pebbles' });
6179 * // => 'hello pebbles'
6180 *
6181 * // using the internal `print` function in "evaluate" delimiters
6182 * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
6183 * // => 'hello barney!'
6184 *
6185 * // using a custom template delimiters
6186 * _.templateSettings = {
6187 * 'interpolate': /{{([\s\S]+?)}}/g
6188 * };
6189 *
6190 * _.template('hello {{ name }}!', { 'name': 'mustache' });
6191 * // => 'hello mustache!'
6192 *
6193 * // using the `imports` option to import jQuery
6194 * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
6195 * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
6196 * // => '<li>fred</li><li>barney</li>'
6197 *
6198 * // using the `sourceURL` option to specify a custom sourceURL for the template
6199 * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
6200 * compiled(data);
6201 * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
6202 *
6203 * // using the `variable` option to ensure a with-statement isn't used in the compiled template
6204 * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
6205 * compiled.source;
6206 * // => function(data) {
6207 * var __t, __p = '', __e = _.escape;
6208 * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
6209 * return __p;
6210 * }
6211 *
6212 * // using the `source` property to inline compiled templates for meaningful
6213 * // line numbers in error messages and a stack trace
6214 * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
6215 * var JST = {\
6216 * "main": ' + _.template(mainText).source + '\
6217 * };\
6218 * ');
6219 */
6220 function template(text, data, options) {
6221 // based on John Resig's `tmpl` implementation
6222 // http://ejohn.org/blog/javascript-micro-templating/
6223 // and Laura Doktorova's doT.js
6224 // https://github.com/olado/doT
6225 var settings = lodash.templateSettings;
6226 text = String(text || '');
6227
6228 // avoid missing dependencies when `iteratorTemplate` is not defined
6229 options = defaults({}, options, settings);
6230
6231 var imports = defaults({}, options.imports, settings.imports),
6232 importsKeys = keys(imports),
6233 importsValues = values(imports);
6234
6235 var isEvaluating,
6236 index = 0,
6237 interpolate = options.interpolate || reNoMatch,
6238 source = "__p += '";
6239
6240 // compile the regexp to match each delimiter
6241 var reDelimiters = RegExp(
6242 (options.escape || reNoMatch).source + '|' +
6243 interpolate.source + '|' +
6244 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
6245 (options.evaluate || reNoMatch).source + '|$'
6246 , 'g');
6247
6248 text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
6249 interpolateValue || (interpolateValue = esTemplateValue);
6250
6251 // escape characters that cannot be included in string literals
6252 source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
6253
6254 // replace delimiters with snippets
6255 if (escapeValue) {
6256 source += "' +\n__e(" + escapeValue + ") +\n'";
6257 }
6258 if (evaluateValue) {
6259 isEvaluating = true;
6260 source += "';\n" + evaluateValue + ";\n__p += '";
6261 }
6262 if (interpolateValue) {
6263 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
6264 }
6265 index = offset + match.length;
6266
6267 // the JS engine embedded in Adobe products requires returning the `match`
6268 // string in order to produce the correct `offset` value
6269 return match;
6270 });
6271
6272 source += "';\n";
6273
6274 // if `variable` is not specified, wrap a with-statement around the generated
6275 // code to add the data object to the top of the scope chain
6276 var variable = options.variable,
6277 hasVariable = variable;
6278
6279 if (!hasVariable) {
6280 variable = 'obj';
6281 source = 'with (' + variable + ') {\n' + source + '\n}\n';
6282 }
6283 // cleanup code by stripping empty strings
6284 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
6285 .replace(reEmptyStringMiddle, '$1')
6286 .replace(reEmptyStringTrailing, '$1;');
6287
6288 // frame code as the function body
6289 source = 'function(' + variable + ') {\n' +
6290 (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
6291 "var __t, __p = '', __e = _.escape" +
6292 (isEvaluating
6293 ? ', __j = Array.prototype.join;\n' +
6294 "function print() { __p += __j.call(arguments, '') }\n"
6295 : ';\n'
6296 ) +
6297 source +
6298 'return __p\n}';
6299
6300 // Use a sourceURL for easier debugging.
6301 // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
6302 var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
6303
6304 try {
6305 var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
6306 } catch(e) {
6307 e.source = source;
6308 throw e;
6309 }
6310 if (data) {
6311 return result(data);
6312 }
6313 // provide the compiled function's source by its `toString` method, in
6314 // supported environments, or the `source` property as a convenience for
6315 // inlining compiled templates during the build process
6316 result.source = source;
6317 return result;
6318 }
6319
6320 /**
6321 * Executes the callback `n` times, returning an array of the results
6322 * of each callback execution. The callback is bound to `thisArg` and invoked
6323 * with one argument; (index).
6324 *
6325 * @static
6326 * @memberOf _
6327 * @category Utilities
6328 * @param {number} n The number of times to execute the callback.
6329 * @param {Function} callback The function called per iteration.
6330 * @param {*} [thisArg] The `this` binding of `callback`.
6331 * @returns {Array} Returns an array of the results of each `callback` execution.
6332 * @example
6333 *
6334 * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
6335 * // => [3, 6, 4]
6336 *
6337 * _.times(3, function(n) { mage.castSpell(n); });
6338 * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
6339 *
6340 * _.times(3, function(n) { this.cast(n); }, mage);
6341 * // => also calls `mage.castSpell(n)` three times
6342 */
6343 function times(n, callback, thisArg) {
6344 n = (n = +n) > -1 ? n : 0;
6345 var index = -1,
6346 result = Array(n);
6347
6348 callback = baseCreateCallback(callback, thisArg, 1);
6349 while (++index < n) {
6350 result[index] = callback(index);
6351 }
6352 return result;
6353 }
6354
6355 /**
6356 * The inverse of `_.escape` this method converts the HTML entities
6357 * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
6358 * corresponding characters.
6359 *
6360 * @static
6361 * @memberOf _
6362 * @category Utilities
6363 * @param {string} string The string to unescape.
6364 * @returns {string} Returns the unescaped string.
6365 * @example
6366 *
6367 * _.unescape('Fred, Barney &amp; Pebbles');
6368 * // => 'Fred, Barney & Pebbles'
6369 */
6370 function unescape(string) {
6371 return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
6372 }
6373
6374 /**
6375 * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
6376 *
6377 * @static
6378 * @memberOf _
6379 * @category Utilities
6380 * @param {string} [prefix] The value to prefix the ID with.
6381 * @returns {string} Returns the unique ID.
6382 * @example
6383 *
6384 * _.uniqueId('contact_');
6385 * // => 'contact_104'
6386 *
6387 * _.uniqueId();
6388 * // => '105'
6389 */
6390 function uniqueId(prefix) {
6391 var id = ++idCounter;
6392 return String(prefix == null ? '' : prefix) + id;
6393 }
6394
6395 /*--------------------------------------------------------------------------*/
6396
6397 /**
6398 * Creates a `lodash` object that wraps the given value with explicit
6399 * method chaining enabled.
6400 *
6401 * @static
6402 * @memberOf _
6403 * @category Chaining
6404 * @param {*} value The value to wrap.
6405 * @returns {Object} Returns the wrapper object.
6406 * @example
6407 *
6408 * var characters = [
6409 * { 'name': 'barney', 'age': 36 },
6410 * { 'name': 'fred', 'age': 40 },
6411 * { 'name': 'pebbles', 'age': 1 }
6412 * ];
6413 *
6414 * var youngest = _.chain(characters)
6415 * .sortBy('age')
6416 * .map(function(chr) { return chr.name + ' is ' + chr.age; })
6417 * .first()
6418 * .value();
6419 * // => 'pebbles is 1'
6420 */
6421 function chain(value) {
6422 value = new lodashWrapper(value);
6423 value.__chain__ = true;
6424 return value;
6425 }
6426
6427 /**
6428 * Invokes `interceptor` with the `value` as the first argument and then
6429 * returns `value`. The purpose of this method is to "tap into" a method
6430 * chain in order to perform operations on intermediate results within
6431 * the chain.
6432 *
6433 * @static
6434 * @memberOf _
6435 * @category Chaining
6436 * @param {*} value The value to provide to `interceptor`.
6437 * @param {Function} interceptor The function to invoke.
6438 * @returns {*} Returns `value`.
6439 * @example
6440 *
6441 * _([1, 2, 3, 4])
6442 * .tap(function(array) { array.pop(); })
6443 * .reverse()
6444 * .value();
6445 * // => [3, 2, 1]
6446 */
6447 function tap(value, interceptor) {
6448 interceptor(value);
6449 return value;
6450 }
6451
6452 /**
6453 * Enables explicit method chaining on the wrapper object.
6454 *
6455 * @name chain
6456 * @memberOf _
6457 * @category Chaining
6458 * @returns {*} Returns the wrapper object.
6459 * @example
6460 *
6461 * var characters = [
6462 * { 'name': 'barney', 'age': 36 },
6463 * { 'name': 'fred', 'age': 40 }
6464 * ];
6465 *
6466 * // without explicit chaining
6467 * _(characters).first();
6468 * // => { 'name': 'barney', 'age': 36 }
6469 *
6470 * // with explicit chaining
6471 * _(characters).chain()
6472 * .first()
6473 * .pick('age')
6474 * .value();
6475 * // => { 'age': 36 }
6476 */
6477 function wrapperChain() {
6478 this.__chain__ = true;
6479 return this;
6480 }
6481
6482 /**
6483 * Produces the `toString` result of the wrapped value.
6484 *
6485 * @name toString
6486 * @memberOf _
6487 * @category Chaining
6488 * @returns {string} Returns the string result.
6489 * @example
6490 *
6491 * _([1, 2, 3]).toString();
6492 * // => '1,2,3'
6493 */
6494 function wrapperToString() {
6495 return String(this.__wrapped__);
6496 }
6497
6498 /**
6499 * Extracts the wrapped value.
6500 *
6501 * @name valueOf
6502 * @memberOf _
6503 * @alias value
6504 * @category Chaining
6505 * @returns {*} Returns the wrapped value.
6506 * @example
6507 *
6508 * _([1, 2, 3]).valueOf();
6509 * // => [1, 2, 3]
6510 */
6511 function wrapperValueOf() {
6512 return this.__wrapped__;
6513 }
6514
6515 /*--------------------------------------------------------------------------*/
6516
6517 // add functions that return wrapped values when chaining
6518 lodash.after = after;
6519 lodash.assign = assign;
6520 lodash.at = at;
6521 lodash.bind = bind;
6522 lodash.bindAll = bindAll;
6523 lodash.bindKey = bindKey;
6524 lodash.chain = chain;
6525 lodash.compact = compact;
6526 lodash.compose = compose;
6527 lodash.constant = constant;
6528 lodash.countBy = countBy;
6529 lodash.create = create;
6530 lodash.createCallback = createCallback;
6531 lodash.curry = curry;
6532 lodash.debounce = debounce;
6533 lodash.defaults = defaults;
6534 lodash.defer = defer;
6535 lodash.delay = delay;
6536 lodash.difference = difference;
6537 lodash.filter = filter;
6538 lodash.flatten = flatten;
6539 lodash.forEach = forEach;
6540 lodash.forEachRight = forEachRight;
6541 lodash.forIn = forIn;
6542 lodash.forInRight = forInRight;
6543 lodash.forOwn = forOwn;
6544 lodash.forOwnRight = forOwnRight;
6545 lodash.functions = functions;
6546 lodash.groupBy = groupBy;
6547 lodash.indexBy = indexBy;
6548 lodash.initial = initial;
6549 lodash.intersection = intersection;
6550 lodash.invert = invert;
6551 lodash.invoke = invoke;
6552 lodash.keys = keys;
6553 lodash.map = map;
6554 lodash.mapValues = mapValues;
6555 lodash.max = max;
6556 lodash.memoize = memoize;
6557 lodash.merge = merge;
6558 lodash.min = min;
6559 lodash.omit = omit;
6560 lodash.once = once;
6561 lodash.pairs = pairs;
6562 lodash.partial = partial;
6563 lodash.partialRight = partialRight;
6564 lodash.pick = pick;
6565 lodash.pluck = pluck;
6566 lodash.property = property;
6567 lodash.pull = pull;
6568 lodash.range = range;
6569 lodash.reject = reject;
6570 lodash.remove = remove;
6571 lodash.rest = rest;
6572 lodash.shuffle = shuffle;
6573 lodash.sortBy = sortBy;
6574 lodash.tap = tap;
6575 lodash.throttle = throttle;
6576 lodash.times = times;
6577 lodash.toArray = toArray;
6578 lodash.transform = transform;
6579 lodash.union = union;
6580 lodash.uniq = uniq;
6581 lodash.values = values;
6582 lodash.where = where;
6583 lodash.without = without;
6584 lodash.wrap = wrap;
6585 lodash.xor = xor;
6586 lodash.zip = zip;
6587 lodash.zipObject = zipObject;
6588
6589 // add aliases
6590 lodash.collect = map;
6591 lodash.drop = rest;
6592 lodash.each = forEach;
6593 lodash.eachRight = forEachRight;
6594 lodash.extend = assign;
6595 lodash.methods = functions;
6596 lodash.object = zipObject;
6597 lodash.select = filter;
6598 lodash.tail = rest;
6599 lodash.unique = uniq;
6600 lodash.unzip = zip;
6601
6602 // add functions to `lodash.prototype`
6603 mixin(lodash);
6604
6605 /*--------------------------------------------------------------------------*/
6606
6607 // add functions that return unwrapped values when chaining
6608 lodash.clone = clone;
6609 lodash.cloneDeep = cloneDeep;
6610 lodash.contains = contains;
6611 lodash.escape = escape;
6612 lodash.every = every;
6613 lodash.find = find;
6614 lodash.findIndex = findIndex;
6615 lodash.findKey = findKey;
6616 lodash.findLast = findLast;
6617 lodash.findLastIndex = findLastIndex;
6618 lodash.findLastKey = findLastKey;
6619 lodash.has = has;
6620 lodash.identity = identity;
6621 lodash.indexOf = indexOf;
6622 lodash.isArguments = isArguments;
6623 lodash.isArray = isArray;
6624 lodash.isBoolean = isBoolean;
6625 lodash.isDate = isDate;
6626 lodash.isElement = isElement;
6627 lodash.isEmpty = isEmpty;
6628 lodash.isEqual = isEqual;
6629 lodash.isFinite = isFinite;
6630 lodash.isFunction = isFunction;
6631 lodash.isNaN = isNaN;
6632 lodash.isNull = isNull;
6633 lodash.isNumber = isNumber;
6634 lodash.isObject = isObject;
6635 lodash.isPlainObject = isPlainObject;
6636 lodash.isRegExp = isRegExp;
6637 lodash.isString = isString;
6638 lodash.isUndefined = isUndefined;
6639 lodash.lastIndexOf = lastIndexOf;
6640 lodash.mixin = mixin;
6641 lodash.noConflict = noConflict;
6642 lodash.noop = noop;
6643 lodash.now = now;
6644 lodash.parseInt = parseInt;
6645 lodash.random = random;
6646 lodash.reduce = reduce;
6647 lodash.reduceRight = reduceRight;
6648 lodash.result = result;
6649 lodash.runInContext = runInContext;
6650 lodash.size = size;
6651 lodash.some = some;
6652 lodash.sortedIndex = sortedIndex;
6653 lodash.template = template;
6654 lodash.unescape = unescape;
6655 lodash.uniqueId = uniqueId;
6656
6657 // add aliases
6658 lodash.all = every;
6659 lodash.any = some;
6660 lodash.detect = find;
6661 lodash.findWhere = find;
6662 lodash.foldl = reduce;
6663 lodash.foldr = reduceRight;
6664 lodash.include = contains;
6665 lodash.inject = reduce;
6666
6667 mixin(function() {
6668 var source = {}
6669 forOwn(lodash, function(func, methodName) {
6670 if (!lodash.prototype[methodName]) {
6671 source[methodName] = func;
6672 }
6673 });
6674 return source;
6675 }(), false);
6676
6677 /*--------------------------------------------------------------------------*/
6678
6679 // add functions capable of returning wrapped and unwrapped values when chaining
6680 lodash.first = first;
6681 lodash.last = last;
6682 lodash.sample = sample;
6683
6684 // add aliases
6685 lodash.take = first;
6686 lodash.head = first;
6687
6688 forOwn(lodash, function(func, methodName) {
6689 var callbackable = methodName !== 'sample';
6690 if (!lodash.prototype[methodName]) {
6691 lodash.prototype[methodName]= function(n, guard) {
6692 var chainAll = this.__chain__,
6693 result = func(this.__wrapped__, n, guard);
6694
6695 return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
6696 ? result
6697 : new lodashWrapper(result, chainAll);
6698 };
6699 }
6700 });
6701
6702 /*--------------------------------------------------------------------------*/
6703
6704 /**
6705 * The semantic version number.
6706 *
6707 * @static
6708 * @memberOf _
6709 * @type string
6710 */
6711 lodash.VERSION = '2.4.1';
6712
6713 // add "Chaining" functions to the wrapper
6714 lodash.prototype.chain = wrapperChain;
6715 lodash.prototype.toString = wrapperToString;
6716 lodash.prototype.value = wrapperValueOf;
6717 lodash.prototype.valueOf = wrapperValueOf;
6718
6719 // add `Array` functions that return unwrapped values
6720 forEach(['join', 'pop', 'shift'], function(methodName) {
6721 var func = arrayRef[methodName];
6722 lodash.prototype[methodName] = function() {
6723 var chainAll = this.__chain__,
6724 result = func.apply(this.__wrapped__, arguments);
6725
6726 return chainAll
6727 ? new lodashWrapper(result, chainAll)
6728 : result;
6729 };
6730 });
6731
6732 // add `Array` functions that return the existing wrapped value
6733 forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
6734 var func = arrayRef[methodName];
6735 lodash.prototype[methodName] = function() {
6736 func.apply(this.__wrapped__, arguments);
6737 return this;
6738 };
6739 });
6740
6741 // add `Array` functions that return new wrapped values
6742 forEach(['concat', 'slice', 'splice'], function(methodName) {
6743 var func = arrayRef[methodName];
6744 lodash.prototype[methodName] = function() {
6745 return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
6746 };
6747 });
6748
6749 return lodash;
6750 }
6751
6752 /*--------------------------------------------------------------------------*/
6753
6754 // expose Lo-Dash
6755 var _ = runInContext();
6756
6757 // some AMD build optimizers like r.js check for condition patterns like the following:
6758 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
6759 // Expose Lo-Dash to the global object even when an AMD loader is present in
6760 // case Lo-Dash is loaded with a RequireJS shim config.
6761 // See http://requirejs.org/docs/api.html#config-shim
6762 root._ = _;
6763
6764 // define as an anonymous module so, through path mapping, it can be
6765 // referenced as the "underscore" module
6766 define(function() {
6767 return _;
6768 });
6769 }
6770 // check for `exports` after `define` in case a build optimizer adds an `exports` object
6771 else if (freeExports && freeModule) {
6772 // in Node.js or RingoJS
6773 if (moduleExports) {
6774 (freeModule.exports = _)._ = _;
6775 }
6776 // in Narwhal or Rhino -require
6777 else {
6778 freeExports._ = _;
6779 }
6780 }
6781 else {
6782 // in a browser or Rhino
6783 root._ = _;
6784 }
6785 }.call(this));